@opencharacter/swn-revised 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 (302) hide show
  1. package/LICENSE +147 -0
  2. package/README.md +128 -2
  3. package/content/armor/armored-undersuit.yaml +8 -0
  4. package/content/armor/armored-vacc-suit.yaml +8 -0
  5. package/content/armor/assault-suit.yaml +8 -0
  6. package/content/armor/combat-field-uniform.yaml +8 -0
  7. package/content/armor/deflector-array.yaml +8 -0
  8. package/content/armor/field-emitter-panoply.yaml +9 -0
  9. package/content/armor/force-pavis.yaml +9 -0
  10. package/content/armor/heavy-primitive-armor.yaml +8 -0
  11. package/content/armor/icarus-harness.yaml +8 -0
  12. package/content/armor/light-primitive-armor.yaml +8 -0
  13. package/content/armor/medium-primitive-armor.yaml +8 -0
  14. package/content/armor/secure-clothing.yaml +8 -0
  15. package/content/armor/security-armor.yaml +8 -0
  16. package/content/armor/shield.yaml +9 -0
  17. package/content/armor/storm-armor.yaml +9 -0
  18. package/content/armor/vestimentum.yaml +8 -0
  19. package/content/armor/warpaint.yaml +8 -0
  20. package/content/armor/woven-body-armor.yaml +8 -0
  21. package/content/backgrounds/barbarian.yaml +20 -0
  22. package/content/backgrounds/clergy.yaml +20 -0
  23. package/content/backgrounds/courtesan.yaml +20 -0
  24. package/content/backgrounds/criminal.yaml +20 -0
  25. package/content/backgrounds/dilettante.yaml +20 -0
  26. package/content/backgrounds/entertainer.yaml +20 -0
  27. package/content/backgrounds/merchant.yaml +20 -0
  28. package/content/backgrounds/noble.yaml +20 -0
  29. package/content/backgrounds/official.yaml +20 -0
  30. package/content/backgrounds/peasant.yaml +20 -0
  31. package/content/backgrounds/physician.yaml +20 -0
  32. package/content/backgrounds/pilot.yaml +20 -0
  33. package/content/backgrounds/politician.yaml +20 -0
  34. package/content/backgrounds/scholar.yaml +20 -0
  35. package/content/backgrounds/soldier.yaml +20 -0
  36. package/content/backgrounds/spacer.yaml +20 -0
  37. package/content/backgrounds/technician.yaml +20 -0
  38. package/content/backgrounds/thug.yaml +20 -0
  39. package/content/backgrounds/vagabond.yaml +20 -0
  40. package/content/backgrounds/worker.yaml +20 -0
  41. package/content/classes/adventurer.yaml +7 -0
  42. package/content/classes/expert.yaml +14 -0
  43. package/content/classes/psychic.yaml +11 -0
  44. package/content/classes/warrior.yaml +27 -0
  45. package/content/cyberware/adrenal-suppression-pump.yaml +17 -0
  46. package/content/cyberware/bioadaptation-augments.yaml +6 -0
  47. package/content/cyberware/body-arsenal-array.yaml +6 -0
  48. package/content/cyberware/body-sculpting.yaml +6 -0
  49. package/content/cyberware/dermal-armor.yaml +8 -0
  50. package/content/cyberware/drone-control-link.yaml +6 -0
  51. package/content/cyberware/eelskin-capacitor-mesh.yaml +7 -0
  52. package/content/cyberware/gecko-anchors.yaml +6 -0
  53. package/content/cyberware/ghost-talker-transceiver.yaml +6 -0
  54. package/content/cyberware/holdout-cavity.yaml +6 -0
  55. package/content/cyberware/holoskin-emitters.yaml +6 -0
  56. package/content/cyberware/identity-submersion-trigger.yaml +6 -0
  57. package/content/cyberware/immunofiltration-system.yaml +6 -0
  58. package/content/cyberware/induced-coma-trigger.yaml +6 -0
  59. package/content/cyberware/neurointruder-alert.yaml +11 -0
  60. package/content/cyberware/panspectral-optics.yaml +6 -0
  61. package/content/cyberware/pressure-sheathing.yaml +6 -0
  62. package/content/cyberware/prosthetic-limb.yaml +6 -0
  63. package/content/cyberware/revenant-wiring.yaml +6 -0
  64. package/content/cyberware/slowtime-window.yaml +7 -0
  65. package/content/cyberware/stabilization-overrides.yaml +8 -0
  66. package/content/cyberware/tagger-nanites.yaml +7 -0
  67. package/content/cyberware/toxin-injector.yaml +7 -0
  68. package/content/cyberware/twitchlock-actuators.yaml +7 -0
  69. package/content/foci/alert.yaml +9 -0
  70. package/content/foci/armsman.yaml +9 -0
  71. package/content/foci/assassin.yaml +5 -0
  72. package/content/foci/authority.yaml +5 -0
  73. package/content/foci/close-combatant.yaml +7 -0
  74. package/content/foci/connected.yaml +5 -0
  75. package/content/foci/die-hard.yaml +7 -0
  76. package/content/foci/diplomat.yaml +10 -0
  77. package/content/foci/gunslinger.yaml +8 -0
  78. package/content/foci/hacker.yaml +10 -0
  79. package/content/foci/healer.yaml +7 -0
  80. package/content/foci/henchkeeper.yaml +7 -0
  81. package/content/foci/ironhide.yaml +7 -0
  82. package/content/foci/psychic-training.yaml +18 -0
  83. package/content/foci/savage-fray.yaml +5 -0
  84. package/content/foci/shocking-assault.yaml +8 -0
  85. package/content/foci/sniper.yaml +10 -0
  86. package/content/foci/specialist.yaml +36 -0
  87. package/content/foci/star-captain.yaml +5 -0
  88. package/content/foci/starfarer.yaml +5 -0
  89. package/content/foci/tinker.yaml +5 -0
  90. package/content/foci/unarmed-combatant.yaml +11 -0
  91. package/content/foci/unique-gift.yaml +6 -0
  92. package/content/foci/wanderer.yaml +5 -0
  93. package/content/foci/wild-psychic-talent.yaml +20 -0
  94. package/content/gear/ammo-20-rounds.yaml +9 -0
  95. package/content/gear/ammo-missile.yaml +8 -0
  96. package/content/gear/atmofilter.yaml +7 -0
  97. package/content/gear/backpack-tl0.yaml +7 -0
  98. package/content/gear/backpack-tl4.yaml +7 -0
  99. package/content/gear/bezoar.yaml +9 -0
  100. package/content/gear/binoculars-tl3.yaml +7 -0
  101. package/content/gear/binoculars-tl4.yaml +7 -0
  102. package/content/gear/bioscanner.yaml +7 -0
  103. package/content/gear/black-slab.yaml +7 -0
  104. package/content/gear/brainwave.yaml +8 -0
  105. package/content/gear/climbing-harness.yaml +7 -0
  106. package/content/gear/comm-server.yaml +7 -0
  107. package/content/gear/compad.yaml +7 -0
  108. package/content/gear/data-phase-tap.yaml +7 -0
  109. package/content/gear/data-protocol.yaml +7 -0
  110. package/content/gear/dataslab.yaml +7 -0
  111. package/content/gear/field-radio.yaml +7 -0
  112. package/content/gear/glowbug.yaml +7 -0
  113. package/content/gear/grapnel-launcher.yaml +7 -0
  114. package/content/gear/grav-chute-tl4.yaml +7 -0
  115. package/content/gear/grav-chute-tl5.yaml +7 -0
  116. package/content/gear/grav-harness.yaml +7 -0
  117. package/content/gear/hush.yaml +8 -0
  118. package/content/gear/instapanel.yaml +8 -0
  119. package/content/gear/lazarus-patch.yaml +8 -0
  120. package/content/gear/lift.yaml +11 -0
  121. package/content/gear/line-shunt.yaml +7 -0
  122. package/content/gear/low-light-goggles.yaml +7 -0
  123. package/content/gear/medkit.yaml +7 -0
  124. package/content/gear/metatool.yaml +7 -0
  125. package/content/gear/navcomp.yaml +7 -0
  126. package/content/gear/portabox.yaml +7 -0
  127. package/content/gear/postech-toolkit.yaml +7 -0
  128. package/content/gear/power-cell-a.yaml +9 -0
  129. package/content/gear/power-cell-b.yaml +8 -0
  130. package/content/gear/pressure-tent.yaml +7 -0
  131. package/content/gear/pretech-cosmetic.yaml +9 -0
  132. package/content/gear/pretech-toolkit.yaml +7 -0
  133. package/content/gear/psych.yaml +8 -0
  134. package/content/gear/rations-1-day.yaml +8 -0
  135. package/content/gear/remote-link-unit.yaml +7 -0
  136. package/content/gear/reverie.yaml +9 -0
  137. package/content/gear/rope-tl0.yaml +7 -0
  138. package/content/gear/rope-tl4.yaml +7 -0
  139. package/content/gear/scout-report.yaml +7 -0
  140. package/content/gear/solar-recharger.yaml +7 -0
  141. package/content/gear/spare-parts.yaml +8 -0
  142. package/content/gear/squeal.yaml +8 -0
  143. package/content/gear/stiletto-charge.yaml +6 -0
  144. package/content/gear/storage-unit.yaml +7 -0
  145. package/content/gear/survey-scanner.yaml +7 -0
  146. package/content/gear/survival-kit.yaml +7 -0
  147. package/content/gear/tailored-antiallergens.yaml +7 -0
  148. package/content/gear/telekinetic-generator.yaml +7 -0
  149. package/content/gear/telescoping-pole.yaml +7 -0
  150. package/content/gear/thermal-flare.yaml +7 -0
  151. package/content/gear/tightbeam-link-unit.yaml +7 -0
  152. package/content/gear/trade-goods.yaml +8 -0
  153. package/content/gear/trade-metals.yaml +8 -0
  154. package/content/gear/translator-torc.yaml +7 -0
  155. package/content/gear/tsunami.yaml +9 -0
  156. package/content/gear/vacc-fresher.yaml +7 -0
  157. package/content/gear/vacc-skin.yaml +7 -0
  158. package/content/gear/vacc-suit.yaml +7 -0
  159. package/content/partial-classes/expert.yaml +5 -0
  160. package/content/partial-classes/psychic.yaml +18 -0
  161. package/content/partial-classes/warrior.yaml +7 -0
  162. package/content/techniques/accelerated-succor.yaml +10 -0
  163. package/content/techniques/alternate-outcome.yaml +10 -0
  164. package/content/techniques/anguished-vision.yaml +10 -0
  165. package/content/techniques/burdened-apportation.yaml +10 -0
  166. package/content/techniques/cloak-powers.yaml +10 -0
  167. package/content/techniques/concert-of-minds.yaml +10 -0
  168. package/content/techniques/cursed-luck.yaml +59 -0
  169. package/content/techniques/deep-intrusion.yaml +10 -0
  170. package/content/techniques/destinys-shield.yaml +10 -0
  171. package/content/techniques/effortless-apportation.yaml +10 -0
  172. package/content/techniques/facile-mind.yaml +10 -0
  173. package/content/techniques/far-thought.yaml +10 -0
  174. package/content/techniques/flawless-mastery.yaml +10 -0
  175. package/content/techniques/force-puppetry.yaml +10 -0
  176. package/content/techniques/forced-outcome.yaml +10 -0
  177. package/content/techniques/holistic-optimization-patterning.yaml +10 -0
  178. package/content/techniques/impact-sump.yaml +10 -0
  179. package/content/techniques/impervious-pavis-of-will.yaml +10 -0
  180. package/content/techniques/intuitive-response.yaml +10 -0
  181. package/content/techniques/invincible-stand.yaml +10 -0
  182. package/content/techniques/kinetic-transversal.yaml +10 -0
  183. package/content/techniques/major-organ-restoration.yaml +10 -0
  184. package/content/techniques/mastered-succor.yaml +10 -0
  185. package/content/techniques/memory-editing.yaml +10 -0
  186. package/content/techniques/metadimensional-friction.yaml +10 -0
  187. package/content/techniques/metamorph.yaml +10 -0
  188. package/content/techniques/mindtracing.yaml +10 -0
  189. package/content/techniques/neural-trap.yaml +10 -0
  190. package/content/techniques/not-my-time.yaml +10 -0
  191. package/content/techniques/offensive-apportation.yaml +10 -0
  192. package/content/techniques/oracle.yaml +6 -0
  193. package/content/techniques/organic-purification-protocols.yaml +10 -0
  194. package/content/techniques/perceptive-dislocation.yaml +10 -0
  195. package/content/techniques/personal-apportation.yaml +6 -0
  196. package/content/techniques/pressure-field.yaml +10 -0
  197. package/content/techniques/proficient-apportation.yaml +10 -0
  198. package/content/techniques/prophecy.yaml +10 -0
  199. package/content/techniques/psychic-refinement.yaml +11 -0
  200. package/content/techniques/psychic-static.yaml +10 -0
  201. package/content/techniques/psychic-succor.yaml +39 -0
  202. package/content/techniques/psychic-tutelage.yaml +10 -0
  203. package/content/techniques/quintessential-reconstruction.yaml +10 -0
  204. package/content/techniques/reactive-telekinesis.yaml +10 -0
  205. package/content/techniques/reflex-response.yaml +10 -0
  206. package/content/techniques/remote-repair.yaml +10 -0
  207. package/content/techniques/rift-reduplication.yaml +10 -0
  208. package/content/techniques/sense-the-need.yaml +10 -0
  209. package/content/techniques/slip-field.yaml +10 -0
  210. package/content/techniques/spatial-awareness.yaml +10 -0
  211. package/content/techniques/spatial-synchrony-mandala.yaml +10 -0
  212. package/content/techniques/stutterjump.yaml +10 -0
  213. package/content/techniques/suppress-cognition.yaml +10 -0
  214. package/content/techniques/surge-momentum.yaml +10 -0
  215. package/content/techniques/suspended-manifestation.yaml +10 -0
  216. package/content/techniques/synthetic-adaptation.yaml +10 -0
  217. package/content/techniques/tangible-force-construct.yaml +10 -0
  218. package/content/techniques/telekinetic-armory.yaml +10 -0
  219. package/content/techniques/telekinetic-expertise.yaml +10 -0
  220. package/content/techniques/telekinetic-flight.yaml +10 -0
  221. package/content/techniques/telekinetic-manipulation.yaml +6 -0
  222. package/content/techniques/telekinetic-ram.yaml +10 -0
  223. package/content/techniques/telepathic-assault.yaml +10 -0
  224. package/content/techniques/telepathic-contact.yaml +6 -0
  225. package/content/techniques/teratic-overload.yaml +10 -0
  226. package/content/techniques/terminal-reflection.yaml +10 -0
  227. package/content/techniques/thermokinesis.yaml +10 -0
  228. package/content/techniques/tissue-integrity-field.yaml +10 -0
  229. package/content/techniques/transmit-thought.yaml +10 -0
  230. package/content/techniques/unity-of-thought.yaml +10 -0
  231. package/content/templates/trained-unarmed.yaml +9 -0
  232. package/content/weapons/advanced-bow.yaml +15 -0
  233. package/content/weapons/anti-vehicle-laser.yaml +18 -0
  234. package/content/weapons/combat-rifle.yaml +18 -0
  235. package/content/weapons/combat-shotgun.yaml +18 -0
  236. package/content/weapons/conversion-bow.yaml +15 -0
  237. package/content/weapons/crude-pistol.yaml +18 -0
  238. package/content/weapons/demo-charge.yaml +13 -0
  239. package/content/weapons/distortion-cannon.yaml +18 -0
  240. package/content/weapons/grenade.yaml +14 -0
  241. package/content/weapons/heavy-machine-gun.yaml +19 -0
  242. package/content/weapons/hydra-array.yaml +18 -0
  243. package/content/weapons/knife.yaml +7 -0
  244. package/content/weapons/large-advanced-weapon.yaml +13 -0
  245. package/content/weapons/large-primitive-weapon.yaml +12 -0
  246. package/content/weapons/laser-pistol.yaml +18 -0
  247. package/content/weapons/laser-rifle.yaml +19 -0
  248. package/content/weapons/mag-pistol.yaml +17 -0
  249. package/content/weapons/mag-rifle.yaml +17 -0
  250. package/content/weapons/medium-advanced-weapon.yaml +13 -0
  251. package/content/weapons/medium-primitive-weapon.yaml +12 -0
  252. package/content/weapons/monoblade-knife.yaml +7 -0
  253. package/content/weapons/monoblade-sword.yaml +4 -0
  254. package/content/weapons/musket.yaml +18 -0
  255. package/content/weapons/plasma-projector.yaml +18 -0
  256. package/content/weapons/primitive-bow.yaml +15 -0
  257. package/content/weapons/railgun.yaml +18 -0
  258. package/content/weapons/revolver.yaml +17 -0
  259. package/content/weapons/rifle.yaml +17 -0
  260. package/content/weapons/rocket-launcher.yaml +18 -0
  261. package/content/weapons/semi-auto-pistol.yaml +17 -0
  262. package/content/weapons/shear-rifle.yaml +19 -0
  263. package/content/weapons/shotgun.yaml +17 -0
  264. package/content/weapons/small-advanced-weapon.yaml +14 -0
  265. package/content/weapons/small-primitive-weapon.yaml +13 -0
  266. package/content/weapons/sniper-rifle.yaml +17 -0
  267. package/content/weapons/spear.yaml +8 -0
  268. package/content/weapons/spike-thrower.yaml +18 -0
  269. package/content/weapons/stun-baton.yaml +14 -0
  270. package/content/weapons/submachine-gun.yaml +18 -0
  271. package/content/weapons/suit-ripper.yaml +11 -0
  272. package/content/weapons/thermal-knife.yaml +7 -0
  273. package/content/weapons/thermal-pistol.yaml +18 -0
  274. package/content/weapons/thunder-gun.yaml +18 -0
  275. package/content/weapons/unarmed.yaml +8 -0
  276. package/content/weapons/void-carbine.yaml +17 -0
  277. package/content/weapons/vortex-cannon.yaml +16 -0
  278. package/content/weapons/wheatcutter-belt.yaml +16 -0
  279. package/dist/i18n/en.d.ts +3 -0
  280. package/dist/i18n/en.js +2 -0
  281. package/dist/i18n/en.json +1356 -0
  282. package/dist/index.d.ts +3 -0
  283. package/dist/index.js +2 -0
  284. package/dist/release.json +30238 -0
  285. package/i18n/en/content.yaml +394 -0
  286. package/i18n/en/foci.yaml +199 -0
  287. package/i18n/en/rules.yaml +759 -0
  288. package/i18n/en/text.yaml +249 -0
  289. package/i18n/en.yaml +1 -0
  290. package/pack.yaml +15 -0
  291. package/package.json +58 -3
  292. package/rules/advancement.yaml +461 -0
  293. package/rules/character.yaml +114 -0
  294. package/rules/checks.yaml +160 -0
  295. package/rules/combat.yaml +312 -0
  296. package/rules/core.yaml +111 -0
  297. package/rules/creation.yaml +633 -0
  298. package/rules/gear.yaml +176 -0
  299. package/rules/layout.yaml +195 -0
  300. package/rules/psionics.yaml +105 -0
  301. package/rules/start.yaml +403 -0
  302. package/rules/tags.yaml +60 -0
@@ -0,0 +1,633 @@
1
+ # Two ways to start: the full procedure (attributes rolled or from the array, a background with
2
+ # its skills picked, taken as quick skills or rolled, a class, foci and a hobby skill) and the
3
+ # quick tables (class and style, background, psychic disciplines, foci and bonus skill, each
4
+ # rolled or picked). The quick tables are the book's random creation.
5
+ creation:
6
+ - { id: standard, action: create-character }
7
+ - { id: quick, action: quick-character }
8
+ - { id: random, action: quick-character, params: { random: true }, random: true }
9
+
10
+ actions:
11
+ # One skill pick at creation: a skill's first pick is level-0, the second level-1, and a third
12
+ # is any other non-psychic skill below level-1. Also the attribute picks of the Growth table.
13
+ - id: gain-skill
14
+ tags: [creation]
15
+ params:
16
+ entry:
17
+ {
18
+ type: enum,
19
+ required: true,
20
+ values:
21
+ [
22
+ administer,
23
+ connect,
24
+ exert,
25
+ fix,
26
+ heal,
27
+ know,
28
+ lead,
29
+ notice,
30
+ perform,
31
+ pilot,
32
+ program,
33
+ punch,
34
+ shoot,
35
+ sneak,
36
+ stab,
37
+ survive,
38
+ talk,
39
+ trade,
40
+ work,
41
+ biopsionics,
42
+ metapsionics,
43
+ precognition,
44
+ telekinesis,
45
+ telepathy,
46
+ teleportation,
47
+ any-combat,
48
+ any-skill,
49
+ stab-or-shoot,
50
+ shoot-or-trade,
51
+ punch-or-stab,
52
+ any-psychic,
53
+ raise-zero,
54
+ any-stat,
55
+ physical,
56
+ mental,
57
+ none,
58
+ ],
59
+ }
60
+ random: { type: boolean, default: false }
61
+ results: [gained]
62
+ steps:
63
+ - id: start
64
+ kind: branch
65
+ sheet: proposed
66
+ cases:
67
+ - when: true
68
+ flags:
69
+ stat: "params.entry in ['any-stat', 'physical', 'mental']"
70
+ pool: >-
71
+ params.entry == 'any-combat' ? ['punch', 'shoot', 'stab']
72
+ : params.entry == 'stab-or-shoot' ? ['stab', 'shoot']
73
+ : params.entry == 'shoot-or-trade' ? ['shoot', 'trade']
74
+ : params.entry == 'punch-or-stab' ? ['punch', 'stab']
75
+ : params.entry == 'any-psychic' ? keysOf('psychic')
76
+ : params.entry == 'any-skill' ? keysOf('general') + keysOf('combat')
77
+ : params.entry == 'raise-zero'
78
+ ? filterList(keysOf('general') + keysOf('combat'),
79
+ fieldOf('skills.{skill}.level', x) == 0)
80
+ : params.entry in keysOf('skill') ? [params.entry] : []
81
+ str: 0
82
+ dex: 0
83
+ con: 0
84
+ int: 0
85
+ wis: 0
86
+ cha: 0
87
+ - id: candidates
88
+ kind: branch
89
+ sheet: proposed
90
+ cases:
91
+ - when: true
92
+ flags:
93
+ open: >-
94
+ flags.stat || params.entry == 'none' ? []
95
+ : countList(flags.pool, fieldOf('skills.{skill}.level', x) < 1) > 0
96
+ ? filterList(flags.pool, fieldOf('skills.{skill}.level', x) < 1)
97
+ : filterList(keysOf('general') + keysOf('combat'),
98
+ fieldOf('skills.{skill}.level', x) < 1)
99
+ - id: choose
100
+ kind: choice
101
+ when: size(flags.open) > 1
102
+ random: params.random
103
+ recommend: flags.open[0]
104
+ options: { values: { formula: flags.open } }
105
+ - id: picked
106
+ kind: branch
107
+ cases:
108
+ - when: true
109
+ flags:
110
+ skill: "size(flags.open) == 1 ? flags.open[0] : has(steps.choose) ? steps.choose.picked : ''"
111
+ - id: gain
112
+ kind: changes
113
+ when: flags.skill != ''
114
+ changes:
115
+ - { type: adjust, field: { formula: "'skills.' + flags.skill + '.level'" }, by: 1 }
116
+ # A psychic skill raised to level-1 brings a level-1 technique of its discipline.
117
+ - id: technique
118
+ kind: choice
119
+ sheet: proposed
120
+ when: "flags.skill in keysOf('psychic') && fieldOf('skills.{psychic}.level', flags.skill) >= 1"
121
+ random: params.random
122
+ recommend: options[0]
123
+ options:
124
+ content:
125
+ type: technique
126
+ where: >-
127
+ item.discipline == flags.skill && !item.core
128
+ && item.level <= fieldOf('skills.{psychic}.level', flags.skill)
129
+ && countCopies(copy.item == item.id) == 0
130
+ changes:
131
+ - { type: addItem, entry: { item: picked.id } }
132
+ # +1 to any attribute below 18, or one of the +2 pairs of the physical or mental ones.
133
+ - id: attribute
134
+ kind: choice
135
+ sheet: proposed
136
+ when: "params.entry == 'any-stat'"
137
+ random: params.random
138
+ recommend: options[0]
139
+ options:
140
+ values:
141
+ { formula: "filterList(keysOf('attr'), fieldOf('attributes.{attr}.score', x) < 18)" }
142
+ changes:
143
+ - type: set
144
+ field: { formula: "'attributes.' + picked.value + '.score'" }
145
+ value: "fieldOf('attributes.{attr}.score', picked.value) + 1"
146
+ - id: pair
147
+ kind: choice
148
+ sheet: proposed
149
+ when: "params.entry in ['physical', 'mental']"
150
+ random: params.random
151
+ recommend: options[0]
152
+ options:
153
+ - { id: str2, when: "params.entry == 'physical'", flags: { str: 2 } }
154
+ - { id: dex2, when: "params.entry == 'physical'", flags: { dex: 2 } }
155
+ - { id: con2, when: "params.entry == 'physical'", flags: { con: 2 } }
156
+ - { id: str-dex, when: "params.entry == 'physical'", flags: { str: 1, dex: 1 } }
157
+ - { id: str-con, when: "params.entry == 'physical'", flags: { str: 1, con: 1 } }
158
+ - { id: dex-con, when: "params.entry == 'physical'", flags: { dex: 1, con: 1 } }
159
+ - { id: int2, when: "params.entry == 'mental'", flags: { int: 2 } }
160
+ - { id: wis2, when: "params.entry == 'mental'", flags: { wis: 2 } }
161
+ - { id: cha2, when: "params.entry == 'mental'", flags: { cha: 2 } }
162
+ - { id: int-wis, when: "params.entry == 'mental'", flags: { int: 1, wis: 1 } }
163
+ - { id: int-cha, when: "params.entry == 'mental'", flags: { int: 1, cha: 1 } }
164
+ - { id: wis-cha, when: "params.entry == 'mental'", flags: { wis: 1, cha: 1 } }
165
+ - id: raise
166
+ kind: changes
167
+ sheet: proposed
168
+ when: has(steps.pair)
169
+ changes:
170
+ - type: set
171
+ when: flags.str > 0
172
+ field: attributes.str.score
173
+ value: 'min(18, attributes.str.score + flags.str)'
174
+ - type: set
175
+ when: flags.dex > 0
176
+ field: attributes.dex.score
177
+ value: 'min(18, attributes.dex.score + flags.dex)'
178
+ - type: set
179
+ when: flags.con > 0
180
+ field: attributes.con.score
181
+ value: 'min(18, attributes.con.score + flags.con)'
182
+ - type: set
183
+ when: flags.int > 0
184
+ field: attributes.int.score
185
+ value: 'min(18, attributes.int.score + flags.int)'
186
+ - type: set
187
+ when: flags.wis > 0
188
+ field: attributes.wis.score
189
+ value: 'min(18, attributes.wis.score + flags.wis)'
190
+ - type: set
191
+ when: flags.cha > 0
192
+ field: attributes.cha.score
193
+ value: 'min(18, attributes.cha.score + flags.cha)'
194
+ - id: result
195
+ kind: outcome
196
+ result: "'gained'"
197
+ data: { skill: flags.skill }
198
+
199
+ # A focus level: a new focus, or the next level of one already held. A new focus's bonus skill
200
+ # is a skill pick at creation and three skill points on advancement.
201
+ - id: gain-focus
202
+ tags: [creation, level-up]
203
+ params:
204
+ kind: { type: enum, values: [any, combat, noncombat], default: any }
205
+ advancement: { type: boolean, default: false }
206
+ random: { type: boolean, default: false }
207
+ results: [gained]
208
+ steps:
209
+ - id: focus
210
+ kind: choice
211
+ sheet: proposed
212
+ random: params.random
213
+ recommend: options[0]
214
+ options:
215
+ content:
216
+ type: focus
217
+ where: >-
218
+ (params.kind == 'any' || item.kind == params.kind)
219
+ && (item.id != @foci.psychic-training || psionics.access != 'none')
220
+ && (item.id != @foci.wild-psychic-talent || psionics.access == 'none')
221
+ && (item.repeatable || countCopies(copy.item == item.id
222
+ && copy.state.level >= item.maxLevel) == 0)
223
+ changes:
224
+ - type: adjustState
225
+ when: '!steps.focus.item.repeatable && countCopies(copy.item == picked.id) > 0'
226
+ copies: { type: focus, where: item.id == steps.focus.picked }
227
+ limit: 1
228
+ key: level
229
+ by: 1
230
+ - type: addItem
231
+ when: steps.focus.item.repeatable || countCopies(copy.item == picked.id) == 0
232
+ entry: { item: picked.id }
233
+ - id: picks
234
+ kind: choice
235
+ sheet: proposed
236
+ when: size(steps.focus.added) > 0
237
+ random: params.random
238
+ options: { pending: { entry: 'steps.focus.added[0]' } }
239
+ - id: bonus
240
+ kind: branch
241
+ sheet: proposed
242
+ cases:
243
+ - when: true
244
+ flags:
245
+ entry: >-
246
+ size(steps.focus.added) == 0 ? 'none'
247
+ : steps.focus.item.skill != 'chosen' ? steps.focus.item.skill
248
+ : size(steps.picks.picked) > 0 ? steps.picks.picked[0] : 'any-skill'
249
+ - id: skill
250
+ kind: action
251
+ when: "!params.advancement && flags.entry != 'none'"
252
+ use: gain-skill
253
+ params: { entry: flags.entry, random: params.random }
254
+ - id: points
255
+ kind: action
256
+ when: "params.advancement && flags.entry != 'none'"
257
+ use: focus-skill-points
258
+ params: { entry: flags.entry, random: params.random }
259
+ - { id: result, kind: outcome, result: "'gained'" }
260
+
261
+ - id: starting-gear
262
+ tags: [creation]
263
+ params:
264
+ random: { type: boolean, default: false }
265
+ results: [equipped]
266
+ steps:
267
+ - id: kit
268
+ kind: choice
269
+ random: params.random
270
+ recommend: >-
271
+ countCopies(copy.item == @classes.warrior) > 0 ? 'soldier'
272
+ : countCopies(copy.item == @classes.psychic) > 0 ? 'medic'
273
+ : countCopies(copy.item == @classes.expert) > 0 ? 'technician' : 'gunslinger'
274
+ options:
275
+ - { id: barbarian }
276
+ - { id: blade }
277
+ - { id: thief }
278
+ - { id: hacker }
279
+ - { id: gunslinger }
280
+ - { id: soldier }
281
+ - { id: scout }
282
+ - { id: medic }
283
+ - { id: civilian }
284
+ - { id: technician }
285
+ - { id: credits }
286
+ - id: credits
287
+ kind: roll
288
+ when: "steps.kit.picked == 'credits'"
289
+ tags: [creation]
290
+ parts: [{ dice: 2d6 }]
291
+ - id: gear
292
+ kind: changes
293
+ changes:
294
+ - {
295
+ type: addItem,
296
+ when: "steps.kit.picked == 'barbarian'",
297
+ entry: { item: "'weapons.spear'", equipped: true },
298
+ }
299
+ - {
300
+ type: addItem,
301
+ when: "steps.kit.picked == 'barbarian'",
302
+ entry: { item: "'armor.light-primitive-armor'", equipped: true },
303
+ }
304
+ - {
305
+ type: addItem,
306
+ when: "steps.kit.picked == 'barbarian'",
307
+ entry: { item: "'armor.shield'", equipped: true },
308
+ }
309
+ - {
310
+ type: addItem,
311
+ when: "steps.kit.picked == 'barbarian'",
312
+ entry: { item: "'weapons.knife'", equipped: true },
313
+ }
314
+ - {
315
+ type: addItem,
316
+ when: "steps.kit.picked == 'barbarian'",
317
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
318
+ }
319
+ - {
320
+ type: addItem,
321
+ when: "steps.kit.picked == 'barbarian'",
322
+ entry: { item: "'gear.rations-1-day'", quantity: 7 },
323
+ }
324
+ - {
325
+ type: addItem,
326
+ when: "steps.kit.picked == 'barbarian'",
327
+ entry: { item: "'gear.rope-tl0'" },
328
+ }
329
+ - {
330
+ type: addItem,
331
+ when: "steps.kit.picked == 'blade'",
332
+ entry: { item: "'weapons.monoblade-sword'", equipped: true },
333
+ }
334
+ - {
335
+ type: addItem,
336
+ when: "steps.kit.picked == 'blade'",
337
+ entry: { item: "'armor.woven-body-armor'", equipped: true },
338
+ }
339
+ - {
340
+ type: addItem,
341
+ when: "steps.kit.picked == 'blade'",
342
+ entry: { item: "'armor.secure-clothing'" },
343
+ }
344
+ - {
345
+ type: addItem,
346
+ when: "steps.kit.picked == 'blade'",
347
+ entry: { item: "'weapons.thermal-knife'", equipped: true },
348
+ }
349
+ - {
350
+ type: addItem,
351
+ when: "steps.kit.picked == 'blade'",
352
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
353
+ }
354
+ - { type: addItem, when: "steps.kit.picked == 'blade'", entry: { item: "'gear.compad'" } }
355
+ - {
356
+ type: addItem,
357
+ when: "steps.kit.picked == 'blade'",
358
+ entry: { item: "'gear.lazarus-patch'" },
359
+ }
360
+ - {
361
+ type: addItem,
362
+ when: "steps.kit.picked == 'thief'",
363
+ entry: { item: "'weapons.laser-pistol'", equipped: true },
364
+ }
365
+ - {
366
+ type: addItem,
367
+ when: "steps.kit.picked == 'thief'",
368
+ entry: { item: "'armor.armored-undersuit'", equipped: true },
369
+ }
370
+ - {
371
+ type: addItem,
372
+ when: "steps.kit.picked == 'thief'",
373
+ entry: { item: "'weapons.monoblade-knife'", equipped: true },
374
+ }
375
+ - {
376
+ type: addItem,
377
+ when: "steps.kit.picked == 'thief'",
378
+ entry: { item: "'gear.climbing-harness'" },
379
+ }
380
+ - {
381
+ type: addItem,
382
+ when: "steps.kit.picked == 'thief'",
383
+ entry: { item: "'gear.low-light-goggles'" },
384
+ }
385
+ - {
386
+ type: addItem,
387
+ when: "steps.kit.picked == 'thief'",
388
+ entry: { item: "'gear.power-cell-a'", quantity: 2 },
389
+ }
390
+ - {
391
+ type: addItem,
392
+ when: "steps.kit.picked == 'thief'",
393
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
394
+ }
395
+ - { type: addItem, when: "steps.kit.picked == 'thief'", entry: { item: "'gear.compad'" } }
396
+ - {
397
+ type: addItem,
398
+ when: "steps.kit.picked == 'thief'",
399
+ entry: { item: "'gear.metatool'" },
400
+ }
401
+ - {
402
+ type: addItem,
403
+ when: "steps.kit.picked == 'hacker'",
404
+ entry: { item: "'weapons.laser-pistol'", equipped: true },
405
+ }
406
+ - {
407
+ type: addItem,
408
+ when: "steps.kit.picked == 'hacker'",
409
+ entry: { item: "'armor.secure-clothing'", equipped: true },
410
+ }
411
+ - {
412
+ type: addItem,
413
+ when: "steps.kit.picked == 'hacker'",
414
+ entry: { item: "'gear.postech-toolkit'" },
415
+ }
416
+ - {
417
+ type: addItem,
418
+ when: "steps.kit.picked == 'hacker'",
419
+ entry: { item: "'gear.spare-parts'", quantity: 3 },
420
+ }
421
+ - {
422
+ type: addItem,
423
+ when: "steps.kit.picked == 'hacker'",
424
+ entry: { item: "'gear.power-cell-a'", quantity: 2 },
425
+ }
426
+ - {
427
+ type: addItem,
428
+ when: "steps.kit.picked == 'hacker'",
429
+ entry: { item: "'gear.dataslab'" },
430
+ }
431
+ - {
432
+ type: addItem,
433
+ when: "steps.kit.picked == 'hacker'",
434
+ entry: { item: "'gear.metatool'" },
435
+ }
436
+ - {
437
+ type: addItem,
438
+ when: "steps.kit.picked == 'hacker'",
439
+ entry: { item: "'gear.line-shunt'", quantity: 2 },
440
+ }
441
+ - {
442
+ type: addItem,
443
+ when: "steps.kit.picked == 'gunslinger'",
444
+ entry: { item: "'weapons.laser-pistol'", equipped: true },
445
+ }
446
+ - {
447
+ type: addItem,
448
+ when: "steps.kit.picked == 'gunslinger'",
449
+ entry: { item: "'armor.armored-undersuit'", equipped: true },
450
+ }
451
+ - {
452
+ type: addItem,
453
+ when: "steps.kit.picked == 'gunslinger'",
454
+ entry: { item: "'weapons.monoblade-knife'", equipped: true },
455
+ }
456
+ - {
457
+ type: addItem,
458
+ when: "steps.kit.picked == 'gunslinger'",
459
+ entry: { item: "'gear.power-cell-a'", quantity: 8 },
460
+ }
461
+ - {
462
+ type: addItem,
463
+ when: "steps.kit.picked == 'gunslinger'",
464
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
465
+ }
466
+ - {
467
+ type: addItem,
468
+ when: "steps.kit.picked == 'gunslinger'",
469
+ entry: { item: "'gear.compad'" },
470
+ }
471
+ - {
472
+ type: addItem,
473
+ when: "steps.kit.picked == 'soldier'",
474
+ entry: { item: "'weapons.combat-rifle'", equipped: true },
475
+ }
476
+ - {
477
+ type: addItem,
478
+ when: "steps.kit.picked == 'soldier'",
479
+ entry: { item: "'armor.woven-body-armor'", equipped: true },
480
+ }
481
+ - {
482
+ type: addItem,
483
+ when: "steps.kit.picked == 'soldier'",
484
+ entry: { item: "'weapons.knife'", equipped: true },
485
+ }
486
+ - {
487
+ type: addItem,
488
+ when: "steps.kit.picked == 'soldier'",
489
+ entry: { item: "'gear.ammo-20-rounds'", quantity: 4 },
490
+ }
491
+ - {
492
+ type: addItem,
493
+ when: "steps.kit.picked == 'soldier'",
494
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
495
+ }
496
+ - {
497
+ type: addItem,
498
+ when: "steps.kit.picked == 'soldier'",
499
+ entry: { item: "'gear.compad'" },
500
+ }
501
+ - {
502
+ type: addItem,
503
+ when: "steps.kit.picked == 'scout'",
504
+ entry: { item: "'weapons.laser-rifle'", equipped: true },
505
+ }
506
+ - {
507
+ type: addItem,
508
+ when: "steps.kit.picked == 'scout'",
509
+ entry: { item: "'armor.armored-vacc-suit'", equipped: true },
510
+ }
511
+ - {
512
+ type: addItem,
513
+ when: "steps.kit.picked == 'scout'",
514
+ entry: { item: "'weapons.knife'", equipped: true },
515
+ }
516
+ - {
517
+ type: addItem,
518
+ when: "steps.kit.picked == 'scout'",
519
+ entry: { item: "'gear.survey-scanner'" },
520
+ }
521
+ - {
522
+ type: addItem,
523
+ when: "steps.kit.picked == 'scout'",
524
+ entry: { item: "'gear.survival-kit'" },
525
+ }
526
+ - {
527
+ type: addItem,
528
+ when: "steps.kit.picked == 'scout'",
529
+ entry: { item: "'gear.binoculars-tl3'" },
530
+ }
531
+ - {
532
+ type: addItem,
533
+ when: "steps.kit.picked == 'scout'",
534
+ entry: { item: "'gear.power-cell-a'", quantity: 8 },
535
+ }
536
+ - {
537
+ type: addItem,
538
+ when: "steps.kit.picked == 'scout'",
539
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
540
+ }
541
+ - { type: addItem, when: "steps.kit.picked == 'scout'", entry: { item: "'gear.compad'" } }
542
+ - {
543
+ type: addItem,
544
+ when: "steps.kit.picked == 'medic'",
545
+ entry: { item: "'weapons.laser-pistol'", equipped: true },
546
+ }
547
+ - {
548
+ type: addItem,
549
+ when: "steps.kit.picked == 'medic'",
550
+ entry: { item: "'armor.secure-clothing'", equipped: true },
551
+ }
552
+ - {
553
+ type: addItem,
554
+ when: "steps.kit.picked == 'medic'",
555
+ entry: { item: "'gear.lazarus-patch'", quantity: 4 },
556
+ }
557
+ - {
558
+ type: addItem,
559
+ when: "steps.kit.picked == 'medic'",
560
+ entry: { item: "'gear.lift'", quantity: 2 },
561
+ }
562
+ - {
563
+ type: addItem,
564
+ when: "steps.kit.picked == 'medic'",
565
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
566
+ }
567
+ - { type: addItem, when: "steps.kit.picked == 'medic'", entry: { item: "'gear.medkit'" } }
568
+ - { type: addItem, when: "steps.kit.picked == 'medic'", entry: { item: "'gear.compad'" } }
569
+ - {
570
+ type: addItem,
571
+ when: "steps.kit.picked == 'medic'",
572
+ entry: { item: "'gear.bioscanner'" },
573
+ }
574
+ - {
575
+ type: addItem,
576
+ when: "steps.kit.picked == 'civilian'",
577
+ entry: { item: "'armor.secure-clothing'", equipped: true },
578
+ }
579
+ - {
580
+ type: addItem,
581
+ when: "steps.kit.picked == 'civilian'",
582
+ entry: { item: "'gear.compad'" },
583
+ }
584
+ - {
585
+ type: addItem,
586
+ when: "steps.kit.picked == 'technician'",
587
+ entry: { item: "'weapons.laser-pistol'", equipped: true },
588
+ }
589
+ - {
590
+ type: addItem,
591
+ when: "steps.kit.picked == 'technician'",
592
+ entry: { item: "'armor.armored-undersuit'", equipped: true },
593
+ }
594
+ - {
595
+ type: addItem,
596
+ when: "steps.kit.picked == 'technician'",
597
+ entry: { item: "'weapons.monoblade-knife'", equipped: true },
598
+ }
599
+ - {
600
+ type: addItem,
601
+ when: "steps.kit.picked == 'technician'",
602
+ entry: { item: "'gear.postech-toolkit'" },
603
+ }
604
+ - {
605
+ type: addItem,
606
+ when: "steps.kit.picked == 'technician'",
607
+ entry: { item: "'gear.spare-parts'", quantity: 6 },
608
+ }
609
+ - {
610
+ type: addItem,
611
+ when: "steps.kit.picked == 'technician'",
612
+ entry: { item: "'gear.power-cell-a'", quantity: 4 },
613
+ }
614
+ - {
615
+ type: addItem,
616
+ when: "steps.kit.picked == 'technician'",
617
+ entry: { item: "'gear.backpack-tl0'", equipped: true },
618
+ }
619
+ - {
620
+ type: addItem,
621
+ when: "steps.kit.picked == 'technician'",
622
+ entry: { item: "'gear.dataslab'" },
623
+ }
624
+ - {
625
+ type: addItem,
626
+ when: "steps.kit.picked == 'technician'",
627
+ entry: { item: "'gear.metatool'" },
628
+ }
629
+ - type: set
630
+ field: credits.current
631
+ value: >-
632
+ steps.kit.picked == 'barbarian' ? 500 : steps.kit.picked == 'blade' ? 50 : steps.kit.picked == 'thief' ? 25 : steps.kit.picked == 'hacker' ? 100 : steps.kit.picked == 'gunslinger' ? 100 : steps.kit.picked == 'soldier' ? 100 : steps.kit.picked == 'scout' ? 25 : steps.kit.picked == 'medic' ? 25 : steps.kit.picked == 'civilian' ? 700 : steps.kit.picked == 'technician' ? 200 : steps.credits.total * 100
633
+ - { id: result, kind: outcome, result: "'equipped'" }