@opencharacter/5e-srd-5.1 0.2.0 → 0.3.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 (93) hide show
  1. package/README.md +53 -3
  2. package/content/backgrounds/acolyte.yaml +22 -0
  3. package/content/classes/barbarian.yaml +57 -0
  4. package/content/classes/bard.yaml +68 -0
  5. package/content/classes/cleric.yaml +83 -0
  6. package/content/classes/druid.yaml +61 -0
  7. package/content/classes/fighter.yaml +75 -0
  8. package/content/classes/monk.yaml +47 -0
  9. package/content/classes/paladin.yaml +76 -0
  10. package/content/classes/ranger.yaml +69 -0
  11. package/content/classes/rogue.yaml +59 -0
  12. package/content/classes/sorcerer.yaml +64 -0
  13. package/content/classes/warlock.yaml +71 -0
  14. package/content/classes/wizard.yaml +56 -0
  15. package/content/features/sorcerer/dragon-ancestor.yaml +1 -43
  16. package/content/features/sorcerer/elemental-affinity.yaml +29 -8
  17. package/content/features/sorcerer/metamagic.yaml +1 -93
  18. package/content/features/wizard/arcane-recovery.yaml +4 -4
  19. package/content/hunter-tactics/colossus-slayer.yaml +4 -0
  20. package/content/hunter-tactics/escape-the-horde.yaml +4 -0
  21. package/content/hunter-tactics/evasion.yaml +6 -0
  22. package/content/hunter-tactics/giant-killer.yaml +4 -0
  23. package/content/hunter-tactics/horde-breaker.yaml +4 -0
  24. package/content/hunter-tactics/multiattack-defense.yaml +4 -0
  25. package/content/hunter-tactics/stand-against-the-tide.yaml +4 -0
  26. package/content/hunter-tactics/steel-will.yaml +4 -0
  27. package/content/hunter-tactics/uncanny-dodge.yaml +6 -0
  28. package/content/hunter-tactics/volley.yaml +6 -0
  29. package/content/hunter-tactics/whirlwind-attack.yaml +6 -0
  30. package/content/invocations/bewitching-whispers.yaml +1 -6
  31. package/content/invocations/dreadful-word.yaml +1 -6
  32. package/content/invocations/minions-of-chaos.yaml +1 -6
  33. package/content/invocations/mire-the-mind.yaml +1 -6
  34. package/content/invocations/sculptor-of-flesh.yaml +1 -6
  35. package/content/invocations/sign-of-ill-omen.yaml +1 -6
  36. package/content/invocations/thief-of-five-fates.yaml +1 -6
  37. package/content/magic-items/arrow-of-slaying.yaml +1 -0
  38. package/content/magic-items/bag-of-holding.yaml +2 -0
  39. package/content/magic-items/efficient-quiver.yaml +2 -0
  40. package/content/magic-items/handy-haversack.yaml +2 -0
  41. package/content/magic-items/holy-avenger.yaml +9 -2
  42. package/content/magic-items/necklace-of-prayer-beads.yaml +1 -1
  43. package/content/magic-items/portable-hole.yaml +2 -0
  44. package/content/magic-items/ring-of-x-ray-vision.yaml +6 -0
  45. package/content/magic-items/robe-of-the-archmagi.yaml +1 -1
  46. package/content/magic-items/staff-of-charming.yaml +17 -12
  47. package/content/magic-items/staff-of-fire.yaml +9 -2
  48. package/content/magic-items/staff-of-frost.yaml +9 -2
  49. package/content/magic-items/staff-of-healing.yaml +9 -2
  50. package/content/magic-items/staff-of-power.yaml +2 -1
  51. package/content/magic-items/staff-of-swarming-insects.yaml +17 -12
  52. package/content/magic-items/staff-of-the-magi.yaml +2 -1
  53. package/content/magic-items/staff-of-the-python.yaml +7 -2
  54. package/content/magic-items/staff-of-the-woodlands.yaml +2 -1
  55. package/content/magic-items/staff-of-withering.yaml +9 -2
  56. package/content/metamagic/careful-spell.yaml +11 -0
  57. package/content/metamagic/distant-spell.yaml +11 -0
  58. package/content/metamagic/empowered-spell.yaml +22 -0
  59. package/content/metamagic/extended-spell.yaml +11 -0
  60. package/content/metamagic/heightened-spell.yaml +11 -0
  61. package/content/metamagic/quickened-spell.yaml +11 -0
  62. package/content/metamagic/subtle-spell.yaml +11 -0
  63. package/content/metamagic/twinned-spell.yaml +16 -0
  64. package/content/subclasses/hunter.yaml +4 -29
  65. package/content/traits/infernal-legacy.yaml +15 -2
  66. package/content/traits/relentless-endurance.yaml +6 -0
  67. package/content/weapons/javelin.yaml +1 -1
  68. package/dist/i18n/en.js +1 -1
  69. package/dist/i18n/en.json +277 -201
  70. package/dist/index.js +1 -1
  71. package/dist/release.json +5795 -5769
  72. package/i18n/en/monster-rules.yaml +1 -1
  73. package/i18n/en/type-fields.yaml +7 -0
  74. package/i18n/en.yaml +268 -223
  75. package/pack.yaml +2 -2
  76. package/package.json +2 -2
  77. package/rules/advancement.yaml +67 -38
  78. package/rules/checks.yaml +1 -1
  79. package/rules/classes.yaml +25 -3
  80. package/rules/combat.yaml +3 -2
  81. package/rules/conditions.yaml +1 -0
  82. package/rules/content-types.yaml +61 -4
  83. package/rules/core.yaml +6 -16
  84. package/rules/creation.yaml +20 -34
  85. package/rules/display.yaml +20 -5
  86. package/rules/equipment.yaml +13 -16
  87. package/rules/magic-items.yaml +19 -1
  88. package/rules/monsters.yaml +7 -1
  89. package/rules/rest.yaml +2 -36
  90. package/rules/spellcasting.yaml +1 -5
  91. package/rules/starting-equipment.yaml +17 -646
  92. package/rules/tags.yaml +12 -12
  93. package/upgrades/0.2.0-to-0.3.0.yaml +152 -0
@@ -267,7 +267,7 @@ display:
267
267
  combat.highJump: { unit: ft, groups: [combat], priority: 2 }
268
268
  combat.critRange: { groups: [combat], priority: 3 }
269
269
  proficiency.bonus: { groups: [combat, summary], priority: 1, format: signed }
270
- level.total: { groups: [summary], priority: 0 }
270
+ level.total: { groups: [summary], priority: 0, showWhen: '!sheet.monster || level.total > 0' }
271
271
  challenge.rating:
272
272
  { groups: [summary], priority: 2, format: fraction, showWhen: level.total == 0 }
273
273
  proficiencies.weapons: { groups: [proficiencies] }
@@ -319,6 +319,7 @@ display:
319
319
  groups: [combat],
320
320
  priority: 2,
321
321
  input: { min: 0, max: 3, widget: dots },
322
+ showWhen: '!sheet.monster',
322
323
  rolls: [{ action: death-save }],
323
324
  }
324
325
  deathSaves.failures:
@@ -326,6 +327,7 @@ display:
326
327
  groups: [combat],
327
328
  priority: 2,
328
329
  input: { min: 0, max: 3, widget: dots },
330
+ showWhen: '!sheet.monster',
329
331
  rolls: [{ action: death-save }],
330
332
  }
331
333
  proficiencies.languages: { groups: [proficiencies], visibility: background }
@@ -336,15 +338,24 @@ display:
336
338
  creature.type: { groups: [summary], priority: 2 }
337
339
  senses.darkvision: { unit: ft, groups: [summary], priority: 2, showWhen: senses.darkvision > 0 }
338
340
  senses.blindsense: { unit: ft, groups: [summary], priority: 2, showWhen: senses.blindsense > 0 }
341
+ # A monster carries only what it was given, so its carrying shows once it has some.
339
342
  carrying.weight:
340
343
  {
341
344
  unit: lb,
342
345
  groups: [summary],
343
346
  priority: 2,
344
347
  visibility: secondary,
348
+ showWhen: '!sheet.monster || carrying.weight > 0',
345
349
  with: [{ field: carrying.capacity, as: max }],
346
350
  }
347
- carrying.capacity: { unit: lb, groups: [summary], priority: 2, visibility: secondary }
351
+ carrying.capacity:
352
+ {
353
+ unit: lb,
354
+ groups: [summary],
355
+ priority: 2,
356
+ visibility: secondary,
357
+ showWhen: '!sheet.monster || carrying.weight > 0',
358
+ }
348
359
  carrying.stowed:
349
360
  {
350
361
  unit: lb,
@@ -354,6 +365,7 @@ display:
354
365
  showWhen: carrying.stowed > 0,
355
366
  }
356
367
  carrying.stowCapacity: { hidden: true }
368
+ carrying.stowUnlimited: { hidden: true }
357
369
  combat.featherFall: { hidden: true }
358
370
  carrying.quivers: { hidden: true }
359
371
  carrying.quiveredAmmunition: { hidden: true }
@@ -361,6 +373,7 @@ display:
361
373
  carrying.quiveredLong: { hidden: true }
362
374
  combat.ignoreArmorStrength: { hidden: true }
363
375
  classes.held: { hidden: true }
376
+ attunement.classUnmet: { hidden: true }
364
377
  creature.race: { hidden: true }
365
378
  magicItems.ignoreRequirements: { hidden: true }
366
379
  combat.missToHit: { hidden: true }
@@ -437,7 +450,6 @@ display:
437
450
  hideInPlainSight.active:
438
451
  { groups: [class-features], priority: 0, showWhen: hideInPlainSight.active }
439
452
  foeSlayer.bonus: { hidden: true }
440
- hunter.colossusSlayer: { hidden: true }
441
453
  sneakAttack.dice: { groups: [class-features], priority: 1, showWhen: sneakAttack.dice > 0 }
442
454
  sorcery.points: { groups: [class-features], priority: 1, showWhen: sorcery.points > 0 }
443
455
  eldritchBlast.beams:
@@ -450,11 +462,14 @@ display:
450
462
  sorcery.left: { groups: [class-features], priority: 1, showWhen: sorcery.points > 0 }
451
463
  sorcery.shortRestRegain: { hidden: true }
452
464
  sorcery.metamagic: { hidden: true }
453
- draconic.damageType: { hidden: true }
454
465
  elementalAffinity.resistant:
455
466
  { groups: [class-features], priority: 0, showWhen: elementalAffinity.resistant }
456
467
  dragonWings.active:
457
- { groups: [class-features], priority: 0, showWhen: draconic.damageType != 'none' }
468
+ {
469
+ groups: [class-features],
470
+ priority: 0,
471
+ showWhen: "size(picksOf('features.sorcerer.dragon-ancestor', 'dragon')) > 0",
472
+ }
458
473
  warlock.boons: { groups: [class-features], priority: 1, showWhen: size(warlock.boons) > 0 }
459
474
  spellcasting.bard.dc:
460
475
  { groups: [spellcasting], priority: 0, showWhen: spellcasting.bard.dc > 0 }
@@ -19,11 +19,13 @@ contentTypes:
19
19
  trade-good,
20
20
  ],
21
21
  required: true,
22
+ open: true,
22
23
  }
23
24
  cost: { type: decimal } # gold pieces, per unit
24
25
  weight: { type: decimal } # pounds, per unit
25
26
  bundle: { type: integer, min: 1 }
26
- ammunition: { type: enum, values: [arrow, blowgun-needle, crossbow-bolt, sling-bullet] }
27
+ ammunition:
28
+ { type: enum, values: [arrow, blowgun-needle, crossbow-bolt, sling-bullet], open: true }
27
29
  state:
28
30
  stowed: { type: boolean, default: false }
29
31
  quivered: { type: boolean, default: false } # in an Efficient Quiver (below)
@@ -38,6 +40,7 @@ contentTypes:
38
40
  type: enum,
39
41
  values: [artisans-tools, gaming-set, musical-instrument, kit, other],
40
42
  required: true,
43
+ open: true,
41
44
  }
42
45
  cost: { type: decimal }
43
46
  weight: { type: decimal }
@@ -54,7 +57,7 @@ contentTypes:
54
57
  vehicle:
55
58
  carried: true
56
59
  fields:
57
- category: { type: enum, values: [drawn, waterborne], required: true }
60
+ category: { type: enum, values: [drawn, waterborne], required: true, open: true }
58
61
  cost: { type: decimal }
59
62
  pulledWeight: { type: decimal }
60
63
  speedMph: { type: decimal }
@@ -65,14 +68,10 @@ fields:
65
68
  formula: >-
66
69
  sumCopies(copy.fields.weight * copy.quantity, has(copy.fields.weight)
67
70
  && has(copy.state.stowed) && copy.state.stowed)
68
- carrying.stowCapacity:
69
- type: decimal
70
- formula: >-
71
- 500 * sumCopies(copy.quantity, copy.item == @magic-items.bag-of-holding)
72
- + 120 * sumCopies(copy.quantity, copy.item == @magic-items.handy-haversack)
73
- carrying.quivers:
74
- type: integer
75
- formula: 'sumCopies(copy.quantity, copy.item == @magic-items.efficient-quiver)'
71
+ # What extradimensional containers and quivers hold: each adds its own (content effects).
72
+ carrying.stowCapacity: { type: decimal, formula: 0, min: 0 }
73
+ carrying.stowUnlimited: { type: boolean, formula: false }
74
+ carrying.quivers: { type: integer, formula: 0, min: 0 }
76
75
  carrying.quiveredAmmunition:
77
76
  type: integer
78
77
  formula: >-
@@ -81,25 +80,23 @@ fields:
81
80
  carrying.quiveredJavelins:
82
81
  type: integer
83
82
  formula: >-
84
- sumCopies(copy.quantity, copy.item == @weapons.javelin
83
+ sumCopies(copy.quantity, 'quiver.javelin' in copy.tags
85
84
  && has(copy.state.quivered) && copy.state.quivered)
86
85
  carrying.quiveredLong:
87
86
  type: integer
88
87
  formula: >-
89
88
  sumCopies(copy.quantity, copy.type == 'weapon'
90
- && copy.item != @weapons.javelin
89
+ && !('quiver.javelin' in copy.tags)
91
90
  && has(copy.state.quivered) && copy.state.quivered)
92
91
 
93
92
  constraints:
94
93
  - id: stowed-without-container
95
94
  check: >-
96
95
  countCopies(has(copy.state.stowed) && copy.state.stowed) == 0
97
- || countCopies(copy.item in [@magic-items.bag-of-holding,
98
- @magic-items.handy-haversack, @magic-items.portable-hole]) > 0
96
+ || carrying.stowUnlimited || carrying.stowCapacity > 0
99
97
  - id: stowed-over-capacity
100
98
  check: >-
101
- carrying.stowed <= carrying.stowCapacity
102
- || countCopies(copy.item == @magic-items.portable-hole) > 0
99
+ carrying.stowUnlimited || carrying.stowed <= carrying.stowCapacity
103
100
  data:
104
101
  stowed: carrying.stowed
105
102
  capacity: carrying.stowCapacity
@@ -3,6 +3,8 @@
3
3
  templateFields:
4
4
  rarity: { type: enum, values: [common, uncommon, rare, very-rare, legendary, artifact] }
5
5
  requiresAttunement: { type: boolean, default: false }
6
+ # Only a character with one of these classes can attune to it.
7
+ attunementClasses: { type: set, of: class }
6
8
  maxCharges: { type: integer, min: 1 }
7
9
  recharge: { type: dice }
8
10
  attackBonus: { type: integer, default: 0 }
@@ -15,7 +17,12 @@ contentTypes:
15
17
  equippable: true
16
18
  fields:
17
19
  category:
18
- { type: enum, values: [potion, ring, rod, scroll, wand, wondrous-item], required: true }
20
+ {
21
+ type: enum,
22
+ values: [potion, ring, rod, scroll, wand, wondrous-item],
23
+ required: true,
24
+ open: true,
25
+ }
19
26
  rarity:
20
27
  {
21
28
  type: enum,
@@ -23,6 +30,7 @@ contentTypes:
23
30
  required: true,
24
31
  }
25
32
  requiresAttunement: { type: boolean }
33
+ attunementClasses: { type: set, of: class }
26
34
  cost: { type: decimal } # gold pieces, where the SRD gives one
27
35
  weight: { type: decimal } # pounds, where the SRD gives one
28
36
  maxCharges: { type: integer, min: 1 }
@@ -40,6 +48,15 @@ contentTypes:
40
48
  state:
41
49
  attuned: { type: boolean, default: false }
42
50
  stowed: { type: boolean, default: false } # in an extradimensional container (equipment.yaml)
51
+ usedToday: { type: set, of: string, default: [] }
52
+ effects:
53
+ # An attuned item for other classes than the character's (attunementClasses).
54
+ - target: attunement.classUnmet
55
+ op: add
56
+ value: 1
57
+ when: >-
58
+ self.attuned && has(item.attunementClasses) && size(item.attunementClasses) > 0
59
+ && countList(item.attunementClasses, x in classes.held) == 0
43
60
 
44
61
  storedSpell:
45
62
  carried: false
@@ -341,6 +358,7 @@ actions:
341
358
  dice: { type: dice, optional: true }
342
359
  damageType:
343
360
  type: enum
361
+ open: true
344
362
  optional: true
345
363
  values:
346
364
  [
@@ -12,6 +12,7 @@ contentTypes:
12
12
  creatureType:
13
13
  {
14
14
  type: enum,
15
+ open: true,
15
16
  values:
16
17
  [
17
18
  aberration,
@@ -53,6 +54,7 @@ contentTypes:
53
54
  sahuagin,
54
55
  titan,
55
56
  ],
57
+ open: true,
56
58
  }
57
59
  shapechanger: { type: boolean }
58
60
  swarm: { type: boolean }
@@ -145,7 +147,7 @@ contentTypes:
145
147
  cr: { type: decimal, required: true, min: 0, max: 30 }
146
148
  xp: { type: integer, min: 0 }
147
149
  legendaryActions: { type: integer, min: 1 }
148
- ownCopies: { type: set, of: monsterAction, default: [] }
150
+ ownCopies: { type: list, of: monsterAction, unique: true, default: [] }
149
151
  innateOncePerDay: { type: set, of: spell, default: [] }
150
152
  innateTwicePerDay: { type: set, of: spell, default: [] }
151
153
  innateThricePerDay: { type: set, of: spell, default: [] }
@@ -222,6 +224,7 @@ contentTypes:
222
224
  - use: change-form
223
225
 
224
226
  monsterSpellcasting:
227
+ grantOnly: true
225
228
  carried: false
226
229
  fields:
227
230
  ability: { type: enum, values: [str, dex, con, int, wis, cha], required: true }
@@ -297,6 +300,7 @@ contentTypes:
297
300
  slashing,
298
301
  thunder,
299
302
  ],
303
+ open: true,
300
304
  }
301
305
  versatileDamage: { type: dice }
302
306
  damage2: { type: dice }
@@ -319,6 +323,7 @@ contentTypes:
319
323
  slashing,
320
324
  thunder,
321
325
  ],
326
+ open: true,
322
327
  }
323
328
  magical: { type: boolean }
324
329
  save: { type: enum, values: [str, dex, con, int, wis, cha] }
@@ -343,6 +348,7 @@ contentTypes:
343
348
  slashing,
344
349
  thunder,
345
350
  ],
351
+ open: true,
346
352
  }
347
353
  saveEffect: { type: enum, values: [half, none], default: none }
348
354
  condition: { type: id, of: condition }
package/rules/rest.yaml CHANGED
@@ -86,6 +86,8 @@ actions:
86
86
  steps:
87
87
  - id: rest
88
88
  kind: changes
89
+ # Content resets its own uses here (`rest.long` changes effects).
90
+ tags: [rest.long]
89
91
  changes:
90
92
  - { type: set, field: hp.current, value: hp.max, when: rest.longRestHeals }
91
93
  - { type: set, field: hp.temp, value: 0 }
@@ -278,32 +280,6 @@ actions:
278
280
  copies: { type: class, where: has(self.wholenessUsed) && self.wholenessUsed }
279
281
  key: wholenessUsed
280
282
  value: false
281
- - type: setState
282
- when: countCopies(copy.item == @races.tiefling) > 0
283
- grants: { where: 'item.id == @traits.infernal-legacy && self.hellishRebukeUsed' }
284
- key: hellishRebukeUsed
285
- value: false
286
- - type: setState
287
- when: countCopies(copy.item == @races.tiefling) > 0
288
- grants: { where: 'item.id == @traits.infernal-legacy && self.darknessUsed' }
289
- key: darknessUsed
290
- value: false
291
- - type: setState
292
- when: >-
293
- countCopies(copy.item == @magic-items.ring-of-x-ray-vision
294
- && copy.state.used) > 0
295
- copies:
296
- {
297
- type: magicItem,
298
- where: 'item.id == @magic-items.ring-of-x-ray-vision && self.used',
299
- }
300
- key: used
301
- value: false
302
- - type: setState
303
- when: countCopies(copy.item == @races.half-orc) > 0
304
- grants: { where: 'item.id == @traits.relentless-endurance && self.used' }
305
- key: used
306
- value: false
307
283
  - type: setState
308
284
  when: countCopies(has(copy.state.signatureSpell1Used) && copy.state.signatureSpell1Used) > 0
309
285
  copies:
@@ -316,16 +292,6 @@ actions:
316
292
  { type: class, where: has(self.signatureSpell2Used) && self.signatureSpell2Used }
317
293
  key: signatureSpell2Used
318
294
  value: false
319
- - type: setState
320
- when: countCopies(copy.item == @classes.warlock) > 0
321
- picks: { where: "item.type == 'invocation' && self.used" }
322
- key: used
323
- value: false
324
- - type: setState
325
- when: countCopies(copy.item == @races.dragonborn) > 0
326
- picks: { where: "item.type == 'draconicAncestry' && self.used" }
327
- key: used
328
- value: false
329
295
  - type: setState
330
296
  when: countCopies(copy.type == 'monsterAction') > 0
331
297
  copies:
@@ -601,6 +601,7 @@ actions:
601
601
  steps:
602
602
  - id: rest
603
603
  kind: changes
604
+ tags: [rest.short]
604
605
  changes:
605
606
  - { type: set, field: pactSlots.used, value: 0 }
606
607
  - type: removeEffect
@@ -685,11 +686,6 @@ actions:
685
686
  { type: class, where: has(self.signatureSpell2Used) && self.signatureSpell2Used }
686
687
  key: signatureSpell2Used
687
688
  value: false
688
- - type: setState
689
- when: countCopies(copy.item == @races.dragonborn) > 0
690
- picks: { where: "item.type == 'draconicAncestry' && self.used" }
691
- key: used
692
- value: false
693
689
  - type: setState
694
690
  when: countCopies(copy.type == 'monsterAction') > 0
695
691
  copies: