@opencharacter/wwn-srd 0.0.0-stage → 0.1.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 (451) hide show
  1. package/LICENSE +144 -0
  2. package/README.md +109 -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 +20 -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 +10 -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 +17 -0
  302. package/content/partials/bard.yaml +8 -0
  303. package/content/partials/beastmaster.yaml +8 -0
  304. package/content/partials/blood-priest.yaml +6 -0
  305. package/content/partials/duelist.yaml +9 -0
  306. package/content/partials/expert.yaml +6 -0
  307. package/content/partials/healer.yaml +8 -0
  308. package/content/partials/mage.yaml +33 -0
  309. package/content/partials/mageslayer.yaml +20 -0
  310. package/content/partials/skinshifter.yaml +8 -0
  311. package/content/partials/thought-noble.yaml +8 -0
  312. package/content/partials/vowed.yaml +40 -0
  313. package/content/partials/warrior.yaml +6 -0
  314. package/content/partials/wise.yaml +44 -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/weapons/blackjack.yaml +8 -0
  399. package/content/weapons/claw-blades.yaml +10 -0
  400. package/content/weapons/club.yaml +10 -0
  401. package/content/weapons/crossbow.yaml +10 -0
  402. package/content/weapons/dagger.yaml +12 -0
  403. package/content/weapons/great-club.yaml +11 -0
  404. package/content/weapons/great-hammer.yaml +11 -0
  405. package/content/weapons/great-hurlant.yaml +11 -0
  406. package/content/weapons/great-sword.yaml +11 -0
  407. package/content/weapons/halberd.yaml +11 -0
  408. package/content/weapons/hand-axe.yaml +12 -0
  409. package/content/weapons/hand-hurlant.yaml +10 -0
  410. package/content/weapons/heavy-spear.yaml +11 -0
  411. package/content/weapons/large-bow.yaml +11 -0
  412. package/content/weapons/large-shield-bash.yaml +11 -0
  413. package/content/weapons/light-spear.yaml +12 -0
  414. package/content/weapons/long-hurlant.yaml +11 -0
  415. package/content/weapons/long-sword.yaml +9 -0
  416. package/content/weapons/mace.yaml +10 -0
  417. package/content/weapons/pike.yaml +11 -0
  418. package/content/weapons/short-sword.yaml +9 -0
  419. package/content/weapons/small-bow.yaml +10 -0
  420. package/content/weapons/small-shield-bash.yaml +9 -0
  421. package/content/weapons/staff.yaml +10 -0
  422. package/content/weapons/stiletto.yaml +10 -0
  423. package/content/weapons/throwing-blade.yaml +11 -0
  424. package/content/weapons/unarmed.yaml +9 -0
  425. package/content/weapons/war-axe.yaml +11 -0
  426. package/content/weapons/war-hammer.yaml +9 -0
  427. package/dist/i18n/en.d.ts +3 -0
  428. package/dist/i18n/en.js +2 -0
  429. package/dist/i18n/en.json +1171 -0
  430. package/dist/index.d.ts +3 -0
  431. package/dist/index.js +2 -0
  432. package/dist/release.json +35216 -0
  433. package/i18n/en/content.yaml +474 -0
  434. package/i18n/en.yaml +696 -0
  435. package/pack.yaml +12 -0
  436. package/package.json +58 -3
  437. package/rules/advancement.yaml +188 -0
  438. package/rules/attributes.yaml +30 -0
  439. package/rules/backgrounds.yaml +59 -0
  440. package/rules/classes.yaml +76 -0
  441. package/rules/combat.yaml +241 -0
  442. package/rules/creation-steps.yaml +258 -0
  443. package/rules/creation.yaml +448 -0
  444. package/rules/display.yaml +597 -0
  445. package/rules/equipment.yaml +45 -0
  446. package/rules/foci.yaml +57 -0
  447. package/rules/health.yaml +176 -0
  448. package/rules/magic.yaml +484 -0
  449. package/rules/saves.yaml +62 -0
  450. package/rules/skills.yaml +93 -0
  451. package/rules/tags.yaml +86 -0
package/pack.yaml ADDED
@@ -0,0 +1,12 @@
1
+ id: wwn-srd
2
+ version: 0.1.0
3
+ specVersion: 0.2.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.1.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.2.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=22"
59
+ },
60
+ "scripts": {}
6
61
  }
@@ -0,0 +1,188 @@
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'
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
+ kind: changes
36
+ changes:
37
+ - { type: adjust, field: level, by: 1 }
38
+ - { type: adjust, field: skillPoints.unspent, by: 3 }
39
+ - { type: adjust, when: class.expert > 0, field: skillPoints.expert, by: 1 }
40
+ # Each die adds the class's bonus and the Constitution modifier.
41
+ - id: hitDice
42
+ kind: roll
43
+ sheet: proposed
44
+ tags: [advancement]
45
+ parts:
46
+ # No die gives less than 1.
47
+ - dice: >-
48
+ hp.dieBonus + attributes.con.mod >= 0 ? (level)d6
49
+ : hp.dieBonus + attributes.con.mod == -1 ? (level)d6min2
50
+ : hp.dieBonus + attributes.con.mod == -2 ? (level)d6min3
51
+ : (level)d6min4
52
+ - value: level * (hp.dieBonus + attributes.con.mod)
53
+ - id: hp
54
+ kind: changes
55
+ changes:
56
+ - type: set
57
+ field: hp.rolled
58
+ value: max(steps.hitDice.total, flags.oldRolled + 1)
59
+ # A Focus gained now puts three skill points toward its bonus skill.
60
+ - id: focus
61
+ kind: action
62
+ sheet: proposed
63
+ when: level in [2, 5, 7, 10]
64
+ use: pick-focus
65
+ params:
66
+ kind: "'any'"
67
+ random: params.random
68
+ points: 3
69
+ - id: arts
70
+ kind: action
71
+ use: pick-arts
72
+ params: { random: params.random }
73
+ # New spells: two for a High Mage, one for another caster. Two partial casting traditions
74
+ # pick one of them to learn from.
75
+ - id: spellTradition
76
+ kind: choice
77
+ sheet: proposed
78
+ random: params.random
79
+ options:
80
+ values: [highmage, elementalist, necromancer, invoker]
81
+ where: "fieldOf('tradition.{trad}.tier', value) > 0"
82
+ recommend: options[0]
83
+ - id: newSpells
84
+ kind: choice
85
+ sheet: proposed
86
+ when: has(steps.spellTradition)
87
+ random: params.random
88
+ repeat:
89
+ max: >-
90
+ steps.spellTradition.picked == 'highmage'
91
+ || (steps.spellTradition.picked == 'invoker' && tradition.invoker.tier == 2) ? 2 : 1
92
+ min: >-
93
+ steps.spellTradition.picked == 'highmage'
94
+ || (steps.spellTradition.picked == 'invoker' && tradition.invoker.tier == 2) ? 2 : 1
95
+ options:
96
+ content:
97
+ type: spell
98
+ where: >-
99
+ item.level <= spells.maxLevel && countCopies(copy.item == item.id) == 0
100
+ && (item.list == 'high'
101
+ || (item.list == 'elementalist' && (steps.spellTradition.picked == 'elementalist'
102
+ || (steps.spellTradition.picked == 'invoker' && invoker.education == 'elementalist')))
103
+ || (item.list == 'necromancer' && (steps.spellTradition.picked == 'necromancer'
104
+ || (steps.spellTradition.picked == 'invoker' && invoker.education == 'necromancer'))))
105
+ recommend: options[0]
106
+ changes:
107
+ - type: addItem
108
+ entry: { item: picked.id }
109
+ # Current hit points rise with the maximum (Die Hard taken now included).
110
+ - id: current
111
+ kind: changes
112
+ sheet: proposed
113
+ changes:
114
+ - type: adjust
115
+ when: hp.max > flags.oldMax
116
+ field: hp.current
117
+ by: hp.max - flags.oldMax
118
+ - id: result
119
+ kind: outcome
120
+ result: "'advanced'"
121
+
122
+ # Spend skill points: a skill's next level costs one more than that level (less any credit),
123
+ # needing character level 3, 6 and 9 for levels 2, 3 and 4; an attribute boost costs one
124
+ # more than the boosts before it, five at most, needing levels 2, 2, 3, 6 and 9. An Expert's
125
+ # extra points go to non-combat skills and attributes only, and are spent first there.
126
+ - id: improve
127
+ tags: [advancement]
128
+ available: '!character.creating && skillPoints.unspent + skillPoints.expert > 0'
129
+ results: [improved]
130
+ steps:
131
+ - id: pick
132
+ kind: choice
133
+ # A combat skill takes no Expert points.
134
+ options:
135
+ values: { formula: "keysOf('skill') + keysOf('attr')" }
136
+ where: >-
137
+ value in keysOf('attr')
138
+ ? attributes.boosts < 5 && fieldOf('attributes.{attr}.score', value) < 18
139
+ && level >= [1, 1, 3, 6, 9][attributes.boosts]
140
+ && attributes.boosts + 1 <= skillPoints.unspent + skillPoints.expert
141
+ : fieldOf('skills.{skill}', value) < 4
142
+ && level >= [1, 1, 3, 6, 9][fieldOf('skills.{skill}', value) + 1]
143
+ && fieldOf('skills.{skill}', value) + 2 - fieldOf('skillCredit.{skill}', value)
144
+ <= skillPoints.unspent
145
+ + (value in ['punch', 'shoot', 'stab'] ? 0 : skillPoints.expert)
146
+ recommend: options[0]
147
+ - id: cost
148
+ kind: branch
149
+ cases:
150
+ - when: "steps.pick.picked in keysOf('attr')"
151
+ flags:
152
+ attribute: true
153
+ cost: attributes.boosts + 1
154
+ expert: min(skillPoints.expert, attributes.boosts + 1)
155
+ - when: true
156
+ flags:
157
+ attribute: false
158
+ cost: >-
159
+ fieldOf('skills.{skill}', steps.pick.picked) + 2
160
+ - fieldOf('skillCredit.{skill}', steps.pick.picked)
161
+ expert: >-
162
+ steps.pick.picked in ['punch', 'shoot', 'stab'] ? 0
163
+ : min(skillPoints.expert, fieldOf('skills.{skill}', steps.pick.picked) + 2
164
+ - fieldOf('skillCredit.{skill}', steps.pick.picked))
165
+ - id: pay
166
+ kind: changes
167
+ changes:
168
+ - type: adjust
169
+ when: flags.attribute
170
+ field: { formula: "'attributes.' + steps.pick.picked + '.score'" }
171
+ by: 1
172
+ - { type: adjust, when: flags.attribute, field: attributes.boosts, by: 1 }
173
+ - type: adjust
174
+ when: '!flags.attribute'
175
+ field: { formula: "'skills.' + steps.pick.picked" }
176
+ by: 1
177
+ - type: set
178
+ when: '!flags.attribute'
179
+ field: { formula: "'skillCredit.' + steps.pick.picked" }
180
+ value: 0
181
+ - { type: adjust, when: flags.expert > 0, field: skillPoints.expert, by: -flags.expert }
182
+ - type: adjust
183
+ when: flags.cost - flags.expert > 0
184
+ field: skillPoints.unspent
185
+ by: -(flags.cost - flags.expert)
186
+ - id: result
187
+ kind: outcome
188
+ 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,59 @@
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
+ values:
31
+ [
32
+ administer,
33
+ connect,
34
+ convince,
35
+ craft,
36
+ exert,
37
+ heal,
38
+ know,
39
+ lead,
40
+ magic,
41
+ notice,
42
+ perform,
43
+ pray,
44
+ punch,
45
+ ride,
46
+ sail,
47
+ shoot,
48
+ sneak,
49
+ stab,
50
+ survive,
51
+ trade,
52
+ work,
53
+ any,
54
+ combat,
55
+ any-stat,
56
+ physical,
57
+ mental,
58
+ ]
59
+ required: true
@@ -0,0 +1,76 @@
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
+ copies: { max: 0 }
62
+
63
+ constraints:
64
+ - id: creation-class
65
+ check: "!character.creating || countCopies(copy.type == 'class') > 0"
66
+ - id: foci-allowed
67
+ check: foci.taken <= foci.allowed
68
+ data: { allowed: foci.allowed }
69
+ # No Mage class pairs with the Mageslayer.
70
+ - id: mageslayer-pairing
71
+ check: tradition.mageslayer.tier == 0 || class.mage == 0
72
+ # A partial Invoker doesn't pair with another partial spellcasting class.
73
+ - id: invoker-pairing
74
+ check: >-
75
+ tradition.invoker.tier != 1
76
+ || 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 }
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 }
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