Update client to add throw consume equip to InventoryItem.
This commit is contained in:
parent
9fce3f1cb8
commit
ae820f5979
22 changed files with 791 additions and 121 deletions
|
|
@ -184,8 +184,9 @@
|
||||||
<string name="character_sheet__delete_dialog__title">Supprimer la feuille de personnage</string>
|
<string name="character_sheet__delete_dialog__title">Supprimer la feuille de personnage</string>
|
||||||
<string name="character_sheet__delete_dialog__description">Êtes-vous sûr de vouloir supprimer "%1$s" ?</string>
|
<string name="character_sheet__delete_dialog__description">Êtes-vous sûr de vouloir supprimer "%1$s" ?</string>
|
||||||
|
|
||||||
<string name="character__inventory__add_to_inventory__action">Ajouter un objet</string>
|
|
||||||
<string name="character__inventory__filter_inventory__label">Filtrer l'inventaire</string>
|
<string name="character__inventory__filter_inventory__label">Filtrer l'inventaire</string>
|
||||||
|
<string name="character__inventory__add_to_inventory__action">Ajouter un objet</string>
|
||||||
|
<string name="character__inventory__use__action">Utiliser</string>
|
||||||
<string name="character__inventory__add_to_purse__title">Ajouter à la bourse</string>
|
<string name="character__inventory__add_to_purse__title">Ajouter à la bourse</string>
|
||||||
<string name="character__inventory__remove_from_purse__title">Retirer de la bourse</string>
|
<string name="character__inventory__remove_from_purse__title">Retirer de la bourse</string>
|
||||||
<string name="character__inventory__filter_item_inventory__label">Filtrer les objets</string>
|
<string name="character__inventory__filter_item_inventory__label">Filtrer les objets</string>
|
||||||
|
|
@ -193,6 +194,9 @@
|
||||||
<string name="character__inventory__inventory__dialog__action">Ajouter à l'inventaire</string>
|
<string name="character__inventory__inventory__dialog__action">Ajouter à l'inventaire</string>
|
||||||
<string name="character__inventory__inventory__dialog__count">Quantité</string>
|
<string name="character__inventory__inventory__dialog__count">Quantité</string>
|
||||||
<string name="character__inventory__inventory__dialog__count_action">Modifier</string>
|
<string name="character__inventory__inventory__dialog__count_action">Modifier</string>
|
||||||
|
<string name="character__inventory__inventory__dialog__throw_action">Jetter</string>
|
||||||
|
<string name="character__inventory__inventory__dialog__equip_action">Equiper</string>
|
||||||
|
<string name="character__inventory__inventory__dialog__consume_action">Utiliser</string>
|
||||||
<string name="character__inventory__description_empty__label">Cet objet n'a pas de description.</string>
|
<string name="character__inventory__description_empty__label">Cet objet n'a pas de description.</string>
|
||||||
|
|
||||||
<string name="tooltip__characteristics__characteristics">Les caractéristiques constituent les aptitudes innées d’un personnage comme son intelligence, sa force, son charisme, etc. Elles ne sont pas acquises, mais peuvent être parfois augmentées par un entraînement ou une utilisation réussie. Les caractéristiques des humains normaux varient de 2 (niveau extrêmement bas) à 20 (maximum du potentiel humain), avec une moyenne de 10 ou 11. Plus une caractéristique est élevée plus le personnage est puissant dans cette aptitude.\nÀ la création de votre personnage, répartissez les valeurs suivantes dans les différentes caractéristiques : 15, 15, 13, 11, 10, 9 et 7.</string>
|
<string name="tooltip__characteristics__characteristics">Les caractéristiques constituent les aptitudes innées d’un personnage comme son intelligence, sa force, son charisme, etc. Elles ne sont pas acquises, mais peuvent être parfois augmentées par un entraînement ou une utilisation réussie. Les caractéristiques des humains normaux varient de 2 (niveau extrêmement bas) à 20 (maximum du potentiel humain), avec une moyenne de 10 ou 11. Plus une caractéristique est élevée plus le personnage est puissant dans cette aptitude.\nÀ la création de votre personnage, répartissez les valeurs suivantes dans les différentes caractéristiques : 15, 15, 13, 11, 10, 9 et 7.</string>
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,35 @@ interface LwaClient {
|
||||||
create: Boolean,
|
create: Boolean,
|
||||||
): APIResponse<Unit>
|
): APIResponse<Unit>
|
||||||
|
|
||||||
|
suspend fun deleteInventory(
|
||||||
|
characterSheetId: String,
|
||||||
|
): APIResponse<Unit>
|
||||||
|
|
||||||
suspend fun createInventoryItem(
|
suspend fun createInventoryItem(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
itemId: String,
|
itemId: String,
|
||||||
): APIResponse<String>
|
): APIResponse<String>
|
||||||
|
|
||||||
suspend fun deleteInventory(
|
suspend fun changeInventoryItemCount(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
count: Float,
|
||||||
|
): APIResponse<Unit>
|
||||||
|
|
||||||
|
suspend fun equipInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
equip: Boolean,
|
||||||
|
): APIResponse<Unit>
|
||||||
|
|
||||||
|
suspend fun consumeInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
): APIResponse<Unit>
|
||||||
|
|
||||||
|
suspend fun deleteInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
): APIResponse<Unit>
|
): APIResponse<Unit>
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
|
|
|
||||||
|
|
@ -192,18 +192,52 @@ class LwaClientImpl(
|
||||||
}
|
}
|
||||||
.body<APIResponse<Unit>>()
|
.body<APIResponse<Unit>>()
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
override suspend fun deleteInventory(characterSheetId: String): APIResponse<Unit> = client
|
||||||
|
.delete("$root/inventory/delete?characterSheetId=$characterSheetId")
|
||||||
|
.body()
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
override suspend fun createInventoryItem(
|
override suspend fun createInventoryItem(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
itemId: String,
|
itemId: String,
|
||||||
): APIResponse<String> = client
|
): APIResponse<String> = client
|
||||||
.put("$root/inventory/create?characterSheetId=$characterSheetId&itemId=$itemId")
|
.put("$root/inventory/item/create?characterSheetId=$characterSheetId&itemId=$itemId")
|
||||||
.body<APIResponse<String>>()
|
.body<APIResponse<String>>()
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
override suspend fun deleteInventory(characterSheetId: String): APIResponse<Unit> = client
|
override suspend fun changeInventoryItemCount(
|
||||||
.delete("$root/inventory/delete?characterSheetId=$characterSheetId")
|
characterSheetId: String,
|
||||||
.body()
|
inventoryId: String,
|
||||||
|
count: Float,
|
||||||
|
): APIResponse<Unit> = client
|
||||||
|
.put("$root/inventory/item/count?characterSheetId=$characterSheetId&inventoryId=$inventoryId&count=$count")
|
||||||
|
.body<APIResponse<Unit>>()
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
override suspend fun equipInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
equip: Boolean,
|
||||||
|
): APIResponse<Unit> = client
|
||||||
|
.put("$root/inventory/item/equip?characterSheetId=$characterSheetId&inventoryId=$inventoryId&equip=$equip")
|
||||||
|
.body<APIResponse<Unit>>()
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
override suspend fun consumeInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
): APIResponse<Unit> = client
|
||||||
|
.put("$root/inventory/item/consume?characterSheetId=$characterSheetId&inventoryId=$inventoryId")
|
||||||
|
.body<APIResponse<Unit>>()
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
override suspend fun deleteInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
): APIResponse<Unit> = client
|
||||||
|
.delete("$root/inventory/item/delete?characterSheetId=$characterSheetId&inventoryId=$inventoryId")
|
||||||
|
.body<APIResponse<Unit>>()
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
override suspend fun getAlterationTags(): APIResponse<List<TagJson>> = client
|
override suspend fun getAlterationTags(): APIResponse<List<TagJson>> = client
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,52 @@ class InventoryRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
suspend fun deleteItem(
|
suspend fun changeInventoryItemCount(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
count: Float,
|
||||||
) {
|
) {
|
||||||
inventoryStore.deleteInventory(
|
inventoryStore.changeInventoryItemCount(
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
count = count,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun consumeInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
inventoryStore.consumeInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun equipInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
val inventory = inventory(characterSheetId = characterSheetId)
|
||||||
|
val inventoryItem = inventory.items.firstOrNull { it.inventoryId == inventoryId }
|
||||||
|
|
||||||
|
inventoryStore.equipInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
equip = inventoryItem?.equipped?.not() ?: true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun deleteInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
inventoryStore.deleteInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,6 +73,16 @@ class InventoryStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun deleteInventory(
|
||||||
|
characterSheetId: String,
|
||||||
|
) {
|
||||||
|
val request = client.deleteInventory(characterSheetId = characterSheetId)
|
||||||
|
if (request.success.not()) {
|
||||||
|
LwaClient.error(error = request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
suspend fun createInventoryItem(
|
suspend fun createInventoryItem(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
|
|
@ -89,10 +99,60 @@ class InventoryStore(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
suspend fun deleteInventory(
|
suspend fun changeInventoryItemCount(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
count: Float,
|
||||||
) {
|
) {
|
||||||
val request = client.deleteInventory(characterSheetId = characterSheetId)
|
val request = client.changeInventoryItemCount(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
count = count,
|
||||||
|
)
|
||||||
|
if (request.success.not()) {
|
||||||
|
LwaClient.error(error = request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun consumeInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
val request = client.consumeInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
if (request.success.not()) {
|
||||||
|
LwaClient.error(error = request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun equipInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
equip: Boolean,
|
||||||
|
) {
|
||||||
|
val request = client.equipInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
equip = equip,
|
||||||
|
)
|
||||||
|
if (request.success.not()) {
|
||||||
|
LwaClient.error(error = request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
suspend fun deleteInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
val request = client.deleteInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
if (request.success.not()) {
|
if (request.success.not()) {
|
||||||
LwaClient.error(error = request)
|
LwaClient.error(error = request)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package com.pixelized.desktop.lwa.ui.composable.character.item
|
package com.pixelized.desktop.lwa.ui.composable.character.item
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -42,7 +45,10 @@ import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
import com.pixelized.desktop.lwa.utils.rememberSaturationFilter
|
import com.pixelized.desktop.lwa.utils.rememberSaturationFilter
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__action
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__action
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__consume_action
|
||||||
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__count_action
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__count_action
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__equip_action
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__throw_action
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_close_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_close_24dp
|
||||||
import org.jetbrains.compose.resources.painterResource
|
import org.jetbrains.compose.resources.painterResource
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
@ -59,12 +65,14 @@ data class ItemDetailDialogUio(
|
||||||
val count: Float,
|
val count: Float,
|
||||||
// options
|
// options
|
||||||
val countable: LwaTextFieldUio?,
|
val countable: LwaTextFieldUio?,
|
||||||
|
val consumable: Boolean,
|
||||||
|
val equipable: Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
object ItemDetailDialogDefault {
|
object ItemDetailDialogDefault {
|
||||||
@Stable
|
@Stable
|
||||||
val paddings = PaddingValues(all = 16.dp)
|
val paddings = PaddingValues(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 8.dp)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
val spacings = 8.dp
|
val spacings = 8.dp
|
||||||
|
|
@ -78,6 +86,9 @@ fun ItemDetailDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onConfirm: (ItemDetailDialogUio) -> Unit,
|
onConfirm: (ItemDetailDialogUio) -> Unit,
|
||||||
onAddItem: (ItemDetailDialogUio) -> Unit,
|
onAddItem: (ItemDetailDialogUio) -> Unit,
|
||||||
|
onEquip: (ItemDetailDialogUio) -> Unit,
|
||||||
|
onConsume: (ItemDetailDialogUio) -> Unit,
|
||||||
|
onThrow: (ItemDetailDialogUio) -> Unit,
|
||||||
) {
|
) {
|
||||||
LwaDialog(
|
LwaDialog(
|
||||||
state = dialog,
|
state = dialog,
|
||||||
|
|
@ -85,7 +96,8 @@ fun ItemDetailDialog(
|
||||||
onConfirm = { dialog.value?.let(onConfirm) ?: onDismissRequest },
|
onConfirm = { dialog.value?.let(onConfirm) ?: onDismissRequest },
|
||||||
) { state ->
|
) { state ->
|
||||||
val layoutDirection = LocalLayoutDirection.current
|
val layoutDirection = LocalLayoutDirection.current
|
||||||
val end = remember(layoutDirection, paddings) { paddings.calculateEndPadding(layoutDirection) }
|
val end =
|
||||||
|
remember(layoutDirection, paddings) { paddings.calculateEndPadding(layoutDirection) }
|
||||||
val top = remember(paddings) { paddings.calculateTopPadding() }
|
val top = remember(paddings) { paddings.calculateTopPadding() }
|
||||||
|
|
||||||
takeIf { state.image?.isNotEmpty() == true }?.let {
|
takeIf { state.image?.isNotEmpty() == true }?.let {
|
||||||
|
|
@ -140,6 +152,7 @@ fun ItemDetailDialog(
|
||||||
|
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = state.inventoryId,
|
targetState = state.inventoryId,
|
||||||
|
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||||
) {
|
) {
|
||||||
when (it) {
|
when (it) {
|
||||||
null -> Row(
|
null -> Row(
|
||||||
|
|
@ -158,14 +171,12 @@ fun ItemDetailDialog(
|
||||||
else -> Column(
|
else -> Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(space = spacings)
|
verticalArrangement = Arrangement.spacedBy(space = spacings)
|
||||||
) {
|
) {
|
||||||
if (state.countable != null) {
|
Row(
|
||||||
Row(
|
modifier = Modifier.fillMaxWidth(),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
horizontalArrangement = Arrangement.spacedBy(space = spacings),
|
||||||
horizontalArrangement = Arrangement.spacedBy(
|
verticalAlignment = Alignment.Bottom,
|
||||||
space = spacings,
|
) {
|
||||||
Alignment.End,
|
if (state.countable != null) {
|
||||||
)
|
|
||||||
) {
|
|
||||||
LwaTextField(
|
LwaTextField(
|
||||||
modifier = Modifier.width(width = 128.dp),
|
modifier = Modifier.width(width = 128.dp),
|
||||||
colors = LwaTextFieldColors(
|
colors = LwaTextFieldColors(
|
||||||
|
|
@ -188,6 +199,34 @@ fun ItemDetailDialog(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier.weight(weight = 1f),
|
||||||
|
)
|
||||||
|
TextButton(
|
||||||
|
onClick = { onThrow(state) },
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(Res.string.character__inventory__inventory__dialog__throw_action),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (state.equipable) {
|
||||||
|
TextButton(
|
||||||
|
onClick = { onEquip(state) },
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(Res.string.character__inventory__inventory__dialog__equip_action),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.consumable) {
|
||||||
|
TextButton(
|
||||||
|
onClick = { onConsume(state) },
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(Res.string.character__inventory__inventory__dialog__consume_action),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ class ItemDetailDialogFactory {
|
||||||
countable = takeIf { item.options.stackable }
|
countable = takeIf { item.options.stackable }
|
||||||
?.let { createFieldFlow(value = format.format(count)) }
|
?.let { createFieldFlow(value = format.format(count)) }
|
||||||
?.createTextField(label = getString(Res.string.character__inventory__inventory__dialog__count)),
|
?.createTextField(label = getString(Res.string.character__inventory__inventory__dialog__count)),
|
||||||
|
consumable = item.options.consumable,
|
||||||
|
equipable = item.options.equipable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,49 +83,99 @@ class ItemDetailDialogViewModel(
|
||||||
suspend fun onAddInventoryItem(
|
suspend fun onAddInventoryItem(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
itemId: String,
|
itemId: String,
|
||||||
) {
|
) : Boolean {
|
||||||
try {
|
try {
|
||||||
// create the inventory item on the server, get the newly create id from that.
|
// create the inventory item on the server, get the newly create id from that.
|
||||||
val inventoryId = inventoryRepository.createInventoryItem(
|
val inventoryId = inventoryRepository.createInventoryItem(
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
itemId = itemId,
|
itemId = itemId,
|
||||||
)
|
)
|
||||||
|
return true
|
||||||
// update the dialog with the id only if this dialog still correspond to this item. (should always be the case but hey).
|
// update the dialog with the id only if this dialog still correspond to this item. (should always be the case but hey).
|
||||||
if (selectedItemId.value?.let { it.itemId == itemId && it.characterSheetId == characterSheetId } == true) {
|
// if (selectedItemId.value?.let { it.itemId == itemId && it.characterSheetId == characterSheetId } == true) {
|
||||||
selectedItemId.update {
|
// selectedItemId.update {
|
||||||
it?.copy(inventoryId = inventoryId)
|
// it?.copy(inventoryId = inventoryId)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
val message = ErrorSnackUio.from(exception)
|
val message = ErrorSnackUio.from(exception)
|
||||||
_error.emit(message)
|
_error.emit(message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun throwInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String?,
|
||||||
|
): Boolean {
|
||||||
|
if (inventoryId == null) return false
|
||||||
|
try {
|
||||||
|
inventoryRepository.deleteInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
val message = ErrorSnackUio.from(exception)
|
||||||
|
_error.emit(message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun consumeInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String?,
|
||||||
|
): Boolean {
|
||||||
|
if (inventoryId == null) return false
|
||||||
|
try {
|
||||||
|
inventoryRepository.consumeInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
val message = ErrorSnackUio.from(exception)
|
||||||
|
_error.emit(message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun equipInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String?,
|
||||||
|
) : Boolean {
|
||||||
|
if (inventoryId == null) return false
|
||||||
|
try {
|
||||||
|
inventoryRepository.equipInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
val message = ErrorSnackUio.from(exception)
|
||||||
|
_error.emit(message)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun changeInventoryItemQuantity(
|
suspend fun changeInventoryItemQuantity(
|
||||||
dialog: ItemDetailDialogUio
|
dialog: ItemDetailDialogUio,
|
||||||
) : Boolean {
|
): Boolean {
|
||||||
if (dialog.countable?.isError?.value == true) return false
|
if (dialog.countable?.isError?.value == true) return false
|
||||||
|
|
||||||
val characterSheetId = dialog.characterSheetId
|
val characterSheetId = dialog.characterSheetId
|
||||||
val inventoryId = dialog.inventoryId ?: return false
|
val inventoryId = dialog.inventoryId ?: return false
|
||||||
val quantity = dialog.countable?.valueFlow?.value ?: return false
|
val quantity = dialog.countable?.valueFlow?.value ?: return false
|
||||||
|
|
||||||
val count = factory.parse(quantity = quantity) ?: return false
|
val count = factory.parse(quantity = quantity)
|
||||||
|
?: quantity.toFloatOrNull()
|
||||||
val inventory = inventoryRepository.inventory(characterSheetId = characterSheetId)
|
?: return false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
inventoryRepository.updateInventory(
|
inventoryRepository.changeInventoryItemCount(
|
||||||
inventory = inventory.copy(
|
characterSheetId = characterSheetId,
|
||||||
items = inventory.items.toMutableList().also { items ->
|
inventoryId = inventoryId,
|
||||||
val index = items.indexOfFirst { item -> item.inventoryId == inventoryId }
|
count = count
|
||||||
items[index] = items[index].copy(
|
|
||||||
count = count,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
create = false,
|
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coil3.compose.rememberDrawScopeSizeResolver
|
|
||||||
import com.pixelized.desktop.lwa.LocalBlurController
|
import com.pixelized.desktop.lwa.LocalBlurController
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.inventory.InventoryDialog
|
import com.pixelized.desktop.lwa.ui.composable.character.inventory.InventoryDialog
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.inventory.InventoryDialogViewModel
|
import com.pixelized.desktop.lwa.ui.composable.character.inventory.InventoryDialogViewModel
|
||||||
|
|
@ -118,6 +117,14 @@ fun CharacterDetailInventory(
|
||||||
inventoryDialogViewModel.showInventoryDialog(
|
inventoryDialogViewModel.showInventoryDialog(
|
||||||
characterSheetId = it,
|
characterSheetId = it,
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
onConsume = {
|
||||||
|
scope.launch {
|
||||||
|
itemDetailDialogViewModel.consumeInventoryItem(
|
||||||
|
characterSheetId = it.characterSheetId,
|
||||||
|
inventoryId = it.inventoryId,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -165,10 +172,14 @@ fun CharacterDetailInventory(
|
||||||
},
|
},
|
||||||
onAddItem = { dialog ->
|
onAddItem = { dialog ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
itemDetailDialogViewModel.onAddInventoryItem(
|
val result = itemDetailDialogViewModel.onAddInventoryItem(
|
||||||
characterSheetId = dialog.characterSheetId,
|
characterSheetId = dialog.characterSheetId,
|
||||||
itemId = dialog.itemId,
|
itemId = dialog.itemId,
|
||||||
)
|
)
|
||||||
|
if (result) {
|
||||||
|
blur.hide()
|
||||||
|
itemDetailDialogViewModel.hideItemDialog()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onConfirm = { dialog ->
|
onConfirm = { dialog ->
|
||||||
|
|
@ -181,12 +192,51 @@ fun CharacterDetailInventory(
|
||||||
itemDetailDialogViewModel.hideItemDialog()
|
itemDetailDialogViewModel.hideItemDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onEquip = { dialog ->
|
||||||
|
scope.launch {
|
||||||
|
val result = itemDetailDialogViewModel.equipInventoryItem(
|
||||||
|
characterSheetId = dialog.characterSheetId,
|
||||||
|
inventoryId = dialog.inventoryId,
|
||||||
|
)
|
||||||
|
if (result) {
|
||||||
|
blur.hide()
|
||||||
|
itemDetailDialogViewModel.hideItemDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onConsume = { dialog ->
|
||||||
|
scope.launch {
|
||||||
|
val result = itemDetailDialogViewModel.consumeInventoryItem(
|
||||||
|
characterSheetId = dialog.characterSheetId,
|
||||||
|
inventoryId = dialog.inventoryId,
|
||||||
|
)
|
||||||
|
if (result) {
|
||||||
|
blur.hide()
|
||||||
|
itemDetailDialogViewModel.hideItemDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onThrow = { dialog ->
|
||||||
|
scope.launch {
|
||||||
|
val result = itemDetailDialogViewModel.throwInventoryItem(
|
||||||
|
characterSheetId = dialog.characterSheetId,
|
||||||
|
inventoryId = dialog.inventoryId,
|
||||||
|
)
|
||||||
|
if (result) {
|
||||||
|
blur.hide()
|
||||||
|
itemDetailDialogViewModel.hideItemDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
ErrorSnackHandler(
|
ErrorSnackHandler(
|
||||||
error = purseViewModel.error,
|
error = purseViewModel.error,
|
||||||
)
|
)
|
||||||
|
ErrorSnackHandler(
|
||||||
|
error = itemDetailDialogViewModel.error,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -197,6 +247,7 @@ private fun CharacterDetailInventoryContent(
|
||||||
inventory: CharacterDetailInventoryUio,
|
inventory: CharacterDetailInventoryUio,
|
||||||
onPurse: (String) -> Unit,
|
onPurse: (String) -> Unit,
|
||||||
onItem: (InventoryItemUio) -> Unit,
|
onItem: (InventoryItemUio) -> Unit,
|
||||||
|
onConsume: (InventoryItemUio) -> Unit,
|
||||||
onAddItem: (String) -> Unit,
|
onAddItem: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -257,6 +308,7 @@ private fun CharacterDetailInventoryContent(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
item = it,
|
item = it,
|
||||||
onClick = { onItem(it) },
|
onClick = { onItem(it) },
|
||||||
|
onConsume = { onConsume(it) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ class CharacterDetailInventoryFactory(
|
||||||
label = item.metadata.label,
|
label = item.metadata.label,
|
||||||
count = it.count,
|
count = it.count,
|
||||||
equipped = it.equipped,
|
equipped = it.equipped,
|
||||||
|
consumable = item.options.consumable,
|
||||||
tooltips = takeIf { item.metadata.description.isNotEmpty() }?.let {
|
tooltips = takeIf { item.metadata.description.isNotEmpty() }?.let {
|
||||||
InventoryItemUio.Tooltips(
|
InventoryItemUio.Tooltips(
|
||||||
label = item.metadata.label,
|
label = item.metadata.label,
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.TextButton
|
||||||
import androidx.compose.material.minimumInteractiveComponentSize
|
import androidx.compose.material.minimumInteractiveComponentSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
|
|
@ -38,6 +39,9 @@ import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout2
|
||||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
import com.pixelized.desktop.lwa.utils.extention.ribbon
|
import com.pixelized.desktop.lwa.utils.extention.ribbon
|
||||||
import com.pixelized.desktop.lwa.utils.rememberSaturationFilter
|
import com.pixelized.desktop.lwa.utils.rememberSaturationFilter
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__use__action
|
||||||
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data class InventoryItemUio(
|
data class InventoryItemUio(
|
||||||
|
|
@ -47,6 +51,7 @@ data class InventoryItemUio(
|
||||||
val label: String,
|
val label: String,
|
||||||
val count: Float,
|
val count: Float,
|
||||||
val equipped: Boolean,
|
val equipped: Boolean,
|
||||||
|
val consumable: Boolean,
|
||||||
val tooltips: Tooltips?,
|
val tooltips: Tooltips?,
|
||||||
) {
|
) {
|
||||||
@Stable
|
@Stable
|
||||||
|
|
@ -60,7 +65,7 @@ data class InventoryItemUio(
|
||||||
@Stable
|
@Stable
|
||||||
object GMCharacterPreviewDefault {
|
object GMCharacterPreviewDefault {
|
||||||
@Stable
|
@Stable
|
||||||
val paddings = PaddingValues(horizontal = 16.dp, vertical = 4.dp)
|
val paddings = PaddingValues(horizontal = 16.dp)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
val spacing: Dp = 4.dp
|
val spacing: Dp = 4.dp
|
||||||
|
|
@ -74,6 +79,7 @@ fun InventoryItem(
|
||||||
spacing: Dp = GMCharacterPreviewDefault.spacing,
|
spacing: Dp = GMCharacterPreviewDefault.spacing,
|
||||||
item: InventoryItemUio,
|
item: InventoryItemUio,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
onConsume: () -> Unit,
|
||||||
) {
|
) {
|
||||||
TooltipLayout2(
|
TooltipLayout2(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -134,30 +140,41 @@ fun InventoryItem(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(paddingValues = padding)
|
.padding(paddingValues = padding)
|
||||||
.then(other = modifier),
|
.then(other = modifier),
|
||||||
horizontalArrangement = Arrangement.spacedBy(space = spacing),
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Text(
|
Row(
|
||||||
modifier = Modifier.alignByBaseline(),
|
horizontalArrangement = Arrangement.spacedBy(space = spacing),
|
||||||
style = MaterialTheme.lwa.typography.base.body1,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 1,
|
|
||||||
text = item.label,
|
|
||||||
)
|
|
||||||
AnimatedContent(
|
|
||||||
modifier = Modifier.alignByBaseline(),
|
|
||||||
targetState = item.count,
|
|
||||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
|
||||||
) {
|
) {
|
||||||
when (it) {
|
Text(
|
||||||
0f, 1f -> Unit
|
modifier = Modifier.alignByBaseline(),
|
||||||
else -> Text(
|
style = MaterialTheme.lwa.typography.base.body1,
|
||||||
style = MaterialTheme.lwa.typography.base.caption,
|
fontWeight = FontWeight.Bold,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
text = "x${it}",
|
text = item.label,
|
||||||
)
|
)
|
||||||
|
AnimatedContent(
|
||||||
|
modifier = Modifier.alignByBaseline(),
|
||||||
|
targetState = item.count,
|
||||||
|
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||||
|
) {
|
||||||
|
when (it) {
|
||||||
|
0f, 1f -> Unit
|
||||||
|
else -> Text(
|
||||||
|
style = MaterialTheme.lwa.typography.base.caption,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1,
|
||||||
|
text = "x${it}",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.consumable) {
|
||||||
|
TextButton(
|
||||||
|
onClick = onConsume,
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(Res.string.character__inventory__use__action))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.pixelized.server.lwa.model.inventory
|
package com.pixelized.server.lwa.model.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.model.item.ItemStore
|
||||||
|
import com.pixelized.server.lwa.server.exception.BusinessException
|
||||||
import com.pixelized.shared.lwa.model.inventory.Inventory
|
import com.pixelized.shared.lwa.model.inventory.Inventory
|
||||||
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
||||||
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactory
|
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactory
|
||||||
|
|
@ -9,9 +11,11 @@ import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
class InventoryService(
|
class InventoryService(
|
||||||
private val inventoryStore: InventoryStore,
|
private val inventoryStore: InventoryStore,
|
||||||
|
private val itemStore: ItemStore,
|
||||||
private val factory: InventoryJsonFactory,
|
private val factory: InventoryJsonFactory,
|
||||||
) {
|
) {
|
||||||
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||||
|
|
@ -51,13 +55,185 @@ class InventoryService(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
fun createItem(
|
fun createInventoryItem(
|
||||||
characterSheetId: String,
|
characterSheetId: String,
|
||||||
itemId: String,
|
itemId: String,
|
||||||
) : String {
|
): String {
|
||||||
return inventoryStore.createItem(
|
// get the inventory of the character, if none create one.
|
||||||
characterSheetId = characterSheetId,
|
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||||
|
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||||
|
// create an inventoryId.
|
||||||
|
val inventoryId = inventory.items.createInventoryId()
|
||||||
|
// create an inventory Item.
|
||||||
|
val item = Inventory.Item(
|
||||||
|
inventoryId = inventoryId,
|
||||||
itemId = itemId,
|
itemId = itemId,
|
||||||
|
count = 1f,
|
||||||
|
equipped = false,
|
||||||
|
)
|
||||||
|
// update the inventory with the updated item.
|
||||||
|
val updatedInventory = inventory.copy(
|
||||||
|
items = inventory.items.toMutableList().also {
|
||||||
|
it.add(item)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// save the inventory
|
||||||
|
inventoryStore.save(
|
||||||
|
inventory = updatedInventory,
|
||||||
|
create = false,
|
||||||
|
)
|
||||||
|
return inventoryId
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
fun changeInventoryItemCount(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
count: Float,
|
||||||
|
) {
|
||||||
|
if (count < 0) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "InventoryItem (id:$inventoryId) quantity cannot go below 0.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// get the inventory of the character, if none create one.
|
||||||
|
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||||
|
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||||
|
// Guard case.
|
||||||
|
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||||
|
if (inventoryItemIndex < 0) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId).",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// update the inventory with the updated item.
|
||||||
|
val updatedInventory = inventory.copy(
|
||||||
|
items = inventory.items.toMutableList().also { items ->
|
||||||
|
if (count == 0f) {
|
||||||
|
items.removeAt(inventoryItemIndex)
|
||||||
|
} else {
|
||||||
|
items[inventoryItemIndex] = items[inventoryItemIndex].copy(count = count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// save the inventory
|
||||||
|
inventoryStore.save(
|
||||||
|
inventory = updatedInventory,
|
||||||
|
create = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
fun consumeInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
// get the inventory of the character, if none create one.
|
||||||
|
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||||
|
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||||
|
// Guard case.
|
||||||
|
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||||
|
if (inventoryItemIndex < 0) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId).",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// other Guard case.
|
||||||
|
val itemId = inventory.items[inventoryItemIndex].itemId
|
||||||
|
val item = itemStore.item(itemId = itemId)
|
||||||
|
?: throw BusinessException(message = "Item (id:$itemId) not found.")
|
||||||
|
if (item.options.consumable.not()) {
|
||||||
|
throw BusinessException(message = "Item (id:$itemId) is not consumable.")
|
||||||
|
}
|
||||||
|
// update the inventory with the updated item.
|
||||||
|
val updatedInventory = inventory.copy(
|
||||||
|
items = inventory.items.toMutableList().also { items ->
|
||||||
|
val inventoryItem = inventory.items[inventoryItemIndex]
|
||||||
|
if (inventoryItem.count - 1f <= 0f) {
|
||||||
|
items.removeAt(inventoryItemIndex)
|
||||||
|
} else {
|
||||||
|
items[inventoryItemIndex] = inventoryItem.copy(count = inventoryItem.count - 1f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// save the inventory
|
||||||
|
inventoryStore.save(
|
||||||
|
inventory = updatedInventory,
|
||||||
|
create = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
fun equipInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
equip: Boolean,
|
||||||
|
) {
|
||||||
|
// get the inventory of the character, if none create one.
|
||||||
|
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||||
|
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||||
|
// Guard case.
|
||||||
|
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||||
|
if (inventoryItemIndex < 0) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId).",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// other Guard case.
|
||||||
|
val itemId = inventory.items[inventoryItemIndex].itemId
|
||||||
|
val item = itemStore.item(itemId = itemId)
|
||||||
|
?: throw BusinessException(message = "Item (id:$itemId) not found.")
|
||||||
|
if (item.options.equipable.not()) {
|
||||||
|
throw BusinessException(message = "Item (id:$itemId) is not equipable.")
|
||||||
|
}
|
||||||
|
// update the inventory with the updated item.
|
||||||
|
val updatedInventory = inventory.copy(
|
||||||
|
items = inventory.items.toMutableList().also { items ->
|
||||||
|
items[inventoryItemIndex] = inventory.items[inventoryItemIndex].copy(
|
||||||
|
equipped = equip
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// save the inventory
|
||||||
|
inventoryStore.save(
|
||||||
|
inventory = updatedInventory,
|
||||||
|
create = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
fun deleteInventoryItem(
|
||||||
|
characterSheetId: String,
|
||||||
|
inventoryId: String,
|
||||||
|
) {
|
||||||
|
// get the inventory of the character, if none create one.
|
||||||
|
val inventory = inventoryStore.inventoryFlow().value[characterSheetId]
|
||||||
|
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||||
|
// Guard case.
|
||||||
|
val inventoryItemIndex = inventory.items.indexOfFirst { it.inventoryId == inventoryId }
|
||||||
|
if (inventoryItemIndex < 0) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "InventoryItem (id:$inventoryId) not found in Inventory(characterSheetId:$characterSheetId)",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// update the inventory with the updated item.
|
||||||
|
val updatedInventory = inventory.copy(
|
||||||
|
items = inventory.items.toMutableList().also { items ->
|
||||||
|
items.removeAt(inventoryItemIndex)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// save the inventory
|
||||||
|
inventoryStore.save(
|
||||||
|
inventory = updatedInventory,
|
||||||
|
create = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<Inventory.Item>.createInventoryId(): String {
|
||||||
|
var inventoryId: String
|
||||||
|
do {
|
||||||
|
inventoryId = UUID.randomUUID().toString()
|
||||||
|
} while (any { inventoryId == it.inventoryId })
|
||||||
|
return inventoryId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,49 +153,7 @@ class InventoryStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws
|
|
||||||
fun createItem(
|
|
||||||
characterSheetId: String,
|
|
||||||
itemId: String,
|
|
||||||
): String {
|
|
||||||
val (updatedInventory, inventoryId) = inventoryFlow.value.toMutableMap().let { characters ->
|
|
||||||
// get the inventory of the character, if none create one.
|
|
||||||
val inventory = characters[characterSheetId]
|
|
||||||
?: Inventory.empty(characterSheetId = characterSheetId)
|
|
||||||
// create an inventoryId.
|
|
||||||
val inventoryId = inventory.items.createInventoryId()
|
|
||||||
// create an inventory Item.
|
|
||||||
val item = Inventory.Item(
|
|
||||||
inventoryId = inventoryId,
|
|
||||||
itemId = itemId,
|
|
||||||
count = 1f,
|
|
||||||
equipped = false,
|
|
||||||
)
|
|
||||||
// update the inventory with the updated item.
|
|
||||||
inventory.copy(
|
|
||||||
items = inventory.items.toMutableList().also {
|
|
||||||
it.add(item)
|
|
||||||
}
|
|
||||||
) to inventoryId
|
|
||||||
}
|
|
||||||
// save the inventory
|
|
||||||
save(
|
|
||||||
inventory = updatedInventory,
|
|
||||||
create = false,
|
|
||||||
)
|
|
||||||
// return the inventory ID.
|
|
||||||
return inventoryId
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun inventoryFile(id: String): File {
|
private fun inventoryFile(id: String): File {
|
||||||
return File("${pathProvider.inventoryPath()}${id}.json")
|
return File("${pathProvider.inventoryPath()}${id}.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Inventory.Item>.createInventoryId(): String {
|
|
||||||
var inventoryId: String
|
|
||||||
do {
|
|
||||||
inventoryId = UUID.randomUUID().toString()
|
|
||||||
} while (any { inventoryId == it.inventoryId })
|
|
||||||
return inventoryId
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,10 @@ class ItemStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun item(itemId: String?): Item? {
|
||||||
|
return itemFlow.value.firstOrNull { it.id == itemId }
|
||||||
|
}
|
||||||
|
|
||||||
fun itemsFlow(): StateFlow<List<Item>> = itemFlow
|
fun itemsFlow(): StateFlow<List<Item>> = itemFlow
|
||||||
|
|
||||||
private fun updateItemsFlow() {
|
private fun updateItemsFlow() {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,12 @@ 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.putCharacterDamage
|
||||||
import com.pixelized.server.lwa.server.rest.character.putCharacterDiminished
|
import com.pixelized.server.lwa.server.rest.character.putCharacterDiminished
|
||||||
import com.pixelized.server.lwa.server.rest.character.putCharacterFatigue
|
import com.pixelized.server.lwa.server.rest.character.putCharacterFatigue
|
||||||
import com.pixelized.server.lwa.server.rest.inventory.createInventory
|
import com.pixelized.server.lwa.server.rest.inventory.changeInventoryItemCount
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.consumeInventoryItem
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.createInventoryItem
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.equipInventoryItem
|
||||||
import com.pixelized.server.lwa.server.rest.inventory.deleteInventory
|
import com.pixelized.server.lwa.server.rest.inventory.deleteInventory
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.deleteInventoryItem
|
||||||
import com.pixelized.server.lwa.server.rest.inventory.getInventory
|
import com.pixelized.server.lwa.server.rest.inventory.getInventory
|
||||||
import com.pixelized.server.lwa.server.rest.inventory.putInventory
|
import com.pixelized.server.lwa.server.rest.inventory.putInventory
|
||||||
import com.pixelized.server.lwa.server.rest.item.deleteItem
|
import com.pixelized.server.lwa.server.rest.item.deleteItem
|
||||||
|
|
@ -218,7 +222,7 @@ class LocalServer {
|
||||||
body = engine.deleteAlteration()
|
body = engine.deleteAlteration()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
route(path = "item") {
|
route(path = "/item") {
|
||||||
get(
|
get(
|
||||||
path = "/all",
|
path = "/all",
|
||||||
body = engine.getItems(),
|
body = engine.getItems(),
|
||||||
|
|
@ -236,7 +240,7 @@ class LocalServer {
|
||||||
body = engine.deleteItem(),
|
body = engine.deleteItem(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
route(path = "tag") {
|
route(path = "/tag") {
|
||||||
get(
|
get(
|
||||||
path = "/character",
|
path = "/character",
|
||||||
body = engine.getCharacterTags(),
|
body = engine.getCharacterTags(),
|
||||||
|
|
@ -250,7 +254,7 @@ class LocalServer {
|
||||||
body = engine.getItemTags(),
|
body = engine.getItemTags(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
route(path = "inventory") {
|
route(path = "/inventory") {
|
||||||
get(
|
get(
|
||||||
path = "/detail",
|
path = "/detail",
|
||||||
body = engine.getInventory(),
|
body = engine.getInventory(),
|
||||||
|
|
@ -259,14 +263,34 @@ class LocalServer {
|
||||||
path = "/update",
|
path = "/update",
|
||||||
body = engine.putInventory()
|
body = engine.putInventory()
|
||||||
)
|
)
|
||||||
put(
|
|
||||||
path = "/create",
|
|
||||||
body = engine.createInventory()
|
|
||||||
)
|
|
||||||
delete(
|
delete(
|
||||||
path = "/delete",
|
path = "/delete",
|
||||||
body = engine.deleteInventory()
|
body = engine.deleteInventory()
|
||||||
)
|
)
|
||||||
|
route(
|
||||||
|
path = "/item"
|
||||||
|
) {
|
||||||
|
put(
|
||||||
|
path = "/create",
|
||||||
|
body = engine.createInventoryItem()
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
path = "/count",
|
||||||
|
body = engine.changeInventoryItemCount()
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
path = "/consume",
|
||||||
|
body = engine.consumeInventoryItem()
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
path = "/equip",
|
||||||
|
body = engine.equipInventoryItem()
|
||||||
|
)
|
||||||
|
delete(
|
||||||
|
path = "/delete",
|
||||||
|
body = engine.deleteInventoryItem()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.itemId
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.deleteInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
|
val inventoryId = call.queryParameters.inventoryId
|
||||||
|
// add the item to the inventory.
|
||||||
|
inventoryService.deleteInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
// API & WebSocket responses.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success(),
|
||||||
|
)
|
||||||
|
webSocket.emit(
|
||||||
|
value = ApiSynchronisation.InventoryUpdate(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.count
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.changeInventoryItemCount(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
|
val inventoryId = call.queryParameters.inventoryId
|
||||||
|
val count = call.queryParameters.count
|
||||||
|
// add the item to the inventory.
|
||||||
|
inventoryService.changeInventoryItemCount(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
count = count,
|
||||||
|
)
|
||||||
|
// API & WebSocket responses.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success(),
|
||||||
|
)
|
||||||
|
webSocket.emit(
|
||||||
|
value = ApiSynchronisation.InventoryUpdate(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.consumeInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
|
val inventoryId = call.queryParameters.inventoryId
|
||||||
|
// add the item to the inventory.
|
||||||
|
inventoryService.consumeInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
)
|
||||||
|
// API & WebSocket responses.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success(),
|
||||||
|
)
|
||||||
|
webSocket.emit(
|
||||||
|
value = ApiSynchronisation.InventoryUpdate(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.equip
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.inventoryId
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.equipInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
|
val inventoryId = call.queryParameters.inventoryId
|
||||||
|
val equip = call.queryParameters.equip
|
||||||
|
|
||||||
|
// add the item to the inventory.
|
||||||
|
inventoryService.equipInventoryItem(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
inventoryId = inventoryId,
|
||||||
|
equip = equip,
|
||||||
|
)
|
||||||
|
// API & WebSocket responses.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success(),
|
||||||
|
)
|
||||||
|
webSocket.emit(
|
||||||
|
value = ApiSynchronisation.InventoryUpdate(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,14 +9,14 @@ import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
import io.ktor.server.response.respond
|
import io.ktor.server.response.respond
|
||||||
import io.ktor.server.routing.RoutingContext
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
fun Engine.createInventory(): suspend RoutingContext.() -> Unit {
|
fun Engine.createInventoryItem(): suspend RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
try {
|
try {
|
||||||
// get the query parameter
|
// get the query parameter
|
||||||
val characterSheetId = call.queryParameters.characterSheetId
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
val itemId = call.queryParameters.itemId
|
val itemId = call.queryParameters.itemId
|
||||||
// add the item to the inventory.
|
// add the item to the inventory.
|
||||||
val inventoryId = inventoryService.createItem(
|
val inventoryId = inventoryService.createInventoryItem(
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
itemId = itemId,
|
itemId = itemId,
|
||||||
)
|
)
|
||||||
|
|
@ -10,6 +10,7 @@ inline fun <reified T> Parameters.param(
|
||||||
): T {
|
): T {
|
||||||
return when (T::class) {
|
return when (T::class) {
|
||||||
String::class -> this[name] as? T
|
String::class -> this[name] as? T
|
||||||
|
Float::class -> this[name]?.toFloatOrNull() as? T
|
||||||
Boolean::class -> this[name]?.toBooleanStrictOrNull() as? T
|
Boolean::class -> this[name]?.toBooleanStrictOrNull() as? T
|
||||||
else -> null
|
else -> null
|
||||||
} ?: throw MissingParameterException(
|
} ?: throw MissingParameterException(
|
||||||
|
|
@ -30,12 +31,24 @@ val Parameters.alterationId: String
|
||||||
code = APIResponse.ErrorCode.AlterationId,
|
code = APIResponse.ErrorCode.AlterationId,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val Parameters.inventoryId: String
|
||||||
|
get() = param(
|
||||||
|
name = "inventoryId",
|
||||||
|
code = APIResponse.ErrorCode.InventoryId,
|
||||||
|
)
|
||||||
|
|
||||||
val Parameters.itemId: String
|
val Parameters.itemId: String
|
||||||
get() = param(
|
get() = param(
|
||||||
name = "itemId",
|
name = "itemId",
|
||||||
code = APIResponse.ErrorCode.ItemId,
|
code = APIResponse.ErrorCode.ItemId,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val Parameters.count: Float
|
||||||
|
get() = param(
|
||||||
|
name = "count",
|
||||||
|
code = APIResponse.ErrorCode.Count,
|
||||||
|
)
|
||||||
|
|
||||||
val Parameters.create: Boolean
|
val Parameters.create: Boolean
|
||||||
get() = param(
|
get() = param(
|
||||||
name = "create",
|
name = "create",
|
||||||
|
|
@ -46,4 +59,10 @@ val Parameters.active: Boolean
|
||||||
get() = param(
|
get() = param(
|
||||||
name = "active",
|
name = "active",
|
||||||
code = APIResponse.ErrorCode.Active,
|
code = APIResponse.ErrorCode.Active,
|
||||||
|
)
|
||||||
|
|
||||||
|
val Parameters.equip: Boolean
|
||||||
|
get() = param(
|
||||||
|
name = "equip",
|
||||||
|
code = APIResponse.ErrorCode.Equip,
|
||||||
)
|
)
|
||||||
|
|
@ -15,13 +15,16 @@ data class APIResponse<T>(
|
||||||
AlterationId,
|
AlterationId,
|
||||||
AlterationName,
|
AlterationName,
|
||||||
ItemId,
|
ItemId,
|
||||||
|
InventoryId,
|
||||||
ItemName,
|
ItemName,
|
||||||
CharacterSheetId,
|
CharacterSheetId,
|
||||||
Create,
|
Create,
|
||||||
Active,
|
Active,
|
||||||
|
Equip,
|
||||||
Damage,
|
Damage,
|
||||||
Fatigue,
|
Fatigue,
|
||||||
Diminished,
|
Diminished,
|
||||||
|
Count,
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue