Compare commits
No commits in common. "56f95094c6c9a1c9df3d92e0c78affb406f13f61" and "7cac929b938e5932b8dd2e318d0955cf2871d14f" have entirely different histories.
56f95094c6
...
7cac929b93
|
|
@ -34,7 +34,7 @@ android {
|
||||||
applicationId = "com.pixelized.rplexicon"
|
applicationId = "com.pixelized.rplexicon"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionName = "0.13.5"
|
versionName = "0.13.0"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.pixelized.rplexicon.data.repository.character.ActionRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||||
|
import com.pixelized.rplexicon.data.repository.character.EquipmentRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.SkillRepository
|
import com.pixelized.rplexicon.data.repository.character.SkillRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.SpellRepository
|
import com.pixelized.rplexicon.data.repository.character.SpellRepository
|
||||||
|
|
@ -43,6 +44,7 @@ class LauncherViewModel @Inject constructor(
|
||||||
skillRepository: SkillRepository,
|
skillRepository: SkillRepository,
|
||||||
descriptionRepository: DescriptionRepository,
|
descriptionRepository: DescriptionRepository,
|
||||||
itemsRepository: ItemsRepository,
|
itemsRepository: ItemsRepository,
|
||||||
|
equipmentRepository: EquipmentRepository,
|
||||||
removeConRepository: RemoteConfigRepository // Unused but injected to initialize it.
|
removeConRepository: RemoteConfigRepository // Unused but injected to initialize it.
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
|
|
@ -110,6 +112,14 @@ class LauncherViewModel @Inject constructor(
|
||||||
_error.emit(FetchErrorUio.Structure(type = Type.INVENTORY))
|
_error.emit(FetchErrorUio.Structure(type = Type.INVENTORY))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val equipment = async {
|
||||||
|
try {
|
||||||
|
equipmentRepository.fetchEquipment()
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, exception.message, exception)
|
||||||
|
_error.emit(FetchErrorUio.Structure(type = Type.EQUIPMENT))
|
||||||
|
}
|
||||||
|
}
|
||||||
awaitAll(characterSheet)
|
awaitAll(characterSheet)
|
||||||
|
|
||||||
val alteration = async {
|
val alteration = async {
|
||||||
|
|
@ -146,7 +156,7 @@ class LauncherViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
awaitAll(order, lexicon, location, quest)
|
awaitAll(order, lexicon, location, quest)
|
||||||
awaitAll(description, inventory, alteration, action, spell, skill)
|
awaitAll(description, inventory, equipment, alteration, action, spell, skill)
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import com.pixelized.rplexicon.utilitary.extentions.local.emphasis
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.fail
|
import com.pixelized.rplexicon.utilitary.extentions.local.fail
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.isBrutalCritical
|
import com.pixelized.rplexicon.utilitary.extentions.local.isBrutalCritical
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.isCritical
|
import com.pixelized.rplexicon.utilitary.extentions.local.isCritical
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.isImprovedCritical
|
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.isSavageAttacks
|
import com.pixelized.rplexicon.utilitary.extentions.local.isSavageAttacks
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.primary
|
import com.pixelized.rplexicon.utilitary.extentions.local.primary
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.secondary
|
import com.pixelized.rplexicon.utilitary.extentions.local.secondary
|
||||||
|
|
@ -739,7 +738,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
val emphasis = status[ability].emphasis
|
val emphasis = status[ability].emphasis
|
||||||
|
|
||||||
// compute the amount of main dice to throw.
|
// compute the amount of main dice to throw.
|
||||||
val amount = if (status[ability].isCritical) {
|
val amount = if (status.isCritical) {
|
||||||
diceThrow?.dice?.count?.times(2)?.let {
|
diceThrow?.dice?.count?.times(2)?.let {
|
||||||
if (ability == Property.PHYSICAL_MELEE_DAMAGE && status.isSavageAttacks) it.plus(
|
if (ability == Property.PHYSICAL_MELEE_DAMAGE && status.isSavageAttacks) it.plus(
|
||||||
1
|
1
|
||||||
|
|
@ -775,17 +774,9 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
// check for flat dice bonus (ex: healing potion 2d4 + 2)
|
// check for flat dice bonus (ex: healing potion 2d4 + 2)
|
||||||
val relatedFlatBonus = diceThrow.flatBonus(name = action)
|
val relatedFlatBonus = diceThrow.flatBonus(name = action)
|
||||||
|
|
||||||
// if the roll can be a critical roll check if the roll is one.
|
// compute the final roll result
|
||||||
val isCriticalSuccess = when {
|
|
||||||
canMakeCriticalRoll && result.value == 20 -> true
|
|
||||||
canMakeCriticalRoll && result.value == 19 && status.isImprovedCritical -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute the roll result. by default display a sum of everything except on a critical
|
|
||||||
val rollResult = when {
|
val rollResult = when {
|
||||||
isCriticalSuccess && result.value == 20 -> "20"
|
canMakeCriticalRoll && result.value == 20 -> "20"
|
||||||
isCriticalSuccess && result.value == 19 -> "19"
|
|
||||||
canMakeCriticalRoll && result.value == 1 -> "1"
|
canMakeCriticalRoll && result.value == 1 -> "1"
|
||||||
else -> "${allValue.sum()}"
|
else -> "${allValue.sum()}"
|
||||||
}
|
}
|
||||||
|
|
@ -794,7 +785,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
return DiceThrowResult(
|
return DiceThrowResult(
|
||||||
dice = RollDiceUio(
|
dice = RollDiceUio(
|
||||||
icon = diceThrow?.dice?.icon ?: R.drawable.ic_d20_24,
|
icon = diceThrow?.dice?.icon ?: R.drawable.ic_d20_24,
|
||||||
isCriticalSuccess = isCriticalSuccess,
|
isCriticalSuccess = canMakeCriticalRoll && result.value == 20,
|
||||||
isCriticalFailure = canMakeCriticalRoll && result.value == 1,
|
isCriticalFailure = canMakeCriticalRoll && result.value == 1,
|
||||||
result = rollResult,
|
result = rollResult,
|
||||||
),
|
),
|
||||||
|
|
@ -803,7 +794,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
title = titleString.uppercase(),
|
title = titleString.uppercase(),
|
||||||
highlight = action.uppercase(),
|
highlight = action.uppercase(),
|
||||||
face = diceThrow?.dice?.faces ?: 20,
|
face = diceThrow?.dice?.faces ?: 20,
|
||||||
isCriticalSuccess = isCriticalSuccess,
|
isCriticalSuccess = canMakeCriticalRoll && result.value == 20,
|
||||||
isCriticalFailure = canMakeCriticalRoll && result.value == 1,
|
isCriticalFailure = canMakeCriticalRoll && result.value == 1,
|
||||||
roll = allValue.toLabel(),
|
roll = allValue.toLabel(),
|
||||||
result = rollResult,
|
result = rollResult,
|
||||||
|
|
@ -1079,7 +1070,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
return this?.flatMap { status ->
|
return this?.flatMap { status ->
|
||||||
status.dices.map { dice ->
|
status.dices.map { dice ->
|
||||||
val localRoll = roll(
|
val localRoll = roll(
|
||||||
amount = if (isCritical) dice.count * 2 else dice.count,
|
amount = if (this@ThrowScope.status.isCritical) dice.count * 2 else dice.count,
|
||||||
faces = dice.faces,
|
faces = dice.faces,
|
||||||
advantage = dice.advantage,
|
advantage = dice.advantage,
|
||||||
disadvantage = dice.disadvantage,
|
disadvantage = dice.disadvantage,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import androidx.annotation.StringRes
|
||||||
import com.pixelized.rplexicon.R
|
import com.pixelized.rplexicon.R
|
||||||
|
|
||||||
data class CharacterSheet(
|
data class CharacterSheet(
|
||||||
val active: Boolean,
|
|
||||||
val name: String,
|
val name: String,
|
||||||
val race: String?,
|
val race: String?,
|
||||||
val proficiency: Int, // Bonus de maîtrise
|
val proficiency: Int, // Bonus de maîtrise
|
||||||
|
|
@ -23,7 +22,7 @@ data class CharacterSheet(
|
||||||
val spell9: Int?, // level 9 spell slot
|
val spell9: Int?, // level 9 spell slot
|
||||||
val dC: Int?, // offensive saving throw.
|
val dC: Int?, // offensive saving throw.
|
||||||
val armorClass: Int, // Classe d'armure
|
val armorClass: Int, // Classe d'armure
|
||||||
val speed: Float, // Vitesse
|
val speed: Int, // Vitesse
|
||||||
val strength: Int, // Force
|
val strength: Int, // Force
|
||||||
val dexterity: Int, // Dextérité
|
val dexterity: Int, // Dextérité
|
||||||
val constitution: Int, // Constitution
|
val constitution: Int, // Constitution
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ class CharacterSheetParser @Inject constructor(
|
||||||
val name = item.parse(column = NAME)
|
val name = item.parse(column = NAME)
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
CharacterSheet(
|
CharacterSheet(
|
||||||
active = item.parseBool(column = ACTIVE) ?: false,
|
|
||||||
name = name,
|
name = name,
|
||||||
race = item.parse(column = RACE),
|
race = item.parse(column = RACE),
|
||||||
proficiency = item.parseInt(column = MASTERY) ?: 2,
|
proficiency = item.parseInt(column = MASTERY) ?: 2,
|
||||||
|
|
@ -51,7 +50,7 @@ class CharacterSheetParser @Inject constructor(
|
||||||
spell9 = item.parseInt(column = SPELL_LEVEL_9),
|
spell9 = item.parseInt(column = SPELL_LEVEL_9),
|
||||||
dC = item.parseInt(column = DD_SAVE_THROW),
|
dC = item.parseInt(column = DD_SAVE_THROW),
|
||||||
armorClass = item.parseInt(column = ARMOR_CLASS) ?: 10,
|
armorClass = item.parseInt(column = ARMOR_CLASS) ?: 10,
|
||||||
speed = item.parseFloat(column = SPEED) ?: 10f,
|
speed = item.parseInt(column = SPEED) ?: 10,
|
||||||
strength = item.parseInt(column = STRENGTH) ?: 10,
|
strength = item.parseInt(column = STRENGTH) ?: 10,
|
||||||
dexterity = item.parseInt(column = DEXTERITY) ?: 10,
|
dexterity = item.parseInt(column = DEXTERITY) ?: 10,
|
||||||
constitution = item.parseInt(column = CONSTITUTION) ?: 10,
|
constitution = item.parseInt(column = CONSTITUTION) ?: 10,
|
||||||
|
|
@ -104,7 +103,6 @@ class CharacterSheetParser @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val ACTIVE = column("Actif")
|
|
||||||
private val NAME = column("Nom")
|
private val NAME = column("Nom")
|
||||||
private val RACE = column("Race")
|
private val RACE = column("Race")
|
||||||
private val LEVEL = column("Niveau")
|
private val LEVEL = column("Niveau")
|
||||||
|
|
@ -159,7 +157,6 @@ class CharacterSheetParser @Inject constructor(
|
||||||
|
|
||||||
private val ROWS
|
private val ROWS
|
||||||
get() = listOf(
|
get() = listOf(
|
||||||
ACTIVE,
|
|
||||||
NAME,
|
NAME,
|
||||||
RACE,
|
RACE,
|
||||||
LEVEL,
|
LEVEL,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.pixelized.rplexicon.data.parser.inventory
|
||||||
|
|
||||||
|
import com.google.api.services.sheets.v4.model.ValueRange
|
||||||
|
import com.pixelized.rplexicon.data.model.Equipment
|
||||||
|
import com.pixelized.rplexicon.data.parser.parserScope
|
||||||
|
import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EquipmentParser @Inject constructor() {
|
||||||
|
|
||||||
|
@Throws(IncompatibleSheetStructure::class)
|
||||||
|
fun parse(data: ValueRange): Map<String, Equipment> = parserScope {
|
||||||
|
lateinit var characters: List<String>
|
||||||
|
val equipments = hashMapOf<String, Equipment.Builder>()
|
||||||
|
|
||||||
|
data.forEachRowIndexed { index, row ->
|
||||||
|
when (index) {
|
||||||
|
// ignore the first column
|
||||||
|
0 -> characters = row.drop(1).map { it.toString() }
|
||||||
|
|
||||||
|
else -> row.drop(1).forEachIndexed { column, item ->
|
||||||
|
val character = characters[column]
|
||||||
|
equipments.getEquipment(name = character).let {
|
||||||
|
when (row[0]) {
|
||||||
|
BACKGROUND -> it.background = item.toItem()
|
||||||
|
HEAD -> it.head = item.toItem()
|
||||||
|
FACE -> it.face = item.toItem()
|
||||||
|
NECK -> it.neck = item.toItem()
|
||||||
|
SHOULDER -> it.shoulder = item.toItem()
|
||||||
|
BODY -> it.body = item.toItem()
|
||||||
|
CHEST -> it.chest = item.toItem()
|
||||||
|
ARM -> it.arm = item.toItem()
|
||||||
|
HAND -> it.hand = item.toItem()
|
||||||
|
RING_1 -> it.ring1 = item.toItem()
|
||||||
|
RING_2 -> it.ring2 = item.toItem()
|
||||||
|
WAIST -> it.waist = item.toItem()
|
||||||
|
FOOT -> it.foot = item.toItem()
|
||||||
|
MAIN_HAND -> it.mainHand = item.toItem()
|
||||||
|
OFF_HAND -> it.offHand = item.toItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return@parserScope characters.associateWith {
|
||||||
|
equipments.getEquipment(name = it).build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun HashMap<String, Equipment.Builder>.getEquipment(name: String) =
|
||||||
|
this.getOrPut(name) { Equipment.Builder() }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val BACKGROUND = "Silhouette"
|
||||||
|
private const val HEAD = "Tête"
|
||||||
|
private const val FACE = "Visage"
|
||||||
|
private const val NECK = "Gorge"
|
||||||
|
private const val SHOULDER = "Épaules"
|
||||||
|
private const val BODY = "Corp"
|
||||||
|
private const val CHEST = "Torse"
|
||||||
|
private const val ARM = "Bras"
|
||||||
|
private const val HAND = "Mains"
|
||||||
|
private const val RING_1 = "Anneau 1"
|
||||||
|
private const val RING_2 = "Anneau 2"
|
||||||
|
private const val WAIST = "Taille"
|
||||||
|
private const val FOOT = "Pieds"
|
||||||
|
private const val MAIN_HAND = "Main droite"
|
||||||
|
private const val OFF_HAND = "Main gauche"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.pixelized.rplexicon.data.repository.character
|
||||||
|
|
||||||
|
import com.pixelized.rplexicon.data.model.Equipment
|
||||||
|
import com.pixelized.rplexicon.data.parser.inventory.EquipmentParser
|
||||||
|
import com.pixelized.rplexicon.data.repository.CharacterBinder
|
||||||
|
import com.pixelized.rplexicon.data.repository.GoogleSheetServiceRepository
|
||||||
|
import com.pixelized.rplexicon.utilitary.Update
|
||||||
|
import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class EquipmentRepository @Inject constructor(
|
||||||
|
private val googleRepository: GoogleSheetServiceRepository,
|
||||||
|
private val equipmentParser: EquipmentParser,
|
||||||
|
) {
|
||||||
|
private val _data = MutableStateFlow<Map<String, Equipment>>(emptyMap())
|
||||||
|
val data: StateFlow<Map<String, Equipment>> get() = _data
|
||||||
|
|
||||||
|
var lastSuccessFullUpdate: Update = Update.INITIAL
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun find(name: String?): Equipment? = _data.value[name]
|
||||||
|
|
||||||
|
@Throws(IncompatibleSheetStructure::class, Exception::class)
|
||||||
|
suspend fun fetchEquipment() {
|
||||||
|
googleRepository.fetch { sheet ->
|
||||||
|
val request = sheet.get(CharacterBinder.ID, CharacterBinder.EQUIPMENT)
|
||||||
|
val data = equipmentParser.parse(data = request.execute())
|
||||||
|
_data.tryEmit(data)
|
||||||
|
lastSuccessFullUpdate = Update.currentTime()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -320,10 +320,7 @@ private fun rememberPortrait(): List<Int> = rememberSaveable {
|
||||||
listOf(
|
listOf(
|
||||||
R.drawable.im_brulkhai,
|
R.drawable.im_brulkhai,
|
||||||
R.drawable.im_leandre,
|
R.drawable.im_leandre,
|
||||||
listOf(
|
R.drawable.im_nelia,
|
||||||
R.drawable.im_nelia,
|
|
||||||
R.drawable.im_nam,
|
|
||||||
).shuffled().first(),
|
|
||||||
R.drawable.im_tigrane,
|
R.drawable.im_tigrane,
|
||||||
R.drawable.im_unathana,
|
R.drawable.im_unathana,
|
||||||
).shuffled()
|
).shuffled()
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,10 @@ enum class CharacterTabUio(@StringRes val label: Int) {
|
||||||
Proficiency(R.string.character_sheet_tab_proficiency),
|
Proficiency(R.string.character_sheet_tab_proficiency),
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(
|
||||||
|
ExperimentalMaterialApi::class,
|
||||||
|
ExperimentalFoundationApi::class,
|
||||||
|
)
|
||||||
@Composable
|
@Composable
|
||||||
fun CharacterSheetScreen(
|
fun CharacterSheetScreen(
|
||||||
viewModel: CharacterSheetViewModel = hiltViewModel(),
|
viewModel: CharacterSheetViewModel = hiltViewModel(),
|
||||||
|
|
@ -487,6 +490,7 @@ private fun CharacterScreenPreview(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun BackHandler(
|
private fun BackHandler(
|
||||||
sheetState: ModalBottomSheetState,
|
sheetState: ModalBottomSheetState,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.pixelized.rplexicon.data.repository.character.ActionRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
|
||||||
|
import com.pixelized.rplexicon.data.repository.character.EquipmentRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
import com.pixelized.rplexicon.data.repository.character.ItemsRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.SkillRepository
|
import com.pixelized.rplexicon.data.repository.character.SkillRepository
|
||||||
import com.pixelized.rplexicon.data.repository.character.SpellRepository
|
import com.pixelized.rplexicon.data.repository.character.SpellRepository
|
||||||
|
|
@ -32,6 +33,7 @@ class CharacterSheetViewModel @Inject constructor(
|
||||||
private val descriptionRepository: DescriptionRepository,
|
private val descriptionRepository: DescriptionRepository,
|
||||||
private val alterationRepository: AlterationRepository,
|
private val alterationRepository: AlterationRepository,
|
||||||
private val itemsRepository: ItemsRepository,
|
private val itemsRepository: ItemsRepository,
|
||||||
|
private val equipmentRepository: EquipmentRepository,
|
||||||
private val actionRepository: ActionRepository,
|
private val actionRepository: ActionRepository,
|
||||||
private val spellRepository: SpellRepository,
|
private val spellRepository: SpellRepository,
|
||||||
private val skillRepository: SkillRepository,
|
private val skillRepository: SkillRepository,
|
||||||
|
|
@ -91,6 +93,16 @@ class CharacterSheetViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val equipment = async {
|
||||||
|
if (force || equipmentRepository.lastSuccessFullUpdate.shouldUpdate()) {
|
||||||
|
try {
|
||||||
|
equipmentRepository.fetchEquipment()
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, exception.message, exception)
|
||||||
|
_error.emit(FetchErrorUio.Structure(type = Type.EQUIPMENT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
awaitAll(characters)
|
awaitAll(characters)
|
||||||
val alterations = async {
|
val alterations = async {
|
||||||
if (force || alterationRepository.lastSuccessFullUpdate.shouldUpdate()) {
|
if (force || alterationRepository.lastSuccessFullUpdate.shouldUpdate()) {
|
||||||
|
|
@ -132,7 +144,7 @@ class CharacterSheetViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
awaitAll(description, alterations, inventory, actions, spells, skills)
|
awaitAll(description, alterations, inventory, equipment, actions, spells, skills)
|
||||||
_isLoading.value = false
|
_isLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ class CharacterSheetUioFactory @Inject constructor() {
|
||||||
),
|
),
|
||||||
speed = LabelPointUio(
|
speed = LabelPointUio(
|
||||||
label = R.string.character_sheet_title_speed,
|
label = R.string.character_sheet_title_speed,
|
||||||
value = "${max(sheet.speed + status[Property.SPEED].sum.toFloat(), 0f)}m",
|
value = "${max(sheet.speed + status[Property.SPEED].sum, 0)}m",
|
||||||
),
|
),
|
||||||
masteries = MasteriesUio(
|
masteries = MasteriesUio(
|
||||||
martial = sheet.martial,
|
martial = sheet.martial,
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,6 @@ class SpellUioFactory @Inject constructor(
|
||||||
val modifier = diceThrow.modifier.sumOf {
|
val modifier = diceThrow.modifier.sumOf {
|
||||||
when (it) {
|
when (it) {
|
||||||
Property.PROFICIENCY -> characterSheet.proficiency
|
Property.PROFICIENCY -> characterSheet.proficiency
|
||||||
Property.STRENGTH -> characterSheet.strength.modifier
|
|
||||||
Property.DEXTERITY -> characterSheet.dexterity.modifier
|
|
||||||
Property.CONSTITUTION -> characterSheet.constitution.modifier
|
|
||||||
Property.INTELLIGENCE -> characterSheet.intelligence.modifier
|
Property.INTELLIGENCE -> characterSheet.intelligence.modifier
|
||||||
Property.WISDOM -> characterSheet.wisdom.modifier
|
Property.WISDOM -> characterSheet.wisdom.modifier
|
||||||
Property.CHARISMA -> characterSheet.charisma.modifier
|
Property.CHARISMA -> characterSheet.charisma.modifier
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,7 @@ fun InventoryPage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun InventoryContent(
|
private fun InventoryContent(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -247,6 +248,7 @@ private fun InventoryContent(
|
||||||
when (item) {
|
when (item) {
|
||||||
is String -> CategoryHeader(
|
is String -> CategoryHeader(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.animateItem()
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(
|
.padding(
|
||||||
start = 16.dp,
|
start = 16.dp,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.composable.draggable
|
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.composable.draggable
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DraggableInventoryElement(
|
fun LazyGridItemScope.DraggableInventoryElement(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
dragDropState: InventoryDragDropState,
|
dragDropState: InventoryDragDropState,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
|
@ -15,6 +18,7 @@ fun DraggableInventoryElement(
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.animateItem()
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
dragDropState.draggedItemElement?.let { element ->
|
dragDropState.draggedItemElement?.let { element ->
|
||||||
this.alpha = when {
|
this.alpha = when {
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,11 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.shape.CutCornerShape
|
import androidx.compose.foundation.shape.CutCornerShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
|
@ -185,9 +183,7 @@ private fun ItemDetailContent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxWidth(),
|
||||||
.fillMaxWidth()
|
|
||||||
.verticalScroll(state = rememberScrollState()),
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(
|
modifier = Modifier.padding(
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,7 @@ import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -148,7 +146,7 @@ class SummaryFactory @Inject constructor(
|
||||||
val data = DataStruct()
|
val data = DataStruct()
|
||||||
characterSheetRepository.data
|
characterSheetRepository.data
|
||||||
.combine(activeAlterationRepository.getActiveAlterations()) { sheets, alterations ->
|
.combine(activeAlterationRepository.getActiveAlterations()) { sheets, alterations ->
|
||||||
data.sheets = sheets.filter { entry -> entry.value.active }
|
data.sheets = sheets
|
||||||
data.alterations = alterations
|
data.alterations = alterations
|
||||||
}
|
}
|
||||||
.combine(firebaseRepository.getCharacters()) { _, fire ->
|
.combine(firebaseRepository.getCharacters()) { _, fire ->
|
||||||
|
|
@ -218,7 +216,7 @@ class SummaryFactory @Inject constructor(
|
||||||
label = (dexterity.modifier + status[Property.INITIATIVE].sum).toLabel()
|
label = (dexterity.modifier + status[Property.INITIATIVE].sum).toLabel()
|
||||||
)
|
)
|
||||||
val speed = label(
|
val speed = label(
|
||||||
label = "${max(sheet.speed + status[Property.SPEED].sum.toFloat(), 0f)}m",
|
label = "${max(sheet.speed + status[Property.SPEED].sum, 0)}m",
|
||||||
)
|
)
|
||||||
val inspiration = proficiency(
|
val inspiration = proficiency(
|
||||||
label = null,
|
label = null,
|
||||||
|
|
@ -655,7 +653,7 @@ class SummaryFactory @Inject constructor(
|
||||||
val data = HeaderStatStruct()
|
val data = HeaderStatStruct()
|
||||||
characterSheetRepository.data
|
characterSheetRepository.data
|
||||||
.combine(throwRepository.getThrows()) { sheets, fire ->
|
.combine(throwRepository.getThrows()) { sheets, fire ->
|
||||||
data.sheets = sheets.filter { entry -> entry.value.active }
|
data.sheets = sheets
|
||||||
data.fires = fire.details
|
data.fires = fire.details
|
||||||
}
|
}
|
||||||
.collect {
|
.collect {
|
||||||
|
|
|
||||||
|
|
@ -224,65 +224,7 @@ object ImageCache {
|
||||||
"https://bg3.wiki/w/images/f/f7/Magic_Initiate_Bard_Icon.webp" to R.drawable.icbg_magic_initiate_bard,
|
"https://bg3.wiki/w/images/f/f7/Magic_Initiate_Bard_Icon.webp" to R.drawable.icbg_magic_initiate_bard,
|
||||||
"https://bg3.wiki/w/images/f/f9/Mage_Hand_Icon.webp" to R.drawable.icbg_mage_hand,
|
"https://bg3.wiki/w/images/f/f9/Mage_Hand_Icon.webp" to R.drawable.icbg_mage_hand,
|
||||||
"https://bg3.wiki/w/images/f/fb/Camp_Rich_B_Purple_Unfaded.png" to R.drawable.icbg_camp_rich_b_purple_unfaded,
|
"https://bg3.wiki/w/images/f/fb/Camp_Rich_B_Purple_Unfaded.png" to R.drawable.icbg_camp_rich_b_purple_unfaded,
|
||||||
"https://bg3.wiki/w/images/b/ba/Rakish_Audacity_Icon.webp" to R.drawable.icbg_rakish_audacity,
|
|
||||||
"https://bg3.wiki/w/images/4/4d/Action_Surge_Icon.webp" to R.drawable.icbg_action_surge_icon,
|
|
||||||
"https://bg3.wiki/w/images/a/a6/Lever_Handle_Unfaded_Icon.png" to R.drawable.icbg_lever_handle_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/a/a5/Pouch_A_Unfaded_Icon.webp" to R.drawable.icbg_pouch_a_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/8/8f/Knife_A_Unfaded_Icon.png" to R.drawable.icbg_knife_a_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/7/78/Studded_Leather_Unfaded_Icon.png" to R.drawable.icbg_studded_leather_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/3/34/Book_Parchment_A_Unfaded.png" to R.drawable.icbg_book_parchment_a_unfaded,
|
|
||||||
"https://bg3.wiki/w/images/2/21/Book_Note_H_Unfaded.png" to R.drawable.icbg_book_note_h_unfaded,
|
|
||||||
"https://bg3.wiki/w/images/7/7b/Book_Grimoire_Unfaded_Icon.png" to R.drawable.icbg_book_grimoire_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/0/02/Gnome_Cunning_Icon.webp" to R.drawable.icbg_gnome_cunning_icon,
|
|
||||||
"https://bg3.wiki/w/images/d/d2/Training_in_War_and_Song_Icon.webp" to R.drawable.icbg_training_in_war_and_song_icon,
|
|
||||||
"https://bg3.wiki/w/images/e/ed/Arcane_Recovery_Icon.webp" to R.drawable.icbg_arcane_recovery_icon,
|
|
||||||
"https://bg3.wiki/w/images/8/80/Bladesong_Icon.webp" to R.drawable.icbg_bladesong_icon,
|
|
||||||
"https://bg3.wiki/w/images/f/fd/Booming_Blade_Icon.webp" to R.drawable.icbg_booming_blade_icon,
|
|
||||||
"https://bg3.wiki/w/images/2/23/Fire_Bolt_Icon.webp" to R.drawable.icbg_fire_bolt_icon,
|
|
||||||
"https://bg3.wiki/w/images/7/7f/Command_Halt_Icon.webp" to R.drawable.icbg_command_halt_icon,
|
|
||||||
"https://bg3.wiki/w/images/0/0d/Mage_Armour_Icon.webp" to R.drawable.icbg_mage_armour_icon,
|
|
||||||
"https://bg3.wiki/w/images/1/17/Ice_Knife_Icon.webp" to R.drawable.icbg_ice_knife_icon,
|
|
||||||
"https://bg3.wiki/w/images/8/8d/Disguise_Self_Icon.webp" to R.drawable.icbg_disguise_self_icon,
|
|
||||||
"https://bg3.wiki/w/images/d/d4/Magic_Missile_Icon.webp" to R.drawable.icbg_magic_missile_icon,
|
|
||||||
"https://bg3.wiki/w/images/6/6e/Shadow_Blade_Icon.webp" to R.drawable.icbg_shadow_blade_icon,
|
|
||||||
"https://bg3.wiki/w/images/b/b9/Wild_Shape_Icon.webp" to R.drawable.icbg_wild_shape_icon,
|
|
||||||
"https://bg3.wiki/w/images/c/c3/See_Invisibility_Icon.webp" to R.drawable.icbg_see_invisibility_icon,
|
|
||||||
"https://bg3.wiki/w/images/5/50/Counterspell_Icon.webp" to R.drawable.icbg_counterspell_icon,
|
|
||||||
"https://bg3.wiki/w/images/0/0a/Unshackling_Strike_Icon.webp" to R.drawable.icbg_unshackling_strike_icon,
|
|
||||||
"https://bg3.wiki/w/images/7/7f/Remove_Curse_Icon.webp" to R.drawable.icbg_remove_curse_icon,
|
|
||||||
"https://bg3.wiki/w/images/4/46/Aberrant_Shape_Icon.webp" to R.drawable.icbg_aberrant_shape_icon,
|
|
||||||
"https://bg3.wiki/w/images/f/f6/Polymorph_Icon.webp" to R.drawable.icbg_polymorph_icon,
|
|
||||||
"https://bg3.wiki/w/images/8/8b/Dueller%27s_Enthusiasm_Icon.webp" to R.drawable.icbg_dueller_enthusiasm_icon,
|
|
||||||
"https://bg3.wiki/w/images/f/ff/Camp_Circus_B_Unfaded_Icon.webp" to R.drawable.icbg_camp_circus_b_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/f/f2/Camp_Aristocrat_Unfaded_Icon.webp" to R.drawable.icbg_camp_aristocrat_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/1/1d/Camp_Rich_C_Red_Unfaded_Icon.webp" to R.drawable.icbg_camp_rich_c_red_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/8/85/Strange_Chunk_of_Amber_Unfaded_Icon.png" to R.drawable.icbg_strange_chunk_of_amber_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/7/72/Toy_Block_A_Unfaded_Icon.png" to R.drawable.icbg_toy_block_a_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/f/f5/Keepsake_Locket_A_Unfaded.png" to R.drawable.icbg_keepsake_locket_a_unfaded,
|
|
||||||
"https://bg3.wiki/w/images/4/4e/Crystal_Fluorite_Shard_Unfaded.png" to R.drawable.icbg_crystal_fluorite_shard_unfaded,
|
|
||||||
"https://bg3.wiki/w/images/1/1b/Moondrop_Pendant_Unfaded.png" to R.drawable.icbg_moondrop_pendant_unfaded,
|
|
||||||
"https://bg3.wiki/w/images/4/47/Gortash%27s_Netherstone_Unfaded_Icon.png" to R.drawable.icbg_gortash_netherstone_unfaded_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/0/0a/Unshackling_Strike_Icon.webp/144px-Unshackling_Strike_Icon.webp.png" to R.drawable.icbg_unshackling_strike,
|
"https://bg3.wiki/w/images/thumb/0/0a/Unshackling_Strike_Icon.webp/144px-Unshackling_Strike_Icon.webp.png" to R.drawable.icbg_unshackling_strike,
|
||||||
"https://bg3.wiki/w/images/thumb/e/e9/Poisoned_Condition_Icon.webp/45px-Poisoned_Condition_Icon.webp.png" to R.drawable.icbg_poisoned_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/0/09/Paralysed_Condition_Icon.webp/45px-Paralysed_Condition_Icon.webp.png" to R.drawable.icbg_paralysed_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/8/8e/Prone_Condition_Icon.webp/38px-Prone_Condition_Icon.webp.png" to R.drawable.icbg_prone_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/6/60/Grappled_Condition_Icon.webp/45px-Grappled_Condition_Icon.webp.png" to R.drawable.icbg_grappled_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/7/70/Blinded_Condition_Icon.webp/38px-Blinded_Condition_Icon.webp.png" to R.drawable.icbg_blinded_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/4/47/Charmed_Condition_Icon.webp/38px-Charmed_Condition_Icon.webp.png" to R.drawable.icbg_charmed_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/7/75/Frightened_Condition_Icon.webp/38px-Frightened_Condition_Icon.webp.png" to R.drawable.icbg_frightened_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/2/20/Restrained_Condition_Icon.webp/45px-Restrained_Condition_Icon.webp.png" to R.drawable.icbg_restrained_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/3/32/Stunned_Condition_Icon.webp/45px-Stunned_Condition_Icon.webp.png" to R.drawable.icbg_stunned_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/9/98/Incapacitated_Condition_Icon.webp/38px-Incapacitated_Condition_Icon.webp.png" to R.drawable.icbg_incapacitated_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/a/a6/Unconscious_Condition_Icon.webp/64px-Unconscious_Condition_Icon.webp.png?20231130005748" to R.drawable.icbg_unconscious_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/d/d7/Invisible_Condition_Icon.webp/45px-Invisible_Condition_Icon.webp.png" to R.drawable.icbg_invisible_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/c/c0/Petrified_Condition_Icon.webp/45px-Petrified_Condition_Icon.webp.png" to R.drawable.icbg_petrified_condition_icon,
|
|
||||||
"https://bg3.wiki/w/images/thumb/2/2e/Background_Sage_Icon.png/180px-Background_Sage_Icon.png" to R.drawable.icbg_background_sage_icon,
|
|
||||||
"https://static.wikia.nocookie.net/witcher/images/3/3d/Tw3_weapon_repair_kit_masters.png/revision/latest?cb=20160410121438" to R.drawable.tw_weapon_repair_kit_masters,
|
|
||||||
"https://static.wikia.nocookie.net/witcher/images/c/c3/Tw3_concealment_kit.png/revision/latest?cb=20170416212412" to R.drawable.tw_concealment_kit,
|
|
||||||
"https://static.wikia.nocookie.net/forgottenrealms/images/e/ee/Forgery_Kit.png/revision/latest?cb=20231120043151" to R.drawable.tw_forgery_kit,
|
|
||||||
"https://static.wikia.nocookie.net/witcher/images/1/1d/Tw3_cloth_doll.png/revision/latest?cb=20160519181719" to R.drawable.tw_cloth_doll,
|
|
||||||
"https://static.wikia.nocookie.net/gensin-impact/images/e/ee/Item_Sentry%27s_Wooden_Whistle.png/revision/latest?cb=20240826125031" to R.drawable.tw_item_sentry_wooden_whistle,
|
|
||||||
"https://s3.eu-west-2.amazonaws.com/www.partynutters.com/img/va093-frog-toad-deluxe-venetian-mask.jpg" to R.drawable.frog_toad_deluxe_venetian_mask,
|
|
||||||
"https://drive.google.com/uc?export=view&id=15D3Jum_X_nw4tWfbaLbEvhTQQbmYCMwf" to R.drawable.ic_dice_advantage,
|
"https://drive.google.com/uc?export=view&id=15D3Jum_X_nw4tWfbaLbEvhTQQbmYCMwf" to R.drawable.ic_dice_advantage,
|
||||||
"https://drive.google.com/uc?export=view&id=17MrL-HAlpqPI5c6APjz5arGYrfma42on" to R.drawable.ic_drive_orc_mask,
|
"https://drive.google.com/uc?export=view&id=17MrL-HAlpqPI5c6APjz5arGYrfma42on" to R.drawable.ic_drive_orc_mask,
|
||||||
"https://drive.google.com/uc?export=view&id=1AeSHg792EwVbkjCNjJaqzC4v0uNj9NRn" to R.drawable.ic_drive_fire_starter,
|
"https://drive.google.com/uc?export=view&id=1AeSHg792EwVbkjCNjJaqzC4v0uNj9NRn" to R.drawable.ic_drive_fire_starter,
|
||||||
|
|
@ -305,13 +247,9 @@ object ImageCache {
|
||||||
"https://drive.google.com/uc?export=view&id=1hPiuG7LQc4KVqBfytAXlo0QVLpWwoKdm" to R.drawable.ic_drive_copper_coin_pile,
|
"https://drive.google.com/uc?export=view&id=1hPiuG7LQc4KVqBfytAXlo0QVLpWwoKdm" to R.drawable.ic_drive_copper_coin_pile,
|
||||||
"https://drive.google.com/uc?export=view&id=1N73d_elaDPND3TVN2SgmBGOStSuY1aB9" to R.drawable.ic_drive_silver_coin_pile,
|
"https://drive.google.com/uc?export=view&id=1N73d_elaDPND3TVN2SgmBGOStSuY1aB9" to R.drawable.ic_drive_silver_coin_pile,
|
||||||
"https://drive.google.com/uc?export=view&id=1N-Rp4d8gTctHE5ST2qzYmT-nqoX6iyjg" to R.drawable.ic_drive_electrum_coin_pile,
|
"https://drive.google.com/uc?export=view&id=1N-Rp4d8gTctHE5ST2qzYmT-nqoX6iyjg" to R.drawable.ic_drive_electrum_coin_pile,
|
||||||
"https://drive.google.com/uc?export=view&id=1sKiDdIakpe1shE0zi-Ip0CineEe1M2H2" to R.drawable.ic_drive_gold_coin_pile,
|
"https://drive.google.com/uc?export=view&id=1sKiDdIakpe1shE0zi-Ip0CineEe1M2H2" to R.drawable.ic_drive_gold_coin_pile
|
||||||
"https://drive.google.com/uc?export=view&id=1Sk2-3paCI59ET9k28HSuZaQVcGb90-A_" to R.drawable.icbg_deafened,
|
|
||||||
"https://drive.google.com/uc?export=view&id=1Amdb2gHrS6SCOa34JlQijWi0u25z62QD" to R.drawable.icbg_green_flame_sword,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val missingUri = mutableSetOf<Uri>()
|
|
||||||
|
|
||||||
fun cache(uri: Uri?): ImageUio = when (uri) {
|
fun cache(uri: Uri?): ImageUio = when (uri) {
|
||||||
null -> {
|
null -> {
|
||||||
R.drawable.icbg_generic_darkness_icon.toImage()
|
R.drawable.icbg_generic_darkness_icon.toImage()
|
||||||
|
|
@ -323,12 +261,8 @@ object ImageCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
uri.also {
|
Log.v("ImageCache", "$uri")
|
||||||
if (missingUri.contains(it).not()) {
|
uri.toImage()
|
||||||
Log.v("ImageCache", "$it")
|
|
||||||
}
|
|
||||||
missingUri.add(it)
|
|
||||||
}.toImage()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,34 +37,22 @@ val List<Alteration.Status>?.mastery: Int
|
||||||
}
|
}
|
||||||
} ?: 0
|
} ?: 0
|
||||||
|
|
||||||
val List<Alteration.Status>?.passivesBonus: Int
|
|
||||||
get() = (if (advantage) 5 else 0) - (if (disadvantage) 5 else 0)
|
|
||||||
|
|
||||||
val List<Alteration.Status>?.isCritical: Boolean
|
|
||||||
get() = this?.any { it.name == CRITIQUE } == true
|
|
||||||
|
|
||||||
// Force a roll to hit a 1
|
|
||||||
val List<Alteration.Status>?.fail: Boolean
|
val List<Alteration.Status>?.fail: Boolean
|
||||||
get() = this?.any { it.fail } ?: false
|
get() = this?.any { it.fail } ?: false
|
||||||
|
|
||||||
// Force a roll to hit a 20
|
val List<Alteration.Status>?.passivesBonus: Int
|
||||||
|
get() = (if (advantage) 5 else 0) - (if (disadvantage) 5 else 0)
|
||||||
|
|
||||||
|
// force a roll to hit a 20
|
||||||
val List<Alteration.Status>?.critical: Boolean
|
val List<Alteration.Status>?.critical: Boolean
|
||||||
get() = this?.any { it.critical } ?: false
|
get() = this?.any { it.critical } ?: false
|
||||||
|
|
||||||
// Add a dice to a critical roll.
|
|
||||||
val Map<Property, List<Alteration.Status>>.isSavageAttacks: Boolean
|
val Map<Property, List<Alteration.Status>>.isSavageAttacks: Boolean
|
||||||
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == SAVAGE_ATTACK } == true
|
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Attaques sauvages" } == true
|
||||||
|
|
||||||
// Add a dice to a critical roll.
|
|
||||||
val Map<Property, List<Alteration.Status>>.isBrutalCritical: Boolean
|
val Map<Property, List<Alteration.Status>>.isBrutalCritical: Boolean
|
||||||
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == BRUTAL_CRITICAL } == true
|
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Critique brutal" } == true
|
||||||
|
|
||||||
// for attack roll, can crit on an 19 or 20
|
// for damage roll, previous attack roll was critical
|
||||||
val Map<Property, List<Alteration.Status>>.isImprovedCritical: Boolean
|
val Map<Property, List<Alteration.Status>>.isCritical: Boolean
|
||||||
get() = this[Property.PHYSICAL_MELEE_ATTACK]?.any { it.name == IMPROVED_CRITICAL } == true ||
|
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Critique" } == true
|
||||||
this[Property.PHYSICAL_RANGE_ATTACK]?.any { it.name == IMPROVED_CRITICAL } == true
|
|
||||||
|
|
||||||
private const val CRITIQUE = "Critique"
|
|
||||||
private const val SAVAGE_ATTACK = "Attaques sauvages"
|
|
||||||
private const val BRUTAL_CRITICAL = "Critique brutal"
|
|
||||||
private const val IMPROVED_CRITICAL = "Critique amélioré"
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 3 KiB |
|
|
@ -6,6 +6,10 @@ pluginManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.6.0"
|
||||||
|
}
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
repositories {
|
repositories {
|
||||||
|
|
|
||||||