Add item specific alteration
This commit is contained in:
parent
2c6fc19a2c
commit
3bda885411
10 changed files with 137 additions and 291 deletions
|
|
@ -20,6 +20,7 @@ import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
|
||||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
|
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.icon
|
import com.pixelized.rplexicon.utilitary.extentions.icon
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.advantage
|
import com.pixelized.rplexicon.utilitary.extentions.local.advantage
|
||||||
|
import com.pixelized.rplexicon.utilitary.extentions.local.critical
|
||||||
import com.pixelized.rplexicon.utilitary.extentions.local.disadvantage
|
import com.pixelized.rplexicon.utilitary.extentions.local.disadvantage
|
||||||
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
|
||||||
|
|
@ -52,7 +53,6 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
val sheet = characterSheetRepository.find(name = diceThrow.character)
|
val sheet = characterSheetRepository.find(name = diceThrow.character)
|
||||||
val alterations = alterationRepository.getAlterations(character = diceThrow.character)
|
val alterations = alterationRepository.getAlterations(character = diceThrow.character)
|
||||||
.filter { alterationId.contains(it.name) }
|
.filter { alterationId.contains(it.name) }
|
||||||
.toStatus()
|
|
||||||
|
|
||||||
return if (sheet != null) {
|
return if (sheet != null) {
|
||||||
when (diceThrow) {
|
when (diceThrow) {
|
||||||
|
|
@ -349,12 +349,15 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
character = diceThrow.character,
|
character = diceThrow.character,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
)
|
)
|
||||||
|
val objectAlterations = alterationRepository.getAlterations(
|
||||||
|
objects = action?.alterations,
|
||||||
|
)
|
||||||
actionThrow(
|
actionThrow(
|
||||||
character = sheet,
|
character = sheet,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
diceThrow = action?.hit,
|
diceThrow = action?.hit,
|
||||||
title = { getString(R.string.dice_roll_attack_hit_title, it) },
|
title = { getString(R.string.dice_roll_attack_hit_title, it) },
|
||||||
alterations = alterations,
|
alterations = alterations + objectAlterations,
|
||||||
ability = Property.PHYSICAL_MELEE_ATTACK,
|
ability = Property.PHYSICAL_MELEE_ATTACK,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -364,12 +367,15 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
character = diceThrow.character,
|
character = diceThrow.character,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
)
|
)
|
||||||
|
val objectAlterations = alterationRepository.getAlterations(
|
||||||
|
objects = action?.alterations,
|
||||||
|
)
|
||||||
actionThrow(
|
actionThrow(
|
||||||
character = sheet,
|
character = sheet,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
diceThrow = action?.damage,
|
diceThrow = action?.damage,
|
||||||
title = { getString(R.string.dice_roll_attack_damage_title, it) },
|
title = { getString(R.string.dice_roll_attack_damage_title, it) },
|
||||||
alterations = alterations,
|
alterations = alterations + objectAlterations,
|
||||||
ability = Property.PHYSICAL_MELEE_DAMAGE,
|
ability = Property.PHYSICAL_MELEE_DAMAGE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -379,12 +385,15 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
character = diceThrow.character,
|
character = diceThrow.character,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
)
|
)
|
||||||
|
val objectAlterations = alterationRepository.getAlterations(
|
||||||
|
objects = action?.alterations,
|
||||||
|
)
|
||||||
actionThrow(
|
actionThrow(
|
||||||
character = sheet,
|
character = sheet,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
diceThrow = action?.hit,
|
diceThrow = action?.hit,
|
||||||
title = { getString(R.string.dice_roll_attack_hit_title, it) },
|
title = { getString(R.string.dice_roll_attack_hit_title, it) },
|
||||||
alterations = alterations,
|
alterations = alterations + objectAlterations,
|
||||||
ability = Property.PHYSICAL_RANGE_ATTACK,
|
ability = Property.PHYSICAL_RANGE_ATTACK,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -394,12 +403,15 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
character = diceThrow.character,
|
character = diceThrow.character,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
)
|
)
|
||||||
|
val objectAlterations = alterationRepository.getAlterations(
|
||||||
|
objects = action?.alterations,
|
||||||
|
)
|
||||||
actionThrow(
|
actionThrow(
|
||||||
character = sheet,
|
character = sheet,
|
||||||
action = diceThrow.weapon,
|
action = diceThrow.weapon,
|
||||||
diceThrow = action?.damage,
|
diceThrow = action?.damage,
|
||||||
title = { getString(R.string.dice_roll_attack_damage_title, it) },
|
title = { getString(R.string.dice_roll_attack_damage_title, it) },
|
||||||
alterations = alterations,
|
alterations = alterations + objectAlterations,
|
||||||
ability = Property.PHYSICAL_RANGE_DAMAGE,
|
ability = Property.PHYSICAL_RANGE_DAMAGE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -414,7 +426,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
action = diceThrow.item,
|
action = diceThrow.item,
|
||||||
diceThrow = action?.effect,
|
diceThrow = action?.effect,
|
||||||
title = { getString(R.string.dice_roll_use_object, it) },
|
title = { getString(R.string.dice_roll_use_object, it) },
|
||||||
alterations = emptyMap(),
|
alterations = emptyList(),
|
||||||
ability = null,
|
ability = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -481,7 +493,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
|
|
||||||
private fun abilityThrow(
|
private fun abilityThrow(
|
||||||
character: CharacterSheet,
|
character: CharacterSheet,
|
||||||
alterations: Map<Property, List<Alteration.Status>>,
|
alterations: List<Alteration>,
|
||||||
abilityLabel: Context.() -> String,
|
abilityLabel: Context.() -> String,
|
||||||
relatedLabel: Context.() -> String?,
|
relatedLabel: Context.() -> String?,
|
||||||
ability: Property,
|
ability: Property,
|
||||||
|
|
@ -499,7 +511,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
|
|
||||||
private fun savingThrow(
|
private fun savingThrow(
|
||||||
character: CharacterSheet,
|
character: CharacterSheet,
|
||||||
alterations: Map<Property, List<Alteration.Status>>,
|
alterations: List<Alteration>,
|
||||||
abilityLabel: Context.() -> String,
|
abilityLabel: Context.() -> String,
|
||||||
relatedLabel: Context.() -> String?,
|
relatedLabel: Context.() -> String?,
|
||||||
ability: Property,
|
ability: Property,
|
||||||
|
|
@ -517,7 +529,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
|
|
||||||
private fun rollAbility(
|
private fun rollAbility(
|
||||||
character: CharacterSheet,
|
character: CharacterSheet,
|
||||||
alterations: Map<Property, List<Alteration.Status>>,
|
alterations: List<Alteration>,
|
||||||
abilityTitle: Context.(label: String) -> String,
|
abilityTitle: Context.(label: String) -> String,
|
||||||
abilityLabel: Context.() -> String,
|
abilityLabel: Context.() -> String,
|
||||||
relatedTitle: Context.(label: String) -> String?,
|
relatedTitle: Context.(label: String) -> String?,
|
||||||
|
|
@ -531,27 +543,30 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
val abilityTitleString = abilityTitle(application, abilityLabelString)
|
val abilityTitleString = abilityTitle(application, abilityLabelString)
|
||||||
|
|
||||||
// check if the roll is affected by some status.
|
// check if the roll is affected by some status.
|
||||||
val advantage = alterations[ability].advantage
|
val advantage = status[ability].advantage
|
||||||
val disadvantage = alterations[ability].disadvantage
|
val disadvantage = status[ability].disadvantage
|
||||||
val fail = alterations[ability].fail
|
|
||||||
|
|
||||||
// main roll
|
// main roll
|
||||||
val result = roll(advantage = advantage, disadvantage = disadvantage, fail = fail)
|
val result = roll(
|
||||||
|
advantage = advantage,
|
||||||
|
disadvantage = disadvantage,
|
||||||
|
fail = status[ability].fail,
|
||||||
|
critical = status[ability].critical,
|
||||||
|
)
|
||||||
|
|
||||||
// fetch and build a list of dice roll base on alterations.
|
// fetch and build a list of dice roll base on alterations.
|
||||||
val diceAlterationBonus = alterations[ability].alterationsBonus()
|
val diceAlterationBonus = status[ability].alterationsBonus()
|
||||||
|
|
||||||
// fetch and build a list of flat bonus
|
// fetch and build a list of flat bonus
|
||||||
val flatAlterationBonus = alterations[ability].flatAlterationBonus()
|
val flatAlterationBonus = status[ability].flatAlterationBonus()
|
||||||
|
|
||||||
// fetch and build the associated characteristic
|
// fetch and build the associated characteristic
|
||||||
val relatedStatBonus = when (relatedStat) {
|
val relatedStatBonus = when (relatedStat) {
|
||||||
Property.STRENGTH -> (character.strength + alterations[relatedStat].sum).modifier
|
Property.STRENGTH -> (character.strength + status[relatedStat].sum).modifier
|
||||||
Property.DEXTERITY -> (character.dexterity + alterations[relatedStat].sum).modifier
|
Property.DEXTERITY -> (character.dexterity + status[relatedStat].sum).modifier
|
||||||
Property.CONSTITUTION -> (character.constitution + alterations[relatedStat].sum).modifier
|
Property.CONSTITUTION -> (character.constitution + status[relatedStat].sum).modifier
|
||||||
Property.INTELLIGENCE -> (character.intelligence + alterations[relatedStat].sum).modifier
|
Property.INTELLIGENCE -> (character.intelligence + status[relatedStat].sum).modifier
|
||||||
Property.WISDOM -> (character.wisdom + alterations[relatedStat].sum).modifier
|
Property.WISDOM -> (character.wisdom + status[relatedStat].sum).modifier
|
||||||
Property.CHARISMA -> (character.charisma + alterations[relatedStat].sum).modifier
|
Property.CHARISMA -> (character.charisma + status[relatedStat].sum).modifier
|
||||||
Property.PROFICIENCY -> character.proficiency
|
Property.PROFICIENCY -> character.proficiency
|
||||||
else -> null
|
else -> null
|
||||||
}?.let { value ->
|
}?.let { value ->
|
||||||
|
|
@ -657,7 +672,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
action: String,
|
action: String,
|
||||||
diceThrow: Throw?,
|
diceThrow: Throw?,
|
||||||
title: Context.(action: String) -> String,
|
title: Context.(action: String) -> String,
|
||||||
alterations: Map<Property, List<Alteration.Status>>,
|
alterations: List<Alteration>,
|
||||||
ability: Property?,
|
ability: Property?,
|
||||||
): DiceThrowResult {
|
): DiceThrowResult {
|
||||||
with(ThrowScope(context = application, character = character, alterations = alterations)) {
|
with(ThrowScope(context = application, character = character, alterations = alterations)) {
|
||||||
|
|
@ -673,17 +688,16 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the roll is affected by some status.
|
// check if the roll is affected by some status.
|
||||||
val advantage = alterations[ability].advantage
|
val advantage = status[ability].advantage
|
||||||
val disadvantage = alterations[ability].disadvantage
|
val disadvantage = status[ability].disadvantage
|
||||||
val fail = alterations[ability].fail
|
|
||||||
|
|
||||||
// compute the amount of main dice to throw.
|
// compute the amount of main dice to throw.
|
||||||
val amount = if (alterations.isCritical) {
|
val amount = if (status.isCritical) {
|
||||||
diceThrow?.amount?.times(2)?.let {
|
diceThrow?.amount?.times(2)?.let {
|
||||||
if (ability == Property.PHYSICAL_MELEE_DAMAGE && alterations.isSavageAttacks)
|
if (ability == Property.PHYSICAL_MELEE_DAMAGE && status.isSavageAttacks)
|
||||||
it.plus(1) else it
|
it.plus(1) else it
|
||||||
}?.let {
|
}?.let {
|
||||||
if (ability == Property.PHYSICAL_MELEE_DAMAGE && alterations.isBrutalCritical)
|
if (ability == Property.PHYSICAL_MELEE_DAMAGE && status.isBrutalCritical)
|
||||||
it.plus(1) else it
|
it.plus(1) else it
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -695,14 +709,15 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
faces = diceThrow?.faces ?: 20,
|
faces = diceThrow?.faces ?: 20,
|
||||||
advantage = advantage,
|
advantage = advantage,
|
||||||
disadvantage = disadvantage,
|
disadvantage = disadvantage,
|
||||||
fail = fail,
|
fail = status[ability].fail,
|
||||||
|
critical = status[ability].critical,
|
||||||
)
|
)
|
||||||
|
|
||||||
// fetch and build a list of dice roll base on alterations.
|
// fetch and build a list of dice roll base on alterations.
|
||||||
val diceAlterationBonus = alterations[ability].alterationsBonus()
|
val diceAlterationBonus = status[ability].alterationsBonus()
|
||||||
|
|
||||||
// fetch and build a list of flat bonus
|
// fetch and build a list of flat bonus
|
||||||
val flatAlterationBonus = alterations[ability].flatAlterationBonus()
|
val flatAlterationBonus = status[ability].flatAlterationBonus()
|
||||||
|
|
||||||
// fetch and build the associated characteristic
|
// fetch and build the associated characteristic
|
||||||
val relatedStatBonus = diceThrow.statBonus(name = action)
|
val relatedStatBonus = diceThrow.statBonus(name = action)
|
||||||
|
|
@ -763,7 +778,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
character: CharacterSheet,
|
character: CharacterSheet,
|
||||||
spell: AssignedSpell?,
|
spell: AssignedSpell?,
|
||||||
level: Int,
|
level: Int,
|
||||||
alterations: Map<Property, List<Alteration.Status>>,
|
alterations: List<Alteration>,
|
||||||
): DiceThrowResult {
|
): DiceThrowResult {
|
||||||
with(ThrowScope(context = application, character = character, alterations = alterations)) {
|
with(ThrowScope(context = application, character = character, alterations = alterations)) {
|
||||||
// retrieve some wording.
|
// retrieve some wording.
|
||||||
|
|
@ -833,7 +848,7 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
|
|
||||||
private fun skillThrow(
|
private fun skillThrow(
|
||||||
character: CharacterSheet,
|
character: CharacterSheet,
|
||||||
alterations: Map<Property, List<Alteration.Status>>,
|
alterations: List<Alteration>,
|
||||||
skill: Skill?,
|
skill: Skill?,
|
||||||
): DiceThrowResult {
|
): DiceThrowResult {
|
||||||
with(ThrowScope(context = application, character = character, alterations = alterations)) {
|
with(ThrowScope(context = application, character = character, alterations = alterations)) {
|
||||||
|
|
@ -848,10 +863,10 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
)
|
)
|
||||||
|
|
||||||
// fetch and build a list of dice roll base on alterations.
|
// fetch and build a list of dice roll base on alterations.
|
||||||
val diceAlterationBonus = alterations[Property.SKILL].alterationsBonus()
|
val diceAlterationBonus = status[Property.SKILL].alterationsBonus()
|
||||||
|
|
||||||
// fetch and build a list of flat bonus
|
// fetch and build a list of flat bonus
|
||||||
val flatAlterationBonus = alterations[Property.SKILL].flatAlterationBonus()
|
val flatAlterationBonus = status[Property.SKILL].flatAlterationBonus()
|
||||||
|
|
||||||
// fetch and build the associated characteristic, proficiency or level
|
// fetch and build the associated characteristic, proficiency or level
|
||||||
val relatedStatBonus = skill?.effect.statBonus(name = skill?.name)
|
val relatedStatBonus = skill?.effect.statBonus(name = skill?.name)
|
||||||
|
|
@ -894,8 +909,10 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
val allValue: MutableList<Int> = mutableListOf(),
|
val allValue: MutableList<Int> = mutableListOf(),
|
||||||
val character: CharacterSheet,
|
val character: CharacterSheet,
|
||||||
val alterations: Map<Property, List<Alteration.Status>>,
|
val alterations: List<Alteration>,
|
||||||
) {
|
) {
|
||||||
|
val status = this.alterations.toStatus()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch any stats / proficiency / level related bonus and build a ThrowsCardUio.Detail for each.
|
* Fetch any stats / proficiency / level related bonus and build a ThrowsCardUio.Detail for each.
|
||||||
*/
|
*/
|
||||||
|
|
@ -905,12 +922,12 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
|
|
||||||
fun Property.statBonus(name: String?): ThrowsCardUio.Detail? {
|
fun Property.statBonus(name: String?): ThrowsCardUio.Detail? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
Property.STRENGTH -> (character.strength + alterations[this].sum).modifier
|
Property.STRENGTH -> (character.strength + this@ThrowScope.status[this].sum).modifier
|
||||||
Property.DEXTERITY -> (character.dexterity + alterations[this].sum).modifier
|
Property.DEXTERITY -> (character.dexterity + this@ThrowScope.status[this].sum).modifier
|
||||||
Property.CONSTITUTION -> (character.constitution + alterations[this].sum).modifier
|
Property.CONSTITUTION -> (character.constitution + this@ThrowScope.status[this].sum).modifier
|
||||||
Property.INTELLIGENCE -> (character.intelligence + alterations[this].sum).modifier
|
Property.INTELLIGENCE -> (character.intelligence + this@ThrowScope.status[this].sum).modifier
|
||||||
Property.WISDOM -> (character.wisdom + alterations[this].sum).modifier
|
Property.WISDOM -> (character.wisdom + this@ThrowScope.status[this].sum).modifier
|
||||||
Property.CHARISMA -> (character.charisma + alterations[this].sum).modifier
|
Property.CHARISMA -> (character.charisma + this@ThrowScope.status[this].sum).modifier
|
||||||
Property.PROFICIENCY -> character.proficiency
|
Property.PROFICIENCY -> character.proficiency
|
||||||
Property.LEVEL -> character.level
|
Property.LEVEL -> character.level
|
||||||
else -> null
|
else -> null
|
||||||
|
|
@ -945,11 +962,12 @@ 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 (alterations.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,
|
||||||
fail = dice.fail
|
fail = status.fail,
|
||||||
|
critical = status.critical,
|
||||||
)
|
)
|
||||||
ThrowsCardUio.Detail(
|
ThrowsCardUio.Detail(
|
||||||
title = dice.title,
|
title = dice.title,
|
||||||
|
|
@ -990,10 +1008,15 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
advantage: Boolean = false,
|
advantage: Boolean = false,
|
||||||
disadvantage: Boolean = false,
|
disadvantage: Boolean = false,
|
||||||
fail: Boolean = false,
|
fail: Boolean = false,
|
||||||
|
critical: Boolean = false,
|
||||||
): DiceRollResult {
|
): DiceRollResult {
|
||||||
val result = when {
|
val result = when {
|
||||||
advantage && !disadvantage -> {
|
advantage && !disadvantage -> {
|
||||||
val roll = List(amount) { random(faces, fail) to random(faces, fail) }
|
val roll = List(amount) {
|
||||||
|
val first = random(faces = faces, fail = fail, critical = critical)
|
||||||
|
val second = random(faces = faces, fail = fail, critical = critical)
|
||||||
|
first to second
|
||||||
|
}
|
||||||
DiceRollResult(
|
DiceRollResult(
|
||||||
label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
|
label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
|
||||||
value = roll.sumOf { max(it.first, it.second) },
|
value = roll.sumOf { max(it.first, it.second) },
|
||||||
|
|
@ -1001,7 +1024,11 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
disadvantage && !advantage -> {
|
disadvantage && !advantage -> {
|
||||||
val roll = List(amount) { random(faces, fail) to random(faces, fail) }
|
val roll = List(amount) {
|
||||||
|
val first = random(faces = faces, fail = fail, critical = critical)
|
||||||
|
val second = random(faces = faces, fail = fail, critical = critical)
|
||||||
|
first to second
|
||||||
|
}
|
||||||
DiceRollResult(
|
DiceRollResult(
|
||||||
label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
|
label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
|
||||||
value = roll.sumOf { min(it.first, it.second) },
|
value = roll.sumOf { min(it.first, it.second) },
|
||||||
|
|
@ -1009,7 +1036,9 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val roll = List(amount) { random(faces, fail) }
|
val roll = List(amount) {
|
||||||
|
random(faces = faces, fail = fail, critical = critical)
|
||||||
|
}
|
||||||
DiceRollResult(
|
DiceRollResult(
|
||||||
label = roll.toLabel(),
|
label = roll.toLabel(),
|
||||||
value = roll.sum(),
|
value = roll.sum(),
|
||||||
|
|
@ -1020,8 +1049,11 @@ class DiceThrowUseCase @Inject constructor(
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun random(faces: Int, fail: Boolean): Int =
|
private fun random(faces: Int, fail: Boolean, critical: Boolean): Int = when {
|
||||||
if (fail) 1 else (Math.random() * faces + 1).toInt()
|
fail && !critical -> 1
|
||||||
|
critical && !fail -> faces
|
||||||
|
else -> (Math.random() * faces + 1).toInt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class DiceRollResult(
|
private data class DiceRollResult(
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@ data class Alteration(
|
||||||
) {
|
) {
|
||||||
data class Status(
|
data class Status(
|
||||||
val name: String,
|
val name: String,
|
||||||
val advantage: Boolean,
|
val advantage: Boolean = false,
|
||||||
val disadvantage: Boolean,
|
val disadvantage: Boolean = false,
|
||||||
val fail: Boolean,
|
val fail: Boolean = false,
|
||||||
|
val critical: Boolean = false,
|
||||||
val dices: List<Roll.Dice> = emptyList(),
|
val dices: List<Roll.Dice> = emptyList(),
|
||||||
val bonus: List<Roll.Bonus> = emptyList(),
|
val bonus: List<Roll.Bonus> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ data class Attack(
|
||||||
val range: String?,
|
val range: String?,
|
||||||
val hit: Throw?,
|
val hit: Throw?,
|
||||||
val damage: Throw?,
|
val damage: Throw?,
|
||||||
|
val alterations: List<String>,
|
||||||
) {
|
) {
|
||||||
enum class Type(val key: String) {
|
enum class Type(val key: String) {
|
||||||
PHYSICAL_MELEE_ATTACK("Mêlée"),
|
PHYSICAL_MELEE_ATTACK("Mêlée"),
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ data class Roll(
|
||||||
val title: String? = null,
|
val title: String? = null,
|
||||||
val advantage: Boolean = false,
|
val advantage: Boolean = false,
|
||||||
val disadvantage: Boolean = false,
|
val disadvantage: Boolean = false,
|
||||||
val fail: Boolean = false,
|
|
||||||
val count: Int,
|
val count: Int,
|
||||||
val faces: Int,
|
val faces: Int,
|
||||||
) {
|
) {
|
||||||
|
|
@ -23,84 +22,4 @@ data class Roll(
|
||||||
val title: String,
|
val title: String,
|
||||||
val value: Int,
|
val value: Int,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun d20(
|
|
||||||
title: String? = null,
|
|
||||||
advantage: Boolean = false,
|
|
||||||
disadvantage: Boolean = false,
|
|
||||||
fail: Boolean = false,
|
|
||||||
amount: Int = 1,
|
|
||||||
) = Roll.Dice(
|
|
||||||
title = title,
|
|
||||||
advantage = advantage,
|
|
||||||
disadvantage = disadvantage,
|
|
||||||
count = amount,
|
|
||||||
fail = fail,
|
|
||||||
faces = 20,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun d12(
|
|
||||||
title: String? = null,
|
|
||||||
advantage: Boolean = false,
|
|
||||||
disadvantage: Boolean = false,
|
|
||||||
amount: Int = 1,
|
|
||||||
) = Roll.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,
|
|
||||||
) = Roll.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,
|
|
||||||
) = Roll.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,
|
|
||||||
) = Roll.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,
|
|
||||||
) = Roll.Dice(
|
|
||||||
title = title,
|
|
||||||
advantage = advantage,
|
|
||||||
disadvantage = disadvantage,
|
|
||||||
count = amount,
|
|
||||||
faces = 4,
|
|
||||||
)
|
|
||||||
|
|
@ -33,6 +33,7 @@ class AttackParser @Inject constructor(
|
||||||
range = row.parse(column = RANGE),
|
range = row.parse(column = RANGE),
|
||||||
hit = throwParser.parse(value = row.parse(column = HIT)),
|
hit = throwParser.parse(value = row.parse(column = HIT)),
|
||||||
damage = throwParser.parse(value = row.parse(column = DAMAGE)),
|
damage = throwParser.parse(value = row.parse(column = DAMAGE)),
|
||||||
|
alterations = row.parseList(column = ALTERATION),
|
||||||
)
|
)
|
||||||
actions
|
actions
|
||||||
.getOrPut(characterSheet.name) { mutableListOf() }
|
.getOrPut(characterSheet.name) { mutableListOf() }
|
||||||
|
|
@ -59,6 +60,7 @@ class AttackParser @Inject constructor(
|
||||||
private val RANGE = column("Portée")
|
private val RANGE = column("Portée")
|
||||||
private val HIT = column("Touché")
|
private val HIT = column("Touché")
|
||||||
private val DAMAGE = column("Dommage")
|
private val DAMAGE = column("Dommage")
|
||||||
private val COLUMNS get() = listOf(CHARACTER, NAME, TYPE, RANGE, HIT, DAMAGE)
|
private val ALTERATION = column("Altérations")
|
||||||
|
private val COLUMNS get() = listOf(CHARACTER, NAME, TYPE, RANGE, HIT, DAMAGE, ALTERATION)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,4 +80,11 @@ class SheetParserScope<T> {
|
||||||
|
|
||||||
fun List<*>.parseUri(column: Column): Uri? =
|
fun List<*>.parseUri(column: Column): Uri? =
|
||||||
parse(column)?.takeIf { it.isNotBlank() }?.toUri()
|
parse(column)?.takeIf { it.isNotBlank() }?.toUri()
|
||||||
|
|
||||||
|
fun List<*>.parseList(column: Column, separator: String = ","): List<String> =
|
||||||
|
parse(column)
|
||||||
|
?.takeIf { it.isNotBlank() }
|
||||||
|
?.split(separator)
|
||||||
|
?.mapNotNull { it.toItem()?.trim() }
|
||||||
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
@ -55,20 +55,24 @@ class AlterationParser @Inject constructor(
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
if (alteration != null) {
|
if (alteration != null) {
|
||||||
characterSheets
|
if (alteration.target == OBJECT && alteration.source == OBJECT) {
|
||||||
.filter { // check if the alteration is applicable to the character
|
alterations
|
||||||
alteration.target.let { target ->
|
.getOrPut(alteration.name) { mutableListOf() }
|
||||||
target == ALL || it.characterClass.any { it.value == target } || target == it.race || target == it.name
|
.add(alteration)
|
||||||
|
} else {
|
||||||
|
characterSheets
|
||||||
|
.filter { // check if the alteration is applicable to the character
|
||||||
|
alteration.target.let { target ->
|
||||||
|
target == ALL || it.characterClass.any { it.value == target } || target == it.race || target == it.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.forEach { // check the default alteration state for that character
|
||||||
.forEach { // check the default alteration state for that character
|
val isActive = row.parseBool(column = column(it.name))
|
||||||
val default = row.parseBool(column = column(it.name))
|
alterations
|
||||||
val assignedAlteration = alteration.copy(
|
.getOrPut(it.name) { mutableListOf() }
|
||||||
active = default ?: false
|
.add(alteration.copy(active = isActive ?: false))
|
||||||
)
|
}
|
||||||
alterations.getOrPut(it.name) { mutableListOf() }
|
}
|
||||||
.add(assignedAlteration)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,30 +86,26 @@ class AlterationParser @Inject constructor(
|
||||||
ADVANTAGE -> Alteration.Status(
|
ADVANTAGE -> Alteration.Status(
|
||||||
name = name,
|
name = name,
|
||||||
advantage = true,
|
advantage = true,
|
||||||
disadvantage = false,
|
|
||||||
fail = false,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
DISADVANTAGE -> Alteration.Status(
|
DISADVANTAGE -> Alteration.Status(
|
||||||
name = name,
|
name = name,
|
||||||
advantage = false,
|
|
||||||
disadvantage = true,
|
disadvantage = true,
|
||||||
fail = false,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
FAIL -> Alteration.Status(
|
FAIL -> Alteration.Status(
|
||||||
name = name,
|
name = name,
|
||||||
advantage = false,
|
|
||||||
disadvantage = false,
|
|
||||||
fail = true,
|
fail = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CRITICAL -> Alteration.Status(
|
||||||
|
name = name,
|
||||||
|
critical = true,
|
||||||
|
)
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Alteration.Status(
|
Alteration.Status(
|
||||||
name = name,
|
name = name,
|
||||||
advantage = false,
|
|
||||||
disadvantage = false,
|
|
||||||
fail = false,
|
|
||||||
dices = diceParser.findAll(title = name, value = value),
|
dices = diceParser.findAll(title = name, value = value),
|
||||||
bonus = flatParser.findAll(title = name, value = value),
|
bonus = flatParser.findAll(title = name, value = value),
|
||||||
)
|
)
|
||||||
|
|
@ -117,6 +117,8 @@ class AlterationParser @Inject constructor(
|
||||||
private const val ADVANTAGE = "adv"
|
private const val ADVANTAGE = "adv"
|
||||||
private const val DISADVANTAGE = "dis"
|
private const val DISADVANTAGE = "dis"
|
||||||
private const val FAIL = "fail"
|
private const val FAIL = "fail"
|
||||||
|
private const val CRITICAL = "crit"
|
||||||
|
private const val OBJECT = "Objet"
|
||||||
|
|
||||||
private val TARGET = column("Cible")
|
private val TARGET = column("Cible")
|
||||||
private val SOURCE = column("Source")
|
private val SOURCE = column("Source")
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,16 @@ class AlterationRepository @Inject constructor(
|
||||||
return _assignedAlterations.value[character] ?: emptyList()
|
return _assignedAlterations.value[character] ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all [Alteration] for a list of objects
|
||||||
|
* @returna list of alterations.
|
||||||
|
*/
|
||||||
|
fun getAlterations(objects: List<String>?): List<Alteration> {
|
||||||
|
return objects?.flatMap { objectAlteration ->
|
||||||
|
_assignedAlterations.value[objectAlteration] ?: emptyList()
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get [Alteration] for a character that affect at least one [Property]
|
* get [Alteration] for a character that affect at least one [Property]
|
||||||
* @param character the character name
|
* @param character the character name
|
||||||
|
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
package com.pixelized.rplexicon.ui.screens.rolls
|
|
||||||
|
|
||||||
import com.pixelized.rplexicon.data.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
|
|
||||||
|
|
||||||
data class RollResult(
|
|
||||||
val dice: RollDiceUio?,
|
|
||||||
val card: ThrowsCardUio?,
|
|
||||||
)
|
|
||||||
|
|
||||||
class ConvertRollIntoDisplayableFactory @Inject constructor() {
|
|
||||||
|
|
||||||
fun roll(
|
|
||||||
roll: Roll,
|
|
||||||
diceMultiplier: Int = 1,
|
|
||||||
): RollResult {
|
|
||||||
val mainDices = roll.dices.firstOrNull()
|
|
||||||
val bonusDicesList = roll.dices.subList(fromIndex = 1, toIndex = roll.dices.size)
|
|
||||||
val allRolledValues = mutableListOf<Int>()
|
|
||||||
|
|
||||||
val (rollDice, rollDetail) = mainDices?.let { dice ->
|
|
||||||
val (label, sum) = dice.roll(multiplier = diceMultiplier)
|
|
||||||
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(multiplier = diceMultiplier)
|
|
||||||
allRolledValues.add(sum)
|
|
||||||
|
|
||||||
dice.toThrowsCardUio(
|
|
||||||
roll = label,
|
|
||||||
result = sum,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val flatBonus = roll.bonus.map { bonus ->
|
|
||||||
allRolledValues.add(bonus.value)
|
|
||||||
|
|
||||||
ThrowsCardUio.Detail(
|
|
||||||
title = bonus.title,
|
|
||||||
result = "${bonus.value}",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return RollResult(
|
|
||||||
dice = rollDice,
|
|
||||||
card = 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 && faces == 20 && result == faces,
|
|
||||||
isCriticalFailure = count == 1 && faces == 20 && 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 DiceRollResult(
|
|
||||||
val label: String,
|
|
||||||
val sum: Int,
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun Roll.Dice.roll(multiplier: Int): DiceRollResult {
|
|
||||||
return when {
|
|
||||||
|
|
||||||
advantage && !disadvantage -> {
|
|
||||||
val roll = List(count * multiplier) { random() to random() }
|
|
||||||
DiceRollResult(
|
|
||||||
label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
|
|
||||||
sum = roll.sumOf { max(it.first, it.second) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
disadvantage && !advantage -> {
|
|
||||||
val roll = List(count * multiplier) { random() to random() }
|
|
||||||
DiceRollResult(
|
|
||||||
label = roll.joinToString(" + ") { "${it.first}~${it.second}" },
|
|
||||||
sum = roll.sumOf { min(it.first, it.second) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
val roll = List(count * multiplier) { random() }
|
|
||||||
DiceRollResult(
|
|
||||||
label = roll.toLabel(),
|
|
||||||
sum = roll.sum(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Roll.Dice.random(): Int = if (fail) 1 else (Math.random() * faces + 1).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -25,11 +25,16 @@ val List<Alteration.Status>?.disadvantage: Boolean
|
||||||
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>?.critical: Boolean
|
||||||
|
get() = this?.any { it.critical } ?: false
|
||||||
|
|
||||||
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 == "Attaques sauvages" } == true
|
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Attaques sauvages" } == true
|
||||||
|
|
||||||
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 == "Critique brutal" } == true
|
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Critique brutal" } == true
|
||||||
|
|
||||||
|
// for damage roll, previous attack roll was critical
|
||||||
val Map<Property, List<Alteration.Status>>.isCritical: Boolean
|
val Map<Property, List<Alteration.Status>>.isCritical: Boolean
|
||||||
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Critique" } == true
|
get() = this[Property.PHYSICAL_MELEE_DAMAGE]?.any { it.name == "Critique" } == true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue