Add an alteration feature to alterate dynamically a character sheet.

This commit is contained in:
Thomas Andres Gomez 2025-02-10 09:10:05 +01:00
parent 8fd2ff3cc4
commit d84bc9bbef
11 changed files with 387 additions and 37 deletions

View file

@ -13,6 +13,8 @@ import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
import com.pixelized.desktop.lwa.repository.settings.SettingsFactory import com.pixelized.desktop.lwa.repository.settings.SettingsFactory
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
import com.pixelized.desktop.lwa.repository.alteration.AlterationStore
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
import com.pixelized.desktop.lwa.repository.settings.SettingsStore import com.pixelized.desktop.lwa.repository.settings.SettingsStore
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetViewModel import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetViewModel
@ -53,6 +55,7 @@ val storeDependencies
get() = module { get() = module {
singleOf(::CharacterSheetStore) singleOf(::CharacterSheetStore)
singleOf(::SettingsStore) singleOf(::SettingsStore)
singleOf(::AlterationStore)
} }
val repositoryDependencies val repositoryDependencies
@ -61,6 +64,7 @@ val repositoryDependencies
singleOf(::CharacterSheetRepository) singleOf(::CharacterSheetRepository)
singleOf(::RollHistoryRepository) singleOf(::RollHistoryRepository)
singleOf(::SettingsRepository) singleOf(::SettingsRepository)
singleOf(::AlterationRepository)
} }
val factoryDependencies val factoryDependencies

View file

@ -4,6 +4,7 @@ package com.pixelized.desktop.lwa.business
import com.pixelized.desktop.lwa.parser.expression.Expression import com.pixelized.desktop.lwa.parser.expression.Expression
import com.pixelized.desktop.lwa.parser.expression.ExpressionParser import com.pixelized.desktop.lwa.parser.expression.ExpressionParser
import com.pixelized.desktop.lwa.parser.word.Word import com.pixelized.desktop.lwa.parser.word.Word
import com.pixelized.desktop.lwa.repository.alteration.model.FieldAlteration
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -15,7 +16,7 @@ class ExpressionUseCase(
fun computeSkillValue( fun computeSkillValue(
sheet: CharacterSheet, sheet: CharacterSheet,
skill: CharacterSheet.Skill, skill: CharacterSheet.Skill,
diminished: Int, alterations: Int,
): Int { ): Int {
val context = Context( val context = Context(
sheet = sheet, sheet = sheet,
@ -36,12 +37,21 @@ class ExpressionUseCase(
expression = skill.level?.let(expressionParser::parse), expression = skill.level?.let(expressionParser::parse),
) )
return max(base + bonus + level - diminished, 0) return max(base + bonus + level + alterations, 0)
} }
fun computeRoll( fun computeRoll(
sheet: CharacterSheet, sheet: CharacterSheet,
expression: String, expression: String,
): Int {
return expressionParser.parse(input = expression)?.let {
computeExpression(sheet = sheet, expression = it)
} ?: 0
}
fun computeExpression(
sheet: CharacterSheet,
expression: Expression,
): Int { ): Int {
val context = Context( val context = Context(
sheet = sheet, sheet = sheet,
@ -49,7 +59,7 @@ class ExpressionUseCase(
) )
print("Evaluate:\"$expression\"") print("Evaluate:\"$expression\"")
return context.evaluate( return context.evaluate(
expression = expressionParser.parse(input = expression), expression = expression,
).also { println(" > $it") } ).also { println(" > $it") }
} }
@ -73,7 +83,7 @@ class ExpressionUseCase(
} }
is Expression.Inversion -> { is Expression.Inversion -> {
-evaluate(expression) -evaluate(expression.expression)
} }
is Expression.Maximum -> { is Expression.Maximum -> {

View file

@ -0,0 +1,63 @@
package com.pixelized.desktop.lwa.repository.alteration
import com.pixelized.desktop.lwa.repository.alteration.model.FieldAlteration
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
// Theses typealias are there for readability only.
private typealias CharacterId = String
private typealias AlterationId = String
class AlterationRepository(
private val store: AlterationStore,
) {
private val activeAlterationIdMapFlow: HashMap<CharacterId, MutableStateFlow<List<AlterationId>>> =
hashMapOf("0f2117e9-e077-4354-8d77-20150df1c462" to MutableStateFlow(listOf("7c00dafa-a67d-4351-8ea9-67d933012cde", "65e37d32-3031-4bf8-9369-d2c45d2efac0")))
fun alterations(characterId: String): Flow<Map<String, List<FieldAlteration>>> {
return activeAlterationIdMapFlow
.getOrPut(characterId) { MutableStateFlow(emptyList()) }
.map { activeAlterationIds ->
val fieldAlterations = hashMapOf<String, MutableList<FieldAlteration>>()
activeAlterationIds.forEach { id: AlterationId ->
store.alteration(alterationId = id)?.let { alteration ->
alteration.fields.forEach { field ->
fieldAlterations.getOrPut(field.fieldId) { mutableListOf() }
.add(
FieldAlteration(
alterationId = alteration.id,
metadata = alteration.metadata,
expression = field.expression,
)
)
}
}
}
fieldAlterations
}
}
fun toggle(characterId: String, alterationId: String) {
// check if the alteration is currently active of inactive.
val active = activeAlterationIdMapFlow[characterId]
?.value
?.contains(alterationId)
?: false
// alteration was active for the character toggle it off.
activeAlterationIdMapFlow[characterId]?.value = activeAlterationIdMapFlow[characterId]
?.value
?.toMutableList()
?.also { list ->
when (active) {
true -> list.remove(alterationId)
else -> list.add(alterationId)
}
}
?: emptyList()
}
}

View file

@ -0,0 +1,81 @@
package com.pixelized.desktop.lwa.repository.alteration
import com.pixelized.desktop.lwa.parser.expression.Expression
import com.pixelized.desktop.lwa.parser.expression.ExpressionParser
import com.pixelized.desktop.lwa.repository.alteration.model.Alteration
import com.pixelized.desktop.lwa.repository.alteration.model.AlterationMetadata
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId.ARMOR
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId.DEX
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId.HEI
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId.MOV
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId.STR
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.ACROBATICS_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.AID_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.ATHLETICS_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.BARGAIN_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.COMBAT_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.DISCRETION_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.INTIMIDATION_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.PERCEPTION_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.PERSUASION_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.SPIEL_ID
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId.THROW_ID
class AlterationStore(
private val expressionParser: ExpressionParser,
) {
private val alterations = mapOf(
"7c00dafa-a67d-4351-8ea9-67d933012cde" to Alteration(
id = "7c00dafa-a67d-4351-8ea9-67d933012cde",
metadata = AlterationMetadata(
name = "Tatouage Mak",
description = "Tatouage des Mak permettant la transformation en loup.",
),
fields = listOf(
Alteration.Field(fieldId = CharacteristicId.PP, expression = "-2".parse()),
)
),
"65e37d32-3031-4bf8-9369-d2c45d2efac0" to Alteration(
id = "65e37d32-3031-4bf8-9369-d2c45d2efac0",
metadata = AlterationMetadata(
name = "Forme de loup",
description = "Capacité spécial des maks de la tribue Palok.",
),
fields = listOf(
Alteration.Field(fieldId = STR, expression = "+1".parse()),
Alteration.Field(fieldId = DEX, expression = "-1".parse()),
Alteration.Field(fieldId = HEI, expression = "-1".parse()),
Alteration.Field(fieldId = MOV, expression = "+5".parse()),
Alteration.Field(fieldId = ARMOR, expression = "+1".parse()),
Alteration.Field(fieldId = COMBAT_ID, expression = "+10".parse()),
Alteration.Field(fieldId = THROW_ID, expression = "-100".parse()),
Alteration.Field(fieldId = ATHLETICS_ID, expression = "+20".parse()),
Alteration.Field(fieldId = ACROBATICS_ID, expression = "-10".parse()),
Alteration.Field(fieldId = PERCEPTION_ID, expression = "+20".parse()),
Alteration.Field(fieldId = PERSUASION_ID, expression = "-20".parse()),
Alteration.Field(fieldId = INTIMIDATION_ID, expression = "+20".parse()),
Alteration.Field(fieldId = SPIEL_ID, expression = "-20".parse()),
Alteration.Field(fieldId = BARGAIN_ID, expression = "-20".parse()),
Alteration.Field(fieldId = DISCRETION_ID, expression = "+20".parse()),
Alteration.Field(fieldId = SLEIGHT_OF_HAND_ID, expression = "-100".parse()),
Alteration.Field(fieldId = AID_ID, expression = "-100".parse()),
Alteration.Field(
fieldId = "40a4dcca-7010-4522-9d58-0cfac0a586e8", // Pistage
expression = "+20".parse()
),
)
)
)
fun alterations(): Collection<Alteration> = alterations.values
fun alteration(alterationId: String): Alteration? = alterations[alterationId]
private fun String.parse(): Expression {
return expressionParser.parse(this)!!
}
}

View file

@ -0,0 +1,14 @@
package com.pixelized.desktop.lwa.repository.alteration.model
import com.pixelized.desktop.lwa.parser.expression.Expression
data class Alteration(
val id: String,
val metadata: AlterationMetadata,
val fields: List<Field>,
) {
data class Field(
val fieldId: String, // this id is not the id of the instance but the id of the impacted characteristic in the character sheet.
val expression: Expression,
)
}

View file

@ -0,0 +1,6 @@
package com.pixelized.desktop.lwa.repository.alteration.model
data class AlterationMetadata(
val name: String,
val description: String,
)

View file

@ -0,0 +1,9 @@
package com.pixelized.desktop.lwa.repository.alteration.model
import com.pixelized.desktop.lwa.parser.expression.Expression
data class FieldAlteration(
val alterationId: String,
val metadata: AlterationMetadata,
val expression: Expression,
)

View file

@ -2,6 +2,7 @@ package com.pixelized.desktop.lwa.screen.characterSheet.detail
import com.pixelized.desktop.lwa.business.ExpressionUseCase import com.pixelized.desktop.lwa.business.ExpressionUseCase
import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio
import com.pixelized.desktop.lwa.repository.alteration.model.FieldAlteration
import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId
@ -40,15 +41,23 @@ import org.jetbrains.compose.resources.getString
class CharacterSheetFactory( class CharacterSheetFactory(
private val skillUseCase: ExpressionUseCase, private val skillUseCase: ExpressionUseCase,
private val expressionUseCase: ExpressionUseCase,
private val skillDescriptionFactory: SkillDescriptionFactory, private val skillDescriptionFactory: SkillDescriptionFactory,
) { ) {
suspend fun convertToUio( suspend fun convertToUio(
sheet: CharacterSheet?, sheet: CharacterSheet?,
diminished: Int, diminished: Int,
alterations: Map<String, List<FieldAlteration>>,
): CharacterSheetPageUio? { ): CharacterSheetPageUio? {
if (sheet == null) return null if (sheet == null) return null
fun List<FieldAlteration>?.sum(): Int {
return this?.sumOf {
expressionUseCase.computeExpression(sheet = sheet, expression = it.expression)
} ?: 0
}
return CharacterSheetPageUio( return CharacterSheetPageUio(
id = sheet.id, id = sheet.id,
name = sheet.name, name = sheet.name,
@ -56,7 +65,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.STR, id = CharacteristicId.STR,
label = getString(Res.string.character_sheet__characteristics__str), label = getString(Res.string.character_sheet__characteristics__str),
value = "${sheet.strength}", value = "${sheet.strength + alterations[CharacteristicId.STR].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__str), title = getString(Res.string.character_sheet__characteristics__str),
description = getString(Res.string.tooltip__characteristics__strength), description = getString(Res.string.tooltip__characteristics__strength),
@ -66,7 +75,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.DEX, id = CharacteristicId.DEX,
label = getString(Res.string.character_sheet__characteristics__dex), label = getString(Res.string.character_sheet__characteristics__dex),
value = "${sheet.dexterity}", value = "${sheet.dexterity + alterations[CharacteristicId.DEX].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__dex), title = getString(Res.string.character_sheet__characteristics__dex),
description = getString(Res.string.tooltip__characteristics__dexterity), description = getString(Res.string.tooltip__characteristics__dexterity),
@ -76,7 +85,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.CON, id = CharacteristicId.CON,
label = getString(Res.string.character_sheet__characteristics__con), label = getString(Res.string.character_sheet__characteristics__con),
value = "${sheet.constitution}", value = "${sheet.constitution + alterations[CharacteristicId.CON].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__con), title = getString(Res.string.character_sheet__characteristics__con),
description = getString(Res.string.tooltip__characteristics__constitution), description = getString(Res.string.tooltip__characteristics__constitution),
@ -86,7 +95,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.HEI, id = CharacteristicId.HEI,
label = getString(Res.string.character_sheet__characteristics__hei), label = getString(Res.string.character_sheet__characteristics__hei),
value = "${sheet.height}", value = "${sheet.height + alterations[CharacteristicId.HEI].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__hei), title = getString(Res.string.character_sheet__characteristics__hei),
description = getString(Res.string.tooltip__characteristics__height), description = getString(Res.string.tooltip__characteristics__height),
@ -96,7 +105,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.INT, id = CharacteristicId.INT,
label = getString(Res.string.character_sheet__characteristics__int), label = getString(Res.string.character_sheet__characteristics__int),
value = "${sheet.intelligence}", value = "${sheet.intelligence + alterations[CharacteristicId.INT].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__int), title = getString(Res.string.character_sheet__characteristics__int),
description = getString(Res.string.tooltip__characteristics__intelligence), description = getString(Res.string.tooltip__characteristics__intelligence),
@ -106,7 +115,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.POW, id = CharacteristicId.POW,
label = getString(Res.string.character_sheet__characteristics__pow), label = getString(Res.string.character_sheet__characteristics__pow),
value = "${sheet.power}", value = "${sheet.power + alterations[CharacteristicId.POW].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__pow), title = getString(Res.string.character_sheet__characteristics__pow),
description = getString(Res.string.tooltip__characteristics__power), description = getString(Res.string.tooltip__characteristics__power),
@ -116,7 +125,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.CHA, id = CharacteristicId.CHA,
label = getString(Res.string.character_sheet__characteristics__cha), label = getString(Res.string.character_sheet__characteristics__cha),
value = "${sheet.charisma}", value = "${sheet.charisma + alterations[CharacteristicId.CHA].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__characteristics__cha), title = getString(Res.string.character_sheet__characteristics__cha),
description = getString(Res.string.tooltip__characteristics__charisma), description = getString(Res.string.tooltip__characteristics__charisma),
@ -128,7 +137,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.MOV, id = CharacteristicId.MOV,
label = getString(Res.string.character_sheet__sub_characteristics__movement), label = getString(Res.string.character_sheet__sub_characteristics__movement),
value = "${sheet.movement}", value = "${sheet.movement + alterations[CharacteristicId.MOV].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__sub_characteristics__movement), title = getString(Res.string.character_sheet__sub_characteristics__movement),
description = getString(Res.string.tooltip__sub_characteristics__movement), description = getString(Res.string.tooltip__sub_characteristics__movement),
@ -138,7 +147,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.HP, id = CharacteristicId.HP,
label = getString(Res.string.character_sheet__sub_characteristics__hit_point), label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
value = "${sheet.currentHp}/${sheet.maxHp}", value = "${sheet.currentHp}/${sheet.maxHp + alterations[CharacteristicId.HP].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__sub_characteristics__hit_point), title = getString(Res.string.character_sheet__sub_characteristics__hit_point),
description = getString(Res.string.tooltip__sub_characteristics__hit_point), description = getString(Res.string.tooltip__sub_characteristics__hit_point),
@ -148,7 +157,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.PP, id = CharacteristicId.PP,
label = getString(Res.string.character_sheet__sub_characteristics__power_point), label = getString(Res.string.character_sheet__sub_characteristics__power_point),
value = "${sheet.currentPp}/${sheet.maxPp}", value = "${sheet.currentPp}/${sheet.maxPp + alterations[CharacteristicId.PP].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__sub_characteristics__power_point), title = getString(Res.string.character_sheet__sub_characteristics__power_point),
description = getString(Res.string.tooltip__sub_characteristics__power_point), description = getString(Res.string.tooltip__sub_characteristics__power_point),
@ -168,7 +177,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.ARMOR, id = CharacteristicId.ARMOR,
label = getString(Res.string.character_sheet__sub_characteristics__armor), label = getString(Res.string.character_sheet__sub_characteristics__armor),
value = "${sheet.armor}", value = "${sheet.armor + alterations[CharacteristicId.ARMOR].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__sub_characteristics__armor), title = getString(Res.string.character_sheet__sub_characteristics__armor),
description = getString(Res.string.tooltip__sub_characteristics__armor), description = getString(Res.string.tooltip__sub_characteristics__armor),
@ -178,7 +187,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.LB, id = CharacteristicId.LB,
label = getString(Res.string.character_sheet__sub_characteristics__learning), label = getString(Res.string.character_sheet__sub_characteristics__learning),
value = "${sheet.learning}", value = "${sheet.learning + alterations[CharacteristicId.LB].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__sub_characteristics__learning), title = getString(Res.string.character_sheet__sub_characteristics__learning),
description = getString(Res.string.tooltip__sub_characteristics__learning), description = getString(Res.string.tooltip__sub_characteristics__learning),
@ -188,7 +197,7 @@ class CharacterSheetFactory(
Characteristic( Characteristic(
id = CharacteristicId.GHP, id = CharacteristicId.GHP,
label = getString(Res.string.character_sheet__sub_characteristics__hp_grow), label = getString(Res.string.character_sheet__sub_characteristics__hp_grow),
value = "${sheet.hpGrow}", value = "${sheet.hpGrow + alterations[CharacteristicId.GHP].sum()}",
tooltips = TooltipUio( tooltips = TooltipUio(
title = getString(Res.string.character_sheet__sub_characteristics__hp_grow), title = getString(Res.string.character_sheet__sub_characteristics__hp_grow),
description = getString(Res.string.tooltip__sub_characteristics__hp_grow), description = getString(Res.string.tooltip__sub_characteristics__hp_grow),
@ -202,7 +211,7 @@ class CharacterSheetFactory(
value = skillUseCase.computeSkillValue( value = skillUseCase.computeSkillValue(
sheet = sheet, sheet = sheet,
skill = skill, skill = skill,
diminished = diminished, alterations = alterations[skill.id].sum(),
), ),
tooltips = skillDescriptionFactory.baseSkillDescription(id = skill.id)?.let { tooltips = skillDescriptionFactory.baseSkillDescription(id = skill.id)?.let {
TooltipUio( TooltipUio(
@ -225,7 +234,7 @@ class CharacterSheetFactory(
value = skillUseCase.computeSkillValue( value = skillUseCase.computeSkillValue(
sheet = sheet, sheet = sheet,
skill = skill, skill = skill,
diminished = diminished, alterations = alterations[skill.id].sum(),
), ),
used = skill.used, used = skill.used,
) )
@ -242,7 +251,7 @@ class CharacterSheetFactory(
value = skillUseCase.computeSkillValue( value = skillUseCase.computeSkillValue(
sheet = sheet, sheet = sheet,
skill = skill, skill = skill,
diminished = diminished, alterations = alterations[skill.id].sum(),
), ),
used = skill.used, used = skill.used,
) )

View file

@ -8,6 +8,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith import androidx.compose.animation.togetherWith
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.ScrollState import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -49,13 +50,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.min
import com.pixelized.desktop.lwa.LocalWindowController import com.pixelized.desktop.lwa.LocalWindowController
import com.pixelized.desktop.lwa.composable.blur.BlurContent import com.pixelized.desktop.lwa.composable.blur.BlurContent
import com.pixelized.desktop.lwa.composable.blur.BlurContentController import com.pixelized.desktop.lwa.composable.blur.BlurContentController
@ -65,11 +63,14 @@ import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.navigation.window.LocalWindow import com.pixelized.desktop.lwa.navigation.window.LocalWindow
import com.pixelized.desktop.lwa.navigation.window.destination.navigateToCharacterSheetEdit import com.pixelized.desktop.lwa.navigation.window.destination.navigateToCharacterSheetEdit
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetStatDialog import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetStatDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialog import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.preview.rememberCharacterSheetPreview
import com.pixelized.desktop.lwa.screen.roll.RollPage import com.pixelized.desktop.lwa.screen.roll.RollPage
import com.pixelized.desktop.lwa.screen.roll.RollViewModel import com.pixelized.desktop.lwa.screen.roll.RollViewModel
import com.pixelized.desktop.lwa.utils.preview.ContentPreview
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.Res
@ -86,7 +87,6 @@ import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
import java.awt.Toolkit
@Stable @Stable
data class CharacterSheetPageUio( data class CharacterSheetPageUio(
@ -131,7 +131,6 @@ fun CharacterSheetPage(
val windowController = LocalWindowController.current val windowController = LocalWindowController.current
val screen = LocalScreenController.current val screen = LocalScreenController.current
val window = LocalWindow.current val window = LocalWindow.current
val density = LocalDensity.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val blurController = remember { BlurContentController() } val blurController = remember { BlurContentController() }
@ -147,10 +146,11 @@ fun CharacterSheetPage(
characterSheet = sheet, characterSheet = sheet,
diminishedValue = viewModel.diminishedValue, diminishedValue = viewModel.diminishedValue,
onDiminished = { onDiminished = {
blurController.show() // blurController.show()
scope.launch { // scope.launch {
viewModel.showDiminishedDialog() // viewModel.showDiminishedDialog()
} // }
viewModel.toggleWolf()
}, },
onEdit = { onEdit = {
windowController.navigateToCharacterSheetEdit( windowController.navigateToCharacterSheetEdit(
@ -273,8 +273,8 @@ fun CharacterSheetPageContent(
onDiminished: () -> Unit, onDiminished: () -> Unit,
onEdit: () -> Unit, onEdit: () -> Unit,
onDelete: () -> Unit, onDelete: () -> Unit,
onCharacteristic: (characteristic: CharacterSheetPageUio.Characteristic) -> Unit, onCharacteristic: (characteristic: Characteristic) -> Unit,
onSubCharacteristic: (characteristic: CharacterSheetPageUio.Characteristic) -> Unit, onSubCharacteristic: (characteristic: Characteristic) -> Unit,
onSkill: (skill: CharacterSheetPageUio.Node) -> Unit, onSkill: (skill: CharacterSheetPageUio.Node) -> Unit,
onUseSkill: (skill: CharacterSheetPageUio.Node) -> Unit, onUseSkill: (skill: CharacterSheetPageUio.Node) -> Unit,
onRoll: (roll: CharacterSheetPageUio.Roll) -> Unit, onRoll: (roll: CharacterSheetPageUio.Roll) -> Unit,
@ -520,7 +520,7 @@ fun CharacterSheetPageContent(
private fun Stat( private fun Stat(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
paddingValues: PaddingValues = PaddingValues(all = 8.dp), paddingValues: PaddingValues = PaddingValues(all = 8.dp),
characteristic: CharacterSheetPageUio.Characteristic, characteristic: Characteristic,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
TooltipLayout( TooltipLayout(
@ -557,8 +557,8 @@ private fun Stat(
private fun SubCharacteristics( private fun SubCharacteristics(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
paddingValues: PaddingValues = PaddingValues(horizontal = 8.dp), paddingValues: PaddingValues = PaddingValues(horizontal = 8.dp),
characteristic: CharacterSheetPageUio.Characteristic, characteristic: Characteristic,
onCharacteristic: ((characteristic: CharacterSheetPageUio.Characteristic) -> Unit)?, onCharacteristic: ((characteristic: Characteristic) -> Unit)?,
) { ) {
TooltipLayout( TooltipLayout(
tooltip = characteristic.tooltips, tooltip = characteristic.tooltips,
@ -667,4 +667,25 @@ private fun Roll(
} }
} }
private fun Modifier.cell(): Modifier = this.fillMaxWidth().height(height = 32.dp) private fun Modifier.cell(): Modifier = this.fillMaxWidth().height(height = 32.dp)
@Composable
@Preview
private fun DecoratedBoxPreview() {
ContentPreview {
CharacterSheetPageContent(
modifier = Modifier.fillMaxSize(),
scrollState = rememberScrollState(),
characterSheet = rememberCharacterSheetPreview(),
diminishedValue = remember { mutableStateOf(null) },
onDiminished = { },
onEdit = { },
onDelete = { },
onCharacteristic = { },
onSubCharacteristic = { },
onSkill = { },
onUseSkill = { },
onRoll = { },
)
}
}

View file

@ -10,6 +10,7 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio
@ -29,6 +30,7 @@ private typealias CSDCDialogUio = CharacterSheetDeleteConfirmationDialogUio
class CharacterSheetViewModel( class CharacterSheetViewModel(
private val repository: CharacterSheetRepository, private val repository: CharacterSheetRepository,
private val alteration: AlterationRepository,
private val factory: CharacterSheetFactory, private val factory: CharacterSheetFactory,
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
) : ViewModel() { ) : ViewModel() {
@ -57,8 +59,9 @@ class CharacterSheetViewModel(
private val sheetFlow = combine( private val sheetFlow = combine(
repository.characterSheetFlow(id = argument.id), repository.characterSheetFlow(id = argument.id),
repository.characterDiminishedFlow(id = argument.id), repository.characterDiminishedFlow(id = argument.id),
transform = { sheet, diminished -> alteration.alterations(characterId = argument.id),
factory.convertToUio(sheet = sheet, diminished = diminished) transform = { sheet, diminished, alterations ->
factory.convertToUio(sheet = sheet, diminished = diminished, alterations = alterations)
}, },
) )
val sheet: State<CharacterSheetPageUio?> val sheet: State<CharacterSheetPageUio?>
@ -68,6 +71,10 @@ class CharacterSheetViewModel(
context = viewModelScope.coroutineContext, context = viewModelScope.coroutineContext,
) )
fun toggleWolf() {
alteration.toggle(argument.id, "65e37d32-3031-4bf8-9369-d2c45d2efac0")
}
fun deleteCharacter(id: String) { fun deleteCharacter(id: String) {
repository.delete(id = id) repository.delete(id = id)
} }

View file

@ -0,0 +1,126 @@
package com.pixelized.desktop.lwa.screen.characterSheet.detail.preview
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
@Composable
@Stable
fun rememberCharacterSheetPreview(): CharacterSheetPageUio {
return remember {
CharacterSheetPageUio(
id = "Koryas_Id",
name = "Koryas",
characteristics = listOf(
Characteristic(
id = CharacteristicId.STR,
label = "Force",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.DEX,
label = "Dexterité",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.CON,
label = "Constitution",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.HEI,
label = "Taille",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.INT,
label = "Intelligence",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.POW,
label = "Pouvoir",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.CHA,
label = "Charisme",
value = "10",
tooltips = null,
editable = false,
),
),
subCharacteristics = listOf(
Characteristic(
id = CharacteristicId.MOV,
label = "Mouvement",
value = "10",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.HP,
label = "Point de vie",
value = "20/20",
tooltips = null,
editable = true,
),
Characteristic(
id = CharacteristicId.PP,
label = "Point de pouvoir",
value = "15/15",
tooltips = null,
editable = true,
),
Characteristic(
id = CharacteristicId.DMG,
label = "Domage bonus",
value = "1d4",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.ARMOR,
label = "Armure",
value = "0",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.LB,
label = "Apprentissage",
value = "0",
tooltips = null,
editable = false,
),
Characteristic(
id = CharacteristicId.GHP,
label = "Bonus de PV",
value = "5",
tooltips = null,
editable = false,
),
),
commonSkills = emptyList(),
specialSKills = emptyList(),
magicsSkills = emptyList(),
actions = emptyList(),
)
}
}