Add campagin + character REST API.

This commit is contained in:
Thomas Andres Gomez 2025-02-24 11:16:21 +01:00
parent 495768e5fe
commit bd4d65fe6a
34 changed files with 592 additions and 162 deletions

View file

@ -2,10 +2,10 @@ package com.pixelized.shared.lwa.model.campaign
data class Campaign(
val characters: Map<String, CharacterInstance>,
val npcs: Map<String, CharacterInstance>,
) {
data class CharacterInstance(
val characteristic: Map<Characteristic, Int>,
val usedSkill: List<String>,
) {
enum class Characteristic {
Damage,
@ -16,6 +16,7 @@ data class Campaign(
companion object {
val EMPTY = Campaign(
characters = emptyMap(),
npcs = emptyMap(),
)
}
}
@ -23,10 +24,12 @@ data class Campaign(
fun Campaign.character(id: String): Campaign.CharacterInstance {
return characters[id] ?: Campaign.CharacterInstance(
characteristic = emptyMap(),
usedSkill = emptyList(),
)
}
val Campaign.CharacterInstance.level
get() = characteristic[Campaign.CharacterInstance.Characteristic.Damage] ?: 1
val Campaign.CharacterInstance.damage
get() = characteristic[Campaign.CharacterInstance.Characteristic.Damage] ?: 0

View file

@ -14,17 +14,21 @@ class CampaignJsonFactory {
json: CampaignJsonV1,
): Campaign {
return Campaign(
characters = json.characters.map { entry ->
entry.key to Campaign.CharacterInstance(
characteristic = entry.value.characteristic.map { char ->
when (char.key) {
CampaignJsonV1.CharacterInstanceJson.Characteristic.Damage -> Campaign.CharacterInstance.Characteristic.Damage
CampaignJsonV1.CharacterInstanceJson.Characteristic.Power -> Campaign.CharacterInstance.Characteristic.Power
} to char.value
}.toMap(),
usedSkill = entry.value.usedSkill,
)
}.toMap()
characters = json.characters.mapValues { convertFromV1(json = it.value) },
npcs = json.npcs.mapValues { convertFromV1(json = it.value) },
)
}
private fun convertFromV1(
json: CampaignJsonV1.CharacterInstanceJson,
): Campaign.CharacterInstance {
return Campaign.CharacterInstance(
characteristic = json.characteristic.map { char ->
when (char.key) {
CampaignJsonV1.CharacterInstanceJson.Characteristic.Damage -> Campaign.CharacterInstance.Characteristic.Damage
CampaignJsonV1.CharacterInstanceJson.Characteristic.Power -> Campaign.CharacterInstance.Characteristic.Power
} to char.value
}.toMap(),
)
}
@ -32,17 +36,21 @@ class CampaignJsonFactory {
data: Campaign,
): CampaignJson {
return CampaignJsonV1(
characters = data.characters.map { entry ->
entry.key to CampaignJsonV1.CharacterInstanceJson(
characteristic = entry.value.characteristic.map { char ->
when (char.key) {
Campaign.CharacterInstance.Characteristic.Damage -> CampaignJsonV1.CharacterInstanceJson.Characteristic.Damage
Campaign.CharacterInstance.Characteristic.Power -> CampaignJsonV1.CharacterInstanceJson.Characteristic.Power
} to char.value
}.toMap(),
usedSkill = entry.value.usedSkill,
)
}.toMap()
characters = data.characters.mapValues { convertToJson(data = it.value) },
npcs = data.npcs.mapValues { convertToJson(data = it.value) },
)
}
private fun convertToJson(
data: Campaign.CharacterInstance,
): CampaignJsonV1.CharacterInstanceJson {
return CampaignJsonV1.CharacterInstanceJson(
characteristic = data.characteristic.map { char ->
when (char.key) {
Campaign.CharacterInstance.Characteristic.Damage -> CampaignJsonV1.CharacterInstanceJson.Characteristic.Damage
Campaign.CharacterInstance.Characteristic.Power -> CampaignJsonV1.CharacterInstanceJson.Characteristic.Power
} to char.value
}.toMap(),
)
}
}

View file

@ -5,12 +5,12 @@ import kotlinx.serialization.Serializable
@Serializable
data class CampaignJsonV1(
val characters: Map<String, CharacterInstanceJson>,
val npcs: Map<String, CharacterInstanceJson>,
) : CampaignJson {
@Serializable
data class CharacterInstanceJson(
val characteristic: Map<Characteristic, Int>,
val usedSkill: List<String>,
) {
enum class Characteristic {
Damage,

View file

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

View file

@ -1,5 +1,6 @@
package com.pixelized.shared.lwa.model.characterSheet
import com.pixelized.shared.lwa.protocol.rest.CharacterPreviewJson
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
@ -98,6 +99,16 @@ class CharacterSheetJsonFactory(
)
}
fun convertToPreviewJson(
sheet: CharacterSheet,
): CharacterPreviewJson {
return CharacterPreviewJson(
id = sheet.id,
name = sheet.name,
level = sheet.level,
)
}
fun convertToJson(
sheet: CharacterSheet,
): CharacterSheetJson {

View file

@ -4,7 +4,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class CharacterSheetJsonV1(
val id: String,
override val id: String,
val name: String,
val portrait: String?,
val thumbnail: String?,

View file

@ -1,10 +0,0 @@
package com.pixelized.shared.lwa.protocol
import kotlinx.serialization.Serializable
@Serializable
data class Message(
val from: String,
val type: MessageType,
val value: String,
)

View file

@ -1,7 +0,0 @@
package com.pixelized.shared.lwa.protocol
enum class MessageType {
Roll,
UpdateSkillUsage,
UpdatePlayerCharacteristic,
}

View file

@ -1,3 +0,0 @@
package com.pixelized.shared.lwa.protocol.payload
sealed interface MessagePayload

View file

@ -0,0 +1,10 @@
package com.pixelized.shared.lwa.protocol.rest
import kotlinx.serialization.Serializable
@Serializable
class CharacterPreviewJson(
val id: String,
val name: String,
val level: Int,
)

View file

@ -0,0 +1,10 @@
package com.pixelized.shared.lwa.protocol.websocket
import com.pixelized.shared.lwa.protocol.websocket.payload.MessagePayload
import kotlinx.serialization.Serializable
@Serializable
data class Message(
val from: String,
val value: MessagePayload,
)

View file

@ -0,0 +1,6 @@
package com.pixelized.shared.lwa.protocol.websocket.payload
import kotlinx.serialization.Serializable
@Serializable
sealed interface MessagePayload

View file

@ -0,0 +1,20 @@
package com.pixelized.shared.lwa.protocol.websocket.payload
import kotlinx.serialization.Serializable
@Serializable
sealed class RestSynchronisation : MessagePayload {
@Serializable
data class CharacterUpdate(
val id: String,
) : RestSynchronisation()
@Serializable
data class CharacterDelete(
val characterId: String,
) : RestSynchronisation()
@Serializable
data object Campaign : RestSynchronisation()
}

View file

@ -1,4 +1,4 @@
package com.pixelized.shared.lwa.protocol.payload
package com.pixelized.shared.lwa.protocol.websocket.payload
import kotlinx.serialization.Serializable

View file

@ -1,4 +1,4 @@
package com.pixelized.shared.lwa.protocol.payload
package com.pixelized.shared.lwa.protocol.websocket.payload
import com.pixelized.shared.lwa.model.campaign.Campaign
import kotlinx.serialization.Serializable

View file

@ -1,4 +1,4 @@
package com.pixelized.shared.lwa.protocol.payload
package com.pixelized.shared.lwa.protocol.websocket.payload
import kotlinx.serialization.Serializable

View file

@ -57,32 +57,49 @@ class CharacterSheetUseCase {
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,
): CharacterSheet {
return character.copy(
commonSkills = character.commonSkills.map { skill ->
if (skill.id == skillId) {
skill.copy(used = skill.used.not())
} else {
skill
}
skill.takeIf { skill.id == skillId }?.copy(used = skill.used.not()) ?: skill
},
specialSkills = character.specialSkills.map { skill ->
if (skill.id == skillId) {
skill.copy(used = skill.used.not())
} else {
skill
}
skill.takeIf { skill.id == skillId }?.copy(used = skill.used.not()) ?: skill
},
magicSkills = character.magicSkills.map { skill ->
if (skill.id == skillId) {
skill.copy(used = skill.used.not())
} else {
skill
}
}
skill.takeIf { skill.id == skillId }?.copy(used = skill.used.not()) ?: skill
},
)
}
}