@opencharacter/swn-revised 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +64 -10
  2. package/content/classes/adventurer.yaml +2 -0
  3. package/content/classes/expert.yaml +2 -0
  4. package/content/classes/psychic.yaml +6 -6
  5. package/content/classes/warrior.yaml +2 -0
  6. package/content/foci/psychic-training.yaml +1 -0
  7. package/content/foci/specialist.yaml +1 -1
  8. package/content/foci/wild-psychic-talent.yaml +1 -0
  9. package/content/kits/barbarian.yaml +17 -0
  10. package/content/kits/blade.yaml +17 -0
  11. package/content/kits/civilian.yaml +12 -0
  12. package/content/kits/credits.yaml +11 -0
  13. package/content/kits/gunslinger.yaml +16 -0
  14. package/content/kits/hacker.yaml +18 -0
  15. package/content/kits/medic.yaml +18 -0
  16. package/content/kits/scout.yaml +19 -0
  17. package/content/kits/soldier.yaml +16 -0
  18. package/content/kits/technician.yaml +19 -0
  19. package/content/kits/thief.yaml +19 -0
  20. package/content/partial-classes/psychic.yaml +4 -6
  21. package/content/styles/expert-nimble.yaml +11 -0
  22. package/content/styles/expert-smart.yaml +11 -0
  23. package/content/styles/expert-smooth.yaml +11 -0
  24. package/content/styles/psychic-adept.yaml +11 -0
  25. package/content/styles/psychic-seer.yaml +11 -0
  26. package/content/styles/warrior-leader.yaml +11 -0
  27. package/content/styles/warrior-melee.yaml +11 -0
  28. package/content/styles/warrior-ranged.yaml +11 -0
  29. package/content/techniques/psychic-succor.yaml +16 -3
  30. package/content/weapons/advanced-bow.yaml +0 -2
  31. package/content/weapons/anti-vehicle-laser.yaml +0 -2
  32. package/content/weapons/combat-rifle.yaml +0 -2
  33. package/content/weapons/combat-shotgun.yaml +0 -2
  34. package/content/weapons/conversion-bow.yaml +0 -2
  35. package/content/weapons/crude-pistol.yaml +0 -2
  36. package/content/weapons/distortion-cannon.yaml +0 -2
  37. package/content/weapons/heavy-machine-gun.yaml +0 -2
  38. package/content/weapons/hydra-array.yaml +0 -2
  39. package/content/weapons/laser-pistol.yaml +0 -2
  40. package/content/weapons/laser-rifle.yaml +0 -2
  41. package/content/weapons/mag-pistol.yaml +0 -2
  42. package/content/weapons/mag-rifle.yaml +0 -2
  43. package/content/weapons/musket.yaml +0 -2
  44. package/content/weapons/plasma-projector.yaml +0 -2
  45. package/content/weapons/primitive-bow.yaml +0 -2
  46. package/content/weapons/railgun.yaml +0 -2
  47. package/content/weapons/revolver.yaml +0 -2
  48. package/content/weapons/rifle.yaml +0 -2
  49. package/content/weapons/rocket-launcher.yaml +0 -2
  50. package/content/weapons/semi-auto-pistol.yaml +0 -2
  51. package/content/weapons/shear-rifle.yaml +0 -2
  52. package/content/weapons/shotgun.yaml +0 -2
  53. package/content/weapons/sniper-rifle.yaml +0 -2
  54. package/content/weapons/spike-thrower.yaml +0 -2
  55. package/content/weapons/submachine-gun.yaml +0 -2
  56. package/content/weapons/thermal-pistol.yaml +0 -2
  57. package/content/weapons/thunder-gun.yaml +0 -2
  58. package/content/weapons/void-carbine.yaml +0 -2
  59. package/content/weapons/vortex-cannon.yaml +0 -2
  60. package/content/weapons/wheatcutter-belt.yaml +0 -2
  61. package/dist/i18n/en.js +1 -1
  62. package/dist/i18n/en.json +140 -85
  63. package/dist/index.js +1 -1
  64. package/dist/release.json +5068 -3511
  65. package/i18n/en/content.yaml +105 -63
  66. package/i18n/en/rules.yaml +35 -22
  67. package/pack.yaml +2 -2
  68. package/package.json +2 -2
  69. package/rules/advancement.yaml +30 -9
  70. package/rules/character.yaml +30 -5
  71. package/rules/checks.yaml +8 -2
  72. package/rules/combat.yaml +11 -2
  73. package/rules/creation.yaml +164 -366
  74. package/rules/gear.yaml +16 -4
  75. package/rules/layout.yaml +4 -2
  76. package/rules/psionics.yaml +64 -4
  77. package/rules/start.yaml +46 -32
  78. package/rules/tags.yaml +11 -0
package/rules/layout.yaml CHANGED
@@ -93,6 +93,7 @@ display:
93
93
  quantity: { hidden: true }
94
94
  state:
95
95
  committed: { priority: 0, showWhen: self.committed > 0 }
96
+ torched: { hidden: true }
96
97
  cyberware: { quantity: { hidden: true } }
97
98
  weapon:
98
99
  state:
@@ -118,7 +119,7 @@ display:
118
119
  with: [{ field: hp.max, as: max }]
119
120
  rolls: [{ action: take-damage }, { action: heal }]
120
121
  hp.max: { groups: [condition], priority: 1 }
121
- hp.rolled: { groups: [condition], priority: 2 }
122
+ hp.rolled: { groups: [condition], priority: 2, visibility: background }
122
123
  hp.perLevel: { hidden: true }
123
124
  strain.current:
124
125
  groups: [condition]
@@ -159,7 +160,8 @@ display:
159
160
  effort.active: { groups: [psionics], priority: 1, showWhen: effort.active > 0 }
160
161
  effort.torched: { groups: [psionics], priority: 2 }
161
162
  psionics.access: { groups: [psionics], priority: 1 }
162
- psionics.discipline: { groups: [psionics], priority: 1, showWhen: "psionics.discipline != ''" }
163
+ psionics.discipline:
164
+ { groups: [psionics], priority: 1, showWhen: "psionics.discipline != 'none'" }
163
165
  psionics.training: { hidden: true }
164
166
  effort.bonus: { hidden: true }
165
167
  effort.wild: { hidden: true }
@@ -21,8 +21,7 @@ fields:
21
21
  effort.active: { type: integer, formula: 0 }
22
22
  effort.available:
23
23
  type: integer
24
- formula: effort.max + effort.torched - effort.scene - effort.day - effort.active
25
- limits: { min: 0 }
24
+ formula: max(0, effort.max + effort.torched - effort.scene - effort.day - effort.active)
26
25
 
27
26
  effects:
28
27
  - target: { rolls: [attack, damage] }
@@ -32,12 +31,49 @@ effects:
32
31
  has(participants.target) && size(participants.target) > 0
33
32
  && participants.target[0].psionics.cursedLuck
34
33
 
34
+ # When the scene ends, torched Effort goes, and with it the techniques it sustained.
35
+ - target: { steps: [rest.scene, rest.night] }
36
+ op: changes
37
+ value:
38
+ changes:
39
+ - type: adjustState
40
+ when: "countCopies(copy.type == 'technique' && copy.state.torched > 0) > 0"
41
+ copies: { type: technique, where: self.torched > 0 }
42
+ key: committed
43
+ by: -self.torched
44
+ - type: setState
45
+ when: "countCopies(copy.type == 'technique' && copy.state.torched > 0) > 0"
46
+ copies: { type: technique, where: self.torched > 0 }
47
+ key: torched
48
+ value: 0
49
+ - type: adjustState
50
+ when: "countPicks(pick.type == 'technique' && pick.state.torched > 0) > 0"
51
+ picks: { where: self.torched > 0 }
52
+ key: committed
53
+ by: -self.torched
54
+ - type: setState
55
+ when: "countPicks(pick.type == 'technique' && pick.state.torched > 0) > 0"
56
+ picks: { where: self.torched > 0 }
57
+ key: torched
58
+ value: 0
59
+ - type: adjustState
60
+ when: "countGrants(grant.type == 'technique' && grant.state.torched > 0) > 0"
61
+ grants: { where: self.torched > 0 }
62
+ key: committed
63
+ by: -self.torched
64
+ - type: setState
65
+ when: "countGrants(grant.type == 'technique' && grant.state.torched > 0) > 0"
66
+ grants: { where: self.torched > 0 }
67
+ key: torched
68
+ value: 0
69
+
35
70
  contentTypes:
36
71
  technique:
37
72
  copies: { perItem: 1 }
38
73
  fields:
39
74
  discipline:
40
75
  type: enum
76
+ open: true
41
77
  required: true
42
78
  values: [biopsionics, metapsionics, precognition, telekinesis, telepathy, teleportation]
43
79
  level: { type: integer, required: true, min: 0, max: 4 }
@@ -46,6 +82,8 @@ contentTypes:
46
82
  state:
47
83
  # Effort Committed to keep the technique going, until it is released.
48
84
  committed: { type: integer, default: 0, min: 0 }
85
+ # The part of it torched Effort pays for, which ends with the scene.
86
+ torched: { type: integer, default: 0, min: 0 }
49
87
  effects:
50
88
  - { target: effort.active, op: add, value: self.committed }
51
89
  actions:
@@ -57,9 +95,12 @@ constraints:
57
95
  - id: psychic-skills
58
96
  check: >-
59
97
  psionics.access == 'unrestricted'
60
- || sumFields(f.value >= 0 && (psionics.access == 'none'
61
- || f.id != 'swn-revised:skills.' + psionics.discipline + '.level') ? 1 : 0,
98
+ || sumFields(f.value >= 0 && (psionics.access == 'none' || psionics.discipline == 'none'
99
+ || f.id != fieldId('skills.{psychic}.level', psionics.discipline)) ? 1 : 0,
62
100
  'skill.psychic' in f.tags) == 0
101
+ # Torching can lower the maximum under what is Committed; the commitments stay until released.
102
+ - id: effort-overcommitted
103
+ check: effort.max + effort.torched - effort.scene - effort.day - effort.active >= 0
63
104
 
64
105
  actions:
65
106
  # Commit a point of Effort for as long as the technique lasts: it stays Committed on the
@@ -81,12 +122,28 @@ actions:
81
122
  countCopies(copy.id == self.id && copy.type == 'technique') > 0 ? 'copy'
82
123
  : countCopies(copy.id == self.id && copy.type == 'focus') > 0 ? 'pick'
83
124
  : 'grant'
125
+ torched: effort.max - effort.scene - effort.day - effort.active <= 0
84
126
  - id: commit
85
127
  kind: changes
86
128
  changes:
87
129
  - { type: adjustState, when: "flags.held == 'copy'", entry: self, key: committed, by: 1 }
88
130
  - { type: adjustState, when: "flags.held == 'pick'", pick: self, key: committed, by: 1 }
89
131
  - { type: adjustState, when: "flags.held == 'grant'", grant: self, key: committed, by: 1 }
132
+ - type: adjustState
133
+ when: "flags.torched && flags.held == 'copy'"
134
+ entry: self
135
+ key: torched
136
+ by: 1
137
+ - type: adjustState
138
+ when: "flags.torched && flags.held == 'pick'"
139
+ pick: self
140
+ key: torched
141
+ by: 1
142
+ - type: adjustState
143
+ when: "flags.torched && flags.held == 'grant'"
144
+ grant: self
145
+ key: torched
146
+ by: 1
90
147
  - { id: result, kind: outcome, result: "'committed'" }
91
148
 
92
149
  # Reclaim the Effort a technique holds, ending it.
@@ -102,4 +159,7 @@ actions:
102
159
  - { type: setState, when: "flags.held == 'copy'", entry: self, key: committed, value: 0 }
103
160
  - { type: setState, when: "flags.held == 'pick'", pick: self, key: committed, value: 0 }
104
161
  - { type: setState, when: "flags.held == 'grant'", grant: self, key: committed, value: 0 }
162
+ - { type: setState, when: "flags.held == 'copy'", entry: self, key: torched, value: 0 }
163
+ - { type: setState, when: "flags.held == 'pick'", pick: self, key: torched, value: 0 }
164
+ - { type: setState, when: "flags.held == 'grant'", grant: self, key: torched, value: 0 }
105
165
  - { id: result, kind: outcome, result: "'released'" }
package/rules/start.yaml CHANGED
@@ -194,7 +194,7 @@ actions:
194
194
  - id: partialPsychic
195
195
  kind: action
196
196
  sheet: proposed
197
- when: "psionics.access == 'restricted' && psionics.discipline != ''"
197
+ when: "psionics.access == 'restricted' && psionics.discipline != 'none'"
198
198
  use: gain-skill
199
199
  params: { entry: psionics.discipline }
200
200
  # One focus level of any kind, then the Expert's non-combat and the Warrior's combat one.
@@ -226,6 +226,7 @@ actions:
226
226
  kind: action
227
227
  use: starting-gear
228
228
  - id: hitPoints
229
+ tags: [creation.finish]
229
230
  kind: changes
230
231
  sheet: proposed
231
232
  changes:
@@ -238,9 +239,10 @@ actions:
238
239
  - { type: finishCreation }
239
240
  - { id: result, kind: outcome, result: "'created'" }
240
241
 
241
- # The quick tables: class and style (d8), background (d20), two psychic disciplines (d6) for
242
- # a psychic, foci (d6 on the style's row) and a bonus skill (d20). With `random`, every table
243
- # is rolled; otherwise each is a pick.
242
+ # The quick tables: class and style (a d8 over the book's eight styles; add-on packs may add
243
+ # styles), background (d20), two psychic disciplines (d6) for a psychic, foci (d6 on the
244
+ # style's row) and a bonus skill (d20). With `random`, every table is rolled; otherwise each is
245
+ # a pick.
244
246
  - id: quick-character
245
247
  tags: [creation]
246
248
  available: character.creating && countCopies(copy.type == 'class') == 0
@@ -251,35 +253,19 @@ actions:
251
253
  - id: style
252
254
  kind: choice
253
255
  random: params.random
254
- recommend: options[0]
255
- options:
256
- - id: expert-smart
257
- flags: { style: 0, class: "'classes.expert'", scores: '[10, 12, 11, 14, 7, 9]' }
258
- - id: expert-smooth
259
- flags: { style: 1, class: "'classes.expert'", scores: '[7, 9, 10, 12, 11, 14]' }
260
- - id: expert-nimble
261
- flags: { style: 2, class: "'classes.expert'", scores: '[10, 14, 12, 11, 9, 7]' }
262
- - id: warrior-melee
263
- flags: { style: 3, class: "'classes.warrior'", scores: '[14, 9, 12, 7, 10, 11]' }
264
- - id: warrior-ranged
265
- flags: { style: 4, class: "'classes.warrior'", scores: '[9, 14, 12, 10, 7, 11]' }
266
- - id: warrior-leader
267
- flags: { style: 5, class: "'classes.warrior'", scores: '[7, 10, 9, 11, 12, 14]' }
268
- - id: psychic-seer
269
- flags: { style: 6, class: "'classes.psychic'", scores: '[9, 11, 12, 10, 14, 7]' }
270
- - id: psychic-adept
271
- flags: { style: 7, class: "'classes.psychic'", scores: '[12, 10, 14, 9, 11, 7]' }
256
+ recommend: 'filterList([@styles.expert-smart, options[0]], x in options)[0]'
257
+ options: { content: { type: style } }
272
258
  - id: setup
273
259
  kind: changes
274
260
  changes:
275
261
  - type: addItem
276
- entry: { id: class, item: flags.class }
277
- - { type: set, field: attributes.str.score, value: 'flags.scores[0]' }
278
- - { type: set, field: attributes.dex.score, value: 'flags.scores[1]' }
279
- - { type: set, field: attributes.con.score, value: 'flags.scores[2]' }
280
- - { type: set, field: attributes.int.score, value: 'flags.scores[3]' }
281
- - { type: set, field: attributes.wis.score, value: 'flags.scores[4]' }
282
- - { type: set, field: attributes.cha.score, value: 'flags.scores[5]' }
262
+ entry: { id: class, item: steps.style.item.class }
263
+ - { type: set, field: attributes.str.score, value: steps.style.item.str }
264
+ - { type: set, field: attributes.dex.score, value: steps.style.item.dex }
265
+ - { type: set, field: attributes.con.score, value: steps.style.item.con }
266
+ - { type: set, field: attributes.int.score, value: steps.style.item.int }
267
+ - { type: set, field: attributes.wis.score, value: steps.style.item.wis }
268
+ - { type: set, field: attributes.cha.score, value: steps.style.item.cha }
283
269
  - id: background
284
270
  kind: choice
285
271
  random: params.random
@@ -302,16 +288,21 @@ actions:
302
288
  params: { entry: steps.background.item.quick2, random: params.random }
303
289
  - id: psychic1
304
290
  kind: action
305
- when: flags.style >= 6
291
+ sheet: proposed
292
+ when: "psionics.access == 'unrestricted'"
306
293
  use: gain-skill
307
294
  params: { entry: "'any-psychic'", random: params.random }
308
295
  - id: psychic2
309
296
  kind: action
310
- when: flags.style >= 6
297
+ sheet: proposed
298
+ when: "psionics.access == 'unrestricted'"
311
299
  use: gain-skill
312
300
  params: { entry: "'any-psychic'", random: params.random }
301
+ # A style with a row of the book's foci table rolls on it; another (an add-on pack's) picks
302
+ # foci as the full procedure does.
313
303
  - id: focusRoll
314
304
  kind: choice
305
+ when: has(steps.style.item.table)
315
306
  random: params.random
316
307
  recommend: options[0]
317
308
  options:
@@ -325,23 +316,28 @@ actions:
325
316
  - id: foci
326
317
  kind: branch
327
318
  cases:
319
+ - when: '!has(steps.style.item.table)'
320
+ flags: { foci: '[]' }
328
321
  - when: true
329
322
  flags:
330
323
  foci: >-
331
- [[[['specialist', 'fix', 'fix'], ['die-hard', 'none', '']], [['hacker', 'program', ''], ['tinker', 'fix', '']], [['specialist', 'know', 'know'], ['healer', 'heal', '']], [['specialist', 'fix', 'fix'], ['tinker', 'fix', '']], [['healer', 'heal', ''], ['ironhide', 'none', '']], [['specialist', 'fix', 'fix'], ['hacker', 'program', '']]], [[['diplomat', 'talk', ''], ['connected', 'connect', '']], [['specialist', 'talk', 'talk'], ['die-hard', 'none', '']], [['diplomat', 'talk', ''], ['alert', 'notice', '']], [['specialist', 'lead', 'lead'], ['authority', 'lead', '']], [['healer', 'heal', ''], ['specialist', 'talk', 'talk']], [['specialist', 'notice', 'notice'], ['specialist', 'talk', 'talk']]], [[['specialist', 'pilot', 'pilot'], ['starfarer', 'pilot', '']], [['healer', 'heal', ''], ['die-hard', 'none', '']], [['tinker', 'fix', ''], ['gunslinger', 'shoot', '']], [['specialist', 'sneak', 'sneak'], ['assassin', 'sneak', '']], [['specialist', 'sneak', 'sneak'], ['specialist', 'exert', 'exert']], [['specialist', 'perform', 'perform'], ['specialist', 'sneak', 'sneak']]], [[['savage-fray', 'stab', ''], ['shocking-assault', 'punch-or-stab', '']], [['assassin', 'sneak', ''], ['specialist', 'sneak', 'sneak']], [['armsman', 'stab', ''], ['close-combatant', 'any-combat', '']], [['close-combatant', 'any-combat', ''], ['savage-fray', 'stab', '']], [['ironhide', 'none', ''], ['die-hard', 'none', '']], [['unarmed-combatant', 'punch', ''], ['close-combatant', 'any-combat', '']]], [[['gunslinger', 'shoot', ''], ['close-combatant', 'any-combat', '']], [['sniper', 'shoot', ''], ['specialist', 'sneak', 'sneak']], [['assassin', 'sneak', ''], ['specialist', 'sneak', 'sneak']], [['ironhide', 'none', ''], ['die-hard', 'none', '']], [['gunslinger', 'shoot', ''], ['tinker', 'fix', '']], [['close-combatant', 'any-combat', ''], ['alert', 'notice', '']]], [[['gunslinger', 'shoot', ''], ['authority', 'lead', '']], [['ironhide', 'none', ''], ['connected', 'connect', '']], [['armsman', 'stab', ''], ['specialist', 'lead', 'lead']], [['gunslinger', 'shoot', ''], ['specialist', 'talk', 'talk']], [['assassin', 'sneak', ''], ['die-hard', 'none', '']], [['close-combatant', 'any-combat', ''], ['henchkeeper', 'lead', '']]], [[['alert', 'notice', '']], [['healer', 'heal', '']], [['specialist', 'notice', 'notice']], [['psychic-training', 'any-psychic', '']], [['savage-fray', 'stab', '']], [['hacker', 'program', '']]], [[['armsman', 'stab', '']], [['ironhide', 'none', '']], [['die-hard', 'none', '']], [['psychic-training', 'any-psychic', '']], [['healer', 'heal', '']], [['unarmed-combatant', 'punch', '']]]][flags.style][flags.row]
324
+ [[[['specialist', 'fix', 'fix'], ['die-hard', 'none', '']], [['hacker', 'program', ''], ['tinker', 'fix', '']], [['specialist', 'know', 'know'], ['healer', 'heal', '']], [['specialist', 'fix', 'fix'], ['tinker', 'fix', '']], [['healer', 'heal', ''], ['ironhide', 'none', '']], [['specialist', 'fix', 'fix'], ['hacker', 'program', '']]], [[['diplomat', 'talk', ''], ['connected', 'connect', '']], [['specialist', 'talk', 'talk'], ['die-hard', 'none', '']], [['diplomat', 'talk', ''], ['alert', 'notice', '']], [['specialist', 'lead', 'lead'], ['authority', 'lead', '']], [['healer', 'heal', ''], ['specialist', 'talk', 'talk']], [['specialist', 'notice', 'notice'], ['specialist', 'talk', 'talk']]], [[['specialist', 'pilot', 'pilot'], ['starfarer', 'pilot', '']], [['healer', 'heal', ''], ['die-hard', 'none', '']], [['tinker', 'fix', ''], ['gunslinger', 'shoot', '']], [['specialist', 'sneak', 'sneak'], ['assassin', 'sneak', '']], [['specialist', 'sneak', 'sneak'], ['specialist', 'exert', 'exert']], [['specialist', 'perform', 'perform'], ['specialist', 'sneak', 'sneak']]], [[['savage-fray', 'stab', ''], ['shocking-assault', 'punch-or-stab', '']], [['assassin', 'sneak', ''], ['specialist', 'sneak', 'sneak']], [['armsman', 'stab', ''], ['close-combatant', 'any-combat', '']], [['close-combatant', 'any-combat', ''], ['savage-fray', 'stab', '']], [['ironhide', 'none', ''], ['die-hard', 'none', '']], [['unarmed-combatant', 'punch', ''], ['close-combatant', 'any-combat', '']]], [[['gunslinger', 'shoot', ''], ['close-combatant', 'any-combat', '']], [['sniper', 'shoot', ''], ['specialist', 'sneak', 'sneak']], [['assassin', 'sneak', ''], ['specialist', 'sneak', 'sneak']], [['ironhide', 'none', ''], ['die-hard', 'none', '']], [['gunslinger', 'shoot', ''], ['tinker', 'fix', '']], [['close-combatant', 'any-combat', ''], ['alert', 'notice', '']]], [[['gunslinger', 'shoot', ''], ['authority', 'lead', '']], [['ironhide', 'none', ''], ['connected', 'connect', '']], [['armsman', 'stab', ''], ['specialist', 'lead', 'lead']], [['gunslinger', 'shoot', ''], ['specialist', 'talk', 'talk']], [['assassin', 'sneak', ''], ['die-hard', 'none', '']], [['close-combatant', 'any-combat', ''], ['henchkeeper', 'lead', '']]], [[['alert', 'notice', '']], [['healer', 'heal', '']], [['specialist', 'notice', 'notice']], [['psychic-training', 'any-psychic', '']], [['savage-fray', 'stab', '']], [['hacker', 'program', '']]], [[['armsman', 'stab', '']], [['ironhide', 'none', '']], [['die-hard', 'none', '']], [['psychic-training', 'any-psychic', '']], [['healer', 'heal', '']], [['unarmed-combatant', 'punch', '']]]][steps.style.item.table][flags.row]
332
325
  - id: focus1
333
326
  kind: changes
327
+ when: size(flags.foci) > 0
334
328
  changes:
335
329
  - type: addItem
336
330
  entry: { item: "'foci.' + flags.foci[0][0]" }
337
331
  - id: focusSkill1
338
332
  kind: action
333
+ when: size(flags.foci) > 0
339
334
  use: gain-skill
340
335
  params:
341
336
  entry: "flags.foci[0][0] == 'specialist' ? flags.foci[0][2] : flags.foci[0][1]"
342
337
  random: params.random
343
338
  - id: focusPicks1
344
339
  kind: choice
340
+ when: size(flags.foci) > 0
345
341
  options: { pending: { entry: 'steps.focus1.added[0]' } }
346
342
  recommend: >-
347
343
  choice.id == 'skill' ? flags.foci[0][2]
@@ -370,6 +366,23 @@ actions:
370
366
  : choice.id == 'discipline' && has(steps.focusSkill2.data)
371
367
  && steps.focusSkill2.data.skill in options ? steps.focusSkill2.data.skill
372
368
  : options[0]
369
+ - id: anyFocus
370
+ kind: action
371
+ when: '!has(steps.style.item.table)'
372
+ use: gain-focus
373
+ params: { random: params.random }
374
+ - id: noncombatFocus
375
+ kind: action
376
+ sheet: proposed
377
+ when: '!has(steps.style.item.table) && class.focus.noncombat > 0'
378
+ use: gain-focus
379
+ params: { kind: "'noncombat'", random: params.random }
380
+ - id: combatFocus
381
+ kind: action
382
+ sheet: proposed
383
+ when: '!has(steps.style.item.table) && class.focus.combat > 0'
384
+ use: gain-focus
385
+ params: { kind: "'combat'", random: params.random }
373
386
  # The d20 table: every non-psychic skill in order, then a level-0 skill raised to level-1.
374
387
  - id: bonus
375
388
  kind: choice
@@ -390,6 +403,7 @@ actions:
390
403
  use: starting-gear
391
404
  params: { random: params.random }
392
405
  - id: hitPoints
406
+ tags: [creation.finish]
393
407
  kind: changes
394
408
  sheet: proposed
395
409
  changes:
package/rules/tags.yaml CHANGED
@@ -48,9 +48,20 @@ tags:
48
48
  - health
49
49
  - combat
50
50
  - psionics
51
+ # Foci open only to a character with psionic access, or only to one without.
52
+ - needs-psionics
53
+ - no-psionics
51
54
  - strain
52
55
  - torch
53
56
  - creation
57
+ # Choice and changes steps an add-on pack's rules effects reach.
58
+ - creation.focus
59
+ - creation.kit
60
+ - creation.finish
61
+ - level-up.focus
62
+ - level-up.level
63
+ - rest.night
64
+ - rest.scene
54
65
  - level-up
55
66
  - failed-check
56
67
  - missed-attack