ReModel: remove the CharacterInstanceId: server

This commit is contained in:
Thomas Andres Gomez 2025-03-24 18:03:41 +01:00
parent a69f95e62d
commit a5adc61e90
61 changed files with 1072 additions and 1038 deletions

View file

@ -4,11 +4,12 @@ import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
import com.pixelized.shared.lwa.model.alteration.AlterationJsonFactory
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonV1Factory
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonV2Factory
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonFactory
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonV1Factory
import com.pixelized.shared.lwa.parser.dice.DiceParser
import com.pixelized.shared.lwa.parser.expression.ExpressionParser
import com.pixelized.shared.lwa.parser.word.WordParser
import com.pixelized.shared.lwa.usecase.CampaignUseCase
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
import com.pixelized.shared.lwa.usecase.ExpressionUseCase
import com.pixelized.shared.lwa.usecase.RollUseCase
@ -38,8 +39,10 @@ val toolsDependencies
val factoryDependencies
get() = module {
factoryOf(::CharacterSheetJsonFactory)
factoryOf(::CharacterSheetJsonV1Factory)
factoryOf(::CampaignJsonFactory)
factoryOf(::CampaignJsonV1Factory)
factoryOf(::CampaignJsonV2Factory)
factoryOf(::AlteredCharacterSheetFactory)
factoryOf(::AlterationJsonFactory)
}
@ -54,7 +57,6 @@ val parserDependencies
val useCaseDependencies
get() = module {
factoryOf(::CharacterSheetUseCase)
factoryOf(::CampaignUseCase)
factoryOf(::SkillStepUseCase)
factoryOf(::RollUseCase)
factoryOf(::ExpressionUseCase)

View file

@ -3,4 +3,6 @@ package com.pixelized.shared.lwa.model.alteration
import kotlinx.serialization.Serializable
@Serializable
sealed interface AlterationJson
sealed interface AlterationJson {
val id: String
}

View file

@ -4,7 +4,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class AlterationJsonV1(
val id: String,
override val id: String,
val metadata: AlterationMetadataJsonV1,
val fields: List<FieldJsonV1>,
) : AlterationJson {

View file

@ -1,53 +1,13 @@
package com.pixelized.shared.lwa.model.campaign
data class Campaign(
val characters: Map<CharacterInstance.Id, CharacterInstance>,
val npcs: Map<CharacterInstance.Id, CharacterInstance>,
val characters: Set<String>,
val npcs: Set<String>,
val scene: Scene,
val options: Options,
) {
val instances = characters + npcs
data class CharacterInstance(
val characteristic: Map<Characteristic, Int>,
val alterations: List<String>,
val diminished: Int,
) {
data class Id(
val prefix: Char,
val characterSheetId: String,
val instanceId: Int,
) {
fun equals(
prefix: Char,
characterSheetId: String?,
instanceId: Int?,
): Boolean {
return this.prefix == prefix &&
this.characterSheetId == characterSheetId &&
this.instanceId == instanceId
}
companion object {
const val PLAYER = 'c'
const val NPC = 'n'
}
}
enum class Characteristic {
Damage,
Power,
}
companion object {
fun empty() = CharacterInstance(
characteristic = emptyMap(),
alterations = emptyList(),
diminished = 0,
)
}
}
data class Scene(
val name: String,
) {
@ -71,28 +31,11 @@ data class Campaign(
}
companion object {
val EMPTY = Campaign(
characters = emptyMap(),
npcs = emptyMap(),
fun empty() = Campaign(
characters = emptySet(),
npcs = emptySet(),
scene = Scene.empty(),
options = Options.empty(),
)
}
}
fun Campaign.character(id: Campaign.CharacterInstance.Id): Campaign.CharacterInstance {
return characters[id] ?: Campaign.CharacterInstance.empty()
}
fun Campaign.npc(id: Campaign.CharacterInstance.Id): Campaign.CharacterInstance {
return npcs[id] ?: Campaign.CharacterInstance.empty()
}
val Campaign.CharacterInstance.level
get() = characteristic[Campaign.CharacterInstance.Characteristic.Damage] ?: 1
val Campaign.CharacterInstance.damage
get() = characteristic[Campaign.CharacterInstance.Characteristic.Damage] ?: 0
val Campaign.CharacterInstance.power
get() = characteristic[Campaign.CharacterInstance.Characteristic.Power] ?: 0
}

View file

@ -0,0 +1,23 @@
package com.pixelized.shared.lwa.model.campaign
import kotlinx.serialization.Serializable
@Serializable
data class CampaignJsonV2(
val characters: Set<String>,
val npcs: Set<String>,
val scene: SceneJsonV2?,
val options: OptionsJsonV2?,
) : CampaignJson {
@Serializable
data class SceneJsonV2(
val name: String,
) : CampaignJson.SceneJson
@Serializable
data class OptionsJsonV2(
val showPlayer: Boolean,
val showNpcs: Boolean,
) : CampaignJson.OptionJson
}

View file

@ -3,38 +3,18 @@ package com.pixelized.shared.lwa.model.campaign.factory
import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.model.campaign.CampaignJson
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV2
class CampaignJsonFactory(
private val v1: CampaignJsonV1Factory,
private val v2: CampaignJsonV2Factory,
) {
fun characterInstanceIdFromJson(
characterInstanceIdJson: String,
): Campaign.CharacterInstance.Id {
return v1.convertFromV1(characterInstanceIdJson)
}
fun convertFromJson(
json: CampaignJson,
): Campaign {
return when (json) {
is CampaignJsonV1 -> v1.convertFromV1(campaignJson = json)
}
}
fun convertFromJson(
json: CampaignJson.CharacterInstanceJson,
): Campaign.CharacterInstance {
return when (json) {
is CampaignJsonV1.CharacterInstanceJsonV1 -> v1.convertFromV1(characterInstanceJson = json)
}
}
fun convertFromJson(
json: CampaignJson.CharacterInstanceJson.CharacteristicJson,
): Campaign.CharacterInstance.Characteristic {
return when (json) {
CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage -> Campaign.CharacterInstance.Characteristic.Damage
CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power -> Campaign.CharacterInstance.Characteristic.Power
is CampaignJsonV1 -> v1.convertFromJson(campaignJson = json)
is CampaignJsonV2 -> v2.convertFromJson(campaignJson = json)
}
}
@ -42,62 +22,26 @@ class CampaignJsonFactory(
json: CampaignJson.SceneJson,
): Campaign.Scene {
return when (json) {
is CampaignJsonV1.SceneJsonV1 -> v1.convertFromV1(sceneJson = json)
is CampaignJsonV1.SceneJsonV1 -> v1.convertFromJson(sceneJson = json)
is CampaignJsonV2.SceneJsonV2 -> v2.convertFromJson(sceneJson = json)
}
}
// Json conversion.
fun convertToJson(
data: Campaign,
campaign: Campaign,
): CampaignJson {
return CampaignJsonV1(
characters = data.characters
.map { convertToJson(id = it.key) to convertToJson(data = it.value) }
.toMap(),
npcs = data.npcs
.map { convertToJson(id = it.key) to convertToJson(data = it.value) }
.toMap(),
scene = CampaignJsonV1.SceneJsonV1(
name = data.scene.name
return CampaignJsonV2(
characters = campaign.characters,
npcs = campaign.npcs,
scene = CampaignJsonV2.SceneJsonV2(
name = campaign.scene.name,
),
options = CampaignJsonV1.OptionsJsonV1(
showPlayer = data.options.showParty,
showNpcs = data.options.showNpcs,
options = CampaignJsonV2.OptionsJsonV2(
showPlayer = campaign.options.showParty,
showNpcs = campaign.options.showNpcs,
)
)
}
fun convertToJson(
id: Campaign.CharacterInstance.Id,
): String {
return "${id.prefix}-${String.format("%03d", id.instanceId)}-${id.characterSheetId}"
}
fun convertToJson(
data: Campaign.CharacterInstance,
): CampaignJsonV1.CharacterInstanceJsonV1 {
return CampaignJsonV1.CharacterInstanceJsonV1(
characteristic = data.characteristic
.map { char -> convertToJson(characteristic = char.key) to char.value }
.toMap(),
alterations = data.alterations,
diminished = data.diminished,
)
}
fun convertToJson(
characteristic: Campaign.CharacterInstance.Characteristic,
): CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1 {
return when (characteristic) {
Campaign.CharacterInstance.Characteristic.Damage -> CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage
Campaign.CharacterInstance.Characteristic.Power -> CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power
}
}
fun convertToJson(
scene: Campaign.Scene,
): CampaignJsonV1.SceneJsonV1 {
return CampaignJsonV1.SceneJsonV1(
name = scene.name,
)
}
}

View file

@ -5,65 +5,25 @@ import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1
class CampaignJsonV1Factory {
fun convertFromV1(
fun convertFromJson(
campaignJson: CampaignJsonV1,
): Campaign {
// Characters & npcs were previously a map of a CharacterInstanceID ( Char + instance number + Character Sheet Id)
// Map to an instance object with data related to said instance (HP / PP / alterations etc.)
// This have been deleted and moved to the CharacterSheet.
return Campaign(
characters = campaignJson.characters
.map {
val key = convertFromV1(characterInstanceIdJson = it.key)
val instance = convertFromV1(characterInstanceJson = it.value)
key to instance
}
.toMap(),
npcs = campaignJson.npcs
.map {
val key = convertFromV1(characterInstanceIdJson = it.key)
val instance = convertFromV1(characterInstanceJson = it.value)
key to instance
}
.toMap(),
characters = emptySet(),
npcs = emptySet(),
scene = campaignJson.scene
?.let { convertFromV1(it) }
?.let { convertFromJson(it) }
?: Campaign.Scene.empty(),
options = campaignJson.options
?.let { convertFromV1(it) }
?:Campaign.Options.empty()
?.let { convertFromJson(it) }
?: Campaign.Options.empty()
)
}
fun convertFromV1(
characterInstanceIdJson: String,
): Campaign.CharacterInstance.Id {
return Campaign.CharacterInstance.Id(
prefix = characterInstanceIdJson.take(1)[0],
characterSheetId = characterInstanceIdJson.drop(2 + 4), // drop the char then the - then the first 3 number then the -
instanceId = characterInstanceIdJson.drop(2).take(3).toIntOrNull() ?: 0,
)
}
fun convertFromV1(
characterInstanceJson: CampaignJsonV1.CharacterInstanceJsonV1,
): Campaign.CharacterInstance {
return Campaign.CharacterInstance(
characteristic = characterInstanceJson.characteristic
.mapKeys { convertFromV1(characteristicJson = it.key) }
.toMap(),
alterations = characterInstanceJson.alterations ?: emptyList(),
diminished = characterInstanceJson.diminished ?: 0,
)
}
fun convertFromV1(
characteristicJson: CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1,
): Campaign.CharacterInstance.Characteristic {
return when (characteristicJson) {
CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage -> Campaign.CharacterInstance.Characteristic.Damage
CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power -> Campaign.CharacterInstance.Characteristic.Power
}
}
fun convertFromV1(
fun convertFromJson(
sceneJson: CampaignJsonV1.SceneJsonV1,
): Campaign.Scene {
return Campaign.Scene(
@ -71,7 +31,7 @@ class CampaignJsonV1Factory {
)
}
fun convertFromV1(
fun convertFromJson(
optionsJson: CampaignJsonV1.OptionsJsonV1,
): Campaign.Options {
return Campaign.Options(

View file

@ -0,0 +1,39 @@
package com.pixelized.shared.lwa.model.campaign.factory
import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV2
class CampaignJsonV2Factory {
fun convertFromJson(
campaignJson: CampaignJsonV2,
): Campaign {
return Campaign(
characters = campaignJson.characters,
npcs = campaignJson.npcs,
scene = campaignJson.scene
?.let { convertFromJson(it) }
?: Campaign.Scene.empty(),
options = campaignJson.options
?.let { convertFromJson(it) }
?: Campaign.Options.empty()
)
}
fun convertFromJson(
sceneJson: CampaignJsonV2.SceneJsonV2,
): Campaign.Scene {
return Campaign.Scene(
name = sceneJson.name
)
}
fun convertFromJson(
optionsJson: CampaignJsonV2.OptionsJsonV2,
): Campaign.Options {
return Campaign.Options(
showParty = optionsJson.showPlayer,
showNpcs = optionsJson.showNpcs
)
}
}

View file

@ -15,9 +15,11 @@ data class CharacterSheet(
val intelligence: Int,
val power: Int,
val charisma: Int,
// sub characteristics
val movement: Int,
val armor: Int,
// alterations
val damage: Int, // damage taken on the hp pool
val fatigue: Int, // damage taken on the pp pool
val diminished: Int,
val alterations: List<String>,
// skills
val commonSkills: List<Skill>,
val specialSkills: List<Skill>,

View file

@ -5,4 +5,5 @@ import kotlinx.serialization.Serializable
@Serializable
sealed interface CharacterSheetJson {
val id: String
val name: String
}

View file

@ -5,7 +5,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class CharacterSheetJsonV1(
override val id: String,
val name: String,
override val name: String,
val portrait: String?,
val thumbnail: String?,
val level: Int,
@ -18,13 +18,16 @@ data class CharacterSheetJsonV1(
val intelligence: Int,
val power: Int,
val charisma: Int,
// alterations
val damage: Int?,
val fatigue: Int?,
val diminished: Int?,
val alterations: List<String>?,
// skills
val skills: List<Skill>,
// occupations
val occupations: List<Skill>,
// magic skill
val magics: List<Skill>,
// attack
// actions
val rolls: List<Roll>,
) : CharacterSheetJson {

View file

@ -1,108 +1,24 @@
package com.pixelized.shared.lwa.model.characterSheet
package com.pixelized.shared.lwa.model.characterSheet.factory
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonV1
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
import com.pixelized.shared.lwa.protocol.rest.CharacterPreviewJson
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
class CharacterSheetJsonFactory(
private val characterSheetUseCase: CharacterSheetUseCase,
private val v1: CharacterSheetJsonV1Factory,
) {
suspend fun convertFromJson(
json: CharacterSheetJson,
): CharacterSheet {
return when (json) {
is CharacterSheetJsonV1 -> convertFromV1(json = json)
is CharacterSheetJsonV1 -> v1.convertFromJson(json = json)
}
}
suspend fun convertFromJson(
json: CharacterPreviewJson,
): CharacterSheetPreview {
return CharacterSheetPreview(
characterSheetId = json.id,
name = json.name,
level = json.level,
)
}
private suspend fun convertFromV1(
json: CharacterSheetJsonV1,
): CharacterSheet = characterSheetUseCase.run {
CharacterSheet(
id = json.id,
name = json.name,
portrait = json.portrait,
thumbnail = json.thumbnail,
level = json.level,
shouldLevelUp = json.shouldLevelUp ?: false,
strength = json.strength,
dexterity = json.dexterity,
constitution = json.constitution,
height = json.height,
intelligence = json.intelligence,
power = json.power,
charisma = json.charisma,
movement = movement(),
armor = armor(),
commonSkills = json.skills.map {
CharacterSheet.Skill(
id = it.id,
label = it.label,
description = it.description,
base = it.base,
bonus = it.bonus,
level = it.level,
occupation = it.occupation,
used = it.used,
)
},
specialSkills = json.occupations.map {
CharacterSheet.Skill(
id = it.id,
label = it.label,
description = it.description,
base = it.base,
bonus = it.bonus,
level = it.level,
occupation = it.occupation,
used = it.used,
)
},
magicSkills = json.magics.map {
CharacterSheet.Skill(
id = it.id,
label = it.label,
description = it.description,
base = it.base,
bonus = it.bonus,
level = it.level,
occupation = it.occupation,
used = it.used,
)
},
actions = json.rolls.map {
CharacterSheet.Roll(
id = it.id,
label = it.label,
description = it.description,
canBeCritical = it.canBeCritical,
roll = it.roll,
)
},
)
}
fun convertToPreviewJson(
sheet: CharacterSheet,
): CharacterPreviewJson {
return CharacterPreviewJson(
id = sheet.id,
portrait = sheet.portrait,
thumbnail = sheet.thumbnail,
name = sheet.name,
level = sheet.level,
)
}
// Json conversion.
fun convertToJson(
sheet: CharacterSheet,
@ -121,6 +37,10 @@ class CharacterSheetJsonFactory(
intelligence = sheet.intelligence,
power = sheet.power,
charisma = sheet.charisma,
damage = sheet.damage,
fatigue = sheet.fatigue,
diminished = sheet.diminished,
alterations = sheet.alterations,
skills = sheet.commonSkills.map {
CharacterSheetJsonV1.Skill(
id = it.id,
@ -169,4 +89,26 @@ class CharacterSheetJsonFactory(
)
return json
}
suspend fun convertFromJson(
json: CharacterPreviewJson,
): CharacterSheetPreview {
return CharacterSheetPreview(
characterSheetId = json.id,
name = json.name,
level = json.level,
)
}
fun convertToPreviewJson(
sheet: CharacterSheet,
): CharacterPreviewJson {
return CharacterPreviewJson(
id = sheet.id,
portrait = sheet.portrait,
thumbnail = sheet.thumbnail,
name = sheet.name,
level = sheet.level,
)
}
}

View file

@ -0,0 +1,78 @@
package com.pixelized.shared.lwa.model.characterSheet.factory
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonV1
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
class CharacterSheetJsonV1Factory(
private val characterSheetUseCase: CharacterSheetUseCase,
) {
suspend fun convertFromJson(
json: CharacterSheetJsonV1,
): CharacterSheet = characterSheetUseCase.run {
CharacterSheet(
id = json.id,
name = json.name,
portrait = json.portrait,
thumbnail = json.thumbnail,
level = json.level,
shouldLevelUp = json.shouldLevelUp ?: false,
strength = json.strength,
dexterity = json.dexterity,
constitution = json.constitution,
height = json.height,
intelligence = json.intelligence,
power = json.power,
charisma = json.charisma,
damage = json.damage ?: 0,
fatigue = json.fatigue ?: 0,
diminished = json.diminished ?: 0,
alterations = json.alterations ?: emptyList(),
commonSkills = json.skills.map {
CharacterSheet.Skill(
id = it.id,
label = it.label,
description = it.description,
base = it.base,
bonus = it.bonus,
level = it.level,
occupation = it.occupation,
used = it.used,
)
},
specialSkills = json.occupations.map {
CharacterSheet.Skill(
id = it.id,
label = it.label,
description = it.description,
base = it.base,
bonus = it.bonus,
level = it.level,
occupation = it.occupation,
used = it.used,
)
},
magicSkills = json.magics.map {
CharacterSheet.Skill(
id = it.id,
label = it.label,
description = it.description,
base = it.base,
bonus = it.bonus,
level = it.level,
occupation = it.occupation,
used = it.used,
)
},
actions = json.rolls.map {
CharacterSheet.Roll(
id = it.id,
label = it.label,
description = it.description,
canBeCritical = it.canBeCritical,
roll = it.roll,
)
},
)
}
}

View file

@ -3,22 +3,17 @@ package com.pixelized.shared.lwa.protocol.websocket
import kotlinx.serialization.Serializable
@Serializable
sealed class RestSynchronisation : SocketMessage {
@Serializable
data class CharacterSheetUpdate(
override val timestamp: Long,
override val characterSheetId: String,
) : RestSynchronisation(), CharacterSheetIdMessage
sealed interface ApiSynchronisation : SocketMessage {
@Serializable
data class CharacterSheetDelete(
override val timestamp: Long,
override val characterSheetId: String,
) : RestSynchronisation(), CharacterSheetIdMessage
) : ApiSynchronisation, CharacterSheetIdMessage
@Serializable
data class Campaign(
data class CharacterSheetUpdate(
override val timestamp: Long,
) : RestSynchronisation()
override val characterSheetId: String,
) : ApiSynchronisation, CharacterSheetIdMessage
}

View file

@ -0,0 +1,37 @@
package com.pixelized.shared.lwa.protocol.websocket
import kotlinx.serialization.Serializable
@Serializable
sealed interface CampaignEvent : SocketMessage {
// TODO Will probably be moved when the scene become more complex, (should already actually)
@Serializable
data class UpdateScene(
override val timestamp: Long,
) : CampaignEvent
@Serializable
data class CharacterRemoved(
override val timestamp: Long,
override val characterSheetId: String,
) : CampaignEvent, CharacterSheetIdMessage
@Serializable
data class CharacterAdded(
override val timestamp: Long,
override val characterSheetId: String,
) : CampaignEvent, CharacterSheetIdMessage
@Serializable
data class NpcRemoved(
override val timestamp: Long,
override val characterSheetId: String,
) : CampaignEvent, CharacterSheetIdMessage
@Serializable
data class NpcAdded(
override val timestamp: Long,
override val characterSheetId: String,
) : CampaignEvent, CharacterSheetIdMessage
}

View file

@ -1,41 +0,0 @@
package com.pixelized.shared.lwa.protocol.websocket
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1
import kotlinx.serialization.Serializable
@Serializable
sealed interface CampaignMessage : SocketMessage, CharacterInstanceIdMessage {
override val prefix: Char
override val characterSheetId: String
override val instanceId: Int
@Serializable
data class UpdateCharacteristic(
override val timestamp: Long,
override val prefix: Char,
override val characterSheetId: String,
override val instanceId: Int,
val characteristic: CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1,
val oldValue: Int,
val newValue: Int,
) : CampaignMessage
@Serializable
data class UpdateDiminished(
override val timestamp: Long,
override val prefix: Char,
override val characterSheetId: String,
override val instanceId: Int,
val diminished: Int,
) : CampaignMessage
@Serializable
data class ToggleActiveAlteration(
override val timestamp: Long,
override val characterSheetId: String,
override val prefix: Char,
override val instanceId: Int,
val alterationId: String,
val active: Boolean,
) : CampaignMessage, CharacterInstanceIdMessage
}

View file

@ -0,0 +1,44 @@
package com.pixelized.shared.lwa.protocol.websocket
import kotlinx.serialization.Serializable
@Serializable
sealed interface CharacterSheetEvent : SocketMessage, CharacterSheetIdMessage {
@Serializable
data class UpdateDamage(
override val characterSheetId: String,
override val timestamp: Long,
val damage: Int,
) : CharacterSheetEvent
@Serializable
data class UpdateFatigue(
override val characterSheetId: String,
override val timestamp: Long,
val fatigue: Int,
) : CharacterSheetEvent
@Serializable
data class UpdateDiminished(
override val timestamp: Long,
override val characterSheetId: String,
val diminished: Int,
) : CharacterSheetEvent
@Serializable
data class UpdateAlteration(
override val timestamp: Long,
override val characterSheetId: String,
val alterationId: String,
val active: Boolean,
) : CharacterSheetEvent
@Serializable
data class UpdateSkillUsageEvent(
override val timestamp: Long,
override val characterSheetId: String,
val skillId: String,
val used: Boolean,
) : CharacterSheetEvent
}

View file

@ -5,11 +5,4 @@ import kotlinx.serialization.Serializable
@Serializable
sealed interface CharacterSheetIdMessage {
val characterSheetId: String
}
@Serializable
sealed interface CharacterInstanceIdMessage : CharacterSheetIdMessage {
override val characterSheetId: String
val prefix: Char
val instanceId: Int
}

View file

@ -1,13 +0,0 @@
package com.pixelized.shared.lwa.protocol.websocket
import kotlinx.serialization.Serializable
@Serializable
sealed interface GameEvent : SocketMessage {
@Serializable
data class DisplayPortrait(
override val timestamp: Long,
val characterSheetId: String?,
) : GameEvent
}

View file

@ -14,4 +14,10 @@ sealed interface GameMasterEvent : SocketMessage {
class TogglePlayer(
override val timestamp: Long,
) : GameMasterEvent
@Serializable
data class DisplayPortrait(
override val timestamp: Long,
val characterSheetId: String?, // nullable so no CharacterSheetIdMessage implementation
) : GameMasterEvent
}

View file

@ -3,19 +3,17 @@ package com.pixelized.shared.lwa.protocol.websocket
import kotlinx.serialization.Serializable
@Serializable
data class RollMessage(
data class RollEvent(
override val timestamp: Long,
override val characterSheetId: String,
val uuid: String,
val prefix: Char,
val characterSheetId: String,
val instanceId: Int?,
val skillLabel: String,
val rollValue: Int,
val resultLabel: String? = null,
val rollDifficulty: String? = null,
val rollSuccessLimit: Int? = null,
val critical: Critical? = null,
) : SocketMessage {
) : SocketMessage, CharacterSheetIdMessage {
enum class Critical {
CRITICAL_SUCCESS,
SPECIAL_SUCCESS,

View file

@ -1,11 +0,0 @@
package com.pixelized.shared.lwa.protocol.websocket
import kotlinx.serialization.Serializable
@Serializable
data class UpdateSkillUsageMessage(
override val timestamp: Long,
override val characterSheetId: String,
val skillId: String,
val used: Boolean,
) : SocketMessage, CharacterSheetIdMessage

View file

@ -1,27 +0,0 @@
package com.pixelized.shared.lwa.usecase
import com.pixelized.shared.lwa.model.campaign.Campaign
class CampaignUseCase {
fun updateCharacteristic(
instance: Campaign.CharacterInstance,
characteristic: Campaign.CharacterInstance.Characteristic,
value: Int,
): Campaign.CharacterInstance {
return instance.copy(
characteristic = instance.characteristic.toMutableMap().also {
it[characteristic] = value
}
)
}
fun updateDiminished(
instance: Campaign.CharacterInstance,
diminished: Int,
): Campaign.CharacterInstance {
return instance.copy(
diminished = diminished,
)
}
}

View file

@ -1,6 +1,5 @@
package com.pixelized.shared.lwa.usecase
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import kotlin.math.ceil
import kotlin.math.max
@ -76,51 +75,4 @@ class CharacterSheetUseCase {
fun hpGrow(constitution: Int): Int {
return (constitution / 3)
}
// Update character sheet.
fun updateLevel(
character: CharacterSheet,
level: Int,
): CharacterSheet {
return character.copy(
level = level,
)
}
fun updateSkillLevel(
character: CharacterSheet,
skillId: String,
level: Int,
): CharacterSheet {
return character.copy(
commonSkills = character.commonSkills.map { skill ->
skill.takeIf { skill.id == skillId }?.copy(level = level) ?: skill
},
specialSkills = character.specialSkills.map { skill ->
skill.takeIf { skill.id == skillId }?.copy(level = level) ?: skill
},
magicSkills = character.magicSkills.map { skill ->
skill.takeIf { skill.id == skillId }?.copy(level = level) ?: skill
},
)
}
fun updateSkillUsage(
character: CharacterSheet,
skillId: String,
used: Boolean,
): CharacterSheet {
return character.copy(
commonSkills = character.commonSkills.map { skill ->
skill.takeIf { skill.id == skillId }?.copy(used = used) ?: skill
},
specialSkills = character.specialSkills.map { skill ->
skill.takeIf { skill.id == skillId }?.copy(used = used) ?: skill
},
magicSkills = character.magicSkills.map { skill ->
skill.takeIf { skill.id == skillId }?.copy(used = used) ?: skill
},
)
}
}