Add support for Hp grow bonus and Leaning bonus.
This commit is contained in:
parent
3419afbe59
commit
ca20078ffa
18 changed files with 526 additions and 402 deletions
|
|
@ -1,8 +1,7 @@
|
|||
package com.pixelized.desktop.lwa
|
||||
|
||||
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
|
||||
import com.pixelized.desktop.lwa.business.CharacterSheetUseCase
|
||||
import com.pixelized.desktop.lwa.business.RollUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillStepUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
|
||||
import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
|
||||
|
|
@ -71,9 +70,8 @@ val parserDependencies
|
|||
|
||||
val useCaseDependencies
|
||||
get() = module {
|
||||
factoryOf(::DamageBonusUseCase)
|
||||
factoryOf(::SkillStepUseCase)
|
||||
factoryOf(::SkillNormalizerUseCase)
|
||||
factoryOf(::RollUseCase)
|
||||
factoryOf(::SkillValueComputationUseCase)
|
||||
factoryOf(::CharacterSheetUseCase)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package com.pixelized.desktop.lwa.business
|
||||
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
|
||||
class CharacterSheetUseCase {
|
||||
|
||||
fun normalize(value: Int): Int {
|
||||
return value - value % 5 // (truncate(value.toFloat() / 5f) * 5f).toInt()
|
||||
}
|
||||
|
||||
fun defaultMovement(): Int = 10
|
||||
|
||||
fun defaultMaxHp(
|
||||
constitution: Int,
|
||||
height: Int,
|
||||
): Int {
|
||||
return (ceil((constitution + height) / 2f).toInt())
|
||||
}
|
||||
|
||||
fun defaultMaxPower(
|
||||
power: Int,
|
||||
): Int {
|
||||
return power
|
||||
}
|
||||
|
||||
fun defaultDamageBonus(
|
||||
strength: Int,
|
||||
height: Int,
|
||||
): String {
|
||||
return defaultDamageBonus(sum = strength + height)
|
||||
}
|
||||
|
||||
fun defaultDamageBonus(
|
||||
sum: Int,
|
||||
): String {
|
||||
return when {
|
||||
sum < 12 -> "-1d6"
|
||||
sum in 12..17 -> "-1d4"
|
||||
sum in 18..22 -> "+0"
|
||||
sum in 23..29 -> "+1d4"
|
||||
sum in 30..39 -> "+1d6"
|
||||
else -> "+2d6"
|
||||
}
|
||||
}
|
||||
|
||||
fun defaultArmor(): Int = 0
|
||||
|
||||
fun defaultLearning(intelligence: Int): Int {
|
||||
return max(0, (intelligence - 10) * 2)
|
||||
}
|
||||
|
||||
fun defaultHpGrow(constitution: Int): Int {
|
||||
return (constitution / 3)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package com.pixelized.desktop.lwa.business
|
||||
|
||||
class DamageBonusUseCase {
|
||||
|
||||
fun bonusDamage(strength: Int, height: Int): String {
|
||||
return bonusDamage(stat = strength + height)
|
||||
}
|
||||
|
||||
fun bonusDamage(stat: Int): String {
|
||||
return when {
|
||||
stat < 12 -> "-1d6"
|
||||
stat in 12..17 -> "-1d4"
|
||||
stat in 18..22 -> "+0"
|
||||
stat in 23..29 -> "+1d4"
|
||||
stat in 30..39 -> "+1d6"
|
||||
else -> "+2d6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,10 +7,6 @@ import kotlin.math.min
|
|||
|
||||
class RollUseCase {
|
||||
|
||||
fun rollD100(): Int {
|
||||
return roll(modifier = null, quantity = 1, faces = 100)
|
||||
}
|
||||
|
||||
fun roll(dice: Instruction.Dice): Int {
|
||||
return roll(
|
||||
modifier = dice.modifier,
|
||||
|
|
@ -19,9 +15,13 @@ class RollUseCase {
|
|||
)
|
||||
}
|
||||
|
||||
fun roll(modifier: Instruction.Dice.Modifier?, quantity: Int, faces: Int): Int {
|
||||
fun roll(
|
||||
modifier: Instruction.Dice.Modifier? = null,
|
||||
quantity: Int = 1,
|
||||
faces: Int,
|
||||
): Int {
|
||||
print("{")
|
||||
return sum(count = quantity) {
|
||||
return sum(count = quantity) { left ->
|
||||
when (modifier) {
|
||||
Instruction.Dice.Modifier.ADVANTAGE -> {
|
||||
val roll1 = roll(faces = faces)
|
||||
|
|
@ -54,6 +54,8 @@ class RollUseCase {
|
|||
null -> {
|
||||
roll(faces = faces).also { print("$it") }
|
||||
}
|
||||
}.also {
|
||||
if (quantity > 1 && left != 1) print(",")
|
||||
}
|
||||
}.also {
|
||||
print("}:")
|
||||
|
|
@ -61,14 +63,14 @@ class RollUseCase {
|
|||
}
|
||||
|
||||
private fun roll(faces: Int): Int {
|
||||
return (Math.random() * faces.toDouble() + 1).toInt()
|
||||
return (Math.random() * faces.toDouble() + 1.0).toInt()
|
||||
}
|
||||
|
||||
private fun sum(count: Int, block: () -> Int): Int {
|
||||
private fun sum(count: Int, block: (Int) -> Int): Int {
|
||||
return if (count > 1) {
|
||||
block() + sum(count - 1, block)
|
||||
block(count) + sum(count - 1, block)
|
||||
} else {
|
||||
block()
|
||||
block(count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
package com.pixelized.desktop.lwa.business
|
||||
|
||||
import kotlin.math.truncate
|
||||
|
||||
class SkillNormalizerUseCase {
|
||||
fun normalize(value: Int): Int {
|
||||
return (truncate(value.toFloat() / 5f) * 5f).toInt()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,15 @@
|
|||
package com.pixelized.desktop.lwa.parser.arithmetic
|
||||
|
||||
sealed class Instruction(
|
||||
val sign: Int,
|
||||
) {
|
||||
class Dice(
|
||||
sign: Int,
|
||||
sealed class Instruction {
|
||||
abstract val sign: Int
|
||||
|
||||
data class Dice(
|
||||
override val sign: Int,
|
||||
val modifier: Modifier?,
|
||||
val quantity: Int,
|
||||
val faces: Int,
|
||||
) : Instruction(
|
||||
sign = sign,
|
||||
) {
|
||||
) : Instruction() {
|
||||
|
||||
enum class Modifier {
|
||||
ADVANTAGE,
|
||||
DISADVANTAGE,
|
||||
|
|
@ -29,23 +28,20 @@ sealed class Instruction(
|
|||
}
|
||||
}
|
||||
|
||||
class Flat(
|
||||
sign: Int,
|
||||
data class Flat(
|
||||
override val sign: Int,
|
||||
val value: Int,
|
||||
) : Instruction(
|
||||
sign = sign,
|
||||
) {
|
||||
) : Instruction() {
|
||||
override fun toString(): String {
|
||||
return "${sign.sign}${value}"
|
||||
}
|
||||
}
|
||||
|
||||
class Word(
|
||||
sign: Int,
|
||||
data class Word(
|
||||
override val sign: Int,
|
||||
val type: Type,
|
||||
) : Instruction(
|
||||
sign = sign
|
||||
) {
|
||||
) : Instruction() {
|
||||
|
||||
enum class Type {
|
||||
BDC, // Damages bonus for melee
|
||||
BDD, // Damages bonus for range
|
||||
|
|
|
|||
|
|
@ -1,34 +1,13 @@
|
|||
package com.pixelized.desktop.lwa.repository.characterSheet
|
||||
|
||||
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
|
||||
import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
|
||||
import com.pixelized.desktop.lwa.business.CharacterSheetUseCase
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJson
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJsonV1
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__acrobatics
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__aid
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__athletics
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__bargain
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__combat
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__discretion
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__dodge
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__empathy
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__grab
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__intimidation
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__perception
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__persuasion
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__search
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__sleight_of_hand
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__spiel
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__throw
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import kotlin.math.ceil
|
||||
|
||||
class CharacterSheetJsonFactory(
|
||||
private val bonusDamageUseCase: DamageBonusUseCase,
|
||||
private val skillDescriptionFactory: SkillDescriptionFactory,
|
||||
private val characterSheetUseCase: CharacterSheetUseCase,
|
||||
) {
|
||||
|
||||
fun convertToJson(
|
||||
|
|
@ -51,6 +30,8 @@ class CharacterSheetJsonFactory(
|
|||
maxPP = if (sheet.overrideMaxPP) sheet.maxPp else null,
|
||||
damageBonus = if (sheet.overrideDamageBonus) sheet.damageBonus else null,
|
||||
armor = if (sheet.overrideArmor) sheet.armor else null,
|
||||
learning = if (sheet.overrideLearning) sheet.learning else null,
|
||||
hpGrowf = if (sheet.overrideHpGrow) sheet.hpGrow else null,
|
||||
skills = sheet.commonSkills.map {
|
||||
CharacterSheetJsonV1.Skill(
|
||||
id = it.id,
|
||||
|
|
@ -108,8 +89,8 @@ class CharacterSheetJsonFactory(
|
|||
|
||||
private suspend fun convertFromV1(
|
||||
json: CharacterSheetJsonV1,
|
||||
): CharacterSheet {
|
||||
val sheet = CharacterSheet(
|
||||
): CharacterSheet = characterSheetUseCase.run {
|
||||
CharacterSheet(
|
||||
id = json.id,
|
||||
name = json.name,
|
||||
strength = json.strength,
|
||||
|
|
@ -120,21 +101,27 @@ class CharacterSheetJsonFactory(
|
|||
power = json.power,
|
||||
charisma = json.charisma,
|
||||
overrideMovement = json.movement != null,
|
||||
movement = json.movement ?: 10,
|
||||
movement = json.movement ?: defaultMovement(),
|
||||
currentHp = json.currentHp,
|
||||
overrideMaxHp = json.maxHp != null,
|
||||
maxHp = json.maxHp ?: (ceil((json.constitution + json.height) / 2f).toInt()),
|
||||
maxHp = json.maxHp ?: defaultMaxHp(
|
||||
constitution = json.constitution,
|
||||
height = json.height,
|
||||
),
|
||||
currentPp = json.currentPP,
|
||||
overrideMaxPP = json.maxPP != null,
|
||||
maxPp = json.maxPP ?: json.power,
|
||||
maxPp = json.maxPP ?: defaultMaxPower(power = json.power),
|
||||
overrideDamageBonus = json.damageBonus != null,
|
||||
damageBonus = json.damageBonus
|
||||
?: bonusDamageUseCase.bonusDamage(
|
||||
strength = json.strength,
|
||||
height = json.height
|
||||
),
|
||||
damageBonus = json.damageBonus ?: defaultDamageBonus(
|
||||
strength = json.strength,
|
||||
height = json.height,
|
||||
),
|
||||
overrideArmor = json.armor != null,
|
||||
armor = json.armor ?: 0,
|
||||
armor = json.armor ?: defaultArmor(),
|
||||
overrideLearning = json.learning != null,
|
||||
learning = json.learning ?: defaultLearning(intelligence = json.intelligence),
|
||||
overrideHpGrow = json.hpGrowf != null,
|
||||
hpGrow = json.hpGrowf ?: defaultHpGrow(constitution = json.constitution),
|
||||
commonSkills = json.skills.map {
|
||||
CharacterSheet.Skill(
|
||||
id = it.id,
|
||||
|
|
@ -179,6 +166,5 @@ class CharacterSheetJsonFactory(
|
|||
)
|
||||
},
|
||||
)
|
||||
return sheet
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,10 @@ data class CharacterSheet(
|
|||
val damageBonus: String,
|
||||
val overrideArmor: Boolean,
|
||||
val armor: Int,
|
||||
val overrideLearning: Boolean,
|
||||
val learning: Int,
|
||||
val overrideHpGrow: Boolean,
|
||||
val hpGrow: Int,
|
||||
// skills
|
||||
val commonSkills: List<Skill>,
|
||||
val specialSkills: List<Skill>,
|
||||
|
|
@ -80,5 +84,7 @@ data class CharacterSheet(
|
|||
const val PP = "PP"
|
||||
const val DMG = "DMG"
|
||||
const val ARMOR = "ARMOR"
|
||||
const val LB = "LEARNING"
|
||||
const val GHP = "HP_GROW"
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,8 @@ data class CharacterSheetJsonV1(
|
|||
val maxPP: Int?,
|
||||
val damageBonus: String?,
|
||||
val armor: Int?,
|
||||
val learning: Int?,
|
||||
val hpGrowf: Int?,
|
||||
// skills
|
||||
val skills: List<Skill>,
|
||||
// occupations
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__charact
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__armor
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__damage_bonus
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hp_grow
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__learning
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__movement
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__power_point
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__charisma
|
||||
|
|
@ -30,6 +32,8 @@ import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics
|
|||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__armor
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__bonus_damage
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hp_grow
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__learning
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__movement
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__power_point
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
|
@ -171,6 +175,26 @@ class CharacterSheetFactory(
|
|||
),
|
||||
editable = false,
|
||||
),
|
||||
Characteristic(
|
||||
id = CharacteristicId.LB,
|
||||
label = getString(Res.string.character_sheet__sub_characteristics__learning),
|
||||
value = "${sheet.learning}",
|
||||
tooltips = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__learning),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__learning),
|
||||
),
|
||||
editable = false,
|
||||
),
|
||||
Characteristic(
|
||||
id = CharacteristicId.GHP,
|
||||
label = getString(Res.string.character_sheet__sub_characteristics__hp_grow),
|
||||
value = "${sheet.hpGrow}",
|
||||
tooltips = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__hp_grow),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__hp_grow),
|
||||
),
|
||||
editable = false,
|
||||
),
|
||||
),
|
||||
commonSkills = sheet.commonSkills.map { skill ->
|
||||
Node(
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ package com.pixelized.desktop.lwa.screen.characterSheet.edit
|
|||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
|
||||
import com.pixelized.desktop.lwa.business.CharacterSheetUseCase
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
|
||||
|
|
@ -45,27 +44,26 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sk
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__armor
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__damage_bonus
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hp_grow
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__learning
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__max_hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__max_power_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__movement
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import java.util.UUID
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class CharacterSheetEditFactory(
|
||||
private val bonusDamageUseCase: DamageBonusUseCase,
|
||||
private val characterSheetUseCase: CharacterSheetUseCase,
|
||||
private val skillFieldFactory: SkillFieldFactory,
|
||||
private val skillDescriptionFactory: SkillDescriptionFactory,
|
||||
private val normalizer: SkillNormalizerUseCase,
|
||||
) {
|
||||
suspend fun updateCharacterSheet(
|
||||
currentSheet: CharacterSheet?,
|
||||
editedSheet: CharacterSheetEditPageUio,
|
||||
): CharacterSheet {
|
||||
val editedMaxHp = editedSheet.maxHp.unpack()?.toIntOrNull() ?: currentSheet?.maxHp ?: 0
|
||||
val editedMaxPp = editedSheet.maxPp.unpack()?.toIntOrNull() ?: currentSheet?.maxPp ?: 0
|
||||
return CharacterSheet(
|
||||
id = editedSheet.id,
|
||||
name = editedSheet.name.value.value,
|
||||
|
|
@ -95,19 +93,11 @@ class CharacterSheetEditFactory(
|
|||
?: currentSheet?.movement
|
||||
?: 10,
|
||||
overrideMaxHp = editedSheet.maxHp.value.value.value.isNotBlank(),
|
||||
maxHp = editedSheet.maxHp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.maxHp
|
||||
?: 0,
|
||||
currentHp = editedSheet.currentHp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.currentHp
|
||||
?: 0,
|
||||
maxHp = editedMaxHp,
|
||||
currentHp = currentSheet?.currentHp?.coerceAtMost(editedMaxHp) ?: editedMaxHp,
|
||||
overrideMaxPP = editedSheet.maxPp.value.value.value.isNotBlank(),
|
||||
maxPp = editedSheet.maxPp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.maxPp
|
||||
?: 0,
|
||||
currentPp = editedSheet.currentPp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.currentPp
|
||||
?: 0,
|
||||
maxPp = editedMaxPp,
|
||||
currentPp = currentSheet?.currentPp?.coerceAtMost(editedMaxPp) ?: editedMaxPp,
|
||||
overrideDamageBonus = editedSheet.damageBonus.value.value.value.isNotBlank(),
|
||||
damageBonus = editedSheet.damageBonus.unpack()
|
||||
?: currentSheet?.damageBonus
|
||||
|
|
@ -116,6 +106,10 @@ class CharacterSheetEditFactory(
|
|||
armor = editedSheet.armor.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.armor
|
||||
?: 0,
|
||||
overrideLearning = editedSheet.learning.value.value.value.isNotBlank(),
|
||||
learning = editedSheet.learning.unpack()?.toIntOrNull() ?: 0,
|
||||
overrideHpGrow = editedSheet.hpGrow.value.value.value.isNotBlank(),
|
||||
hpGrow = editedSheet.hpGrow.unpack()?.toIntOrNull() ?: 0,
|
||||
commonSkills = editedSheet.commonSkills.map { editedSkill ->
|
||||
val currentSkill = currentSheet?.commonSkills?.firstOrNull {
|
||||
it.id == editedSkill.id
|
||||
|
|
@ -236,239 +230,243 @@ class CharacterSheetEditFactory(
|
|||
val specialSkillsLabel = getString(Res.string.character_sheet_edit__skills__special_title)
|
||||
val magicSkillsLabel = getString(Res.string.character_sheet_edit__skills__magic_title)
|
||||
|
||||
val maxHitPoint = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_hit_point),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
|
||||
placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" },
|
||||
)
|
||||
)
|
||||
val maxPowerPoint = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_power_point),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
|
||||
placeholder = derivedStateOf { "${pow()}" },
|
||||
)
|
||||
)
|
||||
|
||||
return CharacterSheetEditPageUio(
|
||||
id = sheet?.id ?: UUID.randomUUID().toString(),
|
||||
name = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
|
||||
value = sheet?.name ?: ""
|
||||
),
|
||||
strength = str,
|
||||
dexterity = dex,
|
||||
constitution = con,
|
||||
height = hei,
|
||||
intelligence = int,
|
||||
power = pow,
|
||||
charisma = cha,
|
||||
movement = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__movement),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideMovement == true) "${sheet.movement}" else "",
|
||||
placeholder = mutableStateOf("10"),
|
||||
)
|
||||
),
|
||||
maxHp = maxHitPoint,
|
||||
currentHp = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
enable = false,
|
||||
placeholder = derivedStateOf {
|
||||
val min = min(
|
||||
sheet?.currentHp ?: Int.MAX_VALUE,
|
||||
maxHitPoint.unpack()?.toIntOrNull() ?: Int.MAX_VALUE,
|
||||
)
|
||||
if (min != Int.MAX_VALUE) "$min" else ""
|
||||
},
|
||||
)
|
||||
),
|
||||
maxPp = maxPowerPoint,
|
||||
currentPp = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
enable = false,
|
||||
placeholder = derivedStateOf {
|
||||
val min = min(
|
||||
sheet?.currentPp ?: Int.MAX_VALUE,
|
||||
maxPowerPoint.unpack()?.toIntOrNull() ?: Int.MAX_VALUE,
|
||||
)
|
||||
if (min != Int.MAX_VALUE) "$min" else ""
|
||||
},
|
||||
)
|
||||
),
|
||||
damageBonus = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideDamageBonus == true) sheet.damageBonus else "",
|
||||
placeholder = derivedStateOf {
|
||||
bonusDamageUseCase.bonusDamage(
|
||||
strength = str(),
|
||||
height = hei()
|
||||
)
|
||||
},
|
||||
)
|
||||
),
|
||||
armor = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__armor),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideArmor == true) "${sheet.armor}" else "",
|
||||
placeholder = mutableStateOf("0"),
|
||||
)
|
||||
),
|
||||
commonSkills = listOf(
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.COMBAT_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__combat),
|
||||
base = derivedStateOf { normalizer.normalize(dex() * 2) },
|
||||
return with(characterSheetUseCase) {
|
||||
CharacterSheetEditPageUio(
|
||||
id = sheet?.id ?: UUID.randomUUID().toString(),
|
||||
name = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
|
||||
value = sheet?.name ?: ""
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.DODGE_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__dodge),
|
||||
base = derivedStateOf { normalizer.normalize(dex() * 2) },
|
||||
strength = str,
|
||||
dexterity = dex,
|
||||
constitution = con,
|
||||
height = hei,
|
||||
intelligence = int,
|
||||
power = pow,
|
||||
charisma = cha,
|
||||
movement = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__movement),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideMovement == true) "${sheet.movement}" else "",
|
||||
placeholder = derivedStateOf {
|
||||
"${characterSheetUseCase.defaultMovement()}"
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.GRAB_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__grab),
|
||||
base = derivedStateOf { normalizer.normalize(str() + hei()) },
|
||||
maxHp = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_hit_point),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
|
||||
placeholder = derivedStateOf {
|
||||
"${
|
||||
characterSheetUseCase.defaultMaxHp(
|
||||
constitution = con(),
|
||||
height = hei()
|
||||
)
|
||||
}"
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.THROW_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__throw),
|
||||
base = derivedStateOf { normalizer.normalize(str() + dex()) },
|
||||
maxPp = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_power_point),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
|
||||
placeholder = derivedStateOf {
|
||||
"${characterSheetUseCase.defaultMaxPower(power = pow())}"
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.ATHLETICS_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__athletics),
|
||||
base = derivedStateOf { normalizer.normalize(str() + con() * 2) },
|
||||
damageBonus = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideDamageBonus == true) sheet.damageBonus else "",
|
||||
placeholder = derivedStateOf {
|
||||
characterSheetUseCase.defaultDamageBonus(
|
||||
strength = str(),
|
||||
height = hei()
|
||||
)
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.ACROBATICS_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__acrobatics),
|
||||
base = derivedStateOf { normalizer.normalize(dex() + con() * 2) },
|
||||
armor = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__armor),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideArmor == true) "${sheet.armor}" else "",
|
||||
placeholder = derivedStateOf {
|
||||
"${characterSheetUseCase.defaultArmor()}"
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.PERCEPTION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__perception),
|
||||
base = derivedStateOf { normalizer.normalize(10 + int() * 2) },
|
||||
learning = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__learning),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideLearning == true) "${sheet.learning}" else "",
|
||||
placeholder = derivedStateOf {
|
||||
"${characterSheetUseCase.defaultLearning(intelligence = int())}"
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SEARCH_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__search),
|
||||
base = derivedStateOf { normalizer.normalize(10 + int() * 2) },
|
||||
hpGrow = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__hp_grow),
|
||||
value = skillFieldFactory.createWrapper(
|
||||
value = if (sheet?.overrideHpGrow == true) "${sheet.hpGrow}" else "",
|
||||
placeholder = derivedStateOf {
|
||||
"${characterSheetUseCase.defaultHpGrow(constitution = con())}"
|
||||
},
|
||||
)
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.EMPATHY_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__empathy),
|
||||
base = derivedStateOf { normalizer.normalize(cha() + int()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.PERSUASION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__persuasion),
|
||||
base = derivedStateOf { normalizer.normalize(cha() * 3) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.INTIMIDATION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__intimidation),
|
||||
base = derivedStateOf { normalizer.normalize(cha() + max(pow(), hei()) * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SPIEL_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__spiel),
|
||||
base = derivedStateOf { normalizer.normalize(cha() * 2 + int()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.BARGAIN_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__bargain),
|
||||
base = derivedStateOf { normalizer.normalize(cha() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.DISCRETION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__discretion),
|
||||
base = derivedStateOf { normalizer.normalize(cha() + dex() * 2 - hei()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__sleight_of_hand),
|
||||
base = derivedStateOf { normalizer.normalize(dex() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.AID_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__aid),
|
||||
base = derivedStateOf { normalizer.normalize(int() + dex()) },
|
||||
),
|
||||
),
|
||||
specialSkills = sheet?.specialSkills?.map { skill ->
|
||||
skillFieldFactory.createSkill(
|
||||
id = skill.id,
|
||||
label = specialSkillsLabel,
|
||||
descriptionValue = skill.description ?: "",
|
||||
labelValue = skill.label,
|
||||
baseValue = skill.base,
|
||||
bonusValue = skill.bonus ?: "",
|
||||
levelValue = skill.level ?: "",
|
||||
options = run {
|
||||
val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
|
||||
listOf(
|
||||
skillFieldFactory.occupationOption(checked = current?.occupation ?: false),
|
||||
skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
|
||||
)
|
||||
},
|
||||
)
|
||||
} ?: emptyList(),
|
||||
magicSkills = sheet?.magicSkills?.map { skill ->
|
||||
skillFieldFactory.createSkill(
|
||||
id = skill.id,
|
||||
label = magicSkillsLabel,
|
||||
descriptionValue = skill.description ?: "",
|
||||
labelValue = skill.label,
|
||||
baseValue = skill.base,
|
||||
bonusValue = skill.bonus ?: "",
|
||||
levelValue = skill.level ?: "",
|
||||
options = run {
|
||||
val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
|
||||
listOf(
|
||||
skillFieldFactory.occupationOption(
|
||||
checked = current?.occupation ?: false
|
||||
),
|
||||
skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
|
||||
)
|
||||
},
|
||||
)
|
||||
} ?: emptyList(),
|
||||
actions = sheet?.actions?.map { action ->
|
||||
ActionFieldUio(
|
||||
id = action.id,
|
||||
label = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
|
||||
value = action.label,
|
||||
commonSkills = listOf(
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.COMBAT_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__combat),
|
||||
base = derivedStateOf { normalize(dex() * 2) },
|
||||
),
|
||||
action = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
|
||||
value = action.roll,
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.DODGE_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__dodge),
|
||||
base = derivedStateOf { normalize(dex() * 2) },
|
||||
),
|
||||
option = skillFieldFactory.deleteOption { onDeleteSkill(action.id) },
|
||||
)
|
||||
} ?: emptyList(),
|
||||
)
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.GRAB_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__grab),
|
||||
base = derivedStateOf { normalize(str() + hei()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.THROW_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__throw),
|
||||
base = derivedStateOf { normalize(str() + dex()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.ATHLETICS_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__athletics),
|
||||
base = derivedStateOf { normalize(str() + con() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.ACROBATICS_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__acrobatics),
|
||||
base = derivedStateOf { normalize(dex() + con() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.PERCEPTION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__perception),
|
||||
base = derivedStateOf { normalize(10 + int() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SEARCH_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__search),
|
||||
base = derivedStateOf { normalize(10 + int() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.EMPATHY_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__empathy),
|
||||
base = derivedStateOf { normalize(cha() + int()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.PERSUASION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__persuasion),
|
||||
base = derivedStateOf { normalize(cha() * 3) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.INTIMIDATION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__intimidation),
|
||||
base = derivedStateOf { normalize(cha() + max(pow(), hei()) * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SPIEL_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__spiel),
|
||||
base = derivedStateOf { normalize(cha() * 2 + int()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.BARGAIN_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__bargain),
|
||||
base = derivedStateOf { normalize(cha() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.DISCRETION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__discretion),
|
||||
base = derivedStateOf { normalize(cha() + dex() * 2 - hei()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__sleight_of_hand),
|
||||
base = derivedStateOf { normalize(dex() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.AID_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__aid),
|
||||
base = derivedStateOf { normalize(int() + dex()) },
|
||||
),
|
||||
),
|
||||
specialSkills = sheet?.specialSkills?.map { skill ->
|
||||
skillFieldFactory.createSkill(
|
||||
id = skill.id,
|
||||
label = specialSkillsLabel,
|
||||
descriptionValue = skill.description ?: "",
|
||||
labelValue = skill.label,
|
||||
baseValue = skill.base,
|
||||
bonusValue = skill.bonus ?: "",
|
||||
levelValue = skill.level ?: "",
|
||||
options = run {
|
||||
val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
|
||||
listOf(
|
||||
skillFieldFactory.occupationOption(current?.occupation ?: false),
|
||||
skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
|
||||
)
|
||||
},
|
||||
)
|
||||
} ?: emptyList(),
|
||||
magicSkills = sheet?.magicSkills?.map { skill ->
|
||||
skillFieldFactory.createSkill(
|
||||
id = skill.id,
|
||||
label = magicSkillsLabel,
|
||||
descriptionValue = skill.description ?: "",
|
||||
labelValue = skill.label,
|
||||
baseValue = skill.base,
|
||||
bonusValue = skill.bonus ?: "",
|
||||
levelValue = skill.level ?: "",
|
||||
options = run {
|
||||
val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
|
||||
listOf(
|
||||
skillFieldFactory.occupationOption(
|
||||
checked = current?.occupation ?: false
|
||||
),
|
||||
skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
|
||||
)
|
||||
},
|
||||
)
|
||||
} ?: emptyList(),
|
||||
actions = sheet?.actions?.map { action ->
|
||||
ActionFieldUio(
|
||||
id = action.id,
|
||||
label = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
|
||||
value = action.label,
|
||||
),
|
||||
action = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
|
||||
value = action.roll,
|
||||
),
|
||||
option = skillFieldFactory.deleteOption { onDeleteSkill(action.id) },
|
||||
)
|
||||
} ?: emptyList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createBaseSkill(
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ data class CharacterSheetEditPageUio(
|
|||
val movement: SimpleFieldUio,
|
||||
val maxHp: SimpleFieldUio,
|
||||
val maxPp: SimpleFieldUio,
|
||||
val currentHp: SimpleFieldUio,
|
||||
val currentPp: SimpleFieldUio,
|
||||
val damageBonus: SimpleFieldUio,
|
||||
val armor: SimpleFieldUio,
|
||||
val learning: SimpleFieldUio,
|
||||
val hpGrow: SimpleFieldUio,
|
||||
val commonSkills: List<BaseSkillFieldUio>,
|
||||
val specialSkills: List<SkillFieldUio>,
|
||||
val magicSkills: List<SkillFieldUio>,
|
||||
|
|
@ -94,11 +94,11 @@ data class CharacterSheetEditPageUio(
|
|||
get() = listOf(
|
||||
movement,
|
||||
maxHp,
|
||||
currentHp,
|
||||
maxPp,
|
||||
currentPp,
|
||||
damageBonus,
|
||||
armor,
|
||||
learning,
|
||||
hpGrow,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue