LevelUp feature.
This commit is contained in:
parent
84515e6d57
commit
16b2b49f03
75 changed files with 2532 additions and 777 deletions
|
|
@ -50,6 +50,8 @@ class AlteredCharacterSheet(
|
|||
|
||||
val name: String = sheet.name
|
||||
|
||||
val shouldLevelUp: Boolean = sheet.shouldLevelUp
|
||||
|
||||
val portrait: String?
|
||||
get() = alterations[PORTRAIT]
|
||||
?.firstNotNullOfOrNull { (it.expression as? Expression.UrlExpression)?.url }
|
||||
|
|
@ -104,7 +106,7 @@ class AlteredCharacterSheet(
|
|||
|
||||
val damageBonus: String
|
||||
get() {
|
||||
val initial = sheetUseCase.damageBonus(
|
||||
val initial = sheetUseCase.meleeBonusDamage(
|
||||
strength = strength,
|
||||
height = height,
|
||||
)
|
||||
|
|
@ -128,8 +130,7 @@ class AlteredCharacterSheet(
|
|||
|
||||
private fun List<FieldAlteration>?.sum() = this?.sumOf {
|
||||
expressionUseCase.computeExpression(
|
||||
sheet = sheet,
|
||||
alterations = alterations,
|
||||
sheet = this@AlteredCharacterSheet,
|
||||
expression = it.expression
|
||||
)
|
||||
} ?: 0
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ data class CharacterSheet(
|
|||
val portrait: String?,
|
||||
val thumbnail: String?,
|
||||
val level: Int,
|
||||
val shouldLevelUp: Boolean,
|
||||
// characteristics
|
||||
val strength: Int,
|
||||
val dexterity: Int,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class CharacterSheetJsonFactory(
|
|||
portrait = json.portrait,
|
||||
thumbnail = json.thumbnail,
|
||||
level = json.level,
|
||||
shouldLevelUp = json.shouldLevelUp ?: false,
|
||||
strength = json.strength,
|
||||
dexterity = json.dexterity,
|
||||
constitution = json.constitution,
|
||||
|
|
@ -100,6 +101,7 @@ class CharacterSheetJsonFactory(
|
|||
thumbnail = sheet.thumbnail,
|
||||
portrait = sheet.portrait,
|
||||
level = sheet.level,
|
||||
shouldLevelUp = sheet.shouldLevelUp,
|
||||
strength = sheet.strength,
|
||||
dexterity = sheet.dexterity,
|
||||
constitution = sheet.constitution,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ data class CharacterSheetJsonV1(
|
|||
val portrait: String?,
|
||||
val thumbnail: String?,
|
||||
val level: Int,
|
||||
val shouldLevelUp: Boolean?,
|
||||
// characteristics
|
||||
val strength: Int,
|
||||
val dexterity: Int,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ sealed interface Expression {
|
|||
}
|
||||
}
|
||||
|
||||
data class Floor5(
|
||||
val expression: Expression?,
|
||||
) : Expression {
|
||||
override fun toString(): String {
|
||||
return "floor5($expression)"
|
||||
}
|
||||
}
|
||||
|
||||
data class Inversion(
|
||||
val expression: Expression,
|
||||
) : Expression {
|
||||
|
|
|
|||
|
|
@ -180,6 +180,25 @@ class ExpressionParser(
|
|||
return Expression.Maximum(first, second)
|
||||
}
|
||||
|
||||
"floor5" -> {
|
||||
// consume the '(' character
|
||||
stack.moveCursor()
|
||||
// evaluate the content of the first parameter.
|
||||
val expression = evaluate()
|
||||
// check that the expression is well formed, need a ).
|
||||
guard(stack.peek() == ')') {
|
||||
Error.ExpectedOperator(
|
||||
expected = ')',
|
||||
actual = stack.peek(),
|
||||
expression = stack.input
|
||||
)
|
||||
}
|
||||
// consume the ')' character
|
||||
stack.moveCursor()
|
||||
// build the final function expression
|
||||
return Expression.Floor5(expression)
|
||||
}
|
||||
|
||||
else -> {
|
||||
val value = token.toIntOrNull()
|
||||
if (value != null) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,36 @@
|
|||
package com.pixelized.shared.lwa.protocol.websocket.payload
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.UUID
|
||||
|
||||
@Serializable
|
||||
data class RollMessage(
|
||||
val characterId: String,
|
||||
val id: RollId,
|
||||
val characterSheetId: String,
|
||||
val skillLabel: String,
|
||||
val rollValue: Int,
|
||||
val resultLabel: String? = null,
|
||||
val rollDifficulty: String? = null,
|
||||
val rollValue: Int,
|
||||
val rollSuccessLimit: Int? = null,
|
||||
val critical: Critical?,
|
||||
val critical: Critical? = null,
|
||||
) : MessagePayload {
|
||||
|
||||
@Serializable
|
||||
data class RollId(
|
||||
val rollId: String,
|
||||
val timestamp: Long,
|
||||
) {
|
||||
companion object {
|
||||
fun create(
|
||||
rollId: String = UUID.randomUUID().toString(),
|
||||
timestamp: Long = System.currentTimeMillis(),
|
||||
) = RollId(
|
||||
rollId = rollId,
|
||||
timestamp = timestamp,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum class Critical {
|
||||
CRITICAL_SUCCESS,
|
||||
SPECIAL_SUCCESS,
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ class CharacterSheetUseCase {
|
|||
return power
|
||||
}
|
||||
|
||||
fun damageBonus(
|
||||
fun meleeBonusDamage(
|
||||
strength: Int,
|
||||
height: Int,
|
||||
): String {
|
||||
return damageBonus(sum = strength + height)
|
||||
return meleeBonusDamage(sum = strength + height)
|
||||
}
|
||||
|
||||
fun damageBonus(
|
||||
fun meleeBonusDamage(
|
||||
sum: Int,
|
||||
): String {
|
||||
return when {
|
||||
|
|
@ -47,6 +47,26 @@ class CharacterSheetUseCase {
|
|||
}
|
||||
}
|
||||
|
||||
fun distanceBonusDamage(
|
||||
strength: Int,
|
||||
height: Int,
|
||||
): String {
|
||||
return distanceBonusDamage(sum = strength + height)
|
||||
}
|
||||
|
||||
fun distanceBonusDamage(
|
||||
sum: Int,
|
||||
): String {
|
||||
return when {
|
||||
sum < 12 -> "-1d3"
|
||||
sum in 12..17 -> "-1d2"
|
||||
sum in 18..22 -> "+0"
|
||||
sum in 23..29 -> "+1d2"
|
||||
sum in 30..39 -> "+1d3"
|
||||
else -> "+2d3"
|
||||
}
|
||||
}
|
||||
|
||||
fun armor(): Int = 0
|
||||
|
||||
fun learning(intelligence: Int): Int {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
package com.pixelized.shared.lwa.usecase
|
||||
|
||||
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheet
|
||||
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.CHA
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.CON
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.DEX
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.HEI
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.INT
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.POW
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.STR
|
||||
import com.pixelized.shared.lwa.parser.expression.Expression
|
||||
import com.pixelized.shared.lwa.parser.expression.ExpressionParser
|
||||
import com.pixelized.shared.lwa.parser.word.Word
|
||||
|
|
@ -22,15 +16,13 @@ class ExpressionUseCase(
|
|||
private val rollUseCase: RollUseCase,
|
||||
) {
|
||||
fun computeSkillValue(
|
||||
sheet: CharacterSheet,
|
||||
sheet: AlteredCharacterSheet,
|
||||
skill: CharacterSheet.Skill,
|
||||
alterations: Map<String, List<FieldAlteration>>,
|
||||
diminished: Int,
|
||||
skill: CharacterSheet.Skill,
|
||||
): Int {
|
||||
val context = Context(
|
||||
sheet = sheet,
|
||||
skill = skill,
|
||||
alterations = alterations,
|
||||
)
|
||||
|
||||
val base: Int = context.evaluate(
|
||||
|
|
@ -56,15 +48,13 @@ class ExpressionUseCase(
|
|||
}
|
||||
|
||||
fun computeRoll(
|
||||
sheet: CharacterSheet,
|
||||
alterations: Map<String, List<FieldAlteration>>,
|
||||
sheet: AlteredCharacterSheet,
|
||||
expression: String,
|
||||
): Int {
|
||||
print("Roll::$expression::")
|
||||
val roll = expressionParser.parse(input = expression)?.let {
|
||||
computeExpression(
|
||||
sheet = sheet,
|
||||
alterations = alterations,
|
||||
expression = it,
|
||||
)
|
||||
} ?: 0
|
||||
|
|
@ -73,14 +63,11 @@ class ExpressionUseCase(
|
|||
}
|
||||
|
||||
fun computeExpression(
|
||||
sheet: CharacterSheet,
|
||||
alterations: Map<String, List<FieldAlteration>>,
|
||||
sheet: AlteredCharacterSheet,
|
||||
expression: Expression,
|
||||
): Int {
|
||||
val context = Context(
|
||||
sheet = sheet,
|
||||
skill = null,
|
||||
alterations = alterations,
|
||||
)
|
||||
return context.evaluate(
|
||||
expression = expression,
|
||||
|
|
@ -113,11 +100,15 @@ class ExpressionUseCase(
|
|||
}
|
||||
|
||||
is Expression.Maximum -> {
|
||||
min(evaluate(expression.first), evaluate(expression.second))
|
||||
max(evaluate(expression.first), evaluate(expression.second))
|
||||
}
|
||||
|
||||
is Expression.Minimum -> {
|
||||
max(evaluate(expression.first), evaluate(expression.second))
|
||||
min(evaluate(expression.first), evaluate(expression.second))
|
||||
}
|
||||
|
||||
is Expression.Floor5 -> {
|
||||
evaluate(expression.expression).let { it - it % 5 }
|
||||
}
|
||||
|
||||
is Expression.Flat -> {
|
||||
|
|
@ -135,29 +126,29 @@ class ExpressionUseCase(
|
|||
is Expression.WordExpression -> when (expression.word.type) {
|
||||
Word.Type.BDC -> evaluate(
|
||||
expression = expressionParser.parse(
|
||||
characterSheetUseCase.damageBonus(
|
||||
strength = sheet.strength + alterations[STR].sum(),
|
||||
height = sheet.height + alterations[HEI].sum(),
|
||||
characterSheetUseCase.meleeBonusDamage(
|
||||
strength = sheet.strength,
|
||||
height = sheet.height,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Word.Type.BDD -> evaluate(
|
||||
expression = expressionParser.parse(
|
||||
characterSheetUseCase.damageBonus(
|
||||
strength = sheet.strength + alterations[STR].sum(),
|
||||
height = sheet.height + alterations[HEI].sum(),
|
||||
characterSheetUseCase.distanceBonusDamage(
|
||||
strength = sheet.strength,
|
||||
height = sheet.height,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Word.Type.STR -> sheet.strength + alterations[STR].sum()
|
||||
Word.Type.DEX -> sheet.dexterity + alterations[DEX].sum()
|
||||
Word.Type.CON -> sheet.constitution + alterations[CON].sum()
|
||||
Word.Type.HEI -> sheet.height + alterations[HEI].sum()
|
||||
Word.Type.INT -> sheet.intelligence + alterations[INT].sum()
|
||||
Word.Type.POW -> sheet.power + alterations[POW].sum()
|
||||
Word.Type.CHA -> sheet.charisma + alterations[CHA].sum()
|
||||
Word.Type.STR -> sheet.strength
|
||||
Word.Type.DEX -> sheet.dexterity
|
||||
Word.Type.CON -> sheet.constitution
|
||||
Word.Type.HEI -> sheet.height
|
||||
Word.Type.INT -> sheet.intelligence
|
||||
Word.Type.POW -> sheet.power
|
||||
Word.Type.CHA -> sheet.charisma
|
||||
}
|
||||
|
||||
null -> 0
|
||||
|
|
@ -165,9 +156,7 @@ class ExpressionUseCase(
|
|||
}
|
||||
|
||||
data class Context(
|
||||
val sheet: CharacterSheet,
|
||||
val skill: CharacterSheet.Skill?,
|
||||
val alterations: Map<String, List<FieldAlteration>>,
|
||||
val sheet: AlteredCharacterSheet,
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue