@opencharacter/wwn-srd 0.0.0-stage → 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 (456) hide show
  1. package/LICENSE +144 -0
  2. package/README.md +147 -2
  3. package/content/armor/buff-coat.yaml +7 -0
  4. package/content/armor/cuirass-and-greaves.yaml +7 -0
  5. package/content/armor/grand-plate.yaml +7 -0
  6. package/content/armor/great-armor.yaml +7 -0
  7. package/content/armor/large-shield.yaml +6 -0
  8. package/content/armor/linothorax.yaml +6 -0
  9. package/content/armor/mail-hauberk.yaml +7 -0
  10. package/content/armor/mail-shirt.yaml +6 -0
  11. package/content/armor/pieced-armor.yaml +7 -0
  12. package/content/armor/plate-armor.yaml +7 -0
  13. package/content/armor/scaled-armor.yaml +7 -0
  14. package/content/armor/small-shield.yaml +6 -0
  15. package/content/armor/war-robe.yaml +7 -0
  16. package/content/armor/war-shirt.yaml +7 -0
  17. package/content/arts/accursed/accursed-blade.yaml +5 -0
  18. package/content/arts/accursed/accursed-bolt.yaml +5 -0
  19. package/content/arts/accursed/bewitching-distraction.yaml +5 -0
  20. package/content/arts/accursed/compelling-shriek.yaml +5 -0
  21. package/content/arts/accursed/devils-bargain.yaml +4 -0
  22. package/content/arts/accursed/dire-pact.yaml +4 -0
  23. package/content/arts/accursed/lying-face.yaml +5 -0
  24. package/content/arts/accursed/night-black-eyes.yaml +4 -0
  25. package/content/arts/accursed/pacted-protection.yaml +4 -0
  26. package/content/arts/accursed/rob-vitality.yaml +5 -0
  27. package/content/arts/accursed/scourging-curse.yaml +5 -0
  28. package/content/arts/accursed/shadowed-steps.yaml +5 -0
  29. package/content/arts/accursed/snaring-speech.yaml +5 -0
  30. package/content/arts/accursed/sorcerous-battery.yaml +5 -0
  31. package/content/arts/accursed/soul-consumption.yaml +5 -0
  32. package/content/arts/accursed/tendrils-of-night.yaml +5 -0
  33. package/content/arts/accursed/unseen-steps.yaml +5 -0
  34. package/content/arts/accursed/weeping-wounds.yaml +5 -0
  35. package/content/arts/accursed/weight-of-sin.yaml +5 -0
  36. package/content/arts/bard/a-thousand-tongues.yaml +5 -0
  37. package/content/arts/bard/battle-cry.yaml +5 -0
  38. package/content/arts/bard/cursed-tune.yaml +5 -0
  39. package/content/arts/bard/deft-fingers.yaml +6 -0
  40. package/content/arts/bard/entangle-incantation.yaml +5 -0
  41. package/content/arts/bard/evoke-emotion.yaml +5 -0
  42. package/content/arts/bard/inspire-dread.yaml +5 -0
  43. package/content/arts/bard/keen-senses.yaml +4 -0
  44. package/content/arts/bard/liberating-song.yaml +5 -0
  45. package/content/arts/bard/rally.yaml +5 -0
  46. package/content/arts/bard/soothe-the-savage.yaml +5 -0
  47. package/content/arts/bard/soothing-graces.yaml +4 -0
  48. package/content/arts/bard/swift-misdirection.yaml +5 -0
  49. package/content/arts/beastmaster/beast-ward.yaml +5 -0
  50. package/content/arts/beastmaster/bind-companion.yaml +5 -0
  51. package/content/arts/beastmaster/eyes-of-the-beast.yaml +5 -0
  52. package/content/arts/beastmaster/feral-toughness.yaml +8 -0
  53. package/content/arts/beastmaster/howl-of-distant-summons.yaml +5 -0
  54. package/content/arts/beastmaster/know-the-weak-spot.yaml +5 -0
  55. package/content/arts/beastmaster/mind-call.yaml +5 -0
  56. package/content/arts/beastmaster/natural-weaponry.yaml +10 -0
  57. package/content/arts/beastmaster/savage-senses.yaml +5 -0
  58. package/content/arts/beastmaster/shared-vitality.yaml +5 -0
  59. package/content/arts/beastmaster/swift-healing.yaml +5 -0
  60. package/content/arts/beastmaster/tongue-of-the-beasts.yaml +5 -0
  61. package/content/arts/blood-priest/a-thousand-tongues.yaml +5 -0
  62. package/content/arts/blood-priest/armor-of-god.yaml +11 -0
  63. package/content/arts/blood-priest/divine-guidance.yaml +5 -0
  64. package/content/arts/blood-priest/fear-no-flame.yaml +5 -0
  65. package/content/arts/blood-priest/god-wills-it.yaml +5 -0
  66. package/content/arts/blood-priest/light-of-faith.yaml +5 -0
  67. package/content/arts/blood-priest/merciful-healing.yaml +5 -0
  68. package/content/arts/blood-priest/sanctified-ward.yaml +5 -0
  69. package/content/arts/blood-priest/smite-the-wicked.yaml +5 -0
  70. package/content/arts/blood-priest/transubstantiation.yaml +5 -0
  71. package/content/arts/blood-priest/turn-false-life.yaml +5 -0
  72. package/content/arts/blood-priest/words-of-mercy.yaml +5 -0
  73. package/content/arts/blood-priest/wrath-of-the-most-high.yaml +5 -0
  74. package/content/arts/duelist/blood-for-blood.yaml +5 -0
  75. package/content/arts/duelist/burst-of-speed.yaml +5 -0
  76. package/content/arts/duelist/code-duello.yaml +5 -0
  77. package/content/arts/duelist/crushing-superiority.yaml +5 -0
  78. package/content/arts/duelist/dauntless-step.yaml +5 -0
  79. package/content/arts/duelist/dodge-doom.yaml +5 -0
  80. package/content/arts/duelist/favored-weapon.yaml +13 -0
  81. package/content/arts/duelist/forced-engagement.yaml +5 -0
  82. package/content/arts/duelist/gentlemans-withdrawal.yaml +5 -0
  83. package/content/arts/duelist/graceful-leap.yaml +5 -0
  84. package/content/arts/duelist/lightning-draw.yaml +5 -0
  85. package/content/arts/duelist/piercing-strike.yaml +5 -0
  86. package/content/arts/duelist/spiritual-weapon.yaml +5 -0
  87. package/content/arts/duelist/unbindable.yaml +5 -0
  88. package/content/arts/duelist/unworthy-rabble.yaml +5 -0
  89. package/content/arts/duelist/whirling-evasion.yaml +10 -0
  90. package/content/arts/elementalist/beckoned-deluge.yaml +5 -0
  91. package/content/arts/elementalist/earthsight.yaml +5 -0
  92. package/content/arts/elementalist/elemental-blast.yaml +5 -0
  93. package/content/arts/elementalist/elemental-resilience.yaml +5 -0
  94. package/content/arts/elementalist/elemental-sparks.yaml +5 -0
  95. package/content/arts/elementalist/flamesight.yaml +5 -0
  96. package/content/arts/elementalist/pavis-of-elements.yaml +8 -0
  97. package/content/arts/elementalist/petrifying-stare.yaml +5 -0
  98. package/content/arts/elementalist/rune-of-destruction.yaml +5 -0
  99. package/content/arts/elementalist/steps-of-air.yaml +5 -0
  100. package/content/arts/elementalist/stunning-shock.yaml +5 -0
  101. package/content/arts/elementalist/thermal-shield.yaml +5 -0
  102. package/content/arts/healer/empowered-healer.yaml +4 -0
  103. package/content/arts/healer/facile-healer.yaml +4 -0
  104. package/content/arts/healer/far-healer.yaml +4 -0
  105. package/content/arts/healer/final-repose.yaml +5 -0
  106. package/content/arts/healer/healers-eye.yaml +5 -0
  107. package/content/arts/healer/healers-knife.yaml +4 -0
  108. package/content/arts/healer/healing-touch.yaml +6 -0
  109. package/content/arts/healer/limb-restoration.yaml +8 -0
  110. package/content/arts/healer/purge-ailment.yaml +5 -0
  111. package/content/arts/healer/refined-restoration.yaml +4 -0
  112. package/content/arts/healer/revive-the-fallen.yaml +8 -0
  113. package/content/arts/healer/swift-healer.yaml +4 -0
  114. package/content/arts/healer/tireless-vigor.yaml +5 -0
  115. package/content/arts/healer/vital-furnace.yaml +5 -0
  116. package/content/arts/high-mage/arcane-lexicon.yaml +5 -0
  117. package/content/arts/high-mage/counter-magic.yaml +5 -0
  118. package/content/arts/high-mage/empowered-sorcery.yaml +5 -0
  119. package/content/arts/high-mage/hang-sorcery.yaml +5 -0
  120. package/content/arts/high-mage/inexorable-effect.yaml +5 -0
  121. package/content/arts/high-mage/iron-resolution.yaml +5 -0
  122. package/content/arts/high-mage/preparatory-countermagic.yaml +5 -0
  123. package/content/arts/high-mage/psychic-conversion.yaml +4 -0
  124. package/content/arts/high-mage/restrained-casting.yaml +5 -0
  125. package/content/arts/high-mage/retain-sorcery.yaml +5 -0
  126. package/content/arts/high-mage/sense-magic.yaml +5 -0
  127. package/content/arts/high-mage/suppress-magic.yaml +5 -0
  128. package/content/arts/high-mage/swift-casting.yaml +5 -0
  129. package/content/arts/high-mage/ward-allies.yaml +5 -0
  130. package/content/arts/high-mage/wizards-grandeur.yaml +5 -0
  131. package/content/arts/mageslayer/absolute-negation.yaml +6 -0
  132. package/content/arts/mageslayer/antimage.yaml +8 -0
  133. package/content/arts/mageslayer/dispel-enchantment.yaml +6 -0
  134. package/content/arts/mageslayer/disrupt-sorcery.yaml +6 -0
  135. package/content/arts/mageslayer/immaculate-body.yaml +5 -0
  136. package/content/arts/mageslayer/immaculate-mind.yaml +5 -0
  137. package/content/arts/mageslayer/know-your-prey.yaml +7 -0
  138. package/content/arts/mageslayer/magebane.yaml +5 -0
  139. package/content/arts/mageslayer/share-the-pain.yaml +6 -0
  140. package/content/arts/mageslayer/spellshield.yaml +5 -0
  141. package/content/arts/mageslayer/ward-ally.yaml +6 -0
  142. package/content/arts/mageslayer/witchfinder.yaml +6 -0
  143. package/content/arts/necromancer/bonetalker.yaml +5 -0
  144. package/content/arts/necromancer/cold-flesh.yaml +6 -0
  145. package/content/arts/necromancer/consume-life-energy.yaml +4 -0
  146. package/content/arts/necromancer/false-death.yaml +5 -0
  147. package/content/arts/necromancer/gravesight.yaml +5 -0
  148. package/content/arts/necromancer/keeper-of-the-gate.yaml +5 -0
  149. package/content/arts/necromancer/life-bridge.yaml +5 -0
  150. package/content/arts/necromancer/master-of-bones.yaml +5 -0
  151. package/content/arts/necromancer/red-harvest.yaml +5 -0
  152. package/content/arts/necromancer/unaging.yaml +4 -0
  153. package/content/arts/necromancer/uncanny-ichor.yaml +4 -0
  154. package/content/arts/necromancer/unliving-persistence.yaml +5 -0
  155. package/content/arts/skinshifter/change-form.yaml +6 -0
  156. package/content/arts/skinshifter/eyes-of-the-hawk.yaml +4 -0
  157. package/content/arts/skinshifter/feline-leap.yaml +4 -0
  158. package/content/arts/skinshifter/feral-prowess.yaml +4 -0
  159. package/content/arts/skinshifter/intrinsic-armor.yaml +4 -0
  160. package/content/arts/skinshifter/manifest-wings.yaml +4 -0
  161. package/content/arts/skinshifter/monkeys-road.yaml +4 -0
  162. package/content/arts/skinshifter/octopus-embrace.yaml +4 -0
  163. package/content/arts/skinshifter/perfect-mimicry.yaml +4 -0
  164. package/content/arts/skinshifter/pliant-flesh.yaml +4 -0
  165. package/content/arts/skinshifter/savage-talons.yaml +4 -0
  166. package/content/arts/skinshifter/sculptors-beauty.yaml +4 -0
  167. package/content/arts/skinshifter/serpents-kiss.yaml +5 -0
  168. package/content/arts/skinshifter/warform.yaml +4 -0
  169. package/content/arts/skinshifter/wisdom-of-fin-and-scale.yaml +4 -0
  170. package/content/arts/thought-noble/block-memory.yaml +5 -0
  171. package/content/arts/thought-noble/elicitation-of-truth.yaml +8 -0
  172. package/content/arts/thought-noble/facile-speech.yaml +7 -0
  173. package/content/arts/thought-noble/far-speech.yaml +5 -0
  174. package/content/arts/thought-noble/hypercognition.yaml +5 -0
  175. package/content/arts/thought-noble/iconograph.yaml +5 -0
  176. package/content/arts/thought-noble/impress-imperative.yaml +5 -0
  177. package/content/arts/thought-noble/mind-light.yaml +4 -0
  178. package/content/arts/thought-noble/mind-over-matter.yaml +5 -0
  179. package/content/arts/thought-noble/mirror-mask.yaml +5 -0
  180. package/content/arts/thought-noble/open-mind.yaml +6 -0
  181. package/content/arts/thought-noble/positive-association.yaml +5 -0
  182. package/content/arts/thought-noble/read-intent.yaml +5 -0
  183. package/content/arts/thought-noble/surface-apprehension.yaml +5 -0
  184. package/content/arts/thought-noble/thoughts-like-razors.yaml +5 -0
  185. package/content/arts/thought-noble/unthinkable-thought.yaml +5 -0
  186. package/content/arts/vowed/brutal-counter.yaml +5 -0
  187. package/content/arts/vowed/faultless-awareness.yaml +4 -0
  188. package/content/arts/vowed/hurling-throw.yaml +5 -0
  189. package/content/arts/vowed/inward-eye.yaml +5 -0
  190. package/content/arts/vowed/leap-of-the-heavens.yaml +5 -0
  191. package/content/arts/vowed/martial-style.yaml +9 -0
  192. package/content/arts/vowed/masters-vigor.yaml +4 -0
  193. package/content/arts/vowed/mob-justice.yaml +5 -0
  194. package/content/arts/vowed/nimble-ascent.yaml +5 -0
  195. package/content/arts/vowed/purified-body.yaml +5 -0
  196. package/content/arts/vowed/revivifying-breath.yaml +5 -0
  197. package/content/arts/vowed/shattering-strike.yaml +5 -0
  198. package/content/arts/vowed/style-weaponry.yaml +4 -0
  199. package/content/arts/vowed/unarmed-might.yaml +10 -0
  200. package/content/arts/vowed/unarmored-defense.yaml +11 -0
  201. package/content/arts/vowed/unobtrusive-step.yaml +5 -0
  202. package/content/arts/wise/auspicious-undertaking.yaml +5 -0
  203. package/content/arts/wise/compel-truth.yaml +5 -0
  204. package/content/arts/wise/deliver-oracle.yaml +5 -0
  205. package/content/arts/wise/dread-awe.yaml +5 -0
  206. package/content/arts/wise/elite-ties.yaml +5 -0
  207. package/content/arts/wise/erudite.yaml +5 -0
  208. package/content/arts/wise/evil-eye.yaml +5 -0
  209. package/content/arts/wise/find-object.yaml +5 -0
  210. package/content/arts/wise/folk-friend.yaml +5 -0
  211. package/content/arts/wise/healer.yaml +7 -0
  212. package/content/arts/wise/holy-sanctity.yaml +5 -0
  213. package/content/arts/wise/ill-fate.yaml +5 -0
  214. package/content/arts/wise/luck-blessing.yaml +5 -0
  215. package/content/arts/wise/personal-impunity.yaml +5 -0
  216. package/content/arts/wise/read-omens.yaml +5 -0
  217. package/content/arts/wise/skilled.yaml +5 -0
  218. package/content/arts/wise/war-curse.yaml +5 -0
  219. package/content/backgrounds/artisan.yaml +18 -0
  220. package/content/backgrounds/barbarian.yaml +18 -0
  221. package/content/classes/adventurer.yaml +16 -0
  222. package/content/classes/expert.yaml +6 -0
  223. package/content/classes/mage.yaml +8 -0
  224. package/content/classes/warrior.yaml +8 -0
  225. package/content/foci/alert.yaml +10 -0
  226. package/content/foci/armored-magic.yaml +9 -0
  227. package/content/foci/armsmaster.yaml +20 -0
  228. package/content/foci/artisan.yaml +5 -0
  229. package/content/foci/assassin.yaml +5 -0
  230. package/content/foci/authority.yaml +5 -0
  231. package/content/foci/close-combatant.yaml +8 -0
  232. package/content/foci/connected.yaml +5 -0
  233. package/content/foci/cultured.yaml +5 -0
  234. package/content/foci/deadeye.yaml +11 -0
  235. package/content/foci/dealmaker.yaml +5 -0
  236. package/content/foci/developed-attribute.yaml +23 -0
  237. package/content/foci/die-hard.yaml +5 -0
  238. package/content/foci/diplomatic-grace.yaml +5 -0
  239. package/content/foci/gifted-chirurgeon.yaml +11 -0
  240. package/content/foci/henchkeeper.yaml +5 -0
  241. package/content/foci/impervious-defense.yaml +5 -0
  242. package/content/foci/impostor.yaml +5 -0
  243. package/content/foci/lucky.yaml +11 -0
  244. package/content/foci/nullifier.yaml +7 -0
  245. package/content/foci/poisoner.yaml +5 -0
  246. package/content/foci/polymath.yaml +10 -0
  247. package/content/foci/rider.yaml +5 -0
  248. package/content/foci/shocking-assault.yaml +9 -0
  249. package/content/foci/snipers-eye.yaml +5 -0
  250. package/content/foci/special-origin.yaml +5 -0
  251. package/content/foci/specialist.yaml +38 -0
  252. package/content/foci/spirit-familiar.yaml +5 -0
  253. package/content/foci/traditional-education.yaml +15 -0
  254. package/content/foci/trapmaster.yaml +5 -0
  255. package/content/foci/unarmed-combatant.yaml +16 -0
  256. package/content/foci/unique-gift.yaml +5 -0
  257. package/content/foci/valiant-defender.yaml +5 -0
  258. package/content/foci/well-met.yaml +3 -0
  259. package/content/foci/whirlwind-assault.yaml +5 -0
  260. package/content/foci/xenoblooded.yaml +22 -0
  261. package/content/gear/arrows.yaml +5 -0
  262. package/content/gear/artisans-equipment.yaml +6 -0
  263. package/content/gear/backpack.yaml +6 -0
  264. package/content/gear/battle-horse.yaml +5 -0
  265. package/content/gear/boots.yaml +6 -0
  266. package/content/gear/candle.yaml +5 -0
  267. package/content/gear/cart.yaml +4 -0
  268. package/content/gear/common-clothes.yaml +6 -0
  269. package/content/gear/cooking-utensils.yaml +5 -0
  270. package/content/gear/criminal-tools.yaml +6 -0
  271. package/content/gear/crowbar.yaml +5 -0
  272. package/content/gear/draft-horse.yaml +5 -0
  273. package/content/gear/dungeoneering-kit.yaml +6 -0
  274. package/content/gear/fine-clothes.yaml +6 -0
  275. package/content/gear/firewood.yaml +6 -0
  276. package/content/gear/flask.yaml +5 -0
  277. package/content/gear/grappling-hook.yaml +5 -0
  278. package/content/gear/healers-pouch.yaml +5 -0
  279. package/content/gear/hurlant-bolts.yaml +5 -0
  280. package/content/gear/iron-spikes.yaml +5 -0
  281. package/content/gear/lantern.yaml +5 -0
  282. package/content/gear/mirror.yaml +4 -0
  283. package/content/gear/mule.yaml +5 -0
  284. package/content/gear/noble-clothes.yaml +6 -0
  285. package/content/gear/noble-courtier-outfit.yaml +6 -0
  286. package/content/gear/oil.yaml +6 -0
  287. package/content/gear/paper.yaml +4 -0
  288. package/content/gear/performers-implements.yaml +6 -0
  289. package/content/gear/rations.yaml +5 -0
  290. package/content/gear/riding-horse.yaml +5 -0
  291. package/content/gear/rope.yaml +5 -0
  292. package/content/gear/sack.yaml +5 -0
  293. package/content/gear/shovel.yaml +5 -0
  294. package/content/gear/small-tool.yaml +5 -0
  295. package/content/gear/tinder-box.yaml +4 -0
  296. package/content/gear/torch.yaml +7 -0
  297. package/content/gear/waterskin.yaml +5 -0
  298. package/content/gear/wilderness-travel-gear.yaml +6 -0
  299. package/content/gear/working-dog.yaml +5 -0
  300. package/content/gear/writing-kit.yaml +5 -0
  301. package/content/partials/accursed.yaml +18 -0
  302. package/content/partials/bard.yaml +9 -0
  303. package/content/partials/beastmaster.yaml +9 -0
  304. package/content/partials/blood-priest.yaml +7 -0
  305. package/content/partials/duelist.yaml +10 -0
  306. package/content/partials/expert.yaml +6 -0
  307. package/content/partials/healer.yaml +9 -0
  308. package/content/partials/mage.yaml +12 -0
  309. package/content/partials/mageslayer.yaml +21 -0
  310. package/content/partials/skinshifter.yaml +9 -0
  311. package/content/partials/thought-noble.yaml +9 -0
  312. package/content/partials/vowed.yaml +41 -0
  313. package/content/partials/warrior.yaml +6 -0
  314. package/content/partials/wise.yaml +45 -0
  315. package/content/spells/elementalist/aqueous-harmony.yaml +5 -0
  316. package/content/spells/elementalist/boreal-wings.yaml +5 -0
  317. package/content/spells/elementalist/burrower-below.yaml +5 -0
  318. package/content/spells/elementalist/calcifying-scourge.yaml +5 -0
  319. package/content/spells/elementalist/elemental-favor.yaml +5 -0
  320. package/content/spells/elementalist/elemental-guardian.yaml +5 -0
  321. package/content/spells/elementalist/elemental-spy.yaml +5 -0
  322. package/content/spells/elementalist/elemental-vallation.yaml +5 -0
  323. package/content/spells/elementalist/flame-scrying.yaml +5 -0
  324. package/content/spells/elementalist/flame-without-end.yaml +5 -0
  325. package/content/spells/elementalist/fury-of-the-elements.yaml +5 -0
  326. package/content/spells/elementalist/like-the-stones.yaml +5 -0
  327. package/content/spells/elementalist/pact-of-stone-and-sea.yaml +5 -0
  328. package/content/spells/elementalist/tremors-of-the-depths.yaml +5 -0
  329. package/content/spells/elementalist/wind-walking.yaml +5 -0
  330. package/content/spells/high/abdication-of-temporal-presence.yaml +5 -0
  331. package/content/spells/high/adopt-the-simulacular-visage.yaml +5 -0
  332. package/content/spells/high/apprehending-the-arcane-form.yaml +5 -0
  333. package/content/spells/high/banishment-to-the-black-glass-labyrinth.yaml +5 -0
  334. package/content/spells/high/calculation-of-the-evoked-servitor.yaml +5 -0
  335. package/content/spells/high/calculation-of-the-phantasmal-eidolon.yaml +5 -0
  336. package/content/spells/high/casting-forth-the-inner-eye.yaml +5 -0
  337. package/content/spells/high/cognitive-supersession-of-the-inferior-orders.yaml +5 -0
  338. package/content/spells/high/conjunct-the-vital-viscera.yaml +5 -0
  339. package/content/spells/high/conjunction-of-the-inexorable-step.yaml +5 -0
  340. package/content/spells/high/contingent-excision-of-arcana.yaml +5 -0
  341. package/content/spells/high/coruscating-coffin.yaml +5 -0
  342. package/content/spells/high/damnation-of-the-sense.yaml +5 -0
  343. package/content/spells/high/dazzling-prismatic-hemicycle.yaml +5 -0
  344. package/content/spells/high/decree-of-ligneous-dissolution.yaml +5 -0
  345. package/content/spells/high/decree-of-lithic-dissolution.yaml +5 -0
  346. package/content/spells/high/deluge-of-hell.yaml +5 -0
  347. package/content/spells/high/disjunctive-temporal-reversion.yaml +5 -0
  348. package/content/spells/high/earth-as-clay.yaml +5 -0
  349. package/content/spells/high/evert-the-inwardness.yaml +5 -0
  350. package/content/spells/high/excellent-transpicuous-transformation.yaml +5 -0
  351. package/content/spells/high/exhalation-of-congelating-cold.yaml +5 -0
  352. package/content/spells/high/extirpate-arcana.yaml +5 -0
  353. package/content/spells/high/foresightful-apprehension.yaml +5 -0
  354. package/content/spells/high/glass-chimes-of-the-bamboo-terrace.yaml +5 -0
  355. package/content/spells/high/grinding-geas.yaml +5 -0
  356. package/content/spells/high/howl-of-light.yaml +5 -0
  357. package/content/spells/high/imperceptible-cerebral-divulgence.yaml +5 -0
  358. package/content/spells/high/ineluctable-shackles-of-volition.yaml +5 -0
  359. package/content/spells/high/inexorable-imputation.yaml +5 -0
  360. package/content/spells/high/invocation-of-the-invincible-citadel.yaml +5 -0
  361. package/content/spells/high/jade-palanquin-of-the-faceless-god.yaml +5 -0
  362. package/content/spells/high/long-amber-moment.yaml +5 -0
  363. package/content/spells/high/mantle-of-disjecting-dissection.yaml +5 -0
  364. package/content/spells/high/obnubilation-of-the-will.yaml +5 -0
  365. package/content/spells/high/ochre-sigil-of-juxtaposition.yaml +5 -0
  366. package/content/spells/high/open-the-high-road.yaml +5 -0
  367. package/content/spells/high/phantasmal-mimesis.yaml +5 -0
  368. package/content/spells/high/phobic-storm.yaml +5 -0
  369. package/content/spells/high/pierce-the-pallid-gate.yaml +5 -0
  370. package/content/spells/high/prudentially-transient-abnegation-of-life.yaml +5 -0
  371. package/content/spells/high/resounding-temporal-echo.yaml +5 -0
  372. package/content/spells/high/scorn-the-fetters-of-earth.yaml +5 -0
  373. package/content/spells/high/sigil-of-aeolian-auctoritas.yaml +5 -0
  374. package/content/spells/high/torment-of-tumefaction.yaml +5 -0
  375. package/content/spells/high/touch-of-elucidating-intangibility.yaml +5 -0
  376. package/content/spells/high/vallation-of-specified-exclusion.yaml +5 -0
  377. package/content/spells/high/velocitous-imbuement.yaml +5 -0
  378. package/content/spells/high/verdant-vallation.yaml +5 -0
  379. package/content/spells/high/visitation-of-the-clement-clime.yaml +5 -0
  380. package/content/spells/high/wardpact-invocation.yaml +5 -0
  381. package/content/spells/high/wind-of-the-final-repose.yaml +5 -0
  382. package/content/spells/necromancer/augment-mortal-vitality.yaml +5 -0
  383. package/content/spells/necromancer/boneshaper.yaml +5 -0
  384. package/content/spells/necromancer/call-of-the-tomb.yaml +5 -0
  385. package/content/spells/necromancer/command-the-dead.yaml +5 -0
  386. package/content/spells/necromancer/compel-flesh.yaml +5 -0
  387. package/content/spells/necromancer/enfeebling-wave.yaml +5 -0
  388. package/content/spells/necromancer/everlasting.yaml +5 -0
  389. package/content/spells/necromancer/festering-curse.yaml +5 -0
  390. package/content/spells/necromancer/final-death.yaml +5 -0
  391. package/content/spells/necromancer/forgetting-the-grave.yaml +5 -0
  392. package/content/spells/necromancer/merge-souls.yaml +5 -0
  393. package/content/spells/necromancer/query-the-skull.yaml +5 -0
  394. package/content/spells/necromancer/raise-corpse.yaml +5 -0
  395. package/content/spells/necromancer/raise-grave-knight.yaml +5 -0
  396. package/content/spells/necromancer/smite-the-dead.yaml +5 -0
  397. package/content/spells/necromancer/terrible-liveliness.yaml +5 -0
  398. package/content/traditions/elementalist.yaml +8 -0
  399. package/content/traditions/high-mage.yaml +8 -0
  400. package/content/traditions/invoker.yaml +9 -0
  401. package/content/traditions/necromancer.yaml +8 -0
  402. package/content/weapons/blackjack.yaml +8 -0
  403. package/content/weapons/claw-blades.yaml +10 -0
  404. package/content/weapons/club.yaml +10 -0
  405. package/content/weapons/crossbow.yaml +10 -0
  406. package/content/weapons/dagger.yaml +12 -0
  407. package/content/weapons/great-club.yaml +11 -0
  408. package/content/weapons/great-hammer.yaml +11 -0
  409. package/content/weapons/great-hurlant.yaml +11 -0
  410. package/content/weapons/great-sword.yaml +11 -0
  411. package/content/weapons/halberd.yaml +11 -0
  412. package/content/weapons/hand-axe.yaml +12 -0
  413. package/content/weapons/hand-hurlant.yaml +10 -0
  414. package/content/weapons/heavy-spear.yaml +11 -0
  415. package/content/weapons/large-bow.yaml +11 -0
  416. package/content/weapons/large-shield-bash.yaml +11 -0
  417. package/content/weapons/light-spear.yaml +12 -0
  418. package/content/weapons/long-hurlant.yaml +11 -0
  419. package/content/weapons/long-sword.yaml +9 -0
  420. package/content/weapons/mace.yaml +10 -0
  421. package/content/weapons/pike.yaml +11 -0
  422. package/content/weapons/short-sword.yaml +9 -0
  423. package/content/weapons/small-bow.yaml +10 -0
  424. package/content/weapons/small-shield-bash.yaml +9 -0
  425. package/content/weapons/staff.yaml +10 -0
  426. package/content/weapons/stiletto.yaml +10 -0
  427. package/content/weapons/throwing-blade.yaml +11 -0
  428. package/content/weapons/unarmed.yaml +9 -0
  429. package/content/weapons/war-axe.yaml +11 -0
  430. package/content/weapons/war-hammer.yaml +9 -0
  431. package/dist/i18n/en.d.ts +3 -0
  432. package/dist/i18n/en.js +2 -0
  433. package/dist/i18n/en.json +1175 -0
  434. package/dist/index.d.ts +3 -0
  435. package/dist/index.js +2 -0
  436. package/dist/release.json +35918 -0
  437. package/i18n/en/content.yaml +472 -0
  438. package/i18n/en.yaml +702 -0
  439. package/pack.yaml +12 -0
  440. package/package.json +58 -3
  441. package/rules/advancement.yaml +186 -0
  442. package/rules/attributes.yaml +30 -0
  443. package/rules/backgrounds.yaml +60 -0
  444. package/rules/classes.yaml +77 -0
  445. package/rules/combat.yaml +241 -0
  446. package/rules/creation-steps.yaml +258 -0
  447. package/rules/creation.yaml +383 -0
  448. package/rules/display.yaml +684 -0
  449. package/rules/equipment.yaml +45 -0
  450. package/rules/foci.yaml +58 -0
  451. package/rules/health.yaml +178 -0
  452. package/rules/magic.yaml +471 -0
  453. package/rules/saves.yaml +62 -0
  454. package/rules/skills.yaml +93 -0
  455. package/rules/tags.yaml +93 -0
  456. package/upgrades/0.1.0-to-0.2.0.yaml +61 -0
package/pack.yaml ADDED
@@ -0,0 +1,12 @@
1
+ id: wwn-srd
2
+ version: 0.2.0
3
+ specVersion: 0.3.0
4
+ license: CC0-1.0
5
+ notices:
6
+ not-affiliated: >-
7
+ This pack is compatible with Worlds Without Number, a game by Sine Nomine Publishing. It is
8
+ an unofficial work built from the game's System Reference Document, which Sine Nomine
9
+ Publishing dedicates to the public domain under CC0; it is not an official Sine Nomine
10
+ Publishing product, and it is not affiliated with, licensed by or endorsed by Sine Nomine
11
+ Publishing.
12
+ defaultLanguage: en
package/package.json CHANGED
@@ -1,6 +1,61 @@
1
1
  {
2
2
  "name": "@opencharacter/wwn-srd",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "Open Character Format pack for the character rules of the Worlds Without Number SRD (CC0). Unofficial.",
5
+ "keywords": [
6
+ "character-sheet",
7
+ "content-pack",
8
+ "fantasy",
9
+ "ocf",
10
+ "open-character-format",
11
+ "rpg",
12
+ "tabletop",
13
+ "ttrpg",
14
+ "worlds-without-number"
15
+ ],
16
+ "homepage": "https://opencharacterformat.org",
17
+ "bugs": {
18
+ "url": "https://github.com/pixelqueue/opencharacter/issues"
19
+ },
20
+ "license": "CC0-1.0",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/pixelqueue/opencharacter.git",
24
+ "directory": "packs/wwn/srd"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "pack.yaml",
29
+ "rules",
30
+ "content",
31
+ "i18n",
32
+ "upgrades",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "type": "module",
37
+ "sideEffects": false,
38
+ "exports": {
39
+ ".": {
40
+ "types": "./dist/index.d.ts",
41
+ "import": "./dist/index.js",
42
+ "default": "./dist/release.json"
43
+ },
44
+ "./release.json": "./dist/release.json",
45
+ "./i18n/*": {
46
+ "types": "./dist/i18n/*.d.ts",
47
+ "import": "./dist/i18n/*.js",
48
+ "default": "./dist/i18n/*.json"
49
+ }
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "devDependencies": {
55
+ "@opencharacter/engine": "0.3.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=22"
59
+ },
60
+ "scripts": {}
6
61
  }
@@ -0,0 +1,186 @@
1
+ fields:
2
+ xp.current: { type: integer, input: true, default: 0, min: 0 }
3
+ # The book's two paces: fast or slow leveling.
4
+ xp.pace: { type: enum, values: [fast, slow], input: true, default: fast }
5
+ xp.nextLevel:
6
+ type: integer
7
+ formula: >-
8
+ level >= 10 ? 0
9
+ : xp.pace == 'fast' ? [3, 6, 12, 18, 27, 39, 54, 72, 93][level - 1]
10
+ : [6, 15, 24, 36, 51, 69, 87, 105, 139][level - 1]
11
+ xp.levelUp: { type: boolean, formula: 'xp.nextLevel > 0 && xp.current >= xp.nextLevel' }
12
+
13
+ followUps:
14
+ - id: level-up
15
+ while: '!character.creating && xp.levelUp'
16
+ action: level-up
17
+
18
+ actions:
19
+ # A new level: hit dice rolled again (at least one more than before), three skill points (four
20
+ # for an Expert), a Focus at levels 2, 5, 7 and 10, the arts the tradition grants, and new
21
+ # spells. Saves and attack bonus follow the level.
22
+ - id: level-up
23
+ tags: [advancement]
24
+ available: '!character.creating && level < 10 && xp.levelUp'
25
+ params:
26
+ random: { type: boolean, default: false }
27
+ results: [advanced]
28
+ steps:
29
+ - id: before
30
+ kind: branch
31
+ cases:
32
+ - when: true
33
+ flags: { oldMax: hp.max, oldRolled: hp.rolled }
34
+ - id: gain
35
+ tags: [advancement.level]
36
+ kind: changes
37
+ changes:
38
+ - { type: adjust, field: level, by: 1 }
39
+ - { type: adjust, field: skillPoints.unspent, by: 3 }
40
+ - { type: adjust, when: class.expert > 0, field: skillPoints.expert, by: 1 }
41
+ # Each die adds the class's bonus and the Constitution modifier.
42
+ - id: hitDice
43
+ kind: roll
44
+ sheet: proposed
45
+ tags: [advancement]
46
+ parts:
47
+ # No die gives less than 1.
48
+ - dice: >-
49
+ hp.dieBonus + attributes.con.mod >= 0 ? (level)d6
50
+ : hp.dieBonus + attributes.con.mod == -1 ? (level)d6min2
51
+ : hp.dieBonus + attributes.con.mod == -2 ? (level)d6min3
52
+ : (level)d6min4
53
+ - value: level * (hp.dieBonus + attributes.con.mod)
54
+ - id: hp
55
+ kind: changes
56
+ changes:
57
+ - type: set
58
+ field: hp.rolled
59
+ value: max(steps.hitDice.total, flags.oldRolled + 1)
60
+ # A Focus gained now puts three skill points toward its bonus skill.
61
+ - id: focus
62
+ kind: action
63
+ sheet: proposed
64
+ when: level in [2, 5, 7, 10]
65
+ use: pick-focus
66
+ params:
67
+ kind: "'any'"
68
+ random: params.random
69
+ points: 3
70
+ - id: arts
71
+ kind: action
72
+ use: pick-arts
73
+ params: { random: params.random }
74
+ # New spells: two for a High Mage, one for another caster. Two partial casting traditions
75
+ # pick one of them to learn from.
76
+ - id: spellTradition
77
+ kind: choice
78
+ sheet: proposed
79
+ random: params.random
80
+ options:
81
+ values: { formula: "keysOf('spellTrad') + ['invoker']" }
82
+ where: "fieldOf('tradition.{trad}.tier', value) > 0"
83
+ recommend: options[0]
84
+ - id: newSpells
85
+ kind: choice
86
+ sheet: proposed
87
+ when: has(steps.spellTradition)
88
+ random: params.random
89
+ repeat:
90
+ max: >-
91
+ steps.spellTradition.picked == 'highmage'
92
+ || (steps.spellTradition.picked == 'invoker' && tradition.invoker.tier == 2) ? 2 : 1
93
+ min: >-
94
+ steps.spellTradition.picked == 'highmage'
95
+ || (steps.spellTradition.picked == 'invoker' && tradition.invoker.tier == 2) ? 2 : 1
96
+ options:
97
+ content:
98
+ type: spell
99
+ where: >-
100
+ item.level <= spells.maxLevel && countCopies(copy.item == item.id) == 0
101
+ && (item.list == 'high' || item.list == steps.spellTradition.picked
102
+ || (steps.spellTradition.picked == 'invoker' && invoker.education == item.list))
103
+ recommend: options[0]
104
+ changes:
105
+ - type: addItem
106
+ entry: { item: picked.id }
107
+ # Current hit points rise with the maximum (Die Hard taken now included).
108
+ - id: current
109
+ kind: changes
110
+ sheet: proposed
111
+ changes:
112
+ - type: adjust
113
+ when: hp.max > flags.oldMax
114
+ field: hp.current
115
+ by: hp.max - flags.oldMax
116
+ - id: result
117
+ kind: outcome
118
+ result: "'advanced'"
119
+
120
+ # Spend skill points: a skill's next level costs one more than that level (less any credit),
121
+ # needing character level 3, 6 and 9 for levels 2, 3 and 4; an attribute boost costs one
122
+ # more than the boosts before it, five at most, needing levels 2, 2, 3, 6 and 9. An Expert's
123
+ # extra points go to non-combat skills and attributes only, and are spent first there.
124
+ - id: improve
125
+ tags: [advancement]
126
+ available: '!character.creating && skillPoints.unspent + skillPoints.expert > 0'
127
+ results: [improved]
128
+ steps:
129
+ - id: pick
130
+ kind: choice
131
+ # A combat skill takes no Expert points.
132
+ options:
133
+ values: { formula: "keysOf('skill') + keysOf('attr')" }
134
+ where: >-
135
+ value in keysOf('attr')
136
+ ? attributes.boosts < 5 && fieldOf('attributes.{attr}.score', value) < 18
137
+ && level >= [1, 1, 3, 6, 9][attributes.boosts]
138
+ && attributes.boosts + 1 <= skillPoints.unspent + skillPoints.expert
139
+ : fieldOf('skills.{skill}', value) < 4
140
+ && level >= [1, 1, 3, 6, 9][fieldOf('skills.{skill}', value) + 1]
141
+ && fieldOf('skills.{skill}', value) + 2 - fieldOf('skillCredit.{skill}', value)
142
+ <= skillPoints.unspent
143
+ + (value in ['punch', 'shoot', 'stab'] ? 0 : skillPoints.expert)
144
+ recommend: options[0]
145
+ - id: cost
146
+ kind: branch
147
+ cases:
148
+ - when: "steps.pick.picked in keysOf('attr')"
149
+ flags:
150
+ attribute: true
151
+ cost: attributes.boosts + 1
152
+ expert: min(skillPoints.expert, attributes.boosts + 1)
153
+ - when: true
154
+ flags:
155
+ attribute: false
156
+ cost: >-
157
+ fieldOf('skills.{skill}', steps.pick.picked) + 2
158
+ - fieldOf('skillCredit.{skill}', steps.pick.picked)
159
+ expert: >-
160
+ steps.pick.picked in ['punch', 'shoot', 'stab'] ? 0
161
+ : min(skillPoints.expert, fieldOf('skills.{skill}', steps.pick.picked) + 2
162
+ - fieldOf('skillCredit.{skill}', steps.pick.picked))
163
+ - id: pay
164
+ kind: changes
165
+ changes:
166
+ - type: adjust
167
+ when: flags.attribute
168
+ field: { formula: "'attributes.' + steps.pick.picked + '.score'" }
169
+ by: 1
170
+ - { type: adjust, when: flags.attribute, field: attributes.boosts, by: 1 }
171
+ - type: adjust
172
+ when: '!flags.attribute'
173
+ field: { formula: "fieldId('skills.{skill}', steps.pick.picked)" }
174
+ by: 1
175
+ - type: set
176
+ when: '!flags.attribute'
177
+ field: { formula: "fieldId('skillCredit.{skill}', steps.pick.picked)" }
178
+ value: 0
179
+ - { type: adjust, when: flags.expert > 0, field: skillPoints.expert, by: -flags.expert }
180
+ - type: adjust
181
+ when: flags.cost - flags.expert > 0
182
+ field: skillPoints.unspent
183
+ by: -(flags.cost - flags.expert)
184
+ - id: result
185
+ kind: outcome
186
+ result: "'improved'"
@@ -0,0 +1,30 @@
1
+ families:
2
+ attr: [str, dex, con, int, wis, cha]
3
+
4
+ fields:
5
+ 'attributes.{attr}.score':
6
+ type: integer
7
+ input: true
8
+ default: 10
9
+ min: 3
10
+ max: 18
11
+ tags: [attribute, 'attr.{attr}']
12
+ # Bonuses and penalties to the modifier, not the score. They keep it within -2 and +2, or +3
13
+ # where a Focus says so (Developed Attribute, Xenoblooded).
14
+ 'attributes.{attr}.modBonus': { type: integer, formula: 0, tags: [mod-bonus, 'attr.{attr}'] }
15
+ 'attributes.{attr}.modCap': { type: integer, formula: 2, tags: [mod-cap, 'attr.{attr}'] }
16
+ 'attributes.{attr}.mod':
17
+ type: integer
18
+ tags: [attribute-mod]
19
+ formula: >-
20
+ max(-2, min(attributes.{attr}.modCap, (attributes.{attr}.score <= 3 ? -2
21
+ : attributes.{attr}.score <= 7 ? -1 : attributes.{attr}.score <= 13 ? 0
22
+ : attributes.{attr}.score <= 17 ? 1 : 2) + attributes.{attr}.modBonus))
23
+
24
+ # Attribute boosts bought with skill points as the character advances (five at most).
25
+ attributes.boosts: { type: integer, input: true, default: 0, min: 0, max: 5 }
26
+ attributes.bestMod:
27
+ type: integer
28
+ formula: >-
29
+ max(attributes.str.mod, attributes.dex.mod, attributes.con.mod, attributes.int.mod,
30
+ attributes.wis.mod, attributes.cha.mod)
@@ -0,0 +1,60 @@
1
+ families:
2
+ backgroundEntry:
3
+ [
4
+ freeSkill,
5
+ growth1,
6
+ growth2,
7
+ growth3,
8
+ growth4,
9
+ growth5,
10
+ growth6,
11
+ learning1,
12
+ learning2,
13
+ learning3,
14
+ learning4,
15
+ learning5,
16
+ learning6,
17
+ learning7,
18
+ learning8,
19
+ ]
20
+
21
+ contentTypes:
22
+ # A background's free skill and its Growth (d6) and Learning (d8) tables. Each entry is a
23
+ # skill, `any` (any skill), `combat` (Stab, Shoot or Punch), or attribute points: `any-stat`
24
+ # (+1 to any), `physical` or `mental` (+2 to one or +1 to two of them).
25
+ background:
26
+ copies: { max: 1 }
27
+ fields:
28
+ '{backgroundEntry}':
29
+ type: enum
30
+ open: true
31
+ values:
32
+ [
33
+ administer,
34
+ connect,
35
+ convince,
36
+ craft,
37
+ exert,
38
+ heal,
39
+ know,
40
+ lead,
41
+ magic,
42
+ notice,
43
+ perform,
44
+ pray,
45
+ punch,
46
+ ride,
47
+ sail,
48
+ shoot,
49
+ sneak,
50
+ stab,
51
+ survive,
52
+ trade,
53
+ work,
54
+ any,
55
+ combat,
56
+ any-stat,
57
+ physical,
58
+ mental,
59
+ ]
60
+ required: true
@@ -0,0 +1,77 @@
1
+ fields:
2
+ level: { type: integer, input: true, default: 1, min: 1, max: 10 }
3
+
4
+ # Each class's perks: 2 for the full class, 1 for a partial one. A Warrior's or an Expert's
5
+ # brings a Focus pick, an Expert's an extra skill point each level. A Mage's tradition counts
6
+ # in `tradition.<key>.tier` (magic.yaml); `class.mage` counts the Mage classes held.
7
+ class.warrior: { type: integer, formula: 0 }
8
+ class.expert: { type: integer, formula: 0 }
9
+ class.mage: { type: integer, formula: 0 }
10
+
11
+ # The class mix's hit dice and attack bonus. Some partial classes count as Warriors or Experts
12
+ # here without their perks (the Bard, the Wise, the Mageslayer); the Duelist's fragility
13
+ # takes the Warrior's +2 away.
14
+ chassis.attackFull: { type: integer, formula: 0 }
15
+ chassis.attackWarrior: { type: integer, formula: 0 }
16
+ chassis.attackExpert: { type: integer, formula: 0 }
17
+ chassis.hitsWarrior: { type: integer, formula: 0 }
18
+ chassis.hitsExpert: { type: integer, formula: 0 }
19
+ chassis.fragile: { type: integer, formula: 0 }
20
+
21
+ # Each hit die is 1d6 plus this: +2 with a Warrior, +0 with an Expert, -1 otherwise.
22
+ # Martial Style keeps it at least +0.
23
+ hp.dieBonus:
24
+ type: integer
25
+ formula: >-
26
+ chassis.hitsWarrior > 0 && chassis.fragile == 0 ? 2
27
+ : chassis.hitsWarrior > 0 || chassis.hitsExpert > 0 ? 0
28
+ : -1
29
+
30
+ attack.base:
31
+ type: integer
32
+ formula: >-
33
+ chassis.attackFull > 0 ? level
34
+ : chassis.attackWarrior > 0 ? [1, 2, 2, 3, 4, 5, 5, 6, 6, 7][level - 1]
35
+ : chassis.attackExpert > 0 ? floor(level / 2)
36
+ : floor(level / 5)
37
+
38
+ # Focus levels: one of any kind, one combat Focus with a Warrior, one non-combat Focus with an
39
+ # Expert, and one more at levels 2, 5, 7 and 10.
40
+ foci.allowed:
41
+ type: integer
42
+ formula: >-
43
+ 1 + (class.warrior > 0 ? 1 : 0) + (class.expert > 0 ? 1 : 0)
44
+ + (level >= 2 ? 1 : 0) + (level >= 5 ? 1 : 0) + (level >= 7 ? 1 : 0)
45
+ + (level >= 10 ? 1 : 0)
46
+ foci.taken:
47
+ type: integer
48
+ formula: "sumCopies(copy.state.level, copy.type == 'focus')"
49
+
50
+ # A Beastmaster's companion's natural hit dice (Feral Toughness adds them to hit points).
51
+ companion.hitDice: { type: integer, input: true, default: 0, min: 0 }
52
+
53
+ # Killing Blow: half the level, rounded up, on every damage roll and Shock.
54
+ damage.killingBlow: { type: integer, formula: 0 }
55
+
56
+ contentTypes:
57
+ class:
58
+ copies: { max: 1 }
59
+ # An Adventurer's two halves.
60
+ partial:
61
+ grantOnly: true
62
+ copies: { max: 0 }
63
+
64
+ constraints:
65
+ - id: creation-class
66
+ check: "!character.creating || countCopies(copy.type == 'class') > 0"
67
+ - id: foci-allowed
68
+ check: foci.taken <= foci.allowed
69
+ data: { allowed: foci.allowed }
70
+ # No Mage class pairs with the Mageslayer.
71
+ - id: mageslayer-pairing
72
+ check: tradition.mageslayer.tier == 0 || class.mage == 0
73
+ # A partial Invoker doesn't pair with another partial spellcasting class.
74
+ - id: invoker-pairing
75
+ check: >-
76
+ tradition.invoker.tier != 1
77
+ || tradition.highmage.tier + tradition.elementalist.tier + tradition.necromancer.tier == 0
@@ -0,0 +1,241 @@
1
+ fields:
2
+ # Martial Style: Punch attacks hit no worse than an Expert of the same level.
3
+ attack.punchBase: { type: integer, formula: attack.base }
4
+
5
+ # Body armor worn (the best of it) and a shield carried.
6
+ armor.wornAc:
7
+ type: integer
8
+ formula: "maxCopies(copy.fields.ac, copy.type == 'armor' && copy.equipped && copy.fields.category != 'shield')"
9
+ # The Encumbrance of the body armor worn, -1 with none.
10
+ armor.wornEnc:
11
+ type: integer
12
+ formula: >-
13
+ countCopies(copy.type == 'armor' && copy.equipped && copy.fields.category != 'shield') > 0
14
+ ? maxCopies(copy.fields.enc, copy.type == 'armor' && copy.equipped
15
+ && copy.fields.category != 'shield')
16
+ : -1
17
+ armor.wornHeavy:
18
+ type: boolean
19
+ formula: >-
20
+ countCopies(copy.type == 'armor' && copy.equipped
21
+ && copy.fields.category in ['medium', 'heavy']) > 0
22
+ armor.shield:
23
+ type: boolean
24
+ formula: "countCopies(copy.type == 'armor' && copy.equipped && copy.fields.category == 'shield') > 0"
25
+ armor.shieldAc:
26
+ type: integer
27
+ formula: "maxCopies(copy.fields.ac, copy.type == 'armor' && copy.equipped && copy.fields.category == 'shield')"
28
+
29
+ # Natural defenses that don't stack with armor (Impervious Defense, Unarmored Defense, Cold
30
+ # Flesh) raise this.
31
+ ac.innate: { type: integer, formula: 10 }
32
+ ac.base: { type: integer, formula: 'max(10, armor.wornAc, ac.innate)' }
33
+ # A shield sets AC to its own, or adds 1 to armor as good or better.
34
+ ac.withShield:
35
+ type: integer
36
+ formula: '!armor.shield ? ac.base : ac.base >= armor.shieldAc ? ac.base + 1 : armor.shieldAc'
37
+ # Bonuses that can't raise AC above 18 (Pavis of Elements).
38
+ ac.cappedBonus: { type: integer, formula: 0 }
39
+ ac.value:
40
+ type: integer
41
+ formula: >-
42
+ ac.withShield + attributes.dex.mod
43
+ + max(0, min(ac.cappedBonus, 18 - ac.withShield - attributes.dex.mod))
44
+
45
+ # Shock bonuses beyond the attribute modifier and Killing Blow (Shocking Assault).
46
+ shock.bonus: { type: integer, formula: 0 }
47
+ # Melee weapon Shock, and unarmed Shock, that treats every target as AC 10.
48
+ shock.ignoresAc: { type: boolean, formula: false }
49
+ shock.unarmedIgnoresAc: { type: boolean, formula: false }
50
+
51
+ # A Duelist's favored weapons and their hit bonus: the Duelist's table, or the level with a
52
+ # partial Warrior.
53
+ duelist.favored: { type: set, of: weapon }
54
+ attack.favoredBase:
55
+ type: integer
56
+ formula: >-
57
+ tradition.duelist.tier == 0 ? attack.base
58
+ : max(attack.base, class.warrior > 0 ? level : [1, 1, 2, 2, 3, 3, 4, 4, 5, 5][level - 1])
59
+
60
+ # Unarmed attacks: the die and Shock that Unarmed Combatant or Unarmed Might give.
61
+ unarmed.die: { type: dice, formula: 1d2 }
62
+ unarmed.shock: { type: integer, formula: 0 }
63
+ unarmed.shockAc: { type: integer, formula: 15 }
64
+
65
+ contentTypes:
66
+ weapon:
67
+ carried: true
68
+ equippable: true
69
+ fields:
70
+ damage: { type: dice, required: true }
71
+ shock: { type: integer, default: 0, min: 0 }
72
+ shockAc: { type: integer, default: 0, min: 0 }
73
+ attribute: { type: enum, values: [str, dex, str-dex], required: true }
74
+ skill: { type: enum, values: [stab, shoot, punch], required: true, open: true }
75
+ rangeShort: { type: integer, min: 0 }
76
+ rangeLong: { type: integer, min: 0 }
77
+ cost: { type: integer, min: 0 }
78
+ costUnit: { type: enum, values: [cp, sp], default: sp }
79
+ enc: { type: integer, default: 1, min: 0 }
80
+ bundle: { type: integer, default: 1, min: 1 }
81
+ wornFree: { type: boolean, default: false }
82
+ actions:
83
+ - use: attack
84
+
85
+ armor:
86
+ carried: true
87
+ equippable: true
88
+ fields:
89
+ ac: { type: integer, required: true, min: 10 }
90
+ category: { type: enum, values: [light, medium, heavy, shield], required: true }
91
+ cost: { type: integer, min: 0 }
92
+ costUnit: { type: enum, values: [cp, sp], default: sp }
93
+ enc: { type: integer, default: 1, min: 0 }
94
+ bundle: { type: integer, default: 1, min: 1 }
95
+ wornFree: { type: boolean, default: false }
96
+ effects:
97
+ # Medium armor's Encumbrance is a penalty to Sneak; heavy armor's to Sneak and Exert.
98
+ - id: sneak-penalty
99
+ target: { rolls: [skill.sneak] }
100
+ op: add
101
+ value: -item.enc
102
+ when: "self.equipped && item.category in ['medium', 'heavy'] && item.enc > 0"
103
+ - id: exert-penalty
104
+ target: { rolls: [skill.exert] }
105
+ op: add
106
+ value: -item.enc
107
+ when: "self.equipped && item.category == 'heavy' && item.enc > 0"
108
+
109
+ standardCopies:
110
+ - { type: weapon, where: "'unarmed' in item.tags" }
111
+
112
+ resultBands:
113
+ attack:
114
+ - { id: hit, when: 'roll.kept[0] == 20' }
115
+ - { id: miss, when: 'roll.kept[0] == 1' }
116
+ - { id: rolled, when: flags.ac < 0 }
117
+ - { id: hit, when: roll.total >= flags.ac, success: true }
118
+ - { id: miss, when: true }
119
+
120
+ actions:
121
+ - id: initiative
122
+ tags: [combat]
123
+ results: [rolled]
124
+ steps:
125
+ - id: roll
126
+ kind: roll
127
+ tags: [initiative]
128
+ parts:
129
+ - dice: 1d8
130
+ - field: "'attributes.dex.mod'"
131
+ - id: result
132
+ kind: outcome
133
+ result: "'rolled'"
134
+ data:
135
+ total: steps.roll.total
136
+
137
+ # A hit roll of 1d20 plus attack bonus, skill (-2 without it) and the weapon's attribute; on a
138
+ # hit, damage; on a melee miss, Shock against a target whose AC is no better than the weapon's.
139
+ - id: attack
140
+ tags: [attack]
141
+ available: self.equipped || 'unarmed' in item.tags
142
+ params:
143
+ targetAc: { type: integer, optional: true }
144
+ thrown: { type: boolean, default: false }
145
+ results: [hit, miss]
146
+ steps:
147
+ - id: setup
148
+ kind: branch
149
+ cases:
150
+ - when: true
151
+ flags:
152
+ mode: >-
153
+ params.thrown ? 'thrown' : item.skill == 'shoot' ? 'ranged'
154
+ : item.skill == 'punch' ? 'unarmed' : 'melee'
155
+ skill: >-
156
+ params.thrown ? max(skills.stab, skills.shoot)
157
+ : fieldOf('skills.{skill}', item.skill)
158
+ attribute: >-
159
+ item.attribute == 'str-dex'
160
+ ? (attributes.str.mod >= attributes.dex.mod ? 'str' : 'dex') : item.attribute
161
+ ac: 'has(params.targetAc) ? params.targetAc : -1'
162
+ dice: "'unarmed' in item.tags ? unarmed.die : item.damage"
163
+ shock: "'unarmed' in item.tags ? unarmed.shock : item.shock"
164
+ shockAc: "'unarmed' in item.tags ? unarmed.shockAc : item.shockAc"
165
+ - id: hitRoll
166
+ kind: roll
167
+ tags: [attack, { formula: "'attack.' + flags.mode" }]
168
+ bands: attack
169
+ parts:
170
+ - dice: 1d20
171
+ - field: >-
172
+ item.skill == 'punch' ? 'attack.punchBase'
173
+ : !params.thrown && item.id in duelist.favored ? 'attack.favoredBase'
174
+ : 'attack.base'
175
+ - value: 'flags.skill >= 0 ? flags.skill : -2'
176
+ - field: "'attributes.' + flags.attribute + '.mod'"
177
+ - id: confirm
178
+ kind: choice
179
+ when: steps.hitRoll.band == 'rolled'
180
+ options: [{ id: hit }, { id: miss }]
181
+ - id: outcome
182
+ kind: branch
183
+ cases:
184
+ - when: true
185
+ flags:
186
+ hit: >-
187
+ steps.hitRoll.band == 'hit'
188
+ || (has(steps.confirm) && steps.confirm.picked == 'hit')
189
+ # What Shock would do; a hit never does less. Thrown and ranged attacks do no Shock.
190
+ - id: shock
191
+ kind: roll
192
+ when: "flags.shock > 0 && flags.mode in ['melee', 'unarmed']"
193
+ tags: [shock, { formula: "'shock.' + flags.mode" }]
194
+ parts:
195
+ - value: flags.shock
196
+ - field: "'attributes.' + flags.attribute + '.mod'"
197
+ - field: "'damage.killingBlow'"
198
+ - field: "'shock.bonus'"
199
+ - id: shockApplies
200
+ kind: branch
201
+ cases:
202
+ - when: true
203
+ flags:
204
+ shockDamage: >-
205
+ has(steps.shock) && flags.ac >= 0
206
+ && (flags.ac <= flags.shockAc
207
+ || (flags.mode == 'melee' && shock.ignoresAc)
208
+ || (flags.mode == 'unarmed' && shock.unarmedIgnoresAc))
209
+ ? max(0, steps.shock.total) : 0
210
+ - id: damage
211
+ kind: roll
212
+ when: flags.hit
213
+ tags: [damage, { formula: "'damage.' + flags.mode" }]
214
+ parts:
215
+ - dice: flags.dice
216
+ tags: [weapon-die]
217
+ - field: "'attributes.' + flags.attribute + '.mod'"
218
+ - value: max(0, skills.punch)
219
+ when: flags.mode == 'unarmed'
220
+ - field: "'damage.killingBlow'"
221
+ - id: totals
222
+ kind: branch
223
+ cases:
224
+ - when: true
225
+ flags:
226
+ dealt: >-
227
+ flags.hit ? max(has(steps.damage) ? steps.damage.total : 0,
228
+ flags.ac < 0 && has(steps.shock) ? steps.shock.total : flags.shockDamage, 0)
229
+ : flags.shockDamage
230
+ - id: deal
231
+ kind: changes
232
+ when: flags.dealt > 0
233
+ to: target
234
+ changes:
235
+ - { type: adjust, field: hp.current, by: -flags.dealt, tags: [damage] }
236
+ - id: result
237
+ kind: outcome
238
+ result: "flags.hit ? 'hit' : 'miss'"
239
+ data:
240
+ total: steps.hitRoll.total
241
+ damage: flags.dealt