Add flat value management for attack skill and spell.

This commit is contained in:
Andres Gomez, Thomas (ITDV RL) 2024-06-03 18:11:58 +02:00
parent 8e9529d4d0
commit 2cc1a0ea70
13 changed files with 262 additions and 119 deletions

View file

@ -843,7 +843,7 @@ class DiceThrowUseCase @Inject constructor(
) )
// fetch and build a list of additional level effect. // fetch and build a list of additional level effect.
val levelBonus = if (spell?.level != null) { val levelBonus = if (spell?.level?.dice != null) {
((spell.spell.level + 1)..level).map { ((spell.spell.level + 1)..level).map {
val localRoll = roll( val localRoll = roll(
amount = spell.level.dice.count, amount = spell.level.dice.count,

View file

@ -3,7 +3,7 @@ package com.pixelized.rplexicon.data.model.roll
import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.Property
class Throw( class Throw(
val dice: Dice, val dice: Dice?,
val flat: Flat?, val flat: Flat?,
val modifier: List<Property>, val modifier: List<Property>,
) )

View file

@ -10,14 +10,11 @@ class ThrowParser @Inject constructor(
) { ) {
fun parse(value: String?): Throw? { fun parse(value: String?): Throw? {
if (value != null) { if (value != null) {
val dice = diceParser.parse(value = value).firstOrNull() return Throw(
if (dice != null) { dice = diceParser.parse(value = value).firstOrNull(),
return Throw( flat = flatValueParser.parse(value = value),
dice = dice, modifier = modifierParser.parse(value = value),
flat = flatValueParser.parse(value = value), )
modifier = modifierParser.parse(value = value),
)
}
} }
return null return null
} }

View file

@ -32,6 +32,7 @@ import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.data.model.Attack import com.pixelized.rplexicon.data.model.Attack
import com.pixelized.rplexicon.ui.composable.AsyncImage import com.pixelized.rplexicon.ui.composable.AsyncImage
import com.pixelized.rplexicon.ui.screens.character.composable.common.DiceButton import com.pixelized.rplexicon.ui.screens.character.composable.common.DiceButton
import com.pixelized.rplexicon.ui.screens.character.composable.common.FlatValue
import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.pixelized.rplexicon.ui.theme.LexiconTheme
import com.pixelized.rplexicon.utilitary.extentions.uri import com.pixelized.rplexicon.utilitary.extentions.uri
@ -42,14 +43,22 @@ data class AttackUio(
val name: String, val name: String,
@StringRes val type: Int, @StringRes val type: Int,
val range: String?, val range: String?,
val hit: Dice?, val hit: Action?,
val damage: Dice?, val damage: Action?,
) { ) {
@Stable @Stable
class Dice( sealed class Action {
@DrawableRes val icon: Int, @Stable
val label: String, class Dice(
) @DrawableRes val icon: Int,
val label: String,
) : Action()
@Stable
class Flat(
val label: String,
) : Action()
}
} }
@Composable @Composable
@ -106,19 +115,31 @@ fun Attack(
Row( Row(
horizontalArrangement = Arrangement.spacedBy(space = 4.dp), horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
) { ) {
weapon.hit?.let { dice -> weapon.hit?.let { action ->
DiceButton( when (action) {
icon = dice.icon, is AttackUio.Action.Dice -> DiceButton(
text = dice.label, icon = action.icon,
onClick = { weapon.name.let(onHit) } text = action.label,
) onClick = { weapon.name.let(onHit) }
)
is AttackUio.Action.Flat -> FlatValue(
text = action.label,
)
}
} }
weapon.damage?.let { dice -> weapon.damage?.let { action ->
DiceButton( when (action) {
icon = dice.icon, is AttackUio.Action.Dice -> DiceButton(
text = dice.label, icon = action.icon,
onClick = { weapon.name.let(onDamage) } text = action.label,
) onClick = { weapon.name.let(onDamage) }
)
is AttackUio.Action.Flat -> FlatValue(
text = action.label,
)
}
} }
} }
} }
@ -147,19 +168,19 @@ private class WeaponPreviewProvider : PreviewParameterProvider<AttackUio> {
override val values: Sequence<AttackUio> = sequenceOf( override val values: Sequence<AttackUio> = sequenceOf(
AttackUio( AttackUio(
icon = R.drawable.ic_crossed_swords_24.uri.toUri(), icon = R.drawable.ic_crossed_swords_24.uri.toUri(),
name = "Dagger", name = "Sans arme",
type = R.string.attack_type_melee, type = R.string.attack_type_melee,
range = "5 ft reach", range = "5 ft reach",
hit = AttackUio.Dice(icon = R.drawable.ic_d20_24, label = "1d20"), hit = AttackUio.Action.Dice(icon = R.drawable.ic_d20_24, label = "1d20"),
damage = AttackUio.Dice(icon = R.drawable.ic_d8_24, label = "1d8"), damage = AttackUio.Action.Flat(label = "1"),
), ),
AttackUio( AttackUio(
icon = R.drawable.ic_pocket_bow_24.uri.toUri(), icon = R.drawable.ic_pocket_bow_24.uri.toUri(),
name = "Long bow", name = "Long bow",
type = R.string.attack_type_range, type = R.string.attack_type_range,
range = "30 ft reach", range = "30 ft reach",
hit = AttackUio.Dice(icon = R.drawable.ic_d20_24, label = "1d20+5"), hit = AttackUio.Action.Dice(icon = R.drawable.ic_d20_24, label = "1d20+5"),
damage = AttackUio.Dice(icon = R.drawable.ic_d8_24, label = "1d8+3"), damage = AttackUio.Action.Dice(icon = R.drawable.ic_d8_24, label = "1d8+3"),
), ),
) )
} }

View file

@ -33,6 +33,7 @@ import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.composable.AsyncImage import com.pixelized.rplexicon.ui.composable.AsyncImage
import com.pixelized.rplexicon.ui.screens.character.composable.common.CounterButton import com.pixelized.rplexicon.ui.screens.character.composable.common.CounterButton
import com.pixelized.rplexicon.ui.screens.character.composable.common.DiceButton import com.pixelized.rplexicon.ui.screens.character.composable.common.DiceButton
import com.pixelized.rplexicon.ui.screens.character.composable.common.FlatValue
import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.pixelized.rplexicon.ui.theme.LexiconTheme
@Stable @Stable
@ -42,15 +43,24 @@ data class SkillItemUio(
val translate: String?, val translate: String?,
val rest: String?, val rest: String?,
val cost: String?, val cost: String?,
val effect: Dice?, val effect: Action?,
val value: Int?, val value: Int?,
val max: Int?, val max: Int?,
val haveDetail: Boolean, val haveDetail: Boolean,
) { ) {
class Dice( @Stable
@DrawableRes val icon: Int, sealed class Action {
val label: String, @Stable
) class Dice(
@DrawableRes val icon: Int,
val label: String,
) : Action()
@Stable
class Flat(
val label: String,
) : Action()
}
} }
@Composable @Composable
@ -131,11 +141,17 @@ fun SkillItem(
} }
skill.effect?.let { effect -> skill.effect?.let { effect ->
DiceButton( when (effect) {
icon = effect.icon, is SkillItemUio.Action.Dice -> DiceButton(
text = effect.label, icon = effect.icon,
onClick = { onThrow(skill) }, text = effect.label,
) onClick = { onThrow(skill) },
)
is SkillItemUio.Action.Flat -> FlatValue(
text = effect.label,
)
}
} }
skill.max?.let { skill.max?.let {
@ -193,7 +209,7 @@ private class CounterItemPreviewProvider : PreviewParameterProvider<SkillItemUio
translate = "Mantle of Inspiration", translate = "Mantle of Inspiration",
rest = null, rest = null,
cost = "Inspiration bardique", cost = "Inspiration bardique",
effect = SkillItemUio.Dice(icon = R.drawable.ic_d6_24, label = "2d6"), effect = SkillItemUio.Action.Dice(icon = R.drawable.ic_d6_24, label = "2d6"),
value = null, value = null,
max = null, max = null,
haveDetail = true, haveDetail = true,

View file

@ -37,6 +37,7 @@ import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.data.model.Spell import com.pixelized.rplexicon.data.model.Spell
import com.pixelized.rplexicon.ui.composable.AsyncImage import com.pixelized.rplexicon.ui.composable.AsyncImage
import com.pixelized.rplexicon.ui.screens.character.composable.common.DiceButton import com.pixelized.rplexicon.ui.screens.character.composable.common.DiceButton
import com.pixelized.rplexicon.ui.screens.character.composable.common.FlatValue
import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.pixelized.rplexicon.ui.theme.LexiconTheme
import com.pixelized.rplexicon.utilitary.extentions.local.icon import com.pixelized.rplexicon.utilitary.extentions.local.icon
import com.pixelized.rplexicon.utilitary.extentions.uri import com.pixelized.rplexicon.utilitary.extentions.uri
@ -50,16 +51,25 @@ data class SpellUio(
val castingTime: String, val castingTime: String,
val range: String, val range: String,
val duration: String, val duration: String,
val hit: Dice?, val hit: Action?,
val effect: Dice?, val effect: Action?,
val changeWithLevel: Boolean, val changeWithLevel: Boolean,
val isWarlock: Boolean, val isWarlock: Boolean,
val ritual: Boolean, val ritual: Boolean,
) { ) {
class Dice( @Stable
@DrawableRes val icon: Int, sealed class Action {
val label: String, @Stable
) class Dice(
@DrawableRes val icon: Int,
val label: String,
) : Action()
@Stable
class Flat(
val label: String,
) : Action()
}
} }
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@ -173,14 +183,20 @@ fun Spell(
Row( Row(
horizontalArrangement = Arrangement.spacedBy(space = 4.dp), horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
) { ) {
spell.hit?.let { dice -> spell.hit?.let { action ->
DiceButton( when (action) {
icon = dice.icon, is SpellUio.Action.Dice -> DiceButton(
text = dice.label, icon = action.icon,
onClick = { spell.name.let(onHit) } text = action.label,
) onClick = { spell.name.let(onHit) }
)
is SpellUio.Action.Flat -> FlatValue(
text = action.label,
)
}
} }
spell.effect?.let { dice -> spell.effect?.let { action ->
when { when {
spell.changeWithLevel && spell.isWarlock.not() -> { spell.changeWithLevel && spell.isWarlock.not() -> {
OutlinedButton( OutlinedButton(
@ -196,19 +212,33 @@ fun Spell(
) )
} }
} }
spell.changeWithLevel && spell.isWarlock -> { spell.changeWithLevel && spell.isWarlock -> {
DiceButton( when (action) {
icon = dice.icon, is SpellUio.Action.Dice -> DiceButton(
text = dice.label, icon = action.icon,
onClick = { onCast(spell.name) }, text = action.label,
) onClick = { onCast(spell.name) },
)
is SpellUio.Action.Flat -> FlatValue(
text = action.label,
)
}
} }
else -> { else -> {
DiceButton( when (action) {
icon = dice.icon, is SpellUio.Action.Dice -> DiceButton(
text = dice.label, icon = action.icon,
onClick = { spell.name.let(onEffect) } text = action.label,
) onClick = { spell.name.let(onEffect) }
)
is SpellUio.Action.Flat -> FlatValue(
text = action.label,
)
}
} }
} }
} }
@ -246,11 +276,11 @@ private class SpellPreviewProvider : PreviewParameterProvider<SpellUio> {
castingTime = "1 action", castingTime = "1 action",
range = "36 mêtres", range = "36 mêtres",
duration = "instantanée", duration = "instantanée",
hit = SpellUio.Dice( hit = SpellUio.Action.Dice(
icon = R.drawable.ic_d20_24, icon = R.drawable.ic_d20_24,
label = "1d20+6", label = "1d20+6",
), ),
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d10_24, icon = R.drawable.ic_d10_24,
label = "1d10", label = "1d10",
), ),
@ -267,7 +297,7 @@ private class SpellPreviewProvider : PreviewParameterProvider<SpellUio> {
range = "18 mêtres", range = "18 mêtres",
duration = "instantanée", duration = "instantanée",
hit = null, hit = null,
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d10_24, icon = R.drawable.ic_d10_24,
label = "1d4", label = "1d4",
), ),
@ -284,7 +314,7 @@ private class SpellPreviewProvider : PreviewParameterProvider<SpellUio> {
range = "contact", range = "contact",
duration = "instantanée", duration = "instantanée",
hit = null, hit = null,
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d8_24, icon = R.drawable.ic_d8_24,
label = "1d8+3", label = "1d8+3",
), ),
@ -301,7 +331,7 @@ private class SpellPreviewProvider : PreviewParameterProvider<SpellUio> {
range = "contact", range = "contact",
duration = "instantanée", duration = "instantanée",
hit = null, hit = null,
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d8_24, icon = R.drawable.ic_d8_24,
label = "1d8+3", label = "1d8+3",
), ),

View file

@ -0,0 +1,42 @@
package com.pixelized.rplexicon.ui.screens.character.composable.common
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.pixelized.rplexicon.ui.theme.LexiconTheme
@Composable
fun FlatValue(
modifier: Modifier = Modifier,
text: String,
) {
Column(
modifier = modifier.minimumInteractiveComponentSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
style = MaterialTheme.typography.titleLarge,
text = text,
)
}
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun DiceButtonPreview() {
LexiconTheme {
Surface {
FlatValue(
text = "5",
)
}
}
}

View file

@ -17,16 +17,15 @@ fun rememberAttackListStatePreview(): State<List<AttackUio>> = remember {
listOf( listOf(
AttackUio( AttackUio(
icon = R.drawable.ic_crossed_swords_24.uri.toUri(), icon = R.drawable.ic_crossed_swords_24.uri.toUri(),
name = "Dagger", name = "Unarmed attack",
type = R.string.attack_type_melee, type = R.string.attack_type_melee,
range = "5 ft reach", range = "5 ft reach",
hit = AttackUio.Dice( hit = AttackUio.Action.Dice(
icon = R.drawable.ic_d20_24, icon = R.drawable.ic_d20_24,
label = "1d20", label = "1d20",
), ),
damage = AttackUio.Dice( damage = AttackUio.Action.Flat(
icon = R.drawable.ic_d8_24, label = "5",
label = "1d8",
), ),
), ),
AttackUio( AttackUio(
@ -34,11 +33,11 @@ fun rememberAttackListStatePreview(): State<List<AttackUio>> = remember {
name = "Long bow", name = "Long bow",
type = R.string.attack_type_range, type = R.string.attack_type_range,
range = "30 ft reach", range = "30 ft reach",
hit = AttackUio.Dice( hit = AttackUio.Action.Dice(
icon = R.drawable.ic_d20_24, icon = R.drawable.ic_d20_24,
label = "1d20+5", label = "1d20+5",
), ),
damage = AttackUio.Dice( damage = AttackUio.Action.Dice(
icon = R.drawable.ic_d8_24, icon = R.drawable.ic_d8_24,
label = "1d8+3" label = "1d8+3"
), ),

View file

@ -30,11 +30,11 @@ fun rememberSpellListStatePreview(): State<List<Pair<SpellHeaderUio, List<SpellU
castingTime = "1 action", castingTime = "1 action",
range = "36 mêtres", range = "36 mêtres",
duration = "instantanée", duration = "instantanée",
hit = SpellUio.Dice( hit = SpellUio.Action.Dice(
icon = R.drawable.ic_d20_24, icon = R.drawable.ic_d20_24,
label = "1d20+6", label = "1d20+6",
), ),
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d10_24, icon = R.drawable.ic_d10_24,
label = "1d10", label = "1d10",
), ),
@ -51,7 +51,7 @@ fun rememberSpellListStatePreview(): State<List<Pair<SpellHeaderUio, List<SpellU
range = "18 mêtres", range = "18 mêtres",
duration = "instantanée", duration = "instantanée",
hit = null, hit = null,
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d10_24, icon = R.drawable.ic_d10_24,
label = "1d4", label = "1d4",
), ),
@ -73,7 +73,7 @@ fun rememberSpellListStatePreview(): State<List<Pair<SpellHeaderUio, List<SpellU
range = "contact", range = "contact",
duration = "instantanée", duration = "instantanée",
hit = null, hit = null,
effect = SpellUio.Dice( effect = SpellUio.Action.Dice(
icon = R.drawable.ic_d8_24, icon = R.drawable.ic_d8_24,
label = "1d8+3", label = "1d8+3",
), ),

View file

@ -1,14 +1,14 @@
package com.pixelized.rplexicon.ui.screens.character.factory package com.pixelized.rplexicon.ui.screens.character.factory
import com.pixelized.rplexicon.R import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.data.model.alteration.Alteration
import com.pixelized.rplexicon.data.model.Attack import com.pixelized.rplexicon.data.model.Attack
import com.pixelized.rplexicon.data.model.CharacterSheet import com.pixelized.rplexicon.data.model.CharacterSheet
import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.Property
import com.pixelized.rplexicon.data.model.alteration.Alteration
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AttackUio import com.pixelized.rplexicon.ui.screens.character.composable.actions.AttackUio
import com.pixelized.rplexicon.utilitary.extentions.icon import com.pixelized.rplexicon.utilitary.extentions.icon
import com.pixelized.rplexicon.utilitary.extentions.toLabel
import com.pixelized.rplexicon.utilitary.extentions.modifier import com.pixelized.rplexicon.utilitary.extentions.modifier
import com.pixelized.rplexicon.utilitary.extentions.toLabel
import javax.inject.Inject import javax.inject.Inject
class AttackUioFactory @Inject constructor() { class AttackUioFactory @Inject constructor() {
@ -31,12 +31,18 @@ class AttackUioFactory @Inject constructor() {
Property.DEXTERITY -> characterSheet.dexterity.modifier Property.DEXTERITY -> characterSheet.dexterity.modifier
else -> 0 else -> 0
} }
} + hitAlteration } + hitAlteration + (diceThrow.flat?.value ?: 0)
// Build the UIO. // Build the UIO.
AttackUio.Dice( when (diceThrow.dice) {
icon = diceThrow.dice.icon, null -> AttackUio.Action.Flat(
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}", label = "$modifier",
) )
else -> AttackUio.Action.Dice(
icon = diceThrow.dice.icon,
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}",
)
}
} }
val damage = attack.damage?.let { diceThrow -> val damage = attack.damage?.let { diceThrow ->
@ -52,12 +58,18 @@ class AttackUioFactory @Inject constructor() {
Property.DEXTERITY -> characterSheet.dexterity.modifier Property.DEXTERITY -> characterSheet.dexterity.modifier
else -> 0 else -> 0
} }
} + damageAlteration } + damageAlteration + (diceThrow.flat?.value ?: 0)
// Build the UIO. // Build the UIO.
AttackUio.Dice( when (diceThrow.dice) {
icon = diceThrow.dice.icon, null -> AttackUio.Action.Flat(
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}", label = "$modifier",
) )
else -> AttackUio.Action.Dice(
icon = diceThrow.dice.icon,
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}"
)
}
} }
return AttackUio( return AttackUio(

View file

@ -7,11 +7,11 @@ import com.pixelized.rplexicon.data.network.CharacterSheetFire
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
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.toLabel
import com.pixelized.rplexicon.utilitary.extentions.local.base import com.pixelized.rplexicon.utilitary.extentions.local.base
import com.pixelized.rplexicon.utilitary.extentions.local.primary import com.pixelized.rplexicon.utilitary.extentions.local.primary
import com.pixelized.rplexicon.utilitary.extentions.local.secondary import com.pixelized.rplexicon.utilitary.extentions.local.secondary
import com.pixelized.rplexicon.utilitary.extentions.modifier import com.pixelized.rplexicon.utilitary.extentions.modifier
import com.pixelized.rplexicon.utilitary.extentions.toLabel
import javax.inject.Inject import javax.inject.Inject
class SkillFactoryUioFactory @Inject constructor( class SkillFactoryUioFactory @Inject constructor(
@ -49,11 +49,17 @@ class SkillFactoryUioFactory @Inject constructor(
translate = description?.original, translate = description?.original,
rest = skill.rest, rest = skill.rest,
cost = skill.cost, cost = skill.cost,
effect = skill.effect?.let { effect = when {
SkillItemUio.Dice( skill.effect?.dice != null -> SkillItemUio.Action.Dice(
icon = it.dice.icon, icon = skill.effect.dice.icon,
label = "${skill.effect.dice.toLabel()}${modifier.toLabel(true)}", label = "${skill.effect.dice.toLabel()}${modifier.toLabel(true)}",
) )
skill.effect != null -> SkillItemUio.Action.Flat(
label = "$modifier",
)
else -> null
}, },
value = fire?.skills?.get(skill.name) ?: 0, value = fire?.skills?.get(skill.name) ?: 0,
max = skill.amount, max = skill.amount,

View file

@ -1,13 +1,14 @@
package com.pixelized.rplexicon.ui.screens.character.factory package com.pixelized.rplexicon.ui.screens.character.factory
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.data.model.AssignedSpell import com.pixelized.rplexicon.data.model.AssignedSpell
import com.pixelized.rplexicon.data.model.CharacterSheet import com.pixelized.rplexicon.data.model.CharacterSheet
import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.Property
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SpellUio import com.pixelized.rplexicon.ui.screens.character.composable.actions.SpellUio
import com.pixelized.rplexicon.utilitary.extentions.icon import com.pixelized.rplexicon.utilitary.extentions.icon
import com.pixelized.rplexicon.utilitary.extentions.toLabel
import com.pixelized.rplexicon.utilitary.extentions.modifier import com.pixelized.rplexicon.utilitary.extentions.modifier
import com.pixelized.rplexicon.utilitary.extentions.toLabel
import javax.inject.Inject import javax.inject.Inject
class SpellUioFactory @Inject constructor( class SpellUioFactory @Inject constructor(
@ -28,11 +29,17 @@ class SpellUioFactory @Inject constructor(
Property.CHARISMA -> characterSheet.charisma.modifier Property.CHARISMA -> characterSheet.charisma.modifier
else -> 0 else -> 0
} }
} + (diceThrow.flat?.value ?: 0)
when (diceThrow.dice) {
null -> SpellUio.Action.Flat(
label = "$modifier",
)
else -> SpellUio.Action.Dice(
icon = diceThrow.dice.icon,
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}",
)
} }
SpellUio.Dice(
icon = diceThrow.dice.icon,
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}",
)
} }
val effect = assignedSpell.effect?.let { diceThrow -> val effect = assignedSpell.effect?.let { diceThrow ->
val modifier = diceThrow.modifier.sumOf { val modifier = diceThrow.modifier.sumOf {
@ -52,25 +59,38 @@ class SpellUioFactory @Inject constructor(
val delta = warlockSpellLevel?.minus(assignedSpell.spell.level) ?: 0 val delta = warlockSpellLevel?.minus(assignedSpell.spell.level) ?: 0
if (warlockSpellLevel == null || level == null || delta <= 0) { if (warlockSpellLevel == null || level == null || delta <= 0) {
// default case of non warlock character of the spell don't scale // default case of non warlock character of the spell don't scale
SpellUio.Dice( when (diceThrow.dice) {
icon = diceThrow.dice.icon, null -> SpellUio.Action.Flat(
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}", label = "$modifier",
) )
} else if (diceThrow.dice.faces == level.dice.faces) {
else -> SpellUio.Action.Dice(
icon = diceThrow.dice.icon,
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}",
)
}
} else if (diceThrow.dice?.faces == level.dice?.faces) {
// warlock character, upscale the spell to warlock spell level // warlock character, upscale the spell to warlock spell level
val upscaleModifier = modifier + (level.flat?.value ?: 0) * delta val upscaleModifier = modifier + (level.flat?.value ?: 0) * delta
val diceCount = diceThrow.dice.count + level.dice.count * delta val diceCount = (diceThrow.dice?.count ?: 0) + (level.dice?.count ?: 0) * delta
SpellUio.Dice(
icon = diceThrow.dice.icon, when (diceThrow.dice) {
label = "${diceCount}d${diceThrow.dice.faces}${upscaleModifier.toLabel(true)}", null -> SpellUio.Action.Flat(
) label = "$modifier",
)
else -> SpellUio.Action.Dice(
icon = diceThrow.dice.icon,
label = "${diceCount}d${diceThrow.dice.faces}${upscaleModifier.toLabel(true)}",
)
}
} else { } else {
// warlock character, case where the dice use to upscale is not the one from the spell. // warlock character, case where the dice use to upscale is not the one from the spell.
val deltaModifier = level.flat?.value?.times(delta) ?: 0 val deltaModifier = level.flat?.value?.times(delta) ?: 0
SpellUio.Dice( SpellUio.Action.Dice(
icon = diceThrow.dice.icon, icon = diceThrow.dice?.icon ?: R.drawable.ic_d4_24,
label = "${diceThrow.dice.toLabel()}${modifier.toLabel(true)}" + label = "${diceThrow.dice?.toLabel()}${modifier.toLabel(true)}" +
"+ ${level.dice.count * delta}d${level.dice.faces}${deltaModifier.toLabel(true)}", "+ ${level.dice?.count?.times(delta)}d${level.dice?.faces}${deltaModifier.toLabel(true)}",
) )
} }
} }

View file

@ -180,7 +180,7 @@ class SpellsViewModel @Inject constructor(
val modifierLabel = modifier val modifierLabel = modifier
.sumOf { modifier -> modifier.toValue(character = character) } .sumOf { modifier -> modifier.toValue(character = character) }
.let { if (it != 0) "${it.signLabel}${abs(it) * level}" else "" } .let { if (it != 0) "${it.signLabel}${abs(it) * level}" else "" }
return when (level > 0) { return when (level > 0 && dice != null) {
true -> "${dice.count * level}d${dice.faces}${modifierLabel}" true -> "${dice.count * level}d${dice.faces}${modifierLabel}"
else -> null else -> null
} }