Skip to content

Commit cf531a7

Browse files
authored
Merge pull request #427 from fmasa/encumbrance-exclude
Option to exclude trapping from Encumbrance calculation
2 parents 0a78f45 + 960efd3 commit cf531a7

File tree

8 files changed

+97
-17
lines changed

8 files changed

+97
-17
lines changed

common/src/commonMain/kotlin/cz/frantisekmasa/wfrp_master/common/character/trappings/EditPlayerDataDialog.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ fun EditPlayerDataDialog(
1717
itemFlaws = trapping.itemFlaws,
1818
quantity = trapping.quantity,
1919
note = trapping.note,
20+
isEncumbranceCounted = trapping.isEncumbranceCounted,
2021
),
2122
onSaveRequest = {
2223
onSaveRequest(
2324
trapping.update(
2425
itemQualities = it.itemQualities,
2526
itemFlaws = it.itemFlaws,
27+
isEncumbranceCounted = it.isEncumbranceCounted,
2628
quantity = it.quantity,
2729
note = it.note,
2830
),
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cz.frantisekmasa.wfrp_master.common.character.trappings
2+
3+
import androidx.compose.foundation.layout.Row
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.MutableState
6+
import androidx.compose.ui.Modifier
7+
import cz.frantisekmasa.wfrp_master.common.Str
8+
import cz.frantisekmasa.wfrp_master.common.core.ui.forms.CheckboxWithText
9+
import cz.frantisekmasa.wfrp_master.common.core.ui.primitives.InfoIcon
10+
import dev.icerock.moko.resources.compose.stringResource
11+
12+
@Composable
13+
fun EncumbranceCountedCheckbox(state: MutableState<Boolean>) {
14+
Row {
15+
CheckboxWithText(
16+
modifier = Modifier.weight(1f),
17+
text = stringResource(Str.trappings_label_encumbrance_counted),
18+
checked = state.value,
19+
onCheckedChange = { state.value = it },
20+
)
21+
InfoIcon(
22+
title = stringResource(Str.trappings_label_encumbrance_counted),
23+
text = stringResource(Str.trappings_label_encumbrance_counted_subtext),
24+
)
25+
}
26+
}

common/src/commonMain/kotlin/cz/frantisekmasa/wfrp_master/common/character/trappings/NonCompendiumTrappingForm.kt

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cz.frantisekmasa.wfrp_master.common.character.trappings
22

3+
import androidx.compose.foundation.layout.Column
34
import androidx.compose.foundation.text.KeyboardOptions
45
import androidx.compose.runtime.Composable
56
import androidx.compose.runtime.MutableState
@@ -91,14 +92,18 @@ fun NonCompendiumTrappingForm(
9192
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
9293
)
9394

94-
TextInput(
95-
label = stringResource(Str.trappings_label_encumbrance_per_unit),
96-
value = formData.encumbrance,
97-
maxLength = 8,
98-
validate = validate,
99-
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
100-
filters = listOf(Filter.DecimalNumber),
101-
)
95+
Column {
96+
TextInput(
97+
label = stringResource(Str.trappings_label_encumbrance_per_unit),
98+
value = formData.encumbrance,
99+
maxLength = 8,
100+
validate = validate,
101+
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
102+
filters = listOf(Filter.DecimalNumber),
103+
)
104+
105+
EncumbranceCountedCheckbox(formData.isEncumbranceCounted)
106+
}
102107

103108
TextInput(
104109
label = stringResource(Str.trappings_label_description),
@@ -170,6 +175,7 @@ private fun TrappingTypeForm(
170175
WeaponQualitiesPicker(formData)
171176
WeaponFlawsPicker(formData)
172177
}
178+
173179
TrappingTypeOption.ARMOUR -> {
174180
SelectBox(
175181
label = stringResource(Str.armour_label_type),
@@ -187,9 +193,11 @@ private fun TrappingTypeForm(
187193
ArmourQualitiesPicker(formData.armourQualities)
188194
ArmourFlawsPicker(formData.armourFlaws)
189195
}
196+
190197
TrappingTypeOption.CLOTHING_OR_ACCESSORY, TrappingTypeOption.PROSTHETIC -> {
191198
WornCheckbox(formData)
192199
}
200+
193201
TrappingTypeOption.CONTAINER -> {
194202
TextInput(
195203
label = stringResource(Str.trappings_label_carries),
@@ -198,6 +206,7 @@ private fun TrappingTypeForm(
198206
)
199207
WornCheckbox(formData)
200208
}
209+
201210
TrappingTypeOption.MELEE_WEAPON -> {
202211
WeaponEquipSelect(formData)
203212
SelectBox(
@@ -216,6 +225,7 @@ private fun TrappingTypeForm(
216225
WeaponQualitiesPicker(formData)
217226
WeaponFlawsPicker(formData)
218227
}
228+
219229
TrappingTypeOption.RANGED_WEAPON -> {
220230
WeaponEquipSelect(formData)
221231
SelectBox(
@@ -241,6 +251,7 @@ private fun TrappingTypeForm(
241251
WeaponQualitiesPicker(formData)
242252
WeaponFlawsPicker(formData)
243253
}
254+
244255
TrappingTypeOption.BOOK_OR_DOCUMENT,
245256
TrappingTypeOption.DRUG_OR_POISON,
246257
TrappingTypeOption.MISCELLANEOUS,
@@ -249,7 +260,8 @@ private fun TrappingTypeForm(
249260
TrappingTypeOption.SPELL_INGREDIENT,
250261
TrappingTypeOption.TOOL_OR_KIT,
251262
TrappingTypeOption.TRADE_TOOLS,
252-
-> {}
263+
-> {
264+
}
253265
}
254266
}
255267

@@ -312,6 +324,7 @@ private class InventoryItemFormData(
312324
val itemFlaws: MutableState<Set<ItemFlaw>>,
313325
val description: InputValue,
314326
val type: TrappingTypeFormData,
327+
val isEncumbranceCounted: MutableState<Boolean>,
315328
) : HydratedFormData<InventoryItem> {
316329
override fun isValid() = listOf(name, encumbrance, quantity, description).all { it.isValid() } && type.isValid()
317330

@@ -337,6 +350,7 @@ private class InventoryItemFormData(
337350
containerId
338351
},
339352
compendiumId = null,
353+
isEncumbranceCounted = isEncumbranceCounted.value,
340354
)
341355
}
342356

@@ -365,6 +379,12 @@ private class InventoryItemFormData(
365379
description = inputValue(item?.description ?: ""),
366380
type = TrappingTypeFormData.fromTrappingType(item?.trappingType),
367381
containerId = item?.containerId ?: defaultContainerId,
382+
isEncumbranceCounted =
383+
rememberSaveable {
384+
mutableStateOf(
385+
item?.isEncumbranceCounted ?: true,
386+
)
387+
},
368388
)
369389
}
370390
}
@@ -396,6 +416,7 @@ private class TrappingTypeFormData(
396416
ammunitionWeaponGroups.value.isNotEmpty() &&
397417
damage.isValid()
398418
}
419+
399420
TrappingTypeOption.ARMOUR -> armourLocations.value.isNotEmpty() && armourPoints.isValid()
400421
TrappingTypeOption.CONTAINER -> carries.isValid()
401422
TrappingTypeOption.MELEE_WEAPON -> damage.isValid()
@@ -423,6 +444,7 @@ private class TrappingTypeFormData(
423444
flaws = weaponFlaws.toMap(),
424445
damage = DamageExpression(damage.value),
425446
)
447+
426448
TrappingTypeOption.ARMOUR ->
427449
TrappingType.Armour(
428450
locations = armourLocations.value,
@@ -432,16 +454,19 @@ private class TrappingTypeFormData(
432454
qualities = armourQualities.toMap(),
433455
flaws = armourFlaws.toMap(),
434456
)
457+
435458
TrappingTypeOption.BOOK_OR_DOCUMENT -> TrappingType.BookOrDocument
436459
TrappingTypeOption.CLOTHING_OR_ACCESSORY ->
437460
TrappingType.ClothingOrAccessory(
438461
worn = worn.value,
439462
)
463+
440464
TrappingTypeOption.CONTAINER ->
441465
TrappingType.Container(
442466
carries = Encumbrance(carries.toDouble()),
443467
worn = worn.value,
444468
)
469+
445470
TrappingTypeOption.DRUG_OR_POISON -> TrappingType.DrugOrPoison
446471
TrappingTypeOption.FOOD_OR_DRINK -> TrappingType.FoodOrDrink
447472
TrappingTypeOption.HERB_OR_DRAUGHT -> TrappingType.HerbOrDraught
@@ -454,6 +479,7 @@ private class TrappingTypeFormData(
454479
flaws = weaponFlaws.toMap(),
455480
equipped = weaponEquipped.value,
456481
)
482+
457483
TrappingTypeOption.PROSTHETIC -> TrappingType.Prosthetic(worn = worn.value)
458484
TrappingTypeOption.RANGED_WEAPON ->
459485
TrappingType.RangedWeapon(
@@ -464,6 +490,7 @@ private class TrappingTypeFormData(
464490
flaws = weaponFlaws.toMap(),
465491
equipped = weaponEquipped.value,
466492
)
493+
467494
TrappingTypeOption.SPELL_INGREDIENT -> TrappingType.SpellIngredient
468495
TrappingTypeOption.MISCELLANEOUS -> null
469496
TrappingTypeOption.TOOL_OR_KIT -> TrappingType.ToolOrKit
@@ -484,6 +511,7 @@ private class TrappingTypeFormData(
484511
weaponQualities = type.qualities,
485512
weaponFlaws = type.flaws,
486513
)
514+
487515
is TrappingType.Armour ->
488516
fromDefaults(
489517
type = TrappingTypeOption.ARMOUR,
@@ -494,18 +522,21 @@ private class TrappingTypeFormData(
494522
armourFlaws = type.flaws,
495523
worn = type.worn,
496524
)
525+
497526
is TrappingType.BookOrDocument -> fromDefaults(TrappingTypeOption.BOOK_OR_DOCUMENT)
498527
is TrappingType.ClothingOrAccessory ->
499528
fromDefaults(
500529
type = TrappingTypeOption.CLOTHING_OR_ACCESSORY,
501530
worn = type.worn,
502531
)
532+
503533
is TrappingType.Container ->
504534
fromDefaults(
505535
type = TrappingTypeOption.CONTAINER,
506536
carries = type.carries,
507537
worn = type.worn,
508538
)
539+
509540
is TrappingType.DrugOrPoison -> fromDefaults(TrappingTypeOption.DRUG_OR_POISON)
510541
is TrappingType.HerbOrDraught -> fromDefaults(TrappingTypeOption.HERB_OR_DRAUGHT)
511542
is TrappingType.MeleeWeapon ->
@@ -518,11 +549,13 @@ private class TrappingTypeFormData(
518549
weaponFlaws = type.flaws,
519550
weaponEquipped = type.equipped,
520551
)
552+
521553
is TrappingType.Prosthetic ->
522554
fromDefaults(
523555
type = TrappingTypeOption.PROSTHETIC,
524556
worn = type.worn,
525557
)
558+
526559
is TrappingType.RangedWeapon ->
527560
fromDefaults(
528561
type = TrappingTypeOption.RANGED_WEAPON,
@@ -533,6 +566,7 @@ private class TrappingTypeFormData(
533566
weaponFlaws = type.flaws,
534567
weaponEquipped = type.equipped,
535568
)
569+
536570
is TrappingType.SpellIngredient -> fromDefaults(TrappingTypeOption.SPELL_INGREDIENT)
537571
TrappingType.FoodOrDrink -> fromDefaults(TrappingTypeOption.FOOD_OR_DRINK)
538572
TrappingType.ToolOrKit -> fromDefaults(TrappingTypeOption.TOOL_OR_KIT)

common/src/commonMain/kotlin/cz/frantisekmasa/wfrp_master/common/character/trappings/TrappingFromCompendiumForm.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ fun TrappingFromCompendiumForm(
4646
val noteField = inputValue(data.note)
4747
val qualityValues = rememberSaveable { mutableStateOf(data.itemQualities) }
4848
val flawValues = rememberSaveable { mutableStateOf(data.itemFlaws) }
49+
val isEncumbranceCounted = rememberSaveable { mutableStateOf(data.isEncumbranceCounted) }
4950
var validate by remember { mutableStateOf(false) }
5051

5152
Scaffold(
@@ -72,6 +73,7 @@ fun TrappingFromCompendiumForm(
7273
itemFlaws = flawValues.value,
7374
quantity = quantityField.toInt().coerceAtLeast(1),
7475
note = noteField.value,
76+
isEncumbranceCounted = isEncumbranceCounted.value,
7577
),
7678
)
7779
onDismissRequest()
@@ -114,12 +116,16 @@ fun TrappingFromCompendiumForm(
114116
selected = flawValues,
115117
)
116118

117-
TextInput(
118-
label = stringResource(Str.trappings_label_quantity),
119-
value = quantityField,
120-
validate = validate,
121-
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
122-
)
119+
Column {
120+
TextInput(
121+
label = stringResource(Str.trappings_label_quantity),
122+
value = quantityField,
123+
validate = validate,
124+
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
125+
)
126+
127+
EncumbranceCountedCheckbox(isEncumbranceCounted)
128+
}
123129
}
124130
}
125131
}
@@ -129,4 +135,5 @@ data class TrappingFromCompendiumPlayerData(
129135
val itemFlaws: Set<ItemFlaw>,
130136
val quantity: Int,
131137
val note: String,
138+
val isEncumbranceCounted: Boolean,
132139
)

common/src/commonMain/kotlin/cz/frantisekmasa/wfrp_master/common/character/trappings/add/AddTrappingScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class AddTrappingScreen(
6565
itemFlaws = emptySet(),
6666
quantity = 1,
6767
note = "",
68+
isEncumbranceCounted = true,
6869
),
6970
onSaveRequest = {
7071
val item =

common/src/commonMain/kotlin/cz/frantisekmasa/wfrp_master/common/core/domain/trappings/InventoryItem.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ data class InventoryItem(
3333
val trappingType: TrappingType? = null,
3434
val itemQualities: Set<ItemQuality> = emptySet(),
3535
val itemFlaws: Set<ItemFlaw> = emptySet(),
36+
val isEncumbranceCounted: Boolean = true,
3637
override val compendiumId: UuidAsString? = null,
3738
) : CharacterItem<InventoryItem, Trapping> {
3839
init {
@@ -42,6 +43,10 @@ data class InventoryItem(
4243

4344
@Stable
4445
val effectiveEncumbrance: Encumbrance get() {
46+
if (!isEncumbranceCounted) {
47+
return Encumbrance.Zero
48+
}
49+
4550
if (containerId != null) {
4651
// Encumbrance of items carried in a container are ignored, see rulebook page 301
4752
return Encumbrance.Zero
@@ -76,6 +81,7 @@ data class InventoryItem(
7681
fun update(
7782
itemQualities: Set<ItemQuality>,
7883
itemFlaws: Set<ItemFlaw>,
84+
isEncumbranceCounted: Boolean,
7985
quantity: Int,
8086
note: String,
8187
): InventoryItem =
@@ -86,6 +92,7 @@ data class InventoryItem(
8692
encumbranceModifier(this.itemQualities, this.itemFlaws),
8793
itemQualities = itemQualities,
8894
itemFlaws = itemFlaws,
95+
isEncumbranceCounted = isEncumbranceCounted,
8996
quantity = quantity,
9097
note = note,
9198
)

common/src/commonMain/moko-resources/base/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,8 @@
678678
<string name="trappings_availability_rare">Rare</string>
679679
<string name="trappings_availability_scarce">Scarce</string>
680680
<string name="trappings_label_availability">Availability</string>
681+
<string name="trappings_label_encumbrance_counted">Count Encumbrance</string>
682+
<string name="trappings_label_encumbrance_counted_subtext">Add this encumbrance to character\'s encumbrance (uncheck if not carried around e.g. a cart)</string>
681683
<string name="trappings_label_carries">Carries</string>
682684
<string name="trappings_label_description">Description (optional)</string>
683685
<string name="trappings_label_encumbrance_per_unit">Encumbrance (per unit)</string>

firebase/firestore.rules

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ service cloud.firestore {
342342
allow delete: if canEditCharacter();
343343

344344
function isValidInventoryItem(item) {
345-
return ["id", "name", "description", "note", "quantity", "encumbrance", "trappingType", "containerId", "compendiumId", "itemQualities", "itemFlaws"].hasAll(item.keys())
345+
return ["id", "name", "description", "note", "quantity", "encumbrance", "trappingType", "containerId", "compendiumId", "itemQualities", "itemFlaws", "isEncumbranceCounted"].hasAll(item.keys())
346346
&& item.id is string && item.id == itemId && isValidUuid(item.id)
347347
&& item.name is string && isNotBlank(item.name) && item.name.size() <= 50
348348
&& item.description is string && item.description.size() <= 2500
@@ -353,7 +353,8 @@ service cloud.firestore {
353353
|| item.containerId == null || containerExists(item.containerId)
354354
)
355355
&& (! ("note" in item) || (item.note is string && item.note.size() <= 500))
356-
&& (!("compendiumId" in item) || (item.compendiumId == null || (item.compendiumId is string && exists(/databases/$(database)/documents/parties/$(partyId)/trappings/$(item.compendiumId)))));
356+
&& (!("compendiumId" in item) || (item.compendiumId == null || (item.compendiumId is string && exists(/databases/$(database)/documents/parties/$(partyId)/trappings/$(item.compendiumId)))))
357+
&& (!("isEncumbranceCounted" in item) || item.isEncumbranceCounted is bool);
357358
}
358359

359360
function containerExists(containerId) {

0 commit comments

Comments
 (0)