ReModel: remove the CharacterInstanceId: server
This commit is contained in:
parent
a69f95e62d
commit
a5adc61e90
61 changed files with 1072 additions and 1038 deletions
|
|
@ -6,11 +6,9 @@ import com.pixelized.shared.lwa.model.campaign.Campaign
|
|||
import com.pixelized.shared.lwa.model.campaign.character
|
||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||
import com.pixelized.shared.lwa.model.campaign.npc
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||
import com.pixelized.shared.lwa.usecase.CampaignUseCase
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -113,25 +111,25 @@ class CampaignStore(
|
|||
campaign(update = true)
|
||||
}
|
||||
|
||||
is CampaignMessage -> {
|
||||
is CampaignEvent -> {
|
||||
val instanceId = Campaign.CharacterInstance.Id(
|
||||
prefix = message.prefix,
|
||||
characterSheetId = message.characterSheetId,
|
||||
instanceId = message.instanceId,
|
||||
)
|
||||
when (message) {
|
||||
is CampaignMessage.UpdateCharacteristic -> updateCharacteristic(
|
||||
is CampaignEvent.UpdateCharacteristic -> updateCharacteristic(
|
||||
characterInstanceId = instanceId,
|
||||
characteristic = factory.convertFromJson(json = message.characteristic),
|
||||
value = message.newValue,
|
||||
)
|
||||
|
||||
is CampaignMessage.UpdateDiminished -> updateDiminished(
|
||||
is CampaignEvent.UpdateDiminished -> updateDiminished(
|
||||
characterInstanceId = instanceId,
|
||||
diminished = message.diminished,
|
||||
)
|
||||
|
||||
is CampaignMessage.ToggleActiveAlteration -> updateAlterations(
|
||||
is CampaignEvent.ToggleActiveAlteration -> updateAlterations(
|
||||
characterInstanceId = instanceId,
|
||||
alterationId = message.alterationId,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ package com.pixelized.desktop.lwa.repository.characterSheet
|
|||
import com.pixelized.desktop.lwa.network.LwaClient
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory
|
||||
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonFactory
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
|
||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
|
||||
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
package com.pixelized.desktop.lwa.repository.roll_history
|
||||
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollEvent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.shareIn
|
||||
|
||||
class RollHistoryRepository(
|
||||
|
|
@ -16,8 +14,8 @@ class RollHistoryRepository(
|
|||
) {
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
|
||||
val rolls: SharedFlow<RollMessage> = network.data
|
||||
.filterIsInstance(RollMessage::class)
|
||||
val rolls: SharedFlow<RollEvent> = network.data
|
||||
.filterIsInstance(RollEvent::class)
|
||||
.shareIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.pixelized.shared.lwa.model.campaign.damage
|
|||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||
import com.pixelized.shared.lwa.model.campaign.power
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
|
||||
class CharacterDetailCharacteristicDialogViewModel(
|
||||
private val characterSheetRepository: CharacterSheetRepository,
|
||||
|
|
@ -84,7 +84,7 @@ class CharacterDetailCharacteristicDialogViewModel(
|
|||
)
|
||||
// share the data through the websocket.
|
||||
network.share(
|
||||
message = CampaignMessage.UpdateCharacteristic(
|
||||
message = CampaignEvent.UpdateCharacteristic(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
prefix = characterInstanceId.prefix,
|
||||
characterSheetId = characterInstanceId.characterSheetId,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope
|
|||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import com.pixelized.desktop.lwa.ui.overlay.roll.DifficultyUio.Difficulty
|
|||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheet
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollEvent
|
||||
import com.pixelized.shared.lwa.usecase.ExpressionUseCase
|
||||
import com.pixelized.shared.lwa.usecase.SkillStepUseCase
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -278,7 +278,7 @@ class RollViewModel(
|
|||
) {
|
||||
val rollAction = rollAction ?: return
|
||||
|
||||
val payload = RollMessage(
|
||||
val payload = RollEvent(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
uuid = UUID.randomUUID().toString(),
|
||||
prefix = rollAction.characterInstanceId.prefix,
|
||||
|
|
@ -297,11 +297,11 @@ class RollViewModel(
|
|||
rollSuccessLimit = rollStep?.success?.last,
|
||||
critical = rollStep?.let {
|
||||
when (roll) {
|
||||
in it.criticalSuccess -> RollMessage.Critical.CRITICAL_SUCCESS
|
||||
in it.specialSuccess -> RollMessage.Critical.SPECIAL_SUCCESS
|
||||
in it.success -> RollMessage.Critical.SUCCESS
|
||||
in it.failure -> RollMessage.Critical.FAILURE
|
||||
in it.criticalFailure -> RollMessage.Critical.CRITICAL_FAILURE
|
||||
in it.criticalSuccess -> RollEvent.Critical.CRITICAL_SUCCESS
|
||||
in it.specialSuccess -> RollEvent.Critical.SPECIAL_SUCCESS
|
||||
in it.success -> RollEvent.Critical.SUCCESS
|
||||
in it.failure -> RollEvent.Critical.FAILURE
|
||||
in it.criticalFailure -> RollEvent.Critical.CRITICAL_FAILURE
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
|
|||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.DiminishedStatDialogUio
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__diminished__label
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
|
@ -56,7 +56,7 @@ class CharacterDiminishedViewModel(
|
|||
) {
|
||||
val diminished = dialog.value().text.toIntOrNull() ?: 0
|
||||
networkRepository.share(
|
||||
message = CampaignMessage.UpdateDiminished(
|
||||
message = CampaignEvent.UpdateDiminished(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
prefix = dialog.characterInstanceId.prefix,
|
||||
characterSheetId = dialog.characterInstanceId.characterSheetId,
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@ import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.RollTextMessag
|
|||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage
|
||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
|
|
@ -37,7 +35,7 @@ class TextMessageFactory(
|
|||
val id = formatId.format(time)
|
||||
|
||||
return when (message) {
|
||||
is RollMessage -> {
|
||||
is RollEvent -> {
|
||||
val sheetPreview = characterSheetRepository
|
||||
.characterPreview(characterId = message.characterSheetId)
|
||||
?: return null
|
||||
|
|
@ -54,18 +52,18 @@ class TextMessageFactory(
|
|||
rollSuccessLimit = takeIf { isGm }?.let { message.rollSuccessLimit },
|
||||
resultLabel = message.resultLabel,
|
||||
resultType = when (message.critical) {
|
||||
RollMessage.Critical.CRITICAL_SUCCESS -> RollTextMessageUio.Critical.CRITICAL_SUCCESS
|
||||
RollMessage.Critical.SPECIAL_SUCCESS -> RollTextMessageUio.Critical.SPECIAL_SUCCESS
|
||||
RollMessage.Critical.SUCCESS -> RollTextMessageUio.Critical.SUCCESS
|
||||
RollMessage.Critical.FAILURE -> RollTextMessageUio.Critical.FAILURE
|
||||
RollMessage.Critical.CRITICAL_FAILURE -> RollTextMessageUio.Critical.CRITICAL_FAILURE
|
||||
RollEvent.Critical.CRITICAL_SUCCESS -> RollTextMessageUio.Critical.CRITICAL_SUCCESS
|
||||
RollEvent.Critical.SPECIAL_SUCCESS -> RollTextMessageUio.Critical.SPECIAL_SUCCESS
|
||||
RollEvent.Critical.SUCCESS -> RollTextMessageUio.Critical.SUCCESS
|
||||
RollEvent.Critical.FAILURE -> RollTextMessageUio.Critical.FAILURE
|
||||
RollEvent.Critical.CRITICAL_FAILURE -> RollTextMessageUio.Critical.CRITICAL_FAILURE
|
||||
null -> null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
is CampaignMessage -> when (message) {
|
||||
is CampaignMessage.UpdateDiminished -> {
|
||||
is CampaignEvent -> when (message) {
|
||||
is CampaignEvent.UpdateDiminished -> {
|
||||
val sheetPreview = characterSheetRepository
|
||||
.characterPreview(characterId = message.characterSheetId)
|
||||
?: return null
|
||||
|
|
@ -78,7 +76,7 @@ class TextMessageFactory(
|
|||
)
|
||||
}
|
||||
|
||||
is CampaignMessage.UpdateCharacteristic -> {
|
||||
is CampaignEvent.UpdateCharacteristic -> {
|
||||
val sheet = characterSheetRepository.characterDetail(
|
||||
characterSheetId = message.characterSheetId,
|
||||
) ?: return null
|
||||
|
|
@ -100,7 +98,7 @@ class TextMessageFactory(
|
|||
)
|
||||
}
|
||||
|
||||
is CampaignMessage.ToggleActiveAlteration -> null // TODO
|
||||
is CampaignEvent.ToggleActiveAlteration -> null // TODO
|
||||
}
|
||||
|
||||
is RestSynchronisation.Campaign -> null
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
|||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetDestination
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.DiminishedStatDialogUio
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -144,7 +144,7 @@ class CharacterSheetViewModel(
|
|||
suspend fun changeDiminished(dialog: DiminishedStatDialogUio) {
|
||||
val diminished = dialog.value().text.toIntOrNull() ?: 0
|
||||
network.share(
|
||||
message = CampaignMessage.UpdateDiminished(
|
||||
message = CampaignEvent.UpdateDiminished(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
prefix = dialog.characterInstanceId.prefix,
|
||||
characterSheetId = dialog.characterInstanceId.characterSheetId,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.pixelized.desktop.lwa.ui.screen.gamemaster
|
|||
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio.Action
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||
|
||||
class GameMasterActionUseCase(
|
||||
private val campaignRepository: CampaignRepository,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,33 @@
|
|||
package com.pixelized.server.lwa.model.alteration
|
||||
|
||||
import com.pixelized.shared.lwa.model.alteration.AlterationJson
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
class AlterationService(
|
||||
store: AlterationStore,
|
||||
) {
|
||||
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||
|
||||
private val alterationsFlow = store.alterationsFlow()
|
||||
|
||||
private val alterationHashFlow = alterationsFlow
|
||||
.map { data -> data.associateBy { it.id } }
|
||||
.stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = emptyMap()
|
||||
)
|
||||
|
||||
fun alterations(): List<AlterationJson> {
|
||||
return alterationsFlow.value
|
||||
}
|
||||
|
||||
fun alteration(alterationId: String): AlterationJson? {
|
||||
return alterationHashFlow.value[alterationId]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,7 @@ package com.pixelized.server.lwa.model.campaign
|
|||
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import com.pixelized.shared.lwa.model.campaign.CampaignJson
|
||||
import com.pixelized.shared.lwa.model.campaign.character
|
||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||
import com.pixelized.shared.lwa.model.campaign.npc
|
||||
import com.pixelized.shared.lwa.usecase.CampaignUseCase
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -17,7 +14,6 @@ import kotlinx.coroutines.flow.stateIn
|
|||
class CampaignService(
|
||||
private val store: CampaignStore,
|
||||
private val factory: CampaignJsonFactory,
|
||||
private val useCase: CampaignUseCase,
|
||||
) {
|
||||
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||
|
||||
|
|
@ -41,36 +37,14 @@ class CampaignService(
|
|||
return campaignJsonFlow.value
|
||||
}
|
||||
|
||||
suspend fun addCharacter(
|
||||
characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
fun addCharacter(
|
||||
characterSheetId: String,
|
||||
): Boolean {
|
||||
// fetch all the current campaign character
|
||||
val characters = campaign.characters.toMutableMap()
|
||||
// check if the character is in the campaign.
|
||||
if (characters.containsKey(characterInstanceId)) return false
|
||||
// update the corresponding character
|
||||
characters[characterInstanceId] = campaign.character(id = characterInstanceId)
|
||||
// save the campaign to the disk + update the flow.
|
||||
return try {
|
||||
store.save(
|
||||
campaign = campaign.copy(characters = characters)
|
||||
)
|
||||
true
|
||||
} catch (exception: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun removeCharacter(
|
||||
characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
): Boolean {
|
||||
// fetch all the current campaign character
|
||||
val characters = campaign.characters.toMutableMap()
|
||||
// check if the character is in the campaign.
|
||||
if (characters.containsKey(characterInstanceId).not()) return false
|
||||
// update the corresponding character
|
||||
characters.remove(characterInstanceId)
|
||||
// save the campaign to the disk + update the flow.
|
||||
// check if the character is already in the campaign.
|
||||
if (campaign.characters.contains(characterSheetId)) return false
|
||||
// update the corresponding instance
|
||||
val characters = campaign.characters.toMutableSet().also { it.add(characterSheetId) }
|
||||
// save the campaign to the disk (update the flow).
|
||||
return try {
|
||||
store.save(
|
||||
campaign = campaign.copy(characters = characters)
|
||||
|
|
@ -82,18 +56,34 @@ class CampaignService(
|
|||
}
|
||||
|
||||
suspend fun addNpc(
|
||||
npcInstanceId: Campaign.CharacterInstance.Id,
|
||||
characterSheetId: String,
|
||||
): Boolean {
|
||||
// check if the character is already in the campaign.
|
||||
if (campaign.npcs.contains(characterSheetId)) return false
|
||||
// update the corresponding instance
|
||||
val characters = campaign.npcs.toMutableSet().also { it.add(characterSheetId) }
|
||||
// save the campaign to the disk (update the flow).
|
||||
return try {
|
||||
store.save(
|
||||
campaign = campaign.copy(npcs = characters)
|
||||
)
|
||||
true
|
||||
} catch (exception: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun removeCharacter(
|
||||
characterSheetId: String,
|
||||
): Boolean {
|
||||
// fetch all the current campaign character
|
||||
val npcs = campaign.npcs.toMutableMap()
|
||||
// check if the character is in the campaign.
|
||||
if (npcs.containsKey(npcInstanceId)) return false
|
||||
// update the corresponding character
|
||||
npcs[npcInstanceId] = campaign.npc(id = npcInstanceId)
|
||||
if (campaign.characters.contains(characterSheetId).not()) return false
|
||||
// update the corresponding instance
|
||||
val characters = campaign.characters.toMutableSet().also { it.remove(characterSheetId) }
|
||||
// save the campaign to the disk + update the flow.
|
||||
return try {
|
||||
store.save(
|
||||
campaign = campaign.copy(npcs = npcs)
|
||||
campaign = campaign.copy(characters = characters)
|
||||
)
|
||||
true
|
||||
} catch (exception: Exception) {
|
||||
|
|
@ -102,18 +92,16 @@ class CampaignService(
|
|||
}
|
||||
|
||||
suspend fun removeNpc(
|
||||
npcInstanceId: Campaign.CharacterInstance.Id,
|
||||
characterSheetId: String,
|
||||
): Boolean {
|
||||
// fetch all the current campaign character
|
||||
val npcs = campaign.npcs.toMutableMap()
|
||||
// check if the character is in the campaign.
|
||||
if (npcs.containsKey(npcInstanceId).not()) return false
|
||||
// update the corresponding character
|
||||
npcs.remove(npcInstanceId)
|
||||
if (campaign.npcs.contains(characterSheetId).not()) return false
|
||||
// update the corresponding instance
|
||||
val characters = campaign.npcs.toMutableSet().also { it.remove(characterSheetId) }
|
||||
// save the campaign to the disk + update the flow.
|
||||
return try {
|
||||
store.save(
|
||||
campaign = campaign.copy(npcs = npcs)
|
||||
campaign = campaign.copy(npcs = characters)
|
||||
)
|
||||
true
|
||||
} catch (exception: Exception) {
|
||||
|
|
@ -124,35 +112,7 @@ class CampaignService(
|
|||
suspend fun removeInstance(
|
||||
characterSheetId: String,
|
||||
): Boolean {
|
||||
// fetch all the current campaign character
|
||||
val characterIds = campaign.characters
|
||||
.filterKeys { it.characterSheetId == characterSheetId }
|
||||
.keys
|
||||
val npcIds = campaign.npcs
|
||||
.filterKeys { it.characterSheetId == characterSheetId }
|
||||
.keys
|
||||
|
||||
// check if the character is in the campaign.
|
||||
if (characterIds.isEmpty() && npcIds.isEmpty()) return false
|
||||
|
||||
// update the corresponding character
|
||||
val characters = campaign.characters.toMutableMap()
|
||||
val npcs = campaign.npcs.toMutableMap()
|
||||
characterIds.forEach(characters::remove)
|
||||
npcIds.forEach(npcs::remove)
|
||||
|
||||
// save the campaign to the disk + update the flow.
|
||||
return try {
|
||||
store.save(
|
||||
campaign = campaign.copy(
|
||||
characters = characters,
|
||||
npcs = npcs,
|
||||
)
|
||||
)
|
||||
true
|
||||
} catch (exception: Exception) {
|
||||
false
|
||||
}
|
||||
return removeCharacter(characterSheetId) || removeNpc(characterSheetId)
|
||||
}
|
||||
|
||||
suspend fun setScene(
|
||||
|
|
@ -171,127 +131,127 @@ class CampaignService(
|
|||
|
||||
// Data manipulation through WebSocket.
|
||||
|
||||
suspend fun updateCharacteristic(
|
||||
characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
characteristic: Campaign.CharacterInstance.Characteristic,
|
||||
value: Int,
|
||||
) {
|
||||
when (characterInstanceId.prefix) {
|
||||
Campaign.CharacterInstance.Id.PLAYER -> {
|
||||
// fetch all the current campaign character
|
||||
val characters = campaign.characters.toMutableMap()
|
||||
// update the corresponding character using the use case.
|
||||
characters[characterInstanceId] = useCase.updateCharacteristic(
|
||||
instance = campaign.character(id = characterInstanceId),
|
||||
characteristic = characteristic,
|
||||
value = value,
|
||||
)
|
||||
// save the campaign to the disk + update the flow.
|
||||
store.save(
|
||||
campaign = campaign.copy(characters = characters)
|
||||
)
|
||||
}
|
||||
|
||||
Campaign.CharacterInstance.Id.NPC -> {
|
||||
// fetch all the current campaign character
|
||||
val npcs = campaign.npcs.toMutableMap()
|
||||
// update the corresponding character using the use case.
|
||||
npcs[characterInstanceId] = useCase.updateCharacteristic(
|
||||
instance = campaign.npc(id = characterInstanceId),
|
||||
characteristic = characteristic,
|
||||
value = value,
|
||||
)
|
||||
// save the campaign to the disk + update the flow.
|
||||
store.save(
|
||||
campaign = campaign.copy(npcs = npcs)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateDiminished(
|
||||
characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
diminished: Int,
|
||||
) {
|
||||
when (characterInstanceId.prefix) {
|
||||
Campaign.CharacterInstance.Id.PLAYER -> {
|
||||
// fetch all the current campaign character
|
||||
val characters = campaign.characters.toMutableMap()
|
||||
// update the corresponding character using the use case.
|
||||
characters[characterInstanceId] = useCase.updateDiminished(
|
||||
instance = campaign.character(id = characterInstanceId),
|
||||
diminished = diminished,
|
||||
)
|
||||
// save the campaign to the disk + update the flow.
|
||||
store.save(
|
||||
campaign = campaign.copy(characters = characters)
|
||||
)
|
||||
}
|
||||
|
||||
Campaign.CharacterInstance.Id.NPC -> {
|
||||
// fetch all the current campaign character
|
||||
val npcs = campaign.npcs.toMutableMap()
|
||||
// update the corresponding character using the use case.
|
||||
npcs[characterInstanceId] = useCase.updateDiminished(
|
||||
instance = campaign.npc(id = characterInstanceId),
|
||||
diminished = diminished,
|
||||
)
|
||||
// save the campaign to the disk + update the flow.
|
||||
store.save(
|
||||
campaign = campaign.copy(npcs = npcs)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun toggleAlteration(
|
||||
characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
alterationId: String,
|
||||
) {
|
||||
when (characterInstanceId.prefix) {
|
||||
Campaign.CharacterInstance.Id.PLAYER -> {
|
||||
// fetch all the current campaign character
|
||||
val characters = campaign.characters.toMutableMap()
|
||||
// update the corresponding character alterations
|
||||
characters[characterInstanceId]?.let { character ->
|
||||
characters[characterInstanceId] = character.copy(
|
||||
alterations = character.alterations.toMutableList().also { alterations ->
|
||||
if (alterations.contains(alterationId)) {
|
||||
alterations.remove(alterationId)
|
||||
} else {
|
||||
alterations.add(alterationId)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
// save the campaign to the disk + update the flow.
|
||||
store.save(
|
||||
campaign = campaign.copy(characters = characters)
|
||||
)
|
||||
}
|
||||
|
||||
Campaign.CharacterInstance.Id.NPC -> {
|
||||
// fetch all the current campaign character
|
||||
val characters = campaign.npcs.toMutableMap()
|
||||
// update the corresponding character alterations
|
||||
characters[characterInstanceId]?.let { character ->
|
||||
characters[characterInstanceId] = character.copy(
|
||||
alterations = character.alterations.toMutableList().also { alterations ->
|
||||
if (alterations.contains(alterationId)) {
|
||||
alterations.remove(alterationId)
|
||||
} else {
|
||||
alterations.add(alterationId)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
// save the campaign to the disk + update the flow.
|
||||
store.save(
|
||||
campaign = campaign.copy(npcs = characters)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// suspend fun updateCharacteristic(
|
||||
// characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
// characteristic: Campaign.CharacterInstance.Characteristic,
|
||||
// value: Int,
|
||||
// ) {
|
||||
// when (characterInstanceId.prefix) {
|
||||
// Campaign.CharacterInstance.Id.PLAYER -> {
|
||||
// // fetch all the current campaign character
|
||||
// val characters = campaign.characters.toMutableMap()
|
||||
// // update the corresponding character using the use case.
|
||||
// characters[characterInstanceId] = useCase.updateCharacteristic(
|
||||
// instance = campaign.character(id = characterInstanceId),
|
||||
// characteristic = characteristic,
|
||||
// value = value,
|
||||
// )
|
||||
// // save the campaign to the disk + update the flow.
|
||||
// store.save(
|
||||
// campaign = campaign.copy(characters = characters)
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// Campaign.CharacterInstance.Id.NPC -> {
|
||||
// // fetch all the current campaign character
|
||||
// val npcs = campaign.npcs.toMutableMap()
|
||||
// // update the corresponding character using the use case.
|
||||
// npcs[characterInstanceId] = useCase.updateCharacteristic(
|
||||
// instance = campaign.npc(id = characterInstanceId),
|
||||
// characteristic = characteristic,
|
||||
// value = value,
|
||||
// )
|
||||
// // save the campaign to the disk + update the flow.
|
||||
// store.save(
|
||||
// campaign = campaign.copy(npcs = npcs)
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// suspend fun updateDiminished(
|
||||
// characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
// diminished: Int,
|
||||
// ) {
|
||||
// when (characterInstanceId.prefix) {
|
||||
// Campaign.CharacterInstance.Id.PLAYER -> {
|
||||
// // fetch all the current campaign character
|
||||
// val characters = campaign.characters.toMutableMap()
|
||||
// // update the corresponding character using the use case.
|
||||
// characters[characterInstanceId] = useCase.updateDiminished(
|
||||
// instance = campaign.character(id = characterInstanceId),
|
||||
// diminished = diminished,
|
||||
// )
|
||||
// // save the campaign to the disk + update the flow.
|
||||
// store.save(
|
||||
// campaign = campaign.copy(characters = characters)
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// Campaign.CharacterInstance.Id.NPC -> {
|
||||
// // fetch all the current campaign character
|
||||
// val npcs = campaign.npcs.toMutableMap()
|
||||
// // update the corresponding character using the use case.
|
||||
// npcs[characterInstanceId] = useCase.updateDiminished(
|
||||
// instance = campaign.npc(id = characterInstanceId),
|
||||
// diminished = diminished,
|
||||
// )
|
||||
// // save the campaign to the disk + update the flow.
|
||||
// store.save(
|
||||
// campaign = campaign.copy(npcs = npcs)
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// suspend fun toggleAlteration(
|
||||
// characterInstanceId: Campaign.CharacterInstance.Id,
|
||||
// alterationId: String,
|
||||
// ) {
|
||||
// when (characterInstanceId.prefix) {
|
||||
// Campaign.CharacterInstance.Id.PLAYER -> {
|
||||
// // fetch all the current campaign character
|
||||
// val characters = campaign.characters.toMutableMap()
|
||||
// // update the corresponding character alterations
|
||||
// characters[characterInstanceId]?.let { character ->
|
||||
// characters[characterInstanceId] = character.copy(
|
||||
// alterations = character.alterations.toMutableList().also { alterations ->
|
||||
// if (alterations.contains(alterationId)) {
|
||||
// alterations.remove(alterationId)
|
||||
// } else {
|
||||
// alterations.add(alterationId)
|
||||
// }
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// // save the campaign to the disk + update the flow.
|
||||
// store.save(
|
||||
// campaign = campaign.copy(characters = characters)
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// Campaign.CharacterInstance.Id.NPC -> {
|
||||
// // fetch all the current campaign character
|
||||
// val characters = campaign.npcs.toMutableMap()
|
||||
// // update the corresponding character alterations
|
||||
// characters[characterInstanceId]?.let { character ->
|
||||
// characters[characterInstanceId] = character.copy(
|
||||
// alterations = character.alterations.toMutableList().also { alterations ->
|
||||
// if (alterations.contains(alterationId)) {
|
||||
// alterations.remove(alterationId)
|
||||
// } else {
|
||||
// alterations.add(alterationId)
|
||||
// }
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// // save the campaign to the disk + update the flow.
|
||||
// store.save(
|
||||
// campaign = campaign.copy(npcs = characters)
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
suspend fun updateToggleParty() {
|
||||
store.save(
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class CampaignStore(
|
|||
private val factory: CampaignJsonFactory,
|
||||
private val json: Json,
|
||||
) {
|
||||
private val campaignFlow = MutableStateFlow(value = Campaign.EMPTY)
|
||||
private val campaignFlow = MutableStateFlow(value = Campaign.empty())
|
||||
|
||||
init {
|
||||
// create the directory if needed.
|
||||
|
|
@ -38,7 +38,7 @@ class CampaignStore(
|
|||
loadCampaign()
|
||||
} catch (exception: Exception) {
|
||||
println(exception) // TODO proper exception handling
|
||||
Campaign.EMPTY
|
||||
Campaign.empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ class CampaignStore(
|
|||
}
|
||||
|
||||
// Guard, if the file is empty we load a default campaign.
|
||||
if (json.isBlank()) return Campaign.EMPTY
|
||||
if (json.isBlank()) return Campaign.empty()
|
||||
|
||||
val campaign = try {
|
||||
val data = this.json.decodeFromString<CampaignJson>(json)
|
||||
|
|
@ -74,7 +74,7 @@ class CampaignStore(
|
|||
fun save(campaign: Campaign) {
|
||||
// convert the data to json format
|
||||
val json = try {
|
||||
factory.convertToJson(data = campaign).let(json::encodeToString)
|
||||
factory.convertToJson(campaign = campaign).let(json::encodeToString)
|
||||
} catch (exception: Exception) {
|
||||
throw JsonConversionException(root = exception)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package com.pixelized.server.lwa.model.character
|
||||
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory
|
||||
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonFactory
|
||||
import com.pixelized.shared.lwa.protocol.rest.CharacterPreviewJson
|
||||
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -14,7 +13,6 @@ import kotlinx.coroutines.flow.stateIn
|
|||
class CharacterSheetService(
|
||||
private val store: CharacterSheetStore,
|
||||
private val factory: CharacterSheetJsonFactory,
|
||||
private val useCase: CharacterSheetUseCase,
|
||||
) {
|
||||
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||
private val sheets get() = sheetsFlow.value
|
||||
|
|
@ -30,12 +28,14 @@ class CharacterSheetService(
|
|||
return sheets.map { factory.convertToPreviewJson(sheet = it.value) }
|
||||
}
|
||||
|
||||
fun characterSheet(id: String): CharacterSheetJson? {
|
||||
return sheets[id]?.let(factory::convertToJson)
|
||||
fun characterSheet(characterSheetId: String): CharacterSheetJson? {
|
||||
return sheets[characterSheetId]?.let(factory::convertToJson)
|
||||
}
|
||||
|
||||
suspend fun updateCharacterSheet(character: CharacterSheetJson) {
|
||||
return store.save(sheet = factory.convertFromJson(character))
|
||||
return store.save(
|
||||
sheet = factory.convertFromJson(character)
|
||||
)
|
||||
}
|
||||
|
||||
fun deleteCharacterSheet(characterSheetId: String): Boolean {
|
||||
|
|
@ -44,30 +44,62 @@ class CharacterSheetService(
|
|||
|
||||
// Data manipulation through WebSocket.
|
||||
|
||||
fun updateCharacterLevel(
|
||||
characterId: String,
|
||||
level: Int,
|
||||
fun updateAlteration(
|
||||
characterSheetId: String,
|
||||
alterationId: String,
|
||||
active: Boolean,
|
||||
) {
|
||||
sheets[characterId]?.let { character ->
|
||||
val update = useCase.updateLevel(
|
||||
character = character,
|
||||
level = level,
|
||||
)
|
||||
sheets[characterSheetId]?.let { character ->
|
||||
val contain = character.alterations.contains(alterationId)
|
||||
if (active && contain.not()) {
|
||||
val alterations = character.alterations.toMutableList().also {
|
||||
it.add(alterationId)
|
||||
}
|
||||
store.save(
|
||||
sheet = character.copy(
|
||||
alterations = alterations,
|
||||
)
|
||||
)
|
||||
}
|
||||
if (active.not() && contain) {
|
||||
val alterations = character.alterations.toMutableList().also {
|
||||
it.remove(alterationId)
|
||||
}
|
||||
store.save(
|
||||
sheet = character.copy(
|
||||
alterations = alterations,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDamage(
|
||||
characterSheetId: String,
|
||||
damage: Int,
|
||||
) {
|
||||
sheets[characterSheetId]?.let { character ->
|
||||
val update = character.copy(damage = damage)
|
||||
store.save(sheet = update)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateCharacterSkillLevel(
|
||||
characterId: String,
|
||||
skillId: String,
|
||||
level: Int,
|
||||
fun updateDiminished(
|
||||
characterSheetId: String,
|
||||
diminished: Int,
|
||||
) {
|
||||
sheets[characterId]?.let { character ->
|
||||
val update = useCase.updateSkillLevel(
|
||||
character = character,
|
||||
skillId = skillId,
|
||||
level = level,
|
||||
)
|
||||
sheets[characterSheetId]?.let { character ->
|
||||
val update = character.copy(diminished = diminished)
|
||||
store.save(sheet = update)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateFatigue(
|
||||
characterSheetId: String,
|
||||
fatigue: Int,
|
||||
) {
|
||||
sheets[characterSheetId]?.let { character ->
|
||||
val update = character.copy(fatigue = fatigue)
|
||||
store.save(sheet = update)
|
||||
}
|
||||
}
|
||||
|
|
@ -78,10 +110,16 @@ class CharacterSheetService(
|
|||
used: Boolean,
|
||||
) {
|
||||
sheets[characterSheetId]?.let { character ->
|
||||
val update = useCase.updateSkillUsage(
|
||||
character = character,
|
||||
skillId = skillId,
|
||||
used = used,
|
||||
val update = 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
|
||||
},
|
||||
)
|
||||
store.save(sheet = update)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.pixelized.server.lwa.model.character
|
|||
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory
|
||||
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonFactory
|
||||
import com.pixelized.shared.lwa.utils.PathProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
|
|||
|
|
@ -3,16 +3,13 @@ package com.pixelized.server.lwa.server
|
|||
import com.pixelized.server.lwa.model.alteration.AlterationService
|
||||
import com.pixelized.server.lwa.model.campaign.CampaignService
|
||||
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage.ToggleActiveAlteration
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollEvent
|
||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
||||
class Engine(
|
||||
|
|
@ -26,55 +23,52 @@ class Engine(
|
|||
suspend fun handle(message: SocketMessage) {
|
||||
when (message) {
|
||||
|
||||
is RollMessage -> Unit // Nothing to do here.
|
||||
|
||||
is CampaignMessage -> {
|
||||
val instanceId = Campaign.CharacterInstance.Id(
|
||||
prefix = message.prefix,
|
||||
characterSheetId = message.characterSheetId,
|
||||
instanceId = message.instanceId,
|
||||
)
|
||||
when (message) {
|
||||
is CampaignMessage.UpdateCharacteristic -> campaignService.updateCharacteristic(
|
||||
characterInstanceId = instanceId,
|
||||
characteristic = campaignJsonFactory.convertFromJson(json = message.characteristic),
|
||||
value = message.newValue,
|
||||
)
|
||||
|
||||
is CampaignMessage.UpdateDiminished -> campaignService.updateDiminished(
|
||||
characterInstanceId = instanceId,
|
||||
diminished = message.diminished,
|
||||
)
|
||||
|
||||
is ToggleActiveAlteration -> campaignService.toggleAlteration(
|
||||
characterInstanceId = instanceId,
|
||||
alterationId = message.alterationId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is UpdateSkillUsageMessage -> characterService.updateCharacterSkillUsage(
|
||||
characterSheetId = message.characterSheetId,
|
||||
skillId = message.skillId,
|
||||
used = message.used,
|
||||
)
|
||||
|
||||
is RestSynchronisation.Campaign -> Unit // Handle in the Rest
|
||||
|
||||
is RestSynchronisation.CharacterSheetUpdate -> Unit // Handle in the Rest
|
||||
|
||||
is RestSynchronisation.CharacterSheetDelete -> Unit // Handle in the Rest
|
||||
|
||||
is ToggleActiveAlteration -> Unit // Handle in the Rest
|
||||
is RollEvent -> Unit // Nothing to do here.
|
||||
|
||||
is GameMasterEvent -> when (message) {
|
||||
is GameMasterEvent.TogglePlayer -> campaignService.updateToggleParty()
|
||||
is GameMasterEvent.ToggleNpc -> campaignService.updateToggleNpc()
|
||||
is GameMasterEvent.DisplayPortrait -> Unit // Nothing to do here.
|
||||
}
|
||||
|
||||
is GameEvent -> when (message) {
|
||||
is GameEvent.DisplayPortrait -> Unit // Nothing to do here.
|
||||
is CharacterSheetEvent -> when (message) {
|
||||
is CharacterSheetEvent.UpdateAlteration -> characterService.updateAlteration(
|
||||
characterSheetId = message.characterSheetId,
|
||||
alterationId = message.alterationId,
|
||||
active = message.active,
|
||||
)
|
||||
|
||||
is CharacterSheetEvent.UpdateDamage -> characterService.updateDamage(
|
||||
characterSheetId = message.characterSheetId,
|
||||
damage = message.damage,
|
||||
)
|
||||
|
||||
is CharacterSheetEvent.UpdateDiminished -> characterService.updateDiminished(
|
||||
characterSheetId = message.characterSheetId,
|
||||
diminished = message.diminished,
|
||||
)
|
||||
|
||||
is CharacterSheetEvent.UpdateFatigue -> characterService.updateFatigue(
|
||||
characterSheetId = message.characterSheetId,
|
||||
fatigue = message.fatigue,
|
||||
)
|
||||
|
||||
is CharacterSheetEvent.UpdateSkillUsageEvent -> characterService.updateCharacterSkillUsage(
|
||||
characterSheetId = message.characterSheetId,
|
||||
skillId = message.skillId,
|
||||
used = message.used,
|
||||
)
|
||||
}
|
||||
|
||||
is CampaignEvent -> when (message) {
|
||||
is CampaignEvent.CharacterAdded -> Unit // TODO
|
||||
is CampaignEvent.CharacterRemoved -> Unit // TODO
|
||||
is CampaignEvent.NpcAdded -> Unit // TODO
|
||||
is CampaignEvent.NpcRemoved -> Unit // TODO
|
||||
is CampaignEvent.UpdateScene -> Unit // TODO
|
||||
}
|
||||
|
||||
is ApiSynchronisation -> Unit // Nothing to do there.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,22 @@
|
|||
package com.pixelized.server.lwa.server
|
||||
|
||||
|
||||
import com.pixelized.server.lwa.server.rest.alteration.getAlteration
|
||||
import com.pixelized.server.lwa.server.rest.alteration.getAlterations
|
||||
import com.pixelized.server.lwa.server.rest.campaign.deleteCampaignNpc
|
||||
import com.pixelized.server.lwa.server.rest.campaign.removeCampaignNpc
|
||||
import com.pixelized.server.lwa.server.rest.campaign.getCampaign
|
||||
import com.pixelized.server.lwa.server.rest.campaign.putCampaignCharacter
|
||||
import com.pixelized.server.lwa.server.rest.campaign.putCampaignNpc
|
||||
import com.pixelized.server.lwa.server.rest.campaign.putCampaignScene
|
||||
import com.pixelized.server.lwa.server.rest.campaign.putToggleAlteration
|
||||
import com.pixelized.server.lwa.server.rest.campaign.removeCampaignCharacter
|
||||
import com.pixelized.server.lwa.server.rest.character.deleteCharacter
|
||||
import com.pixelized.server.lwa.server.rest.character.getCharacter
|
||||
import com.pixelized.server.lwa.server.rest.character.getCharacters
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacter
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacterAlteration
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacterDamage
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacterDiminished
|
||||
import com.pixelized.server.lwa.server.rest.character.putCharacterFatigue
|
||||
import com.pixelized.shared.lwa.SERVER_PORT
|
||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||
import com.pixelized.shared.lwa.sharedModuleDependencies
|
||||
|
|
@ -111,40 +115,66 @@ class LocalServer {
|
|||
}
|
||||
}
|
||||
)
|
||||
get(
|
||||
path = "/alterations",
|
||||
body = engine.getAlterations(),
|
||||
)
|
||||
get(
|
||||
path = "/characters",
|
||||
body = engine.getCharacters(),
|
||||
)
|
||||
route(path = "/character") {
|
||||
route(
|
||||
path = "/alteration",
|
||||
) {
|
||||
get(
|
||||
path = "/all",
|
||||
body = engine.getAlterations(),
|
||||
)
|
||||
get(
|
||||
path = "/detail",
|
||||
body = engine.getAlteration(),
|
||||
)
|
||||
}
|
||||
route(
|
||||
path = "/character",
|
||||
) {
|
||||
get(
|
||||
path = "/all",
|
||||
body = engine.getCharacters(),
|
||||
)
|
||||
get(
|
||||
path = "/detail",
|
||||
body = engine.getCharacter(),
|
||||
)
|
||||
put(
|
||||
path = "/update",
|
||||
body = engine.putCharacter(),
|
||||
)
|
||||
delete(
|
||||
path = "/delete",
|
||||
body = engine.deleteCharacter(),
|
||||
)
|
||||
route(
|
||||
path = "/update",
|
||||
) {
|
||||
put(
|
||||
path = "/sheet",
|
||||
body = engine.putCharacter(),
|
||||
)
|
||||
put(
|
||||
path = "/damage",
|
||||
body = engine.putCharacterDamage(),
|
||||
)
|
||||
put(
|
||||
path = "/fatigue",
|
||||
body = engine.putCharacterFatigue(),
|
||||
)
|
||||
put(
|
||||
path = "/diminished",
|
||||
body = engine.putCharacterDiminished(),
|
||||
)
|
||||
put(
|
||||
path = "/alteration",
|
||||
body = engine.putCharacterAlteration(),
|
||||
)
|
||||
}
|
||||
}
|
||||
route(path = "/campaign") {
|
||||
get(
|
||||
path = "",
|
||||
body = engine.getCampaign(),
|
||||
)
|
||||
put(
|
||||
path = "/toggleAlteration",
|
||||
body = engine.putToggleAlteration(),
|
||||
)
|
||||
route(path = "/character") {
|
||||
put(
|
||||
path = "/update",
|
||||
path = "/add",
|
||||
body = engine.putCampaignCharacter(),
|
||||
)
|
||||
delete(
|
||||
|
|
@ -154,12 +184,12 @@ class LocalServer {
|
|||
}
|
||||
route(path = "/npc") {
|
||||
put(
|
||||
path = "/update",
|
||||
path = "/add",
|
||||
body = engine.putCampaignNpc(),
|
||||
)
|
||||
delete(
|
||||
path = "/delete",
|
||||
body = engine.deleteCampaignNpc(),
|
||||
body = engine.removeCampaignNpc(),
|
||||
)
|
||||
}
|
||||
put(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package com.pixelized.server.lwa.server.rest.alteration
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.alterationId
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.getAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val alterationId = call.queryParameters.alterationId
|
||||
// get the alteration of the given id.
|
||||
val alteration = alterationService
|
||||
.alteration(alterationId = alterationId)
|
||||
?: error("Alteration with id:$alterationId not found.")
|
||||
// send it back to the user.
|
||||
call.respond(
|
||||
message = alteration,
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = exception.localizedMessage,
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ import io.ktor.server.response.respond
|
|||
|
||||
fun Engine.getAlterations(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
call.respond(alterationService.alterations())
|
||||
call.respond(
|
||||
message = alterationService.alterations(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterInstanceId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
|
|
@ -10,21 +10,24 @@ fun Engine.removeCampaignCharacter(): suspend io.ktor.server.routing.RoutingCont
|
|||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterInstanceId = call.queryParameters.characterInstanceId
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// remove the character form the party
|
||||
val updated = campaignService.removeCharacter(characterInstanceId = characterInstanceId)
|
||||
val updated = campaignService.removeCharacter(
|
||||
characterSheetId = characterSheetId,
|
||||
)
|
||||
// error case
|
||||
if (!updated) {
|
||||
error("Unexpected error when removing character (id:$characterInstanceId) from party.")
|
||||
if (updated.not()) {
|
||||
error("Unexpected error when removing character (characterSheetId:$characterSheetId) from party.")
|
||||
}
|
||||
// API & WebSocket responses
|
||||
call.respondText(
|
||||
text = "$HttpStatusCode.Accepted",
|
||||
status = HttpStatusCode.Accepted,
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
RestSynchronisation.Campaign(
|
||||
value = CampaignEvent.CharacterRemoved(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
|
|
@ -1,29 +1,29 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterInstanceId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.deleteCampaignNpc(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
fun Engine.removeCampaignNpc(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterInstanceId = call.queryParameters.characterInstanceId
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// remove the character form the party
|
||||
val updated = campaignService.removeNpc(npcInstanceId = characterInstanceId)
|
||||
val updated = campaignService.removeNpc(characterSheetId = characterSheetId)
|
||||
// error case
|
||||
if (!updated) {
|
||||
error("Unexpected error when removing character (id:$characterInstanceId) from npcs.")
|
||||
if (updated.not()) {
|
||||
error("Unexpected error when removing character (characterSheetId:$characterSheetId) from npcs.")
|
||||
}
|
||||
// API & WebSocket responses
|
||||
call.respondText(
|
||||
text = "$HttpStatusCode.Accepted",
|
||||
status = HttpStatusCode.Accepted,
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
RestSynchronisation.Campaign(
|
||||
value = CampaignEvent.UpdateScene(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
|
@ -5,6 +5,8 @@ import io.ktor.server.response.respond
|
|||
|
||||
fun Engine.getCampaign(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
call.respond(campaignService.campaignJson())
|
||||
call.respond(
|
||||
message = campaignService.campaignJson(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCampaignCharacter(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// add the character to the party.
|
||||
val update = campaignService.addCharacter(characterSheetId = characterSheetId)
|
||||
// error case
|
||||
if (update.not()) {
|
||||
error("Unexpected error occurred when the character instance was added to the party")
|
||||
}
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "Character $characterSheetId successfully added to the party",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CampaignEvent.CharacterAdded(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${exception.message}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCampaignNpc(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// add the character to the npcs.
|
||||
val update = campaignService.addNpc(characterSheetId = characterSheetId)
|
||||
// error case
|
||||
if (update.not()) {
|
||||
error("Unexpected error occurred when the character instance was added to the npcs")
|
||||
}
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "Character $characterSheetId successfully added to the npcs",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CampaignEvent.NpcAdded(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${exception.message}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,40 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV2
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.request.receive
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCampaignScene(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
val form = call.receive<CampaignJsonV1.SceneJsonV1>()
|
||||
|
||||
val scene = campaignJsonFactory.convertFromJson(json = form)
|
||||
|
||||
val updated = campaignService.setScene(scene = scene)
|
||||
|
||||
val code = when (updated) {
|
||||
true -> HttpStatusCode.Accepted
|
||||
else -> HttpStatusCode.UnprocessableEntity
|
||||
}
|
||||
|
||||
call.respondText(
|
||||
text = "$code",
|
||||
status = code,
|
||||
)
|
||||
|
||||
webSocket.emit(
|
||||
RestSynchronisation.Campaign(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
try {
|
||||
// Get the scene json from the body of the request
|
||||
val form = call.receive<CampaignJsonV2.SceneJsonV2>()
|
||||
// convert the scene into the a usable data model.
|
||||
val scene = campaignJsonFactory.convertFromJson(json = form)
|
||||
// update the campaign.
|
||||
val updated = campaignService.setScene(scene = scene)
|
||||
// error case
|
||||
if (updated.not()) {
|
||||
error("Unexpected error when updating the scene.")
|
||||
}
|
||||
// API & WebSocket responses
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CampaignEvent.UpdateScene(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = exception.localizedMessage,
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCampaignCharacter(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// check if the character is already in the party.
|
||||
val instanceId = campaignService.campaign().characters.keys
|
||||
.firstOrNull { key -> key.characterSheetId == characterSheetId }
|
||||
// handle the error case.
|
||||
if (instanceId != null) {
|
||||
error("Character (characterSheetId:$characterSheetId) Already in party")
|
||||
}
|
||||
// create the instance id for the character.
|
||||
val id = Campaign.CharacterInstance.Id(
|
||||
prefix = Campaign.CharacterInstance.Id.PLAYER,
|
||||
characterSheetId = characterSheetId,
|
||||
instanceId = 0,
|
||||
)
|
||||
// add the character to the party.
|
||||
if (campaignService.addCharacter(id).not()) {
|
||||
error("Unexpected error occurred when the character instance was added to the party")
|
||||
}
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "Character $characterSheetId successfully added to the party",
|
||||
status = HttpStatusCode.Accepted,
|
||||
)
|
||||
webSocket.emit(
|
||||
RestSynchronisation.Campaign(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.run {
|
||||
respondText(
|
||||
text = "${exception.message}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCampaignNpc(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// compute the npc id base on similar character sheets.
|
||||
val instanceId = campaignService.campaign().npcs.keys
|
||||
.filter { it.characterSheetId == characterSheetId }
|
||||
.reduceOrNull { acc, id ->
|
||||
if (acc.instanceId < id.instanceId) {
|
||||
id
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
}
|
||||
// create the instance id for the character.
|
||||
val id = Campaign.CharacterInstance.Id(
|
||||
prefix = Campaign.CharacterInstance.Id.NPC,
|
||||
characterSheetId = characterSheetId,
|
||||
instanceId = instanceId?.let { it.instanceId + 1 } ?: 0,
|
||||
)
|
||||
// add the character to the npcs.
|
||||
if (campaignService.addNpc(id).not()) {
|
||||
error("Unexpected error occurred when the character instance was added to the npcs")
|
||||
}
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "Character $characterSheetId successfully added to the npcs",
|
||||
status = HttpStatusCode.Accepted,
|
||||
)
|
||||
webSocket.emit(
|
||||
RestSynchronisation.Campaign(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.run {
|
||||
respondText(
|
||||
text = "${exception.message}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package com.pixelized.server.lwa.server.rest.campaign
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterInstanceId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.request.receive
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putToggleAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterInstanceId = call.queryParameters.characterInstanceId
|
||||
|
||||
// fetch the query parameters
|
||||
val alterationId = call.receive<String>()
|
||||
|
||||
// Update the alteration
|
||||
campaignService.toggleAlteration(
|
||||
characterInstanceId = characterInstanceId,
|
||||
alterationId = alterationId,
|
||||
)
|
||||
// build the Http response & send it
|
||||
call.respondText(
|
||||
text = "$HttpStatusCode.Accepted",
|
||||
status = HttpStatusCode.Accepted,
|
||||
)
|
||||
|
||||
val isAlterationActive = campaignService.campaign()
|
||||
.instances[characterInstanceId]
|
||||
?.alterations
|
||||
?.contains(alterationId)
|
||||
?: false
|
||||
|
||||
// share the modification to all client through the websocket.
|
||||
webSocket.emit(
|
||||
CampaignMessage.ToggleActiveAlteration(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
prefix = characterInstanceId.prefix,
|
||||
characterSheetId = characterInstanceId.characterSheetId,
|
||||
instanceId = characterInstanceId.instanceId,
|
||||
alterationId = alterationId,
|
||||
active = isAlterationActive,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = exception.localizedMessage,
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package com.pixelized.server.lwa.server.rest.character
|
|||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
|
|
@ -12,7 +12,9 @@ fun Engine.deleteCharacter(): suspend io.ktor.server.routing.RoutingContext.() -
|
|||
|
||||
val deleted = characterService.deleteCharacterSheet(
|
||||
characterSheetId = characterSheetId
|
||||
) && campaignService.removeInstance(
|
||||
)
|
||||
// Remove the character fom the campaign if needed.
|
||||
campaignService.removeInstance(
|
||||
characterSheetId = characterSheetId,
|
||||
)
|
||||
|
||||
|
|
@ -22,7 +24,7 @@ fun Engine.deleteCharacter(): suspend io.ktor.server.routing.RoutingContext.() -
|
|||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
RestSynchronisation.CharacterSheetDelete(
|
||||
value = ApiSynchronisation.CharacterSheetDelete(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -8,12 +8,18 @@ import io.ktor.server.response.respondText
|
|||
|
||||
fun Engine.getCharacter(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
val id = call.queryParameters.characterSheetId
|
||||
val body = characterService.characterSheet(id)
|
||||
|
||||
if (body != null) {
|
||||
call.respond(body)
|
||||
} else {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
// get the character sheet of the given id.
|
||||
val characterSheet = characterService
|
||||
.characterSheet(characterSheetId = characterSheetId)
|
||||
?: error("CharacterSheet with id:$characterSheetId not found.")
|
||||
// send it back to the user.
|
||||
call.respond(
|
||||
message = characterSheet,
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
||||
status = HttpStatusCode.UnprocessableEntity
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import io.ktor.server.response.respond
|
|||
|
||||
fun Engine.getCharacters(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
call.respond(characterService.characters())
|
||||
call.respond(
|
||||
message = characterService.characters(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,26 +2,33 @@ package com.pixelized.server.lwa.server.rest.character
|
|||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
|
||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.request.receive
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCharacter(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
val form = call.receive<CharacterSheetJson>()
|
||||
characterService.updateCharacterSheet(
|
||||
character = form
|
||||
)
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK
|
||||
)
|
||||
webSocket.emit(
|
||||
RestSynchronisation.CharacterSheetUpdate(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = form.id,
|
||||
),
|
||||
)
|
||||
try {
|
||||
val form = call.receive<CharacterSheetJson>()
|
||||
characterService.updateCharacterSheet(
|
||||
character = form,
|
||||
)
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = ApiSynchronisation.CharacterSheetUpdate(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = form.id,
|
||||
),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.pixelized.server.lwa.server.rest.character
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.alterationId
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCharacterAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val alterationId = call.queryParameters.alterationId
|
||||
val active = call.queryParameters["active"]?.toBooleanStrictOrNull()
|
||||
?: error("Missing active parameter.")
|
||||
// Update the character damage
|
||||
characterService.updateAlteration(
|
||||
characterSheetId = characterSheetId,
|
||||
alterationId = alterationId,
|
||||
active = active
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CharacterSheetEvent.UpdateAlteration(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
alterationId = alterationId,
|
||||
active = active,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.pixelized.server.lwa.server.rest.character
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCharacterDamage(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val damage = call.queryParameters["damage"]?.toIntOrNull()
|
||||
?: error("Missing damage parameter.")
|
||||
// Update the character damage
|
||||
characterService.updateDamage(
|
||||
characterSheetId = characterSheetId,
|
||||
damage = damage
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CharacterSheetEvent.UpdateDamage(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
damage = damage,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.pixelized.server.lwa.server.rest.character
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCharacterDiminished(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val diminished = call.queryParameters["diminished"]?.toIntOrNull()
|
||||
?: error("Missing diminished parameter.")
|
||||
// Update the character damage
|
||||
characterService.updateDiminished(
|
||||
characterSheetId = characterSheetId,
|
||||
diminished = diminished
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CharacterSheetEvent.UpdateDiminished(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
diminished = diminished,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.pixelized.server.lwa.server.rest.character
|
||||
|
||||
import com.pixelized.server.lwa.server.Engine
|
||||
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.response.respondText
|
||||
|
||||
fun Engine.putCharacterFatigue(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||
return {
|
||||
try {
|
||||
// get the query parameter
|
||||
val characterSheetId = call.queryParameters.characterSheetId
|
||||
val fatigue = call.queryParameters["fatigue"]?.toIntOrNull()
|
||||
?: error("Missing fatigue parameter.")
|
||||
// Update the character damage
|
||||
characterService.updateFatigue(
|
||||
characterSheetId = characterSheetId,
|
||||
fatigue = fatigue
|
||||
)
|
||||
// API & WebSocket responses.
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.OK}",
|
||||
status = HttpStatusCode.OK,
|
||||
)
|
||||
webSocket.emit(
|
||||
value = CharacterSheetEvent.UpdateFatigue(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
characterSheetId = characterSheetId,
|
||||
fatigue = fatigue,
|
||||
)
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
call.respondText(
|
||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
||||
status = HttpStatusCode.UnprocessableEntity,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +1,9 @@
|
|||
package com.pixelized.server.lwa.utils.extentions
|
||||
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import io.ktor.http.Parameters
|
||||
|
||||
val Parameters.characterInstanceId: Campaign.CharacterInstance.Id
|
||||
get() = Campaign.CharacterInstance.Id(
|
||||
characterSheetId = characterSheetId,
|
||||
instanceId = instanceId,
|
||||
prefix = prefix,
|
||||
)
|
||||
|
||||
val Parameters.characterSheetId
|
||||
get() = this["characterSheetId"] ?: error("Missing character sheet id.")
|
||||
get() = this["characterSheetId"] ?: error("Missing characterSheetId parameter.")
|
||||
|
||||
val Parameters.instanceId: Int
|
||||
get() = this["instanceId"]?.toIntOrNull() ?: error("Missing character instance id.")
|
||||
|
||||
val Parameters.prefix: Char
|
||||
get() = this["prefix"]?.get(0) ?: error("Missing character prefix.")
|
||||
val Parameters.alterationId
|
||||
get() = this["alterationId"] ?: error("Missing alterationId parameter.")
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@ import kotlinx.serialization.Serializable
|
|||
@Serializable
|
||||
sealed interface CharacterSheetJson {
|
||||
val id: String
|
||||
val name: String
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue