Compare commits
1 commit
main
...
feature/Ch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6f2a8b4f8 |
11 changed files with 490 additions and 109 deletions
|
|
@ -5,8 +5,13 @@ import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBoxUio
|
|||
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField
|
||||
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMActionFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMCharacteristicFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMSkillFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.common.tag.GMTagFactory
|
||||
import com.pixelized.desktop.lwa.utils.extention.constitution
|
||||
import com.pixelized.desktop.lwa.utils.extention.dexterity
|
||||
import com.pixelized.desktop.lwa.utils.extention.height
|
||||
import com.pixelized.desktop.lwa.utils.extention.strength
|
||||
import com.pixelized.desktop.lwa.utils.extention.unpack
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CommonSkillId.ACROBATICS_ID
|
||||
|
|
@ -109,6 +114,13 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sk
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_base
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_description
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_label
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__charisma
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__constitution
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__dexterity
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__height
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__intelligence
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__power
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__strength
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import java.util.UUID
|
||||
|
||||
|
|
@ -132,20 +144,17 @@ class GMCharacterEditFactory(
|
|||
level = form.level.unpack()
|
||||
?: error("Missing character level"),
|
||||
shouldLevelUp = form.levelUp.checked.value,
|
||||
strength = form.characteristics.strength.unpack()
|
||||
?: error("Missing character strength"),
|
||||
dexterity = form.characteristics.dexterity.unpack()
|
||||
?: error("Missing character dexterity"),
|
||||
constitution = form.characteristics.constitution.unpack()
|
||||
?: error("Missing character constitution"),
|
||||
height = form.characteristics.height.unpack()
|
||||
?: error("Missing character height"),
|
||||
intelligence = form.characteristics.intelligence.unpack()
|
||||
?: error("Missing character intelligence"),
|
||||
power = form.characteristics.power.unpack()
|
||||
?: error("Missing character power"),
|
||||
charisma = form.characteristics.charisma.unpack()
|
||||
?: error("Missing character charisma"),
|
||||
characteristics = form.characteristics.map { characteristic ->
|
||||
val characteristicId: String = characteristic.id.unpack()
|
||||
?: error("Missing characteristic id")
|
||||
CharacterSheet.Characteristic(
|
||||
id = characteristicId,
|
||||
label = characteristic.label.unpack() ?: "",
|
||||
description = characteristic.description.unpack() ?: "",
|
||||
base = characteristic.base.unpack() ?: 0,
|
||||
level = characteristic.level.unpack() ?: 0,
|
||||
)
|
||||
},
|
||||
alterations = sheet?.alterations ?: emptyList(),
|
||||
damage = sheet?.damage ?: 0,
|
||||
fatigue = sheet?.fatigue ?: 0,
|
||||
|
|
@ -185,7 +194,6 @@ class GMCharacterEditFactory(
|
|||
magicSkills = form.magicSkills.map { editedSkill ->
|
||||
val skillId: String = editedSkill.id.unpack()
|
||||
?: error("Missing skill id")
|
||||
|
||||
CharacterSheet.Skill(
|
||||
id = skillId,
|
||||
label = editedSkill.label.unpack()
|
||||
|
|
@ -333,10 +341,18 @@ class GMCharacterEditFactory(
|
|||
actions = sheet?.actions?.map { createAction(action = it) } ?: emptyList())
|
||||
}
|
||||
|
||||
private suspend fun createCharacteristic(
|
||||
scope: CoroutineScope,
|
||||
skill: CharacterSheet.Skill,
|
||||
characteristics: List<GMCharacteristicFieldUio>,
|
||||
): List<GMCharacteristicFieldUio> {
|
||||
|
||||
}
|
||||
|
||||
private suspend fun createCommonSkill(
|
||||
scope: CoroutineScope,
|
||||
skill: CharacterSheet.Skill,
|
||||
characteristics: GMCharacterEditPageUio.CharacteristicsUio,
|
||||
characteristics: List<GMCharacteristicFieldUio>,
|
||||
): GMSkillFieldUio {
|
||||
val baseLabel = getString(Res.string.character_sheet_edit__skills__base_label)
|
||||
val idFlow = createLwaTextFieldFlow(
|
||||
|
|
@ -585,6 +601,23 @@ class GMCharacterEditFactory(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun commonCharacteristicDescription(
|
||||
skillId: String,
|
||||
): String? {
|
||||
return when (skillId) {
|
||||
CharacterSheet.CharacteristicId.STR -> Res.string.tooltip__characteristics__strength
|
||||
CharacterSheet.CharacteristicId.CON -> Res.string.tooltip__characteristics__constitution
|
||||
CharacterSheet.CharacteristicId.HEI -> Res.string.tooltip__characteristics__height
|
||||
CharacterSheet.CharacteristicId.INT -> Res.string.tooltip__characteristics__intelligence
|
||||
CharacterSheet.CharacteristicId.POW -> Res.string.tooltip__characteristics__power
|
||||
CharacterSheet.CharacteristicId.DEX -> Res.string.tooltip__characteristics__dexterity
|
||||
CharacterSheet.CharacteristicId.CHA -> Res.string.tooltip__characteristics__charisma
|
||||
else -> null
|
||||
}?.let {
|
||||
getString(it)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun commonSkillDescription(
|
||||
skillId: String,
|
||||
): String? {
|
||||
|
|
@ -639,10 +672,11 @@ class GMCharacterEditFactory(
|
|||
|
||||
private fun commonSkillBaseFlow(
|
||||
scope: CoroutineScope,
|
||||
characteristics: GMCharacterEditPageUio.CharacteristicsUio,
|
||||
characteristics: List<GMCharacteristicFieldUio>,
|
||||
skillId: String,
|
||||
): MutableStateFlow<String> {
|
||||
val flow = combine(
|
||||
characteristics.map { it. }
|
||||
characteristics.strength.valueFlow.map { it.toIntOrNull() ?: 0 },
|
||||
characteristics.dexterity.valueFlow.map { it.toIntOrNull() ?: 0 },
|
||||
characteristics.constitution.valueFlow.map { it.toIntOrNull() ?: 0 },
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.dialog.GMCharact
|
|||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.dialog.GMCharacterSheetCopyDialogViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMActionField
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMActionFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMCharacteristicField
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMCharacteristicFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMSkillField
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item.GMSkillFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.admin.common.tag.GMTagButton
|
||||
|
|
@ -96,27 +98,13 @@ data class GMCharacterEditPageUio(
|
|||
val externalLink: LwaTextFieldUio,
|
||||
val level: LwaTextFieldUio,
|
||||
val levelUp: LwaCheckBoxUio,
|
||||
val characteristics: CharacteristicsUio,
|
||||
val characteristics: List<GMCharacteristicFieldUio>,
|
||||
val tags: MutableStateFlow<List<GMTagUio>>,
|
||||
val commonSkills: List<GMSkillFieldUio>,
|
||||
val specialSkills: List<GMSkillFieldUio>,
|
||||
val magicSkills: List<GMSkillFieldUio>,
|
||||
val actions: List<GMActionFieldUio>,
|
||||
) {
|
||||
@Stable
|
||||
data class CharacteristicsUio(
|
||||
val strength: LwaTextFieldUio,
|
||||
val dexterity: LwaTextFieldUio,
|
||||
val constitution: LwaTextFieldUio,
|
||||
val height: LwaTextFieldUio,
|
||||
val intelligence: LwaTextFieldUio,
|
||||
val power: LwaTextFieldUio,
|
||||
val charisma: LwaTextFieldUio,
|
||||
) {
|
||||
val values =
|
||||
listOf(strength, dexterity, constitution, height, intelligence, power, charisma)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@Stable
|
||||
object GMCharacterEditPageDefault {
|
||||
|
|
@ -166,6 +154,13 @@ fun GMCharacterEditPage(
|
|||
onTag = { tag ->
|
||||
viewModel.addTag(tag = tag)
|
||||
},
|
||||
onCharacteristicAdd = {
|
||||
|
||||
},
|
||||
onCharacteristicDelete = { index ->
|
||||
focus.clearFocus(force = true)
|
||||
scope.launch { viewModel.deleteCharacteristic(index = index) }
|
||||
},
|
||||
onSpecialSkillAdd = {
|
||||
focus.clearFocus(force = true)
|
||||
scope.launch { viewModel.addSpecialSkill() }
|
||||
|
|
@ -244,6 +239,8 @@ fun GMCharacterEditContent(
|
|||
onSaveAs: () -> Unit,
|
||||
onSave: () -> Unit,
|
||||
onTag: (GMTagUio) -> Unit,
|
||||
onCharacteristicAdd: () -> Unit,
|
||||
onCharacteristicDelete: (Int) -> Unit,
|
||||
onSpecialSkillAdd: () -> Unit,
|
||||
onSpecialSkillDelete: (Int) -> Unit,
|
||||
onMagicSkillAdd: () -> Unit,
|
||||
|
|
@ -482,17 +479,17 @@ fun GMCharacterEditContent(
|
|||
text = "Characteristics",
|
||||
)
|
||||
}
|
||||
items(
|
||||
items = form.characteristics.values,
|
||||
key = { "characteristics-${it.labelFlow}" },
|
||||
) { characteristic ->
|
||||
LwaTextField(
|
||||
itemsIndexed(
|
||||
items = form.characteristics,
|
||||
key = { _, item -> item.key },
|
||||
) { index, characteristic ->
|
||||
GMCharacteristicField(
|
||||
modifier = Modifier
|
||||
.animateItem()
|
||||
.fillMaxWidth()
|
||||
.padding(paddingValues = horizontalPadding),
|
||||
field = characteristic,
|
||||
singleLine = true,
|
||||
characteristic = characteristic,
|
||||
onDelete = { onCharacteristicDelete(index) },
|
||||
)
|
||||
}
|
||||
item(key = "CommonSkillsTitle") {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,18 @@ class GMCharacterEditViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun deleteCharacteristic(
|
||||
index: Int
|
||||
) {
|
||||
_form.update { form ->
|
||||
form?.copy(
|
||||
characteristics = form.characteristics.toMutableList().also {
|
||||
it.removeAt(index)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteSpecialSkill(
|
||||
index: Int,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,144 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.admin.character.edit.item
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
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.platform.LocalFocusManager
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField
|
||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
|
||||
import com.pixelized.desktop.lwa.utils.extention.moveFocusOnTab
|
||||
|
||||
@Stable
|
||||
data class GMCharacteristicFieldUio(
|
||||
val key: String,
|
||||
val id: LwaTextFieldUio,
|
||||
val label: LwaTextFieldUio,
|
||||
val description: LwaTextFieldUio,
|
||||
val base: LwaTextFieldUio,
|
||||
val level: LwaTextFieldUio,
|
||||
)
|
||||
|
||||
@Stable
|
||||
object GMCharacteristicFieldDefault {
|
||||
@Stable
|
||||
val spacing: DpSize = DpSize(4.dp, 4.dp)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GMCharacteristicField(
|
||||
modifier: Modifier = Modifier,
|
||||
spacing: DpSize = GMCharacteristicFieldDefault.spacing,
|
||||
characteristic: GMCharacteristicFieldUio,
|
||||
onDelete: ((GMCharacteristicFieldUio) -> Unit)?,
|
||||
) {
|
||||
val focus = LocalFocusManager.current
|
||||
val showMenu = remember { mutableStateOf(false) }
|
||||
val onDismissRequest = remember {
|
||||
{
|
||||
focus.clearFocus(force = true)
|
||||
showMenu.value = false
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
verticalArrangement = Arrangement.spacedBy(space = spacing.height),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
|
||||
) {
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
field = skill.id,
|
||||
)
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
field = skill.label,
|
||||
)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
|
||||
) {
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
field = skill.base,
|
||||
)
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
field = skill.level,
|
||||
)
|
||||
}
|
||||
skill.description?.let { description ->
|
||||
LwaTextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.moveFocusOnTab(focusManager = LocalFocusManager.current),
|
||||
field = description,
|
||||
singleLine = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
Box {
|
||||
IconButton(
|
||||
onClick = { showMenu.value = showMenu.value.not() },
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = showMenu.value,
|
||||
offset = DpOffset(x = (-48).dp - spacing.width, y = (-48).dp),
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
modifier = modifier,
|
||||
enabled = onDelete != null,
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onDelete?.invoke(skill)
|
||||
},
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
text = "Supprimer",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.pixelized.shared.lwa.model
|
|||
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.ARMOR
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.CHA
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.CON
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.DEX
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.DMG
|
||||
|
|
@ -69,37 +68,24 @@ class AlteredCharacterSheet(
|
|||
val level: Int
|
||||
get() = sheet.level + fieldAlterations[LVL].sum()
|
||||
|
||||
val strength: Int
|
||||
get() = sheet.strength + fieldAlterations[STR].sum()
|
||||
|
||||
val dexterity: Int
|
||||
get() = sheet.dexterity + fieldAlterations[DEX].sum()
|
||||
|
||||
val constitution: Int
|
||||
get() = sheet.constitution + fieldAlterations[CON].sum()
|
||||
|
||||
val height: Int
|
||||
get() = sheet.height + fieldAlterations[HEI].sum()
|
||||
|
||||
val intelligence: Int
|
||||
get() = sheet.intelligence + fieldAlterations[INT].sum()
|
||||
|
||||
val power: Int
|
||||
get() = sheet.power + fieldAlterations[POW].sum()
|
||||
|
||||
val charisma: Int
|
||||
get() = sheet.charisma + fieldAlterations[CHA].sum()
|
||||
/**
|
||||
* see CharacterSheet.CharacteristicId
|
||||
*/
|
||||
fun characteristic(id: String): Int =
|
||||
sheet.characteristics.firstOrNull { it.id == id }?.let { characteristic ->
|
||||
characteristic.base + characteristic.level + fieldAlterations[id].sum()
|
||||
} ?: 0
|
||||
|
||||
val maxHp: Int
|
||||
get() = sheetUseCase.maxHp(
|
||||
constitution = constitution,
|
||||
height = height,
|
||||
constitution = characteristic(id = CON),
|
||||
height = characteristic(id = HEI),
|
||||
level = level,
|
||||
) + fieldAlterations[HP].sum()
|
||||
|
||||
val maxPp: Int
|
||||
get() = sheetUseCase.maxPp(
|
||||
power = power,
|
||||
power = characteristic(id = POW),
|
||||
) + fieldAlterations[PP].sum()
|
||||
|
||||
val damage: Int
|
||||
|
|
@ -125,19 +111,21 @@ class AlteredCharacterSheet(
|
|||
|
||||
val reflex: Int
|
||||
get() = sheetUseCase.reflex(
|
||||
strength = strength,
|
||||
dexterity = dexterity,
|
||||
intelligence = intelligence,
|
||||
strength = characteristic(id = STR),
|
||||
dexterity = characteristic(id = DEX),
|
||||
intelligence = characteristic(id = INT),
|
||||
) + fieldAlterations[REFLEX].sum()
|
||||
|
||||
val initiative: Int
|
||||
get() = sheetUseCase.initiative(dexterity = dexterity) + fieldAlterations[INITIATIVE].sum()
|
||||
get() = sheetUseCase.initiative(
|
||||
dexterity = characteristic(id = DEX)
|
||||
) + fieldAlterations[INITIATIVE].sum()
|
||||
|
||||
val damageBonus: String
|
||||
get() {
|
||||
val initial = sheetUseCase.meleeBonusDamage(
|
||||
strength = strength,
|
||||
height = height,
|
||||
strength = characteristic(id = STR),
|
||||
height = characteristic(id = HEI),
|
||||
)
|
||||
return fieldAlterations[DMG]
|
||||
?.joinToString(separator = "+") { it.expression.toString() }
|
||||
|
|
@ -147,12 +135,12 @@ class AlteredCharacterSheet(
|
|||
|
||||
val learning: Int
|
||||
get() = sheetUseCase.learning(
|
||||
intelligence = intelligence
|
||||
intelligence = characteristic(id = INT),
|
||||
) + fieldAlterations[LB].sum()
|
||||
|
||||
val hpGrow: Int
|
||||
get() = sheetUseCase.hpGrow(
|
||||
constitution = constitution,
|
||||
constitution = characteristic(id = CON),
|
||||
) + fieldAlterations[GHP].sum()
|
||||
|
||||
// Helper method
|
||||
|
|
|
|||
|
|
@ -10,13 +10,7 @@ data class CharacterSheet(
|
|||
val level: Int,
|
||||
val shouldLevelUp: Boolean,
|
||||
// characteristics
|
||||
val strength: Int,
|
||||
val dexterity: Int,
|
||||
val constitution: Int,
|
||||
val height: Int,
|
||||
val intelligence: Int,
|
||||
val power: Int,
|
||||
val charisma: Int,
|
||||
val characteristics: List<Characteristic>,
|
||||
// alterations
|
||||
val damage: Int, // damage taken on the hp pool
|
||||
val fatigue: Int, // damage taken on the pp pool
|
||||
|
|
@ -35,6 +29,14 @@ data class CharacterSheet(
|
|||
?: specialSkills.firstOrNull { it.id == id }
|
||||
?: magicSkills.firstOrNull { it.id == id }
|
||||
|
||||
data class Characteristic(
|
||||
val id: String,
|
||||
val label: String,
|
||||
val description: String?,
|
||||
val base: Int,
|
||||
val level: Int,
|
||||
)
|
||||
|
||||
data class Skill(
|
||||
val id: String,
|
||||
val label: String,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package com.pixelized.shared.lwa.model.characterSheet
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class CharacterSheetJsonV2(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
val job: String?,
|
||||
val portrait: String?,
|
||||
val thumbnail: String?,
|
||||
val externalLink: String?,
|
||||
val level: Int,
|
||||
val shouldLevelUp: Boolean?,
|
||||
// characteristics
|
||||
val characteristics: List<Characteristic>,
|
||||
// alterations
|
||||
val damage: Int?,
|
||||
val fatigue: Int?,
|
||||
val diminished: Int?,
|
||||
val alterations: List<String>?,
|
||||
// skills
|
||||
val skills: List<Skill>,
|
||||
val occupations: List<Skill>,
|
||||
val magics: List<Skill>,
|
||||
// actions
|
||||
val rolls: List<Roll>,
|
||||
// tags
|
||||
val tag: List<String>?,
|
||||
) : CharacterSheetJson {
|
||||
|
||||
@Serializable
|
||||
data class Characteristic(
|
||||
val id: String,
|
||||
val label: String,
|
||||
val description: String?,
|
||||
val base: Int,
|
||||
val level: Int,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Skill(
|
||||
val id: String,
|
||||
val label: String,
|
||||
val description: String?,
|
||||
val base: String,
|
||||
val bonus: String?,
|
||||
val level: Int,
|
||||
val occupation: Boolean,
|
||||
val used: Boolean,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Roll(
|
||||
val id: String,
|
||||
val label: String,
|
||||
val description: String?,
|
||||
val canBeCritical: Boolean,
|
||||
val roll: String,
|
||||
val special: String?,
|
||||
val critical: String?,
|
||||
)
|
||||
}
|
||||
|
|
@ -3,18 +3,21 @@ package com.pixelized.shared.lwa.model.characterSheet.factory
|
|||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonV1
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonV2
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
|
||||
import com.pixelized.shared.lwa.protocol.rest.CharacterPreviewJson
|
||||
|
||||
|
||||
class CharacterSheetJsonFactory(
|
||||
private val v1: CharacterSheetJsonV1Factory,
|
||||
private val v2: CharacterSheetJsonV2Factory,
|
||||
) {
|
||||
fun convertFromJson(
|
||||
json: CharacterSheetJson,
|
||||
): CharacterSheet {
|
||||
return when (json) {
|
||||
is CharacterSheetJsonV1 -> v1.convertFromJson(json = json)
|
||||
is CharacterSheetJsonV2 -> v2.convertFromJson(json = json)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -23,7 +26,7 @@ class CharacterSheetJsonFactory(
|
|||
fun convertToJson(
|
||||
sheet: CharacterSheet,
|
||||
): CharacterSheetJson {
|
||||
val json = CharacterSheetJsonV1(
|
||||
val json = CharacterSheetJsonV2(
|
||||
id = sheet.id,
|
||||
name = sheet.name,
|
||||
job = sheet.job,
|
||||
|
|
@ -32,19 +35,21 @@ class CharacterSheetJsonFactory(
|
|||
externalLink = sheet.externalLink,
|
||||
level = sheet.level,
|
||||
shouldLevelUp = sheet.shouldLevelUp,
|
||||
strength = sheet.strength,
|
||||
dexterity = sheet.dexterity,
|
||||
constitution = sheet.constitution,
|
||||
height = sheet.height,
|
||||
intelligence = sheet.intelligence,
|
||||
power = sheet.power,
|
||||
charisma = sheet.charisma,
|
||||
characteristics = sheet.characteristics.map {
|
||||
CharacterSheetJsonV2.Characteristic(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
base = it.base,
|
||||
level = it.level,
|
||||
)
|
||||
},
|
||||
damage = sheet.damage,
|
||||
fatigue = sheet.fatigue,
|
||||
diminished = sheet.diminished,
|
||||
alterations = sheet.alterations,
|
||||
skills = sheet.commonSkills.map {
|
||||
CharacterSheetJsonV1.Skill(
|
||||
CharacterSheetJsonV2.Skill(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
|
|
@ -56,7 +61,7 @@ class CharacterSheetJsonFactory(
|
|||
)
|
||||
},
|
||||
occupations = sheet.specialSkills.map {
|
||||
CharacterSheetJsonV1.Skill(
|
||||
CharacterSheetJsonV2.Skill(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
|
|
@ -68,7 +73,7 @@ class CharacterSheetJsonFactory(
|
|||
)
|
||||
},
|
||||
magics = sheet.magicSkills.map {
|
||||
CharacterSheetJsonV1.Skill(
|
||||
CharacterSheetJsonV2.Skill(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
|
|
@ -80,7 +85,7 @@ class CharacterSheetJsonFactory(
|
|||
)
|
||||
},
|
||||
rolls = sheet.actions.map {
|
||||
CharacterSheetJsonV1.Roll(
|
||||
CharacterSheetJsonV2.Roll(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
|
|
|
|||
|
|
@ -19,13 +19,57 @@ class CharacterSheetJsonV1Factory(
|
|||
externalLink = json.externalLink,
|
||||
level = json.level,
|
||||
shouldLevelUp = json.shouldLevelUp ?: false,
|
||||
strength = json.strength,
|
||||
dexterity = json.dexterity,
|
||||
constitution = json.constitution,
|
||||
height = json.height,
|
||||
intelligence = json.intelligence,
|
||||
power = json.power,
|
||||
charisma = json.charisma,
|
||||
characteristics = listOf(
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.STR,
|
||||
label = "Force",
|
||||
description = "La Force représente essentiellement la puissance musculaire du personnage. Elle ne décrit pas nécessairement la masse musculaire brute, mais l’efficacité avec laquelle le personnage exerce ses muscles pour accomplir des actions physiques pénibles.\n\n- Bonus aux dégats\n- Réflexe\n- Athlétisme\n- Lancer\n- Saisie",
|
||||
base = json.strength,
|
||||
level = 0,
|
||||
),
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.DEX,
|
||||
label = "Dextérité",
|
||||
description = "La Constitution est une mesure de la ténacité et de la résilience du personnage. Elle sert à résister aux maladies. Mais son aspect le plus important réside dans la détermination du nombre de dommages qu’un personnage peut supporter avant de succomber.\n\n- Point de vie maximum\n- Athlétisme\n- Acrobatie",
|
||||
base = json.dexterity,
|
||||
level = 0,
|
||||
),
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.CON,
|
||||
label = "Constitution",
|
||||
description = "La Taille est une mesure de la masse du personnage. Elle ne représente pas forcément la taille en centimètres, mais une idée générale de sa masse physique. Un personnage à la TAI élevée peut être très grand et mince, ou petit et massif, ou de taille moyenne en surpoids.\n\n- Bonus aux dégats\n- Point de vie maximum\n- Saisie\n- Intimidation\n- Discrétion (impact négatif)",
|
||||
base = json.constitution,
|
||||
level = 0,
|
||||
),
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.HEI,
|
||||
label = "Taille",
|
||||
description = "L’Intelligence représente la capacité de discernement du personnage. Elle ne mesure pas nécessairement la somme d’informations mémorisées, mais l’aptitude au raisonnement, l’acuité intellectuelle, la capacité à résoudre des problèmes et l’intuition.\n\n- Bonus d'apprentissage\n- Réflexe\n- Perception\n- Recherche\n- Empathie\n- Baratin\n- Premiers soins",
|
||||
base = json.height,
|
||||
level = 0,
|
||||
),
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.INT,
|
||||
label = "Intelligence",
|
||||
description = "Le Pouvoir est une mesure presque intangible de la force de volonté, du dynamisme intérieur et de l’énergie spirituelle. Il représente également le potentiel magique du personnage.\n\n- Points de pouvoir maximum\n- Intimidation",
|
||||
base = json.intelligence,
|
||||
level = 0,
|
||||
),
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.POW,
|
||||
label = "Pouvoir",
|
||||
description = "La Dextérité mesure la coordination œil-main, la vitesse physique et l’agilité générale. La DEX détermine à quelle vitesse un personnage peut agir en combat.\n\n- Initiative\n- Réflexe\n- Bagarre\n- Esquive\n- Lancer\n- Acrobatie\n- Discrétion\n- Escamotage\n- Premiers soins",
|
||||
base = json.power,
|
||||
level = 0,
|
||||
),
|
||||
CharacterSheet.Characteristic(
|
||||
id = CharacterSheet.CharacteristicId.CHA,
|
||||
label = "Charisme",
|
||||
description = "Il représente plusieurs aspects allant de la grâce à la beauté en passant par l’attraction que le personnage exerce sur les autres. Un personnage avec un CHA élevé se remarque dans une foule en raison d’une intangible combinaison de charme et de présence.\n\n- Empathie\n- Persuasion\n- Persuasion\n- Intimidation\n- Baratin\n- Marchandage\n- Discrétion",
|
||||
base = json.charisma,
|
||||
level = 0,
|
||||
),
|
||||
),
|
||||
damage = json.damage ?: 0,
|
||||
fatigue = json.fatigue ?: 0,
|
||||
diminished = json.diminished ?: 0,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
package com.pixelized.shared.lwa.model.characterSheet.factory
|
||||
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonV2
|
||||
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
|
||||
|
||||
class CharacterSheetJsonV2Factory(
|
||||
private val characterSheetUseCase: CharacterSheetUseCase,
|
||||
) {
|
||||
fun convertFromJson(
|
||||
json: CharacterSheetJsonV2,
|
||||
): CharacterSheet = characterSheetUseCase.run {
|
||||
CharacterSheet(
|
||||
id = json.id,
|
||||
name = json.name,
|
||||
job = json.job ?: "",
|
||||
portrait = json.portrait,
|
||||
thumbnail = json.thumbnail,
|
||||
externalLink = json.externalLink,
|
||||
level = json.level,
|
||||
shouldLevelUp = json.shouldLevelUp ?: false,
|
||||
characteristics = json.characteristics.map {
|
||||
CharacterSheet.Characteristic(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
base = it.base,
|
||||
level = it.level,
|
||||
)
|
||||
},
|
||||
damage = json.damage ?: 0,
|
||||
fatigue = json.fatigue ?: 0,
|
||||
diminished = json.diminished ?: 0,
|
||||
alterations = json.alterations ?: emptyList(),
|
||||
commonSkills = json.skills.map {
|
||||
CharacterSheet.Skill(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
base = it.base,
|
||||
bonus = it.bonus,
|
||||
level = it.level,
|
||||
occupation = it.occupation,
|
||||
used = it.used,
|
||||
)
|
||||
},
|
||||
specialSkills = json.occupations.map {
|
||||
CharacterSheet.Skill(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
base = it.base,
|
||||
bonus = it.bonus,
|
||||
level = it.level,
|
||||
occupation = it.occupation,
|
||||
used = it.used,
|
||||
)
|
||||
},
|
||||
magicSkills = json.magics.map {
|
||||
CharacterSheet.Skill(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
base = it.base,
|
||||
bonus = it.bonus,
|
||||
level = it.level,
|
||||
occupation = it.occupation,
|
||||
used = it.used,
|
||||
)
|
||||
},
|
||||
actions = json.rolls.map {
|
||||
CharacterSheet.Roll(
|
||||
id = it.id,
|
||||
label = it.label,
|
||||
description = it.description,
|
||||
canBeCritical = it.canBeCritical,
|
||||
default = it.roll,
|
||||
special = it.special,
|
||||
critical = it.critical,
|
||||
)
|
||||
},
|
||||
tags = json.tag ?: emptyList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,13 @@ package com.pixelized.shared.lwa.usecase
|
|||
import com.pixelized.shared.lwa.model.AlteredCharacterSheet
|
||||
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.CHA
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.CON
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.DEX
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.HEI
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.INT
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.POW
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.STR
|
||||
import com.pixelized.shared.lwa.parser.expression.Expression
|
||||
import com.pixelized.shared.lwa.parser.expression.ExpressionParser
|
||||
import com.pixelized.shared.lwa.parser.word.Word
|
||||
|
|
@ -128,8 +135,8 @@ class ExpressionUseCase(
|
|||
Word.Type.BDC -> evaluate(
|
||||
expression = expressionParser.parse(
|
||||
characterSheetUseCase.meleeBonusDamage(
|
||||
strength = sheet.strength,
|
||||
height = sheet.height,
|
||||
strength = sheet.characteristic(id = STR),
|
||||
height = sheet.characteristic(id = HEI),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -137,19 +144,19 @@ class ExpressionUseCase(
|
|||
Word.Type.BDD -> evaluate(
|
||||
expression = expressionParser.parse(
|
||||
characterSheetUseCase.distanceBonusDamage(
|
||||
strength = sheet.strength,
|
||||
height = sheet.height,
|
||||
strength = sheet.characteristic(id = STR),
|
||||
height = sheet.characteristic(id = HEI),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Word.Type.STR -> sheet.strength
|
||||
Word.Type.DEX -> sheet.dexterity
|
||||
Word.Type.CON -> sheet.constitution
|
||||
Word.Type.HEI -> sheet.height
|
||||
Word.Type.INT -> sheet.intelligence
|
||||
Word.Type.POW -> sheet.power
|
||||
Word.Type.CHA -> sheet.charisma
|
||||
Word.Type.STR -> sheet.characteristic(id = STR)
|
||||
Word.Type.DEX -> sheet.characteristic(id = DEX)
|
||||
Word.Type.CON -> sheet.characteristic(id = CON)
|
||||
Word.Type.HEI -> sheet.characteristic(id = HEI)
|
||||
Word.Type.INT -> sheet.characteristic(id = INT)
|
||||
Word.Type.POW -> sheet.characteristic(id = POW)
|
||||
Word.Type.CHA -> sheet.characteristic(id = CHA)
|
||||
}
|
||||
|
||||
null -> 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue