diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d16df8c..450fb38 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -107,6 +107,8 @@ dependencies {
implementation("androidx.compose.material3:material3:1.1.1")
debugImplementation("androidx.compose.ui:ui-tooling:1.5.0")
+ implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1")
+
// Navigation
implementation("androidx.navigation:navigation-compose:2.7.1")
diff --git a/app/src/debug/ic_launcher-playstore.png b/app/src/debug/ic_launcher-playstore.png
new file mode 100644
index 0000000..e3ffc6b
Binary files /dev/null and b/app/src/debug/ic_launcher-playstore.png differ
diff --git a/app/src/debug/res/drawable/ic_launcher_foreground.xml b/app/src/debug/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..c27306f
--- /dev/null
+++ b/app/src/debug/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher.webp b/app/src/debug/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..74016a2
Binary files /dev/null and b/app/src/debug/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..48e185f
Binary files /dev/null and b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher.webp b/app/src/debug/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..b29de0f
Binary files /dev/null and b/app/src/debug/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..60210e6
Binary files /dev/null and b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/debug/res/mipmap-xhdpi/ic_launcher.webp b/app/src/debug/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..0d633d3
Binary files /dev/null and b/app/src/debug/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..cbb6ac3
Binary files /dev/null and b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/debug/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/debug/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..2eea795
Binary files /dev/null and b/app/src/debug/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..6eab1d3
Binary files /dev/null and b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..2432737
Binary files /dev/null and b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..64e523e
Binary files /dev/null and b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/debug/res/values/ic_launcher_background.xml b/app/src/debug/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..0530591
--- /dev/null
+++ b/app/src/debug/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #1C1B1F
+
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
index 1ec6937..689d52b 100644
Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/com/pixelized/rplexicon/MainActivity.kt b/app/src/main/java/com/pixelized/rplexicon/MainActivity.kt
index d164a5d..58eb864 100644
--- a/app/src/main/java/com/pixelized/rplexicon/MainActivity.kt
+++ b/app/src/main/java/com/pixelized/rplexicon/MainActivity.kt
@@ -2,8 +2,8 @@ package com.pixelized.rplexicon
import android.app.Activity
import android.os.Bundle
-import android.util.Log
import androidx.activity.ComponentActivity
+import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
@@ -15,13 +15,19 @@ import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Modifier
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
-import com.pixelized.rplexicon.facotry.RollParser
+import androidx.hilt.navigation.compose.hiltViewModel
+import com.pixelized.rplexicon.ui.composable.BlurredOverlayHost
import com.pixelized.rplexicon.ui.navigation.ScreenNavHost
+import com.pixelized.rplexicon.ui.screens.rolls.BlurredRollOverlayHostState
+import com.pixelized.rplexicon.ui.screens.rolls.RollOverlay
+import com.pixelized.rplexicon.ui.screens.rolls.RollOverlayViewModel
+import com.pixelized.rplexicon.ui.screens.rolls.rememberBlurredRollOverlayHostState
import com.pixelized.rplexicon.ui.theme.LexiconTheme
import dagger.hilt.android.AndroidEntryPoint
@@ -31,6 +37,12 @@ val LocalActivity = staticCompositionLocalOf {
val LocalSnack = staticCompositionLocalOf {
error("SnackbarHostState not available")
}
+val RollSnack = staticCompositionLocalOf {
+ error("SnackbarHostState not available")
+}
+val LocalRollOverlay = compositionLocalOf {
+ error("LocalRollOverlay not yet ready")
+}
val NO_WINDOW_INSETS = WindowInsets(0, 0, 0, 0)
@AndroidEntryPoint
@@ -49,9 +61,15 @@ class MainActivity : ComponentActivity() {
setContent {
LexiconTheme {
+ val rollViewModel = hiltViewModel()
+ val overlay = rememberBlurredRollOverlayHostState(
+ viewModel = rollViewModel,
+ )
+
CompositionLocalProvider(
LocalActivity provides this,
- LocalSnack provides remember { SnackbarHostState() }
+ LocalSnack provides remember { SnackbarHostState() },
+ LocalRollOverlay provides overlay,
) {
Scaffold(
contentWindowInsets = NO_WINDOW_INSETS,
@@ -62,7 +80,17 @@ class MainActivity : ComponentActivity() {
.padding(paddingValues = padding),
color = MaterialTheme.colorScheme.background
) {
- ScreenNavHost()
+ BlurredOverlayHost(
+ rollOverlayState = overlay,
+ overlay = {
+ RollOverlay(
+ viewModel = rollViewModel,
+ )
+ },
+ content = {
+ ScreenNavHost()
+ },
+ )
}
},
snackbarHost = {
@@ -72,6 +100,9 @@ class MainActivity : ComponentActivity() {
)
}
)
+ BackHandler(enabled = overlay.isOverlayVisible) {
+ overlay.hideOverlay()
+ }
}
}
}
diff --git a/app/src/main/java/com/pixelized/rplexicon/facotry/ConvertCharacterSheetIntoDisplayableFactory.kt b/app/src/main/java/com/pixelized/rplexicon/facotry/ConvertCharacterSheetIntoDisplayableFactory.kt
new file mode 100644
index 0000000..fe0a0c5
--- /dev/null
+++ b/app/src/main/java/com/pixelized/rplexicon/facotry/ConvertCharacterSheetIntoDisplayableFactory.kt
@@ -0,0 +1,186 @@
+package com.pixelized.rplexicon.facotry
+
+import com.pixelized.rplexicon.R
+import com.pixelized.rplexicon.model.CharacterSheet
+import com.pixelized.rplexicon.ui.screens.character.CharacterSheetUio
+import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
+import com.pixelized.rplexicon.ui.screens.character.composable.SavingsThrowsUio
+import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
+import com.pixelized.rplexicon.utilitary.extentions.modifier
+import javax.inject.Inject
+
+class ConvertCharacterSheetIntoDisplayableFactory @Inject constructor() {
+
+ fun toUio(sheet: CharacterSheet): CharacterSheetUio {
+ return CharacterSheetUio(
+ strength = StatUio(
+ label = R.string.character_sheet_stat_strength,
+ value = sheet.strength,
+ modifier = sheet.strength.modifier,
+ ),
+ dexterity = StatUio(
+ label = R.string.character_sheet_stat_dexterity,
+ value = sheet.dexterity,
+ modifier = sheet.dexterity.modifier,
+ ),
+ constitution = StatUio(
+ label = R.string.character_sheet_stat_constitution,
+ value = sheet.constitution,
+ modifier = sheet.constitution.modifier,
+ ),
+ intelligence = StatUio(
+ label = R.string.character_sheet_stat_intelligence,
+ value = sheet.intelligence,
+ modifier = sheet.intelligence.modifier,
+ ),
+ wisdom = StatUio(
+ label = R.string.character_sheet_stat_wisdom,
+ value = sheet.wisdom,
+ modifier = sheet.wisdom.modifier,
+ ),
+ charisma = StatUio(
+ label = R.string.character_sheet_stat_charisma,
+ value = sheet.charisma,
+ modifier = sheet.charisma.modifier,
+ ),
+ strengthSavingThrows = SavingsThrowsUio(
+ label = R.string.character_sheet_stat_strength,
+ multiplier = sheet.strengthSavingThrows,
+ modifier = sheet.strength.modifier + sheet.strengthSavingThrows * sheet.proficiency,
+ ),
+ dexteritySavingThrows = SavingsThrowsUio(
+ label = R.string.character_sheet_stat_dexterity,
+ multiplier = sheet.dexteritySavingThrows,
+ modifier = sheet.dexterity.modifier + sheet.dexteritySavingThrows * sheet.proficiency,
+ ),
+ constitutionSavingThrows = SavingsThrowsUio(
+ label = R.string.character_sheet_stat_constitution,
+ multiplier = sheet.constitutionSavingThrows,
+ modifier = sheet.constitution.modifier + sheet.constitutionSavingThrows * sheet.proficiency,
+ ),
+ intelligenceSavingThrows = SavingsThrowsUio(
+ label = R.string.character_sheet_stat_intelligence,
+ multiplier = sheet.intelligenceSavingThrows,
+ modifier = sheet.intelligence.modifier + sheet.intelligenceSavingThrows * sheet.proficiency,
+ ),
+ wisdomSavingThrows = SavingsThrowsUio(
+ label = R.string.character_sheet_stat_wisdom,
+ multiplier = sheet.wisdomSavingThrows,
+ modifier = sheet.wisdom.modifier + sheet.wisdomSavingThrows * sheet.proficiency,
+ ),
+ charismaSavingThrows = SavingsThrowsUio(
+ label = R.string.character_sheet_stat_charisma,
+ multiplier = sheet.charismaSavingThrows,
+ modifier = sheet.charisma.modifier + sheet.charismaSavingThrows * sheet.proficiency,
+ ),
+ acrobatics = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_acrobatics,
+ related = R.string.character_sheet_stat_dexterity_short,
+ multiplier = sheet.acrobatics,
+ modifier = sheet.dexterity.modifier + sheet.acrobatics * sheet.proficiency,
+ ),
+ animalHandling = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_animal_handling,
+ related = R.string.character_sheet_stat_wisdom_short,
+ multiplier = sheet.animalHandling,
+ modifier = sheet.wisdom.modifier + sheet.animalHandling * sheet.proficiency,
+ ),
+ arcana = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_arcana,
+ related = R.string.character_sheet_stat_intelligence_short,
+ multiplier = sheet.arcana,
+ modifier = sheet.intelligence.modifier + sheet.arcana * sheet.proficiency,
+ ),
+ athletics = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_athletics,
+ related = R.string.character_sheet_stat_strength_short,
+ multiplier = sheet.athletics,
+ modifier = sheet.strength.modifier + sheet.athletics * sheet.proficiency,
+ ),
+ deception = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_deception,
+ related = R.string.character_sheet_stat_charisma_short,
+ multiplier = sheet.deception,
+ modifier = sheet.charisma.modifier + sheet.deception * sheet.proficiency,
+ ),
+ history = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_history,
+ related = R.string.character_sheet_stat_intelligence_short,
+ multiplier = sheet.history,
+ modifier = sheet.intelligence.modifier + sheet.history * sheet.proficiency,
+ ),
+ insight = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_insight,
+ related = R.string.character_sheet_stat_wisdom_short,
+ multiplier = sheet.insight,
+ modifier = sheet.wisdom.modifier + sheet.insight * sheet.proficiency,
+ ),
+ intimidation = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_intimidation,
+ related = R.string.character_sheet_stat_charisma_short,
+ multiplier = sheet.intimidation,
+ modifier = sheet.charisma.modifier + sheet.intimidation * sheet.proficiency,
+ ),
+ investigation = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_investigation,
+ related = R.string.character_sheet_stat_intelligence_short,
+ multiplier = sheet.investigation,
+ modifier = sheet.intelligence.modifier + sheet.investigation * sheet.proficiency,
+ ),
+ medicine = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_medicine,
+ related = R.string.character_sheet_stat_wisdom_short,
+ multiplier = sheet.medicine,
+ modifier = sheet.wisdom.modifier + sheet.medicine * sheet.proficiency,
+ ),
+ nature = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_nature,
+ related = R.string.character_sheet_stat_intelligence_short,
+ multiplier = sheet.nature,
+ modifier = sheet.intelligence.modifier + sheet.nature * sheet.proficiency,
+ ),
+ perception = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_perception,
+ related = R.string.character_sheet_stat_wisdom_short,
+ multiplier = sheet.perception,
+ modifier = sheet.wisdom.modifier + sheet.perception * sheet.proficiency,
+ ),
+ performance = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_performance,
+ related = R.string.character_sheet_stat_charisma_short,
+ multiplier = sheet.performance,
+ modifier = sheet.charisma.modifier + sheet.performance * sheet.proficiency,
+ ),
+ persuasion = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_persuasion,
+ related = R.string.character_sheet_stat_charisma_short,
+ multiplier = sheet.persuasion,
+ modifier = sheet.charisma.modifier + sheet.persuasion * sheet.proficiency,
+ ),
+ religion = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_religion,
+ related = R.string.character_sheet_stat_intelligence_short,
+ multiplier = sheet.religion,
+ modifier = sheet.intelligence.modifier + sheet.religion * sheet.proficiency,
+ ),
+ sleightOfHand = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_sleight_of_hand,
+ related = R.string.character_sheet_stat_dexterity_short,
+ multiplier = sheet.sleightOfHand,
+ modifier = sheet.dexterity.modifier + sheet.sleightOfHand * sheet.proficiency,
+ ),
+ stealth = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_stealth,
+ related = R.string.character_sheet_stat_dexterity_short,
+ multiplier = sheet.stealth,
+ modifier = sheet.dexterity.modifier + sheet.stealth * sheet.proficiency,
+ ),
+ survival = ProficiencyUio(
+ label = R.string.character_sheet_proficiency_survival,
+ related = R.string.character_sheet_stat_wisdom_short,
+ multiplier = sheet.survival,
+ modifier = sheet.wisdom.modifier + sheet.survival * sheet.proficiency,
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/rplexicon/facotry/ConvertRollIntoDisplayableFactory.kt b/app/src/main/java/com/pixelized/rplexicon/facotry/ConvertRollIntoDisplayableFactory.kt
new file mode 100644
index 0000000..4b76b1a
--- /dev/null
+++ b/app/src/main/java/com/pixelized/rplexicon/facotry/ConvertRollIntoDisplayableFactory.kt
@@ -0,0 +1,125 @@
+package com.pixelized.rplexicon.facotry
+
+import com.pixelized.rplexicon.model.Roll
+import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
+import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
+import com.pixelized.rplexicon.utilitary.extentions.icon
+import com.pixelized.rplexicon.utilitary.extentions.toLabel
+import javax.inject.Inject
+import kotlin.math.max
+import kotlin.math.min
+
+class ConvertRollIntoDisplayableFactory @Inject constructor() {
+
+ fun roll(roll: Roll): Pair {
+
+ val mainDices = roll.dices.firstOrNull()
+ val bonusDicesList = roll.dices.subList(fromIndex = 1, toIndex = roll.dices.size)
+ val allRolledValues = mutableListOf()
+
+ val (rollDice, rollDetail) = mainDices?.let { dice ->
+ val (label, sum) = dice.roll()
+ allRolledValues.add(sum)
+
+ val diceIcon = dice.toRollCardUio(result = sum)
+ val cardDetail = dice.toThrowsCardUio(roll = label, result = sum)
+
+ diceIcon to listOf(cardDetail)
+ } ?: (null to emptyList())
+
+ val isCriticalSuccess = rollDice?.isCriticalSuccess ?: false
+ val isCriticalFailure = rollDice?.isCriticalFailure ?: false
+
+ val diceBonus = bonusDicesList.map { dice ->
+ val (label, sum) = dice.roll()
+ allRolledValues.add(sum)
+
+ dice.toThrowsCardUio(
+ roll = label,
+ result = sum,
+ )
+ }
+
+ val flatBonus = roll.bonus.map { bonus ->
+ allRolledValues.add(bonus.value)
+
+ ThrowsCardUio.Detail(
+ title = bonus.label,
+ result = "${bonus.value}",
+ )
+ }
+
+ return rollDice to ThrowsCardUio(
+ title = roll.title,
+ highlight = roll.highlight,
+ dice = mainDices?.faces?.icon,
+ roll = allRolledValues.toLabel(),
+ result = when {
+ isCriticalSuccess -> (mainDices?.faces ?: 20).toString()
+ isCriticalFailure -> "1"
+ else -> "${allRolledValues.sum()}"
+ },
+ isCriticalSuccess = isCriticalSuccess,
+ isCriticalFailure = isCriticalFailure,
+ details = rollDetail + diceBonus + flatBonus,
+ )
+ }
+}
+
+private fun Roll.Dice.toRollCardUio(result: Int) = RollDiceUio(
+ icon = faces.icon,
+ isCriticalSuccess = count == 1 && result == faces,
+ isCriticalFailure = count == 1 && result == 1,
+ result = "$result",
+)
+
+private fun Roll.Dice.toThrowsCardUio(roll: String, result: Int) = ThrowsCardUio.Detail(
+ title = title,
+ throws = ThrowsCardUio.Throw(
+ dice = faces.icon,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ roll = label,
+ result = roll,
+ ),
+ result = "$result",
+)
+
+private data class RollResult(
+ val label: String,
+ val sum: Int,
+)
+
+private fun Roll.Dice.roll(): RollResult {
+ return when {
+ advantage -> {
+ val roll = List(count) {
+ (Math.random() * faces + 1).toInt() to (Math.random() * faces + 1).toInt()
+ }
+ RollResult(
+ label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
+ sum = roll.sumOf { max(it.first, it.second) },
+ )
+ }
+
+ disadvantage -> {
+ val roll = List(count) {
+ (Math.random() * faces + 1).toInt() to (Math.random() * faces + 1).toInt()
+ }
+ RollResult(
+ label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
+ sum = roll.sumOf { min(it.first, it.second) },
+ )
+ }
+
+ else -> {
+ val roll = List(count) {
+ (Math.random() * faces + 1).toInt()
+ }
+ RollResult(
+ label = roll.toLabel(),
+ sum = roll.sum(),
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/rplexicon/facotry/RollParser.kt b/app/src/main/java/com/pixelized/rplexicon/facotry/RollParser.kt
index 152049d..82b4b3d 100644
--- a/app/src/main/java/com/pixelized/rplexicon/facotry/RollParser.kt
+++ b/app/src/main/java/com/pixelized/rplexicon/facotry/RollParser.kt
@@ -2,6 +2,7 @@ package com.pixelized.rplexicon.facotry
import com.pixelized.rplexicon.model.CharacterSheet
import com.pixelized.rplexicon.model.Roll
+import com.pixelized.rplexicon.utilitary.extentions.modifier
import javax.inject.Inject
class RollParser @Inject constructor() {
@@ -17,14 +18,15 @@ class RollParser @Inject constructor() {
val bonus = bonusRegex.findAll(item).map { bonus ->
Roll.Bonus(
label = bonus.value,
- bonus = bonus.value.parseBonus(characterSheet = characterSheet),
+ value = bonus.value.parseBonus(characterSheet = characterSheet),
)
}
dices.toList() to bonus.toList()
} ?: (null to null)
return Roll(
- label = label.toString(),
+ title = label.toString(),
+ highlight = null,
dices = dices ?: emptyList(),
bonus = bonus ?: emptyList(),
)
@@ -34,14 +36,13 @@ class RollParser @Inject constructor() {
characterSheet: CharacterSheet,
): Int = when (this?.lowercase()) {
"bonus" -> characterSheet.proficiency
- "force" -> characterSheet.strengthBonus
+ "force" -> characterSheet.strength.modifier
else -> 0
}
private fun MatchResult.parseDice(): Roll.Dice {
val (count, faces) = destructured
return Roll.Dice(
- label = value,
count = count.toIntOrNull() ?: 0,
faces = faces.toIntOrNull() ?: 0,
)
diff --git a/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheet.kt b/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheet.kt
index 0ed7116..10842c2 100644
--- a/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheet.kt
+++ b/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheet.kt
@@ -1,8 +1,5 @@
package com.pixelized.rplexicon.model
-import androidx.compose.runtime.Stable
-
-@Stable
data class CharacterSheet(
val hitPoint: Int, // Point de vie
val armorClass: Int, // Classe d'armure
@@ -37,35 +34,7 @@ data class CharacterSheet(
val sleightOfHand: Int, // DEX, Représentation
val stealth: Int, // DEX, Survie
val survival: Int, // WIS, Tromperie
-) {
- val proficiencyBonus: Int = kotlin.math.floor(proficiency / 2 - 5f).toInt()
- val strengthBonus: Int = kotlin.math.floor(strength / 2 - 5f).toInt()
- val dexterityBonus: Int = kotlin.math.floor(dexterity / 2 - 5f).toInt()
- val constitutionBonus: Int = kotlin.math.floor(constitution / 2 - 5f).toInt()
- val intelligenceBonus: Int = kotlin.math.floor(intelligence / 2 - 5f).toInt()
-}
-
-@Stable
-data class Roll(
- val label: String,
- val dices: List,
- val bonus: List,
-) {
- @Stable
- data class Dice(
- val label: String,
- val count: Int,
- val faces: Int,
- )
-
- @Stable
- data class Bonus(
- val label: String,
- val bonus: Int,
- )
-}
-
-
+)
diff --git a/app/src/main/java/com/pixelized/rplexicon/model/Roll.kt b/app/src/main/java/com/pixelized/rplexicon/model/Roll.kt
new file mode 100644
index 0000000..2bccd99
--- /dev/null
+++ b/app/src/main/java/com/pixelized/rplexicon/model/Roll.kt
@@ -0,0 +1,108 @@
+package com.pixelized.rplexicon.model
+
+import androidx.compose.runtime.Stable
+
+@Stable
+data class Roll(
+ val title: String,
+ val highlight: String? = null,
+ val dices: List,
+ val bonus: List,
+) {
+ @Stable
+ data class Dice(
+ val title: String? = null,
+ val advantage: Boolean = false,
+ val disadvantage: Boolean = false,
+ val count: Int,
+ val faces: Int,
+ ) {
+ val label: String = "${count}d${faces}"
+
+ companion object {
+ fun d20(
+ title: String? = null,
+ advantage: Boolean = false,
+ disadvantage: Boolean = false,
+ amount: Int = 1,
+ ) = Dice(
+ title = title,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ count = amount,
+ faces = 20,
+ )
+
+ fun d12(
+ title: String? = null,
+ advantage: Boolean = false,
+ disadvantage: Boolean = false,
+ amount: Int = 1,
+ ) = Dice(
+ title = title,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ count = amount,
+ faces = 12,
+ )
+
+ fun d10(
+ title: String? = null,
+ advantage: Boolean = false,
+ disadvantage: Boolean = false,
+ amount: Int = 1,
+ ) = Dice(
+ title = title,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ count = amount,
+ faces = 10,
+ )
+
+ fun d8(
+ title: String? = null,
+ advantage: Boolean = false,
+ disadvantage: Boolean = false,
+ amount: Int = 1,
+ ) = Dice(
+ title = title,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ count = amount,
+ faces = 8,
+ )
+
+ fun d6(
+ title: String? = null,
+ advantage: Boolean = false,
+ disadvantage: Boolean = false,
+ amount: Int = 1,
+ ) = Dice(
+ title = title,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ count = amount,
+ faces = 6,
+ )
+
+ fun d4(
+ title: String? = null,
+ advantage: Boolean = false,
+ disadvantage: Boolean = false,
+ amount: Int = 1,
+ ) = Dice(
+ title = title,
+ advantage = advantage,
+ disadvantage = disadvantage,
+ count = amount,
+ faces = 4,
+ )
+ }
+ }
+
+ @Stable
+ data class Bonus(
+ val label: String,
+ val value: Int,
+ )
+}
diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/CharacterSheetRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/CharacterSheetRepository.kt
index 6c7c48e..aa7ac07 100644
--- a/app/src/main/java/com/pixelized/rplexicon/repository/CharacterSheetRepository.kt
+++ b/app/src/main/java/com/pixelized/rplexicon/repository/CharacterSheetRepository.kt
@@ -1,12 +1,13 @@
package com.pixelized.rplexicon.repository
-import android.util.Log
import com.google.api.services.sheets.v4.model.ValueRange
import com.pixelized.rplexicon.facotry.RollParser
import com.pixelized.rplexicon.model.CharacterSheet
import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure
import com.pixelized.rplexicon.utilitary.exceptions.ServiceNotReady
import com.pixelized.rplexicon.utilitary.extentions.sheet
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
import javax.inject.Singleton
@@ -15,6 +16,13 @@ class CharacterSheetRepository @Inject constructor(
private val googleRepository: GoogleSheetServiceRepository,
private val rollParser: RollParser,
) {
+ private val _data = MutableStateFlow