Add passive proficiency to the character sheet.

This commit is contained in:
Thomas Andres Gomez 2023-12-18 11:35:42 +01:00
parent 70ae338e23
commit 805bdc65bc
7 changed files with 196 additions and 20 deletions

View file

@ -25,7 +25,7 @@ import com.pixelized.rplexicon.ui.theme.LexiconTheme
data class CharacterSheetHeaderUio(
val armorClass: LabelPointUio,
val hitPoint: LabelPointUio,
val speed: LabelPointUio,
val dC: LabelPointUio?,
val resource: ResourcePointUio?,
val death: DeathThrowUio? = null
@ -57,9 +57,6 @@ fun CharacterSheetHeader(
alignment = Alignment.CenterHorizontally
),
) {
header.value?.speed?.let {
LabelPoint(label = it)
}
header.value?.armorClass?.let {
LabelPoint(label = it)
}

View file

@ -0,0 +1,129 @@
package com.pixelized.rplexicon.ui.screens.character.composable.character
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.theme.LexiconTheme
@Stable
data class PassivesUio(
val speed: Int,
val perception: Int,
val investigation: Int,
val insight: Int,
)
@Composable
fun Passives(
modifier: Modifier = Modifier,
padding: PaddingValues = PaddingValues(all = 4.dp),
titleStyle: TextStyle = MaterialTheme.typography.labelSmall,
titleWeight: FontWeight = FontWeight.Light,
valueStyle: TextStyle = MaterialTheme.typography.headlineMedium,
valueWeight: FontWeight = FontWeight.Medium,
passives: PassivesUio,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(padding)
.then(other = modifier),
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.Bottom,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
style = titleStyle,
fontWeight = titleWeight,
textAlign = TextAlign.Center,
text = stringResource(id = R.string.character_sheet_title_speed),
)
Text(
style = valueStyle,
fontWeight = valueWeight,
text = "${passives.speed}m"
)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
style = titleStyle,
fontWeight = titleWeight,
textAlign = TextAlign.Center,
text = stringResource(id = R.string.character_sheet_proficiency_perception),
)
Text(
style = valueStyle,
fontWeight = valueWeight,
text = "${passives.perception}",
)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
style = titleStyle,
fontWeight = titleWeight,
textAlign = TextAlign.Center,
text = stringResource(id = R.string.character_sheet_proficiency_investigation),
)
Text(
style = valueStyle,
fontWeight = valueWeight,
text = "${passives.investigation}",
)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
style = titleStyle,
fontWeight = titleWeight,
textAlign = TextAlign.Center,
text = stringResource(id = R.string.character_sheet_proficiency_insight),
)
Text(
style = valueStyle,
fontWeight = valueWeight,
text = "${passives.insight}",
)
}
}
}
@Composable
@Preview
private fun PassivesPreview() {
LexiconTheme {
Surface {
Passives(
passives = PassivesUio(
speed = 10,
perception = 19,
investigation = 8,
insight = 14,
)
)
}
}
}

View file

@ -26,11 +26,6 @@ fun rememberCharacterHeaderStatePreview(
value = "125",
max = "/ 150",
),
speed = LabelPointUio(
label = R.string.character_sheet_title_speed,
value = "30",
max = "m",
),
dC = LabelPointUio(
label = R.string.character_sheet_title_dc,
value = "13",

View file

@ -7,6 +7,7 @@ import androidx.compose.runtime.remember
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.screens.character.composable.character.LabelPointUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.MasteriesUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.PassivesUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.ProficiencyUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.StatUio
import com.pixelized.rplexicon.ui.screens.character.pages.proficiency.CharacterSheetUio
@ -176,11 +177,17 @@ fun rememberCharacterSheetStatePreview() = remember {
modifier = 4,
),
),
passives = PassivesUio(
speed = 10,
perception = 19,
investigation = 9,
insight = 14,
),
masteries = MasteriesUio(
martial = listOf("Common & war weapons", "Light & Medium & Heavy Armors"),
languages = listOf("Common", "Orc", "Elvish"),
others = listOf("Pan flute"),
)
),
)
)
}

View file

@ -28,11 +28,6 @@ class CharacterSheetHeaderUioFactory @Inject constructor(
value = sheetHeaderData?.ca?.let { "$it" } ?: " ",
max = null,
),
speed = LabelPointUio(
label = R.string.character_sheet_title_speed,
value = sheetHeaderData?.speed?.let { "$it" } ?: " ",
max = "m",
),
hitPoint = LabelPointUio(
label = R.string.character_sheet_title_hp,
value = convertToHitPointLabel(hitPoint = fireHeaderData),

View file

@ -6,9 +6,12 @@ import com.pixelized.rplexicon.data.model.CharacterSheet
import com.pixelized.rplexicon.data.model.Property
import com.pixelized.rplexicon.ui.screens.character.composable.character.LabelPointUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.MasteriesUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.PassivesUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.ProficiencyUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.StatUio
import com.pixelized.rplexicon.ui.screens.character.pages.proficiency.CharacterSheetUio
import com.pixelized.rplexicon.utilitary.extentions.local.advantage
import com.pixelized.rplexicon.utilitary.extentions.local.disadvantage
import com.pixelized.rplexicon.utilitary.extentions.local.sum
import com.pixelized.rplexicon.utilitary.extentions.modifier
import com.pixelized.rplexicon.utilitary.extentions.toLabel
@ -190,6 +193,24 @@ class CharacterSheetUioFactory @Inject constructor() {
modifier = charisma.modifier + alterations[Property.DECEPTION].sum + sheet.deception * proficiency,
),
),
passives = PassivesUio(
speed = sheet.speed,
perception = alterations[Property.PERCEPTION].let {
val advantage = if (it.advantage) 5 else 0
val disadvantage = if (it.disadvantage) 5 else 0
10 + wisdom.modifier + it.sum + sheet.perception * proficiency + advantage - disadvantage
},
investigation = alterations[Property.INVESTIGATION].let {
val advantage = if (it.advantage) 5 else 0
val disadvantage = if (it.disadvantage) 5 else 0
10 + intelligence.modifier + it.sum + sheet.investigation * proficiency + advantage - disadvantage
},
insight = alterations[Property.INSIGHT].let {
val advantage = if (it.advantage) 5 else 0
val disadvantage = if (it.disadvantage) 5 else 0
10 + wisdom.modifier + it.sum + sheet.insight * proficiency + advantage - disadvantage
},
),
masteries = MasteriesUio(
martial = sheet.martial,
languages = sheet.languages,

View file

@ -30,6 +30,7 @@ import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@ -39,6 +40,8 @@ import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.screens.character.composable.character.LabelPointUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.Masteries
import com.pixelized.rplexicon.ui.screens.character.composable.character.MasteriesUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.Passives
import com.pixelized.rplexicon.ui.screens.character.composable.character.PassivesUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.Proficiency
import com.pixelized.rplexicon.ui.screens.character.composable.character.ProficiencyUio
import com.pixelized.rplexicon.ui.screens.character.composable.character.Stat
@ -54,6 +57,7 @@ data class CharacterSheetUio(
val savingThrows: List<ProficiencyUio>,
val proficiencies: List<ProficiencyUio>,
val masteries: MasteriesUio,
val passives: PassivesUio,
)
@Composable
@ -154,6 +158,17 @@ fun ProficiencyPageContent(
text = stringResource(id = R.string.character_sheet_title_proficiencies)
)
},
passives = {
Passives(
passives = sheet.passives,
)
Text(
modifier = Modifier.padding(vertical = 4.dp),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center,
text = "Passives",
)
},
masteries = {
Masteries(
masteries = sheet.masteries,
@ -171,6 +186,7 @@ private fun ProficiencyLayout(
stats: @Composable ColumnScope.() -> Unit,
savingThrows: @Composable ColumnScope.() -> Unit,
proficiencies: @Composable ColumnScope.() -> Unit,
passives: @Composable ColumnScope.() -> Unit,
masteries: @Composable ColumnScope.() -> Unit,
) {
val density = LocalDensity.current
@ -197,7 +213,15 @@ private fun ProficiencyLayout(
content = proficiencies,
)
Column(
modifier = Modifier.layoutId("Masteries"),
modifier = Modifier
.layoutId("PassivesId")
.ddBorder(inner = inner, outline = outline),
content = passives,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween,
)
Column(
modifier = Modifier.layoutId("MasteriesId"),
horizontalAlignment = Alignment.CenterHorizontally,
content = masteries,
)
@ -206,6 +230,9 @@ private fun ProficiencyLayout(
val spacingPx = with(density) { spacing.toPx().toInt() }
val statsWidth = with(density) { 100.dp.toPx().toInt() }
val passivesMeasure = measurables.passives.measure(
constraints = constraints
)
val proficienciesWidth = constraints.maxWidth - statsWidth - spacingPx
val savingThrowsMeasure = measurables.savingThrows.measure(
constraints.copy(
@ -228,11 +255,11 @@ private fun ProficiencyLayout(
maxHeight = statsHeight,
)
)
val othersMeasure = measurables.others.measure(constraints)
val masteriesMeasure = measurables.masteries.measure(constraints)
layout(
width = constraints.maxWidth,
height = statsMeasure.height + othersMeasure.measuredHeight + spacingPx,
height = statsMeasure.height + masteriesMeasure.height + passivesMeasure.height + spacingPx * 2,
) {
statsMeasure.place(
x = 0,
@ -246,10 +273,14 @@ private fun ProficiencyLayout(
x = statsWidth + spacingPx,
y = savingThrowsMeasure.height + spacingPx,
)
othersMeasure.place(
passivesMeasure.place(
x = 0,
y = statsHeight + spacingPx,
)
masteriesMeasure.place(
x = 0,
y = passivesMeasure.height + statsHeight + spacingPx * 2,
)
}
}
)
@ -258,7 +289,8 @@ private fun ProficiencyLayout(
val List<Measurable>.stats get() = first { it.layoutId == "StatsId" }
val List<Measurable>.savingThrows get() = first { it.layoutId == "SavingThrowsId" }
val List<Measurable>.proficiencies get() = first { it.layoutId == "ProficienciesId" }
val List<Measurable>.others get() = first { it.layoutId == "Masteries" }
val List<Measurable>.masteries get() = first { it.layoutId == "MasteriesId" }
val List<Measurable>.passives get() = first { it.layoutId == "PassivesId" }
@Composable
@Preview(uiMode = UI_MODE_NIGHT_NO, heightDp = 1300)