Add passive proficiency to the character sheet.
This commit is contained in:
		
							parent
							
								
									70ae338e23
								
							
						
					
					
						commit
						805bdc65bc
					
				
					 7 changed files with 196 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"),
 | 
			
		||||
            )
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue