Allow negative value into the character sheet bonuses.
This commit is contained in:
parent
8d93d46cce
commit
d93ffd9499
8 changed files with 154 additions and 45 deletions
|
|
@ -63,6 +63,8 @@
|
|||
<string name="character_sheet_edit__skills__aid">Premiers soins</string>
|
||||
<string name="character_sheet_edit__occupation__title">Occupations</string>
|
||||
<string name="character_sheet_edit__occupation__add_action">Ajouter une occupation</string>
|
||||
<string name="character_sheet_edit__actions__name_label">Nom</string>
|
||||
<string name="character_sheet_edit__actions__action_label">Bonus</string>
|
||||
<string name="character_sheet_edit__magic__title">Compétences magiques</string>
|
||||
<string name="character_sheet_edit__magic__add_action">Ajouter une compétence magique</string>
|
||||
<string name="character_sheet_edit__delete__label">Supprimer</string>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class SkillValueComputationUseCase(
|
|||
baseSum
|
||||
}
|
||||
|
||||
return max(base + skill.bonus + skill.level - diminished, 0)
|
||||
return max(base + (skill.bonus ?: 0) + (skill.level ?: 0) - diminished, 0)
|
||||
}
|
||||
|
||||
fun computeRoll(
|
||||
|
|
@ -83,8 +83,8 @@ class SkillValueComputationUseCase(
|
|||
if (damageBonusInstructions is Instruction.Dice) {
|
||||
RollUseCase.roll(
|
||||
quantity = damageBonusInstructions.quantity,
|
||||
faces = damageBonusInstructions.faces
|
||||
) / 2
|
||||
faces = damageBonusInstructions.faces / 2,
|
||||
)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ data class CharacterSheet(
|
|||
val id: String,
|
||||
val label: String,
|
||||
val base: String,
|
||||
val bonus: Int,
|
||||
val level: Int,
|
||||
val bonus: Int?,
|
||||
val level: Int?,
|
||||
val occupation: Boolean,
|
||||
val used: Boolean,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ data class CharacterSheetJsonV1(
|
|||
val id: String,
|
||||
val label: String,
|
||||
val base: String,
|
||||
val bonus: Int,
|
||||
val level: Int,
|
||||
val bonus: Int?,
|
||||
val level: Int?,
|
||||
val occupation: Boolean,
|
||||
val used: Boolean,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.derivedStateOf
|
||||
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
|
||||
import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.common.occupation
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__cha
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__con
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__dex
|
||||
|
|
@ -53,7 +55,6 @@ import kotlin.math.min
|
|||
class CharacterSheetEditFactory(
|
||||
private val bonusDamageUseCase: DamageBonusUseCase,
|
||||
private val skillFactory: SkillFieldFactory,
|
||||
private val parser: ArithmeticParser,
|
||||
) {
|
||||
fun updateCharacterSheet(
|
||||
currentSheet: CharacterSheet?,
|
||||
|
|
@ -92,9 +93,9 @@ class CharacterSheetEditFactory(
|
|||
CharacterSheet.Skill(
|
||||
id = editedSkill.id,
|
||||
label = editedSkill.label,
|
||||
base = "${editedSkill.base}",
|
||||
bonus = editedSkill.bonus.value.value.toIntOrNull() ?: 0,
|
||||
level = editedSkill.level.value.value.toIntOrNull() ?: 0,
|
||||
base = "${editedSkill.base.value}",
|
||||
bonus = editedSkill.bonus.value.value.toIntOrNull(),
|
||||
level = editedSkill.level.value.value.toIntOrNull(),
|
||||
occupation = editedSkill.option.checked.value,
|
||||
used = currentSkill?.used ?: false,
|
||||
)
|
||||
|
|
@ -107,8 +108,8 @@ class CharacterSheetEditFactory(
|
|||
id = editedSkill.id,
|
||||
label = editedSkill.label.value.value,
|
||||
base = editedSkill.base.value.value,
|
||||
bonus = editedSkill.bonus.value.value.toIntOrNull() ?: 0,
|
||||
level = editedSkill.level.value.value.toIntOrNull() ?: 0,
|
||||
bonus = editedSkill.bonus.value.value.toIntOrNull(),
|
||||
level = editedSkill.level.value.value.toIntOrNull(),
|
||||
occupation = editedSkill.options.occupation,
|
||||
used = currentSkill?.used ?: false,
|
||||
)
|
||||
|
|
@ -121,17 +122,17 @@ class CharacterSheetEditFactory(
|
|||
id = editedSkill.id,
|
||||
label = editedSkill.label.value.value,
|
||||
base = editedSkill.base.value.value,
|
||||
bonus = editedSkill.bonus.value.value.toIntOrNull() ?: 0,
|
||||
level = editedSkill.level.value.value.toIntOrNull() ?: 0,
|
||||
bonus = editedSkill.bonus.value.value.toIntOrNull(),
|
||||
level = editedSkill.level.value.value.toIntOrNull(),
|
||||
occupation = editedSkill.options.occupation,
|
||||
used = currentSkill?.used ?: false,
|
||||
)
|
||||
},
|
||||
actions = editedSheet.actions.map {
|
||||
CharacterSheet.Roll(
|
||||
id = "", // TODO
|
||||
label = it.label.value,
|
||||
roll = it.unpack(),
|
||||
id = it.id,
|
||||
label = it.label.value.value,
|
||||
roll = it.action.value.value,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -139,7 +140,7 @@ class CharacterSheetEditFactory(
|
|||
|
||||
suspend fun convertToUio(
|
||||
sheet: CharacterSheet?,
|
||||
onDeleteSkill: (skillId: String) -> Unit,
|
||||
onDeleteSkill: (id: String) -> Unit,
|
||||
): CharacterSheetEditPageUio {
|
||||
val str = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__str),
|
||||
|
|
@ -149,27 +150,27 @@ class CharacterSheetEditFactory(
|
|||
val dex = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__dex),
|
||||
initialValue = sheet?.dexterity?.toString() ?: "",
|
||||
valuePlaceHolder = { "11" }
|
||||
valuePlaceHolder = { "10" }
|
||||
)
|
||||
val con = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__con),
|
||||
initialValue = sheet?.constitution?.toString() ?: "",
|
||||
valuePlaceHolder = { "15" }
|
||||
valuePlaceHolder = { "10" }
|
||||
)
|
||||
val hei = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__hei),
|
||||
initialValue = sheet?.height?.toString() ?: "",
|
||||
valuePlaceHolder = { "13" }
|
||||
valuePlaceHolder = { "10" }
|
||||
)
|
||||
val int = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__int),
|
||||
initialValue = sheet?.intelligence?.toString() ?: "",
|
||||
valuePlaceHolder = { "9" }
|
||||
valuePlaceHolder = { "10" }
|
||||
)
|
||||
val pow = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__pow),
|
||||
initialValue = sheet?.power?.toString() ?: "",
|
||||
valuePlaceHolder = { "15" }
|
||||
valuePlaceHolder = { "10" }
|
||||
)
|
||||
val cha = FieldUio.create(
|
||||
initialLabel = getString(Res.string.character_sheet_edit__characteristics__cha),
|
||||
|
|
@ -339,8 +340,8 @@ class CharacterSheetEditFactory(
|
|||
label = specialSkillsLabel,
|
||||
labelValue = skill.label,
|
||||
baseValue = skill.base,
|
||||
bonusValue = skill.bonus.takeIf { it > 0 }?.toString() ?: "",
|
||||
levelValue = skill.level.takeIf { it > 0 }?.toString() ?: "",
|
||||
bonusValue = skill.bonus?.toString() ?: "",
|
||||
levelValue = skill.level?.toString() ?: "",
|
||||
options = run {
|
||||
val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
|
||||
listOf(
|
||||
|
|
@ -356,8 +357,8 @@ class CharacterSheetEditFactory(
|
|||
label = magicSkillsLabel,
|
||||
labelValue = skill.label,
|
||||
baseValue = skill.base,
|
||||
bonusValue = skill.bonus.takeIf { it > 0 }?.toString() ?: "",
|
||||
levelValue = skill.level.takeIf { it > 0 }?.toString() ?: "",
|
||||
bonusValue = skill.bonus?.toString() ?: "",
|
||||
levelValue = skill.level?.toString() ?: "",
|
||||
options = run {
|
||||
val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
|
||||
listOf(
|
||||
|
|
@ -367,7 +368,20 @@ class CharacterSheetEditFactory(
|
|||
},
|
||||
)
|
||||
} ?: emptyList(),
|
||||
actions = emptyList(),
|
||||
actions = sheet?.actions?.map { action ->
|
||||
ActionFieldUio(
|
||||
id = action.id,
|
||||
label = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__name_label),
|
||||
value = action.label,
|
||||
),
|
||||
action = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__action_label),
|
||||
value = action.roll,
|
||||
),
|
||||
option = skillFactory.deleteOption { onDeleteSkill(action.id) },
|
||||
)
|
||||
} ?: emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -385,17 +399,16 @@ class CharacterSheetEditFactory(
|
|||
base = base,
|
||||
bonus = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__bonus_label),
|
||||
value = skill?.bonus?.takeIf { it > 0 }?.toString() ?: "",
|
||||
value = skill?.bonus?.toString() ?: "",
|
||||
),
|
||||
level = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__level_label),
|
||||
value = skill?.level?.takeIf { it > 0 }?.toString() ?: "",
|
||||
value = skill?.level?.toString() ?: "",
|
||||
),
|
||||
option = skillFactory.occupationOption(skill?.occupation ?: false),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private inline fun <reified T> FieldUio.unpack(): T {
|
||||
val tmp = value.value.ifBlank { valuePlaceHolder.value }
|
||||
return when (T::class) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Icon
|
||||
|
|
@ -32,6 +33,8 @@ import com.pixelized.desktop.lwa.LocalWindowController
|
|||
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
|
||||
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
|
||||
import com.pixelized.desktop.lwa.navigation.window.LocalWindow
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionField
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillForm
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
|
||||
|
|
@ -74,7 +77,7 @@ data class CharacterSheetEditPageUio(
|
|||
val commonSkills: List<BaseSkillFieldUio>,
|
||||
val specialSkills: List<SkillFieldUio>,
|
||||
val magicSkills: List<SkillFieldUio>,
|
||||
val actions: List<FieldUio>,
|
||||
val actions: List<ActionFieldUio>,
|
||||
) {
|
||||
val characteristics
|
||||
get() = listOf(
|
||||
|
|
@ -340,12 +343,15 @@ fun CharacterSheetEdit(
|
|||
}
|
||||
}
|
||||
|
||||
form.actions.forEach {
|
||||
Form(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
valueWidth = 120.dp,
|
||||
field = it,
|
||||
)
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
form.actions.forEach {
|
||||
ActionField(
|
||||
modifier = Modifier.fillMaxWidth().padding(end = (4 + 2).dp),
|
||||
action = it
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ import androidx.lifecycle.ViewModel
|
|||
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetEditDestination
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_title
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_title
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
|
@ -73,10 +75,16 @@ class CharacterSheetEditViewModel(
|
|||
}
|
||||
|
||||
suspend fun onNewAction() {
|
||||
val field = FieldUio.create(
|
||||
initialLabel = "",
|
||||
isLabelEditable = true,
|
||||
valuePlaceHolder = { "" },
|
||||
val id = UUID.randomUUID().toString()
|
||||
val field = ActionFieldUio(
|
||||
id = id,
|
||||
label = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__name_label),
|
||||
),
|
||||
action = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__action_label),
|
||||
),
|
||||
option = skillFactory.deleteOption { deleteSkill(id) },
|
||||
)
|
||||
val actions = _characterSheet.value.actions.toMutableList().also {
|
||||
it.add(field)
|
||||
|
|
@ -94,6 +102,9 @@ class CharacterSheetEditViewModel(
|
|||
magicSkills = _characterSheet.value.magicSkills.toMutableList().also { skills ->
|
||||
skills.removeIf { it.id == skillId }
|
||||
},
|
||||
actions = _characterSheet.value.actions.toMutableList().also { actions ->
|
||||
actions.removeIf { it.id == skillId }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.DropDownActionMenuItem
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
|
||||
|
||||
@Stable
|
||||
data class ActionFieldUio(
|
||||
val id: String,
|
||||
val label: TextFieldWrapperUio,
|
||||
val action: TextFieldWrapperUio,
|
||||
val option: ActionOption.DeleteOptionUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun ActionField(
|
||||
modifier: Modifier = Modifier,
|
||||
action: ActionFieldUio,
|
||||
) {
|
||||
val showMenu = remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
TextFieldWrapper(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
wrapper = action.label,
|
||||
)
|
||||
TextFieldWrapper(
|
||||
modifier = Modifier.width(width = (192+4).dp),
|
||||
wrapper = action.action,
|
||||
)
|
||||
Box {
|
||||
IconButton(
|
||||
onClick = { showMenu.value = showMenu.value.not() },
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = showMenu.value,
|
||||
onDismissRequest = { showMenu.value = false }
|
||||
) {
|
||||
DropDownActionMenuItem(
|
||||
wrapper = action.option,
|
||||
onClick = {
|
||||
showMenu.value = false
|
||||
action.option.onOption()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue