@opencharacter/swn-revised 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +64 -10
  2. package/content/classes/adventurer.yaml +2 -0
  3. package/content/classes/expert.yaml +2 -0
  4. package/content/classes/psychic.yaml +6 -6
  5. package/content/classes/warrior.yaml +2 -0
  6. package/content/foci/psychic-training.yaml +1 -0
  7. package/content/foci/specialist.yaml +1 -1
  8. package/content/foci/wild-psychic-talent.yaml +1 -0
  9. package/content/kits/barbarian.yaml +17 -0
  10. package/content/kits/blade.yaml +17 -0
  11. package/content/kits/civilian.yaml +12 -0
  12. package/content/kits/credits.yaml +11 -0
  13. package/content/kits/gunslinger.yaml +16 -0
  14. package/content/kits/hacker.yaml +18 -0
  15. package/content/kits/medic.yaml +18 -0
  16. package/content/kits/scout.yaml +19 -0
  17. package/content/kits/soldier.yaml +16 -0
  18. package/content/kits/technician.yaml +19 -0
  19. package/content/kits/thief.yaml +19 -0
  20. package/content/partial-classes/psychic.yaml +4 -6
  21. package/content/styles/expert-nimble.yaml +11 -0
  22. package/content/styles/expert-smart.yaml +11 -0
  23. package/content/styles/expert-smooth.yaml +11 -0
  24. package/content/styles/psychic-adept.yaml +11 -0
  25. package/content/styles/psychic-seer.yaml +11 -0
  26. package/content/styles/warrior-leader.yaml +11 -0
  27. package/content/styles/warrior-melee.yaml +11 -0
  28. package/content/styles/warrior-ranged.yaml +11 -0
  29. package/content/techniques/psychic-succor.yaml +16 -3
  30. package/content/weapons/advanced-bow.yaml +0 -2
  31. package/content/weapons/anti-vehicle-laser.yaml +0 -2
  32. package/content/weapons/combat-rifle.yaml +0 -2
  33. package/content/weapons/combat-shotgun.yaml +0 -2
  34. package/content/weapons/conversion-bow.yaml +0 -2
  35. package/content/weapons/crude-pistol.yaml +0 -2
  36. package/content/weapons/distortion-cannon.yaml +0 -2
  37. package/content/weapons/heavy-machine-gun.yaml +0 -2
  38. package/content/weapons/hydra-array.yaml +0 -2
  39. package/content/weapons/laser-pistol.yaml +0 -2
  40. package/content/weapons/laser-rifle.yaml +0 -2
  41. package/content/weapons/mag-pistol.yaml +0 -2
  42. package/content/weapons/mag-rifle.yaml +0 -2
  43. package/content/weapons/musket.yaml +0 -2
  44. package/content/weapons/plasma-projector.yaml +0 -2
  45. package/content/weapons/primitive-bow.yaml +0 -2
  46. package/content/weapons/railgun.yaml +0 -2
  47. package/content/weapons/revolver.yaml +0 -2
  48. package/content/weapons/rifle.yaml +0 -2
  49. package/content/weapons/rocket-launcher.yaml +0 -2
  50. package/content/weapons/semi-auto-pistol.yaml +0 -2
  51. package/content/weapons/shear-rifle.yaml +0 -2
  52. package/content/weapons/shotgun.yaml +0 -2
  53. package/content/weapons/sniper-rifle.yaml +0 -2
  54. package/content/weapons/spike-thrower.yaml +0 -2
  55. package/content/weapons/submachine-gun.yaml +0 -2
  56. package/content/weapons/thermal-pistol.yaml +0 -2
  57. package/content/weapons/thunder-gun.yaml +0 -2
  58. package/content/weapons/void-carbine.yaml +0 -2
  59. package/content/weapons/vortex-cannon.yaml +0 -2
  60. package/content/weapons/wheatcutter-belt.yaml +0 -2
  61. package/dist/i18n/en.js +1 -1
  62. package/dist/i18n/en.json +140 -85
  63. package/dist/index.js +1 -1
  64. package/dist/release.json +5068 -3511
  65. package/i18n/en/content.yaml +105 -63
  66. package/i18n/en/rules.yaml +35 -22
  67. package/pack.yaml +2 -2
  68. package/package.json +2 -2
  69. package/rules/advancement.yaml +30 -9
  70. package/rules/character.yaml +30 -5
  71. package/rules/checks.yaml +8 -2
  72. package/rules/combat.yaml +11 -2
  73. package/rules/creation.yaml +164 -366
  74. package/rules/gear.yaml +16 -4
  75. package/rules/layout.yaml +4 -2
  76. package/rules/psionics.yaml +64 -4
  77. package/rules/start.yaml +46 -32
  78. package/rules/tags.yaml +11 -0
@@ -11,11 +11,13 @@ actions:
11
11
  # One skill pick at creation: a skill's first pick is level-0, the second level-1, and a third
12
12
  # is any other non-psychic skill below level-1. Also the attribute picks of the Growth table.
13
13
  - id: gain-skill
14
+ available: character.creating
14
15
  tags: [creation]
15
16
  params:
16
17
  entry:
17
18
  {
18
19
  type: enum,
20
+ open: true,
19
21
  required: true,
20
22
  values:
21
23
  [
@@ -112,7 +114,11 @@ actions:
112
114
  kind: changes
113
115
  when: flags.skill != ''
114
116
  changes:
115
- - { type: adjust, field: { formula: "'skills.' + flags.skill + '.level'" }, by: 1 }
117
+ - {
118
+ type: adjust,
119
+ field: { formula: "fieldId('skills.{skill}.level', flags.skill)" },
120
+ by: 1,
121
+ }
116
122
  # A psychic skill raised to level-1 brings a level-1 technique of its discipline.
117
123
  - id: technique
118
124
  kind: choice
@@ -199,6 +205,7 @@ actions:
199
205
  # A focus level: a new focus, or the next level of one already held. A new focus's bonus skill
200
206
  # is a skill pick at creation and three skill points on advancement.
201
207
  - id: gain-focus
208
+ listed: false
202
209
  tags: [creation, level-up]
203
210
  params:
204
211
  kind: { type: enum, values: [any, combat, noncombat], default: any }
@@ -208,6 +215,7 @@ actions:
208
215
  steps:
209
216
  - id: focus
210
217
  kind: choice
218
+ tags: [{ formula: "params.advancement ? 'level-up.focus' : 'creation.focus'" }]
211
219
  sheet: proposed
212
220
  random: params.random
213
221
  recommend: options[0]
@@ -216,19 +224,23 @@ actions:
216
224
  type: focus
217
225
  where: >-
218
226
  (params.kind == 'any' || item.kind == params.kind)
219
- && (item.id != @foci.psychic-training || psionics.access != 'none')
220
- && (item.id != @foci.wild-psychic-talent || psionics.access == 'none')
227
+ && !('needs-psionics' in item.tags && psionics.access == 'none')
228
+ && !('no-psionics' in item.tags && psionics.access != 'none')
221
229
  && (item.repeatable || countCopies(copy.item == item.id
222
230
  && copy.state.level >= item.maxLevel) == 0)
223
231
  changes:
224
232
  - type: adjustState
225
- when: '!steps.focus.item.repeatable && countCopies(copy.item == picked.id) > 0'
233
+ when: >-
234
+ has(picked.item) && !picked.item.repeatable
235
+ && countCopies(copy.item == picked.id) > 0
226
236
  copies: { type: focus, where: item.id == steps.focus.picked }
227
237
  limit: 1
228
238
  key: level
229
239
  by: 1
230
240
  - type: addItem
231
- when: steps.focus.item.repeatable || countCopies(copy.item == picked.id) == 0
241
+ when: >-
242
+ has(picked.item)
243
+ && (picked.item.repeatable || countCopies(copy.item == picked.id) == 0)
232
244
  entry: { item: picked.id }
233
245
  - id: picks
234
246
  kind: choice
@@ -259,375 +271,161 @@ actions:
259
271
  - { id: result, kind: outcome, result: "'gained'" }
260
272
 
261
273
  - id: starting-gear
274
+ available: character.creating
262
275
  tags: [creation]
263
276
  params:
264
277
  random: { type: boolean, default: false }
265
278
  results: [equipped]
266
279
  steps:
280
+ # A package (an add-on pack's too), or credits instead: the class's own package is
281
+ # recommended. The package's own action adds its gear and credits.
267
282
  - id: kit
283
+ tags: [creation.kit]
268
284
  kind: choice
285
+ sheet: proposed
269
286
  random: params.random
270
- recommend: >-
271
- countCopies(copy.item == @classes.warrior) > 0 ? 'soldier'
272
- : countCopies(copy.item == @classes.psychic) > 0 ? 'medic'
273
- : countCopies(copy.item == @classes.expert) > 0 ? 'technician' : 'gunslinger'
274
- options:
275
- - { id: barbarian }
276
- - { id: blade }
277
- - { id: thief }
278
- - { id: hacker }
279
- - { id: gunslinger }
280
- - { id: soldier }
281
- - { id: scout }
282
- - { id: medic }
283
- - { id: civilian }
284
- - { id: technician }
285
- - { id: credits }
286
- - id: credits
287
- kind: roll
288
- when: "steps.kit.picked == 'credits'"
289
- tags: [creation]
290
- parts: [{ dice: 2d6 }]
291
- - id: gear
287
+ options: { content: { type: kit } }
288
+ prefer: "countCopies(copy.type == 'class' && copy.fields.kit == item.id)"
289
+ changes:
290
+ - type: addItem
291
+ when: has(picked.item)
292
+ entry: { id: kit, item: picked.id }
293
+ - id: unpack
294
+ kind: action
295
+ when: has(steps.kit.item)
296
+ sheet: proposed
297
+ entry: "'kit'"
298
+ use: unpack
299
+ - id: unpacked
292
300
  kind: changes
301
+ when: has(steps.kit.item)
293
302
  changes:
294
- - {
295
- type: addItem,
296
- when: "steps.kit.picked == 'barbarian'",
297
- entry: { item: "'weapons.spear'", equipped: true },
298
- }
299
- - {
300
- type: addItem,
301
- when: "steps.kit.picked == 'barbarian'",
302
- entry: { item: "'armor.light-primitive-armor'", equipped: true },
303
- }
304
- - {
305
- type: addItem,
306
- when: "steps.kit.picked == 'barbarian'",
307
- entry: { item: "'armor.shield'", equipped: true },
308
- }
309
- - {
310
- type: addItem,
311
- when: "steps.kit.picked == 'barbarian'",
312
- entry: { item: "'weapons.knife'", equipped: true },
313
- }
314
- - {
315
- type: addItem,
316
- when: "steps.kit.picked == 'barbarian'",
317
- entry: { item: "'gear.backpack-tl0'", equipped: true },
318
- }
319
- - {
320
- type: addItem,
321
- when: "steps.kit.picked == 'barbarian'",
322
- entry: { item: "'gear.rations-1-day'", quantity: 7 },
323
- }
324
- - {
325
- type: addItem,
326
- when: "steps.kit.picked == 'barbarian'",
327
- entry: { item: "'gear.rope-tl0'" },
328
- }
329
- - {
330
- type: addItem,
331
- when: "steps.kit.picked == 'blade'",
332
- entry: { item: "'weapons.monoblade-sword'", equipped: true },
333
- }
334
- - {
335
- type: addItem,
336
- when: "steps.kit.picked == 'blade'",
337
- entry: { item: "'armor.woven-body-armor'", equipped: true },
338
- }
339
- - {
340
- type: addItem,
341
- when: "steps.kit.picked == 'blade'",
342
- entry: { item: "'armor.secure-clothing'" },
343
- }
344
- - {
345
- type: addItem,
346
- when: "steps.kit.picked == 'blade'",
347
- entry: { item: "'weapons.thermal-knife'", equipped: true },
348
- }
349
- - {
350
- type: addItem,
351
- when: "steps.kit.picked == 'blade'",
352
- entry: { item: "'gear.backpack-tl0'", equipped: true },
353
- }
354
- - { type: addItem, when: "steps.kit.picked == 'blade'", entry: { item: "'gear.compad'" } }
355
- - {
356
- type: addItem,
357
- when: "steps.kit.picked == 'blade'",
358
- entry: { item: "'gear.lazarus-patch'" },
359
- }
360
- - {
361
- type: addItem,
362
- when: "steps.kit.picked == 'thief'",
363
- entry: { item: "'weapons.laser-pistol'", equipped: true },
364
- }
365
- - {
366
- type: addItem,
367
- when: "steps.kit.picked == 'thief'",
368
- entry: { item: "'armor.armored-undersuit'", equipped: true },
369
- }
370
- - {
371
- type: addItem,
372
- when: "steps.kit.picked == 'thief'",
373
- entry: { item: "'weapons.monoblade-knife'", equipped: true },
374
- }
375
- - {
376
- type: addItem,
377
- when: "steps.kit.picked == 'thief'",
378
- entry: { item: "'gear.climbing-harness'" },
379
- }
380
- - {
381
- type: addItem,
382
- when: "steps.kit.picked == 'thief'",
383
- entry: { item: "'gear.low-light-goggles'" },
384
- }
385
- - {
386
- type: addItem,
387
- when: "steps.kit.picked == 'thief'",
388
- entry: { item: "'gear.power-cell-a'", quantity: 2 },
389
- }
390
- - {
391
- type: addItem,
392
- when: "steps.kit.picked == 'thief'",
393
- entry: { item: "'gear.backpack-tl0'", equipped: true },
394
- }
395
- - { type: addItem, when: "steps.kit.picked == 'thief'", entry: { item: "'gear.compad'" } }
396
- - {
397
- type: addItem,
398
- when: "steps.kit.picked == 'thief'",
399
- entry: { item: "'gear.metatool'" },
400
- }
401
- - {
402
- type: addItem,
403
- when: "steps.kit.picked == 'hacker'",
404
- entry: { item: "'weapons.laser-pistol'", equipped: true },
405
- }
406
- - {
407
- type: addItem,
408
- when: "steps.kit.picked == 'hacker'",
409
- entry: { item: "'armor.secure-clothing'", equipped: true },
410
- }
411
- - {
412
- type: addItem,
413
- when: "steps.kit.picked == 'hacker'",
414
- entry: { item: "'gear.postech-toolkit'" },
415
- }
416
- - {
417
- type: addItem,
418
- when: "steps.kit.picked == 'hacker'",
419
- entry: { item: "'gear.spare-parts'", quantity: 3 },
420
- }
421
- - {
422
- type: addItem,
423
- when: "steps.kit.picked == 'hacker'",
424
- entry: { item: "'gear.power-cell-a'", quantity: 2 },
425
- }
426
- - {
427
- type: addItem,
428
- when: "steps.kit.picked == 'hacker'",
429
- entry: { item: "'gear.dataslab'" },
430
- }
431
- - {
432
- type: addItem,
433
- when: "steps.kit.picked == 'hacker'",
434
- entry: { item: "'gear.metatool'" },
435
- }
436
- - {
437
- type: addItem,
438
- when: "steps.kit.picked == 'hacker'",
439
- entry: { item: "'gear.line-shunt'", quantity: 2 },
440
- }
441
- - {
442
- type: addItem,
443
- when: "steps.kit.picked == 'gunslinger'",
444
- entry: { item: "'weapons.laser-pistol'", equipped: true },
445
- }
446
- - {
447
- type: addItem,
448
- when: "steps.kit.picked == 'gunslinger'",
449
- entry: { item: "'armor.armored-undersuit'", equipped: true },
450
- }
451
- - {
452
- type: addItem,
453
- when: "steps.kit.picked == 'gunslinger'",
454
- entry: { item: "'weapons.monoblade-knife'", equipped: true },
455
- }
456
- - {
457
- type: addItem,
458
- when: "steps.kit.picked == 'gunslinger'",
459
- entry: { item: "'gear.power-cell-a'", quantity: 8 },
460
- }
461
- - {
462
- type: addItem,
463
- when: "steps.kit.picked == 'gunslinger'",
464
- entry: { item: "'gear.backpack-tl0'", equipped: true },
465
- }
466
- - {
467
- type: addItem,
468
- when: "steps.kit.picked == 'gunslinger'",
469
- entry: { item: "'gear.compad'" },
470
- }
471
- - {
472
- type: addItem,
473
- when: "steps.kit.picked == 'soldier'",
474
- entry: { item: "'weapons.combat-rifle'", equipped: true },
475
- }
476
- - {
477
- type: addItem,
478
- when: "steps.kit.picked == 'soldier'",
479
- entry: { item: "'armor.woven-body-armor'", equipped: true },
480
- }
481
- - {
482
- type: addItem,
483
- when: "steps.kit.picked == 'soldier'",
484
- entry: { item: "'weapons.knife'", equipped: true },
485
- }
486
- - {
487
- type: addItem,
488
- when: "steps.kit.picked == 'soldier'",
489
- entry: { item: "'gear.ammo-20-rounds'", quantity: 4 },
490
- }
491
- - {
492
- type: addItem,
493
- when: "steps.kit.picked == 'soldier'",
494
- entry: { item: "'gear.backpack-tl0'", equipped: true },
495
- }
496
- - {
497
- type: addItem,
498
- when: "steps.kit.picked == 'soldier'",
499
- entry: { item: "'gear.compad'" },
500
- }
501
- - {
502
- type: addItem,
503
- when: "steps.kit.picked == 'scout'",
504
- entry: { item: "'weapons.laser-rifle'", equipped: true },
505
- }
506
- - {
507
- type: addItem,
508
- when: "steps.kit.picked == 'scout'",
509
- entry: { item: "'armor.armored-vacc-suit'", equipped: true },
510
- }
511
- - {
512
- type: addItem,
513
- when: "steps.kit.picked == 'scout'",
514
- entry: { item: "'weapons.knife'", equipped: true },
515
- }
516
- - {
517
- type: addItem,
518
- when: "steps.kit.picked == 'scout'",
519
- entry: { item: "'gear.survey-scanner'" },
520
- }
521
- - {
522
- type: addItem,
523
- when: "steps.kit.picked == 'scout'",
524
- entry: { item: "'gear.survival-kit'" },
525
- }
526
- - {
527
- type: addItem,
528
- when: "steps.kit.picked == 'scout'",
529
- entry: { item: "'gear.binoculars-tl3'" },
530
- }
531
- - {
532
- type: addItem,
533
- when: "steps.kit.picked == 'scout'",
534
- entry: { item: "'gear.power-cell-a'", quantity: 8 },
535
- }
536
- - {
537
- type: addItem,
538
- when: "steps.kit.picked == 'scout'",
539
- entry: { item: "'gear.backpack-tl0'", equipped: true },
540
- }
541
- - { type: addItem, when: "steps.kit.picked == 'scout'", entry: { item: "'gear.compad'" } }
542
- - {
543
- type: addItem,
544
- when: "steps.kit.picked == 'medic'",
545
- entry: { item: "'weapons.laser-pistol'", equipped: true },
546
- }
547
- - {
548
- type: addItem,
549
- when: "steps.kit.picked == 'medic'",
550
- entry: { item: "'armor.secure-clothing'", equipped: true },
551
- }
552
- - {
553
- type: addItem,
554
- when: "steps.kit.picked == 'medic'",
555
- entry: { item: "'gear.lazarus-patch'", quantity: 4 },
556
- }
557
- - {
558
- type: addItem,
559
- when: "steps.kit.picked == 'medic'",
560
- entry: { item: "'gear.lift'", quantity: 2 },
561
- }
562
- - {
563
- type: addItem,
564
- when: "steps.kit.picked == 'medic'",
565
- entry: { item: "'gear.backpack-tl0'", equipped: true },
566
- }
567
- - { type: addItem, when: "steps.kit.picked == 'medic'", entry: { item: "'gear.medkit'" } }
568
- - { type: addItem, when: "steps.kit.picked == 'medic'", entry: { item: "'gear.compad'" } }
569
- - {
570
- type: addItem,
571
- when: "steps.kit.picked == 'medic'",
572
- entry: { item: "'gear.bioscanner'" },
573
- }
574
- - {
575
- type: addItem,
576
- when: "steps.kit.picked == 'civilian'",
577
- entry: { item: "'armor.secure-clothing'", equipped: true },
578
- }
579
- - {
580
- type: addItem,
581
- when: "steps.kit.picked == 'civilian'",
582
- entry: { item: "'gear.compad'" },
583
- }
584
- - {
585
- type: addItem,
586
- when: "steps.kit.picked == 'technician'",
587
- entry: { item: "'weapons.laser-pistol'", equipped: true },
588
- }
589
- - {
590
- type: addItem,
591
- when: "steps.kit.picked == 'technician'",
592
- entry: { item: "'armor.armored-undersuit'", equipped: true },
593
- }
594
- - {
595
- type: addItem,
596
- when: "steps.kit.picked == 'technician'",
597
- entry: { item: "'weapons.monoblade-knife'", equipped: true },
598
- }
599
- - {
600
- type: addItem,
601
- when: "steps.kit.picked == 'technician'",
602
- entry: { item: "'gear.postech-toolkit'" },
603
- }
604
- - {
605
- type: addItem,
606
- when: "steps.kit.picked == 'technician'",
607
- entry: { item: "'gear.spare-parts'", quantity: 6 },
608
- }
609
- - {
610
- type: addItem,
611
- when: "steps.kit.picked == 'technician'",
612
- entry: { item: "'gear.power-cell-a'", quantity: 4 },
613
- }
614
- - {
615
- type: addItem,
616
- when: "steps.kit.picked == 'technician'",
617
- entry: { item: "'gear.backpack-tl0'", equipped: true },
618
- }
619
- - {
620
- type: addItem,
621
- when: "steps.kit.picked == 'technician'",
622
- entry: { item: "'gear.dataslab'" },
623
- }
624
- - {
625
- type: addItem,
626
- when: "steps.kit.picked == 'technician'",
627
- entry: { item: "'gear.metatool'" },
628
- }
629
- - type: set
630
- field: credits.current
631
- value: >-
632
- steps.kit.picked == 'barbarian' ? 500 : steps.kit.picked == 'blade' ? 50 : steps.kit.picked == 'thief' ? 25 : steps.kit.picked == 'hacker' ? 100 : steps.kit.picked == 'gunslinger' ? 100 : steps.kit.picked == 'soldier' ? 100 : steps.kit.picked == 'scout' ? 25 : steps.kit.picked == 'medic' ? 25 : steps.kit.picked == 'civilian' ? 700 : steps.kit.picked == 'technician' ? 200 : steps.credits.total * 100
303
+ - { type: removeItem, entry: kit }
304
+ # A kit may ready more than half Strength. Readied gear, then all but one weapon (the
305
+ # weakest first), are stowed while they fit within Strength. Past that, readied gear, a
306
+ # shield, the last weapon and then armor are stowed anyway, and Stowed gear, weapons and
307
+ # armor past Strength are left behind (the heaviest first), so play starts unencumbered.
308
+ - id: stowGear
309
+ kind: choice
310
+ sheet: proposed
311
+ repeat: { max: 20, min: 20 }
312
+ options:
313
+ copies:
314
+ type: gear
315
+ where: >-
316
+ self.equipped && has(item.enc) && item.enc > 0
317
+ && encumbrance.readied > encumbrance.readiedLimit
318
+ && encumbrance.stowed + item.enc * ceil(self.quantity / item.bundle)
319
+ <= encumbrance.stowedLimit
320
+ prefer: item.enc
321
+ changes:
322
+ - { type: equip, entry: picked, equipped: false }
323
+ - id: stowWeapon
324
+ kind: choice
325
+ sheet: proposed
326
+ repeat: { max: 20, min: 20 }
327
+ options:
328
+ copies:
329
+ type: weapon
330
+ where: >-
331
+ self.equipped && has(item.enc) && item.enc > 0
332
+ && countCopies(copy.type == 'weapon' && copy.equipped && has(copy.fields.enc)
333
+ && copy.fields.enc > 0) > 1
334
+ && encumbrance.readied > encumbrance.readiedLimit
335
+ && encumbrance.stowed + item.enc * ceil(self.quantity / item.bundle)
336
+ <= encumbrance.stowedLimit
337
+ prefer: -maxOf(item.damage)
338
+ changes:
339
+ - { type: equip, entry: picked, equipped: false }
340
+ - id: stowGearOver
341
+ kind: choice
342
+ sheet: proposed
343
+ repeat: { max: 20, min: 20 }
344
+ options:
345
+ copies:
346
+ type: gear
347
+ where: >-
348
+ self.equipped && has(item.enc) && item.enc > 0
349
+ && encumbrance.readied > encumbrance.readiedLimit
350
+ prefer: item.enc
351
+ changes:
352
+ - { type: equip, entry: picked, equipped: false }
353
+ - id: stowShield
354
+ kind: choice
355
+ sheet: proposed
356
+ repeat: { max: 20, min: 20 }
357
+ options:
358
+ copies:
359
+ type: armor
360
+ where: >-
361
+ self.equipped && has(item.enc) && item.enc > 0 && item.shield
362
+ && encumbrance.readied > encumbrance.readiedLimit
363
+ prefer: item.enc
364
+ changes:
365
+ - { type: equip, entry: picked, equipped: false }
366
+ - id: stowLastWeapon
367
+ kind: choice
368
+ sheet: proposed
369
+ repeat: { max: 20, min: 20 }
370
+ options:
371
+ copies:
372
+ type: weapon
373
+ where: >-
374
+ self.equipped && has(item.enc) && item.enc > 0
375
+ && encumbrance.readied > encumbrance.readiedLimit
376
+ prefer: -maxOf(item.damage)
377
+ changes:
378
+ - { type: equip, entry: picked, equipped: false }
379
+ - id: stowArmor
380
+ kind: choice
381
+ sheet: proposed
382
+ repeat: { max: 20, min: 20 }
383
+ options:
384
+ copies:
385
+ type: armor
386
+ where: >-
387
+ self.equipped && has(item.enc) && item.enc > 0
388
+ && encumbrance.readied > encumbrance.readiedLimit
389
+ prefer: item.enc
390
+ changes:
391
+ - { type: equip, entry: picked, equipped: false }
392
+ - id: dropGear
393
+ kind: choice
394
+ sheet: proposed
395
+ repeat: { max: 20, min: 20 }
396
+ options:
397
+ copies:
398
+ type: gear
399
+ where: >-
400
+ !self.equipped && !self.stored && has(item.enc) && item.enc > 0
401
+ && encumbrance.stowed > encumbrance.stowedLimit
402
+ prefer: 'item.enc * ceil(self.quantity / item.bundle)'
403
+ changes:
404
+ - { type: removeItem, entry: picked }
405
+ - id: dropWeapon
406
+ kind: choice
407
+ sheet: proposed
408
+ repeat: { max: 20, min: 20 }
409
+ options:
410
+ copies:
411
+ type: weapon
412
+ where: >-
413
+ !self.equipped && !self.stored && has(item.enc) && item.enc > 0
414
+ && encumbrance.stowed > encumbrance.stowedLimit
415
+ prefer: 'item.enc * ceil(self.quantity / item.bundle)'
416
+ changes:
417
+ - { type: removeItem, entry: picked }
418
+ - id: dropArmor
419
+ kind: choice
420
+ sheet: proposed
421
+ repeat: { max: 20, min: 20 }
422
+ options:
423
+ copies:
424
+ type: armor
425
+ where: >-
426
+ !self.equipped && !self.stored && has(item.enc) && item.enc > 0
427
+ && encumbrance.stowed > encumbrance.stowedLimit
428
+ prefer: 'item.enc * ceil(self.quantity / item.bundle)'
429
+ changes:
430
+ - { type: removeItem, entry: picked }
633
431
  - { id: result, kind: outcome, result: "'equipped'" }
package/rules/gear.yaml CHANGED
@@ -84,17 +84,21 @@ standardCopies:
84
84
  - { type: weapon, where: "'unarmed' in item.tags" }
85
85
 
86
86
  contentTypes:
87
+ # A starting package: its own `unpack` action adds its gear and sets the credits.
88
+ kit:
89
+ carried: false
90
+
87
91
  weapon:
88
92
  carried: true
89
93
  equippable: true
90
94
  fields:
91
95
  damage: { type: dice, required: true }
92
- skill: { type: enum, values: [punch, shoot, stab], required: true }
96
+ skill: { type: enum, values: [punch, shoot, stab], required: true, open: true }
93
97
  attribute: { type: enum, values: [str, dex, str-dex] }
94
98
  range: { type: integer, min: 0 }
95
99
  maxRange: { type: integer, min: 0 }
96
100
  magazine: { type: integer, min: 1 }
97
- ammo: { type: enum, values: [rounds, cell-a, cell-b, missile] }
101
+ ammo: { type: enum, values: [rounds, cell-a, cell-b, missile], open: true }
98
102
  shock: { type: integer, min: 0 }
99
103
  shockAc: { type: integer, min: 0 }
100
104
  burst: { type: boolean, default: false }
@@ -115,6 +119,12 @@ contentTypes:
115
119
  techLevel: { type: integer, min: 0, max: 6 }
116
120
  state:
117
121
  stored: { type: boolean, default: false }
122
+ # Rounds in the magazine of a weapon that has one.
123
+ loaded:
124
+ type: integer
125
+ min: 0
126
+ max: 'has(item.magazine) ? item.magazine : 0'
127
+ default: 'has(item.magazine) ? item.magazine : 0'
118
128
  actions:
119
129
  - use: attack
120
130
  - use: reload
@@ -124,7 +134,8 @@ contentTypes:
124
134
  equippable: true
125
135
  fields:
126
136
  ac: { type: integer, required: true, min: 10 }
127
- category: { type: enum, values: [primitive, street, combat, powered], required: true }
137
+ category:
138
+ { type: enum, values: [primitive, street, combat, powered], required: true, open: true }
128
139
  shield: { type: boolean, default: false }
129
140
  # Strength counted higher for encumbrance while worn.
130
141
  strength: { type: integer, default: 0, min: 0 }
@@ -147,9 +158,10 @@ contentTypes:
147
158
  category:
148
159
  type: enum
149
160
  required: true
161
+ open: true
150
162
  values: [ammo-power, communications, computing, field, pharmaceutical, tools-medical]
151
163
  # What a weapon reloads with.
152
- kind: { type: enum, values: [rounds, cell-a, cell-b, missile] }
164
+ kind: { type: enum, values: [rounds, cell-a, cell-b, missile], open: true }
153
165
  # A drug: the Heal skill needed to apply it, the System Strain it adds and what it heals.
154
166
  healSkill: { type: integer, min: 0 }
155
167
  strain: { type: integer, default: 0, min: 0 }