@opencharacter/orc-2e 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 (39) hide show
  1. package/README.md +7 -6
  2. package/content/backgrounds/driver.yaml +3 -3
  3. package/content/backgrounds/farmhand.yaml +1 -1
  4. package/content/backgrounds/miner.yaml +1 -1
  5. package/content/backgrounds/nomad.yaml +1 -1
  6. package/content/backgrounds/raised-by-belief.yaml +16 -16
  7. package/content/backgrounds/scholar.yaml +4 -4
  8. package/content/classes/champion/resistance.yaml +2 -0
  9. package/content/classes/wizard.yaml +0 -6
  10. package/content/feats/ancestry/changeling-lore.yaml +3 -1
  11. package/content/feats/archetype/gladiator/gladiator-dedication.yaml +1 -1
  12. package/content/feats/archetype/scout/terrain-scout.yaml +6 -0
  13. package/content/feats/archetype/viking/viking-dedication.yaml +3 -1
  14. package/content/feats/skill/additional-lore.yaml +12 -0
  15. package/content/feats/skill/assurance.yaml +8 -30
  16. package/content/feats/skill/terrain-stalker.yaml +1 -0
  17. package/content/features/wizard/arcane-bond.yaml +8 -4
  18. package/content/heritages/deep-orc.yaml +3 -1
  19. package/content/heritages/woodstalker-lizardfolk.yaml +3 -1
  20. package/content/spells/enduring-might.yaml +2 -0
  21. package/content/spells/energy-absorption.yaml +2 -0
  22. package/content/spells/fire-shield.yaml +31 -0
  23. package/content/spells/flame-barrier.yaml +2 -0
  24. package/content/spells/shield.yaml +2 -0
  25. package/dist/i18n/en.js +1 -1
  26. package/dist/i18n/en.json +14 -2
  27. package/dist/index.js +1 -1
  28. package/dist/release.json +1532 -799
  29. package/i18n/en/archetypes.yaml +4 -0
  30. package/i18n/en/lores-pc2.yaml +6 -0
  31. package/i18n/en/spellcasting.yaml +1 -0
  32. package/i18n/en/spells-high.yaml +1 -0
  33. package/i18n/en/wizard.yaml +2 -2
  34. package/pack.yaml +2 -2
  35. package/package.json +2 -2
  36. package/rules/lores-pc2.yaml +47 -0
  37. package/rules/spellcasting.yaml +11 -4
  38. package/rules/wizard.yaml +1 -1
  39. package/upgrades/0.1.0-to-0.2.0.yaml +11 -0
package/README.md CHANGED
@@ -28,9 +28,9 @@ const { ruleset } = loaded;
28
28
 
29
29
  // A new character, made by the random creation start: every pick is drawn, so it finishes.
30
30
  const blank = {
31
- specVersion: '0.1.0',
31
+ specVersion: '0.2.0',
32
32
  id: 'new-character',
33
- packs: [{ id: 'orc-2e', version: '0.1.0' }],
33
+ packs: [{ id: 'orc-2e', version: '0.2.0' }],
34
34
  creating: true,
35
35
  };
36
36
  const created = startAction(ruleset, blank, {
@@ -271,7 +271,7 @@ reading is listed under [Rule readings](#rule-readings).
271
271
  first of three Lores of the player's choice, named by the subject the player writes
272
272
  (`skills.lore.custom1.subject`); Additional Lore offers all three. Assurance (farmhand, nomad, raised by belief, scholar) is an action for the skill it's
273
273
  chosen for: a fixed 10 + the proficiency bonus against the DC, no dice and no other bonus or
274
- penalty. Content can grant Assurance for a named skill (the grant's `skill` state): each background's Assurance is for the skill the book names (the driver's Lore, the scholar's and raised by belief's chosen skill, an inline option each). Player Core 2's eight new Lores and its
274
+ penalty. Its skill is a pick (any skill, or a trained Lore), which content granting Assurance for a named skill presets: each background's Assurance is for the skill the book names (the driver's Lore, the scholar's and raised by belief's chosen skill, an inline option each). Player Core 2's eight new Lores and its
275
275
  ten ancestry Lores are `rules/lores-pc2.yaml`; the cursed background's Warding Sign is the
276
276
  situational choice `wardingSign`, the feybound's Fey's Fortune `fortune`.
277
277
  - **Feats:** a slot per level for ancestry (1, 5, 9, 13, 17), general (3, 7, 11, 15, 19; skill feats
@@ -428,8 +428,9 @@ reading is listed under [Rule readings](#rule-readings).
428
428
  `prepare-spells` (inputs per rank the slot counts read); Improved Familiar Attunement
429
429
  and Staff Nexus text). Split Slot: `prepare-spells` may put a second
430
430
  spell in one slot below the highest rank, its copy naming the first's (`split`); casting either
431
- expends both. Drain Bonded Item is an action (the ranks drained today are the
432
- class copy's state, which `daily-preparations` clears). Feats: Counterspell (the expending),
431
+ expends both. Drain Bonded Item is an action (the ranks drained today, `bondDrained`, and
432
+ Linked Focus's `linkedFocusUsed` are Arcane Bond's saved grant state, which `daily-preparations`
433
+ clears). Feats: Counterspell (the expending),
433
434
  Linked Focus and twelve more, text where they shape a spell's range, area or traits.
434
435
  - **The cleric** (Player Core): Wisdom, divine prepared, and the divine font's 4 to 6 extra slots
435
436
  of heal or harm at the highest rank (to 9th), which `prepare-spells` fills. The deity is the
@@ -825,7 +826,7 @@ reads it as below. These are the pack's provisional calls; a table may rule othe
825
826
  any other Lore is a homebrew increases input and a trained-by-increase input (tagged
826
827
  `skill-increase`, they join level-up) and rank and modifier fields, trained by a homebrew
827
828
  effect granting its tag into `skills.trained`. The class's free skills and `extra-training`
828
- offer the first seven Lores only: a value choice lists its values.
829
+ offer the first seven Lores only: their lists are written out, as no formula lists fields by tag.
829
830
 
830
831
  ## Sources
831
832
 
@@ -1,6 +1,6 @@
1
1
  id: backgrounds.driver
2
2
  type: background
3
- # Assurance gets the picked Lore through its `skill` state, so its own choice isn't asked.
3
+ # Assurance's skill choice is preset to the picked Lore.
4
4
  effects:
5
5
  - target: skills.trained
6
6
  op: grant
@@ -27,7 +27,7 @@ choices:
27
27
  }
28
28
  - { target: skills.trainings, op: add, value: 1 }
29
29
  grants:
30
- - { item: feats.skill.assurance, state: { skill: "'skill.lore.driving'" } }
30
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.lore.driving }] } }
31
31
  - id: piloting
32
32
  effects:
33
33
  - {
@@ -38,4 +38,4 @@ choices:
38
38
  }
39
39
  - { target: skills.trainings, op: add, value: 1 }
40
40
  grants:
41
- - { item: feats.skill.assurance, state: { skill: "'skill.lore.piloting'" } }
41
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.lore.piloting }] } }
@@ -15,7 +15,7 @@ effects:
15
15
  }
16
16
  - { target: skills.trainings, op: add, value: 2 }
17
17
  grants:
18
- - { item: feats.skill.assurance, state: { skill: "'skill.athletics'" } }
18
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.athletics }] } }
19
19
  choices:
20
20
  - id: boost
21
21
  unique: background-boosts
@@ -15,7 +15,7 @@ effects:
15
15
  }
16
16
  - { target: skills.trainings, op: add, value: 2 }
17
17
  grants:
18
- - item: feats.skill.terrain-expertise
18
+ - { item: feats.skill.terrain-expertise, choices: { terrain: [{ option: underground }] } }
19
19
  choices:
20
20
  - id: boost
21
21
  unique: background-boosts
@@ -9,7 +9,7 @@ effects:
9
9
  }
10
10
  - { target: skills.trainings, op: add, value: 1 }
11
11
  grants:
12
- - { item: feats.skill.assurance, state: { skill: "'skill.survival'" } }
12
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.survival }] } }
13
13
  choices:
14
14
  - id: boost
15
15
  unique: background-boosts
@@ -28,7 +28,7 @@ choices:
28
28
  when: "!('skill.acrobatics' in skills.chosen)"
29
29
  - { target: skills.trainings, op: add, value: 1 }
30
30
  grants:
31
- - { item: feats.skill.assurance, state: { skill: "'skill.acrobatics'" } }
31
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.acrobatics }] } }
32
32
  - id: arcana
33
33
  effects:
34
34
  - target: skills.trained
@@ -37,7 +37,7 @@ choices:
37
37
  when: "!('skill.arcana' in skills.chosen)"
38
38
  - { target: skills.trainings, op: add, value: 1 }
39
39
  grants:
40
- - { item: feats.skill.assurance, state: { skill: "'skill.arcana'" } }
40
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.arcana }] } }
41
41
  - id: athletics
42
42
  effects:
43
43
  - target: skills.trained
@@ -46,7 +46,7 @@ choices:
46
46
  when: "!('skill.athletics' in skills.chosen)"
47
47
  - { target: skills.trainings, op: add, value: 1 }
48
48
  grants:
49
- - { item: feats.skill.assurance, state: { skill: "'skill.athletics'" } }
49
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.athletics }] } }
50
50
  - id: crafting
51
51
  effects:
52
52
  - target: skills.trained
@@ -55,7 +55,7 @@ choices:
55
55
  when: "!('skill.crafting' in skills.chosen)"
56
56
  - { target: skills.trainings, op: add, value: 1 }
57
57
  grants:
58
- - { item: feats.skill.assurance, state: { skill: "'skill.crafting'" } }
58
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.crafting }] } }
59
59
  - id: deception
60
60
  effects:
61
61
  - target: skills.trained
@@ -64,7 +64,7 @@ choices:
64
64
  when: "!('skill.deception' in skills.chosen)"
65
65
  - { target: skills.trainings, op: add, value: 1 }
66
66
  grants:
67
- - { item: feats.skill.assurance, state: { skill: "'skill.deception'" } }
67
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.deception }] } }
68
68
  - id: diplomacy
69
69
  effects:
70
70
  - target: skills.trained
@@ -73,7 +73,7 @@ choices:
73
73
  when: "!('skill.diplomacy' in skills.chosen)"
74
74
  - { target: skills.trainings, op: add, value: 1 }
75
75
  grants:
76
- - { item: feats.skill.assurance, state: { skill: "'skill.diplomacy'" } }
76
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.diplomacy }] } }
77
77
  - id: intimidation
78
78
  effects:
79
79
  - target: skills.trained
@@ -82,7 +82,7 @@ choices:
82
82
  when: "!('skill.intimidation' in skills.chosen)"
83
83
  - { target: skills.trainings, op: add, value: 1 }
84
84
  grants:
85
- - { item: feats.skill.assurance, state: { skill: "'skill.intimidation'" } }
85
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.intimidation }] } }
86
86
  - id: medicine
87
87
  effects:
88
88
  - target: skills.trained
@@ -91,7 +91,7 @@ choices:
91
91
  when: "!('skill.medicine' in skills.chosen)"
92
92
  - { target: skills.trainings, op: add, value: 1 }
93
93
  grants:
94
- - { item: feats.skill.assurance, state: { skill: "'skill.medicine'" } }
94
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.medicine }] } }
95
95
  - id: nature
96
96
  effects:
97
97
  - target: skills.trained
@@ -100,7 +100,7 @@ choices:
100
100
  when: "!('skill.nature' in skills.chosen)"
101
101
  - { target: skills.trainings, op: add, value: 1 }
102
102
  grants:
103
- - { item: feats.skill.assurance, state: { skill: "'skill.nature'" } }
103
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.nature }] } }
104
104
  - id: occultism
105
105
  effects:
106
106
  - target: skills.trained
@@ -109,7 +109,7 @@ choices:
109
109
  when: "!('skill.occultism' in skills.chosen)"
110
110
  - { target: skills.trainings, op: add, value: 1 }
111
111
  grants:
112
- - { item: feats.skill.assurance, state: { skill: "'skill.occultism'" } }
112
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.occultism }] } }
113
113
  - id: performance
114
114
  effects:
115
115
  - target: skills.trained
@@ -118,7 +118,7 @@ choices:
118
118
  when: "!('skill.performance' in skills.chosen)"
119
119
  - { target: skills.trainings, op: add, value: 1 }
120
120
  grants:
121
- - { item: feats.skill.assurance, state: { skill: "'skill.performance'" } }
121
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.performance }] } }
122
122
  - id: religion
123
123
  effects:
124
124
  - target: skills.trained
@@ -127,7 +127,7 @@ choices:
127
127
  when: "!('skill.religion' in skills.chosen)"
128
128
  - { target: skills.trainings, op: add, value: 1 }
129
129
  grants:
130
- - { item: feats.skill.assurance, state: { skill: "'skill.religion'" } }
130
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.religion }] } }
131
131
  - id: society
132
132
  effects:
133
133
  - target: skills.trained
@@ -136,7 +136,7 @@ choices:
136
136
  when: "!('skill.society' in skills.chosen)"
137
137
  - { target: skills.trainings, op: add, value: 1 }
138
138
  grants:
139
- - { item: feats.skill.assurance, state: { skill: "'skill.society'" } }
139
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.society }] } }
140
140
  - id: stealth
141
141
  effects:
142
142
  - target: skills.trained
@@ -145,7 +145,7 @@ choices:
145
145
  when: "!('skill.stealth' in skills.chosen)"
146
146
  - { target: skills.trainings, op: add, value: 1 }
147
147
  grants:
148
- - { item: feats.skill.assurance, state: { skill: "'skill.stealth'" } }
148
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.stealth }] } }
149
149
  - id: survival
150
150
  effects:
151
151
  - target: skills.trained
@@ -154,7 +154,7 @@ choices:
154
154
  when: "!('skill.survival' in skills.chosen)"
155
155
  - { target: skills.trainings, op: add, value: 1 }
156
156
  grants:
157
- - { item: feats.skill.assurance, state: { skill: "'skill.survival'" } }
157
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.survival }] } }
158
158
  - id: thievery
159
159
  effects:
160
160
  - target: skills.trained
@@ -163,4 +163,4 @@ choices:
163
163
  when: "!('skill.thievery' in skills.chosen)"
164
164
  - { target: skills.trainings, op: add, value: 1 }
165
165
  grants:
166
- - { item: feats.skill.assurance, state: { skill: "'skill.thievery'" } }
166
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.thievery }] } }
@@ -26,7 +26,7 @@ choices:
26
26
  when: "!('skill.arcana' in skills.chosen)"
27
27
  - { target: skills.trainings, op: add, value: 1 }
28
28
  grants:
29
- - { item: feats.skill.assurance, state: { skill: "'skill.arcana'" } }
29
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.arcana }] } }
30
30
  - id: nature
31
31
  effects:
32
32
  - target: skills.trained
@@ -35,7 +35,7 @@ choices:
35
35
  when: "!('skill.nature' in skills.chosen)"
36
36
  - { target: skills.trainings, op: add, value: 1 }
37
37
  grants:
38
- - { item: feats.skill.assurance, state: { skill: "'skill.nature'" } }
38
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.nature }] } }
39
39
  - id: occultism
40
40
  effects:
41
41
  - target: skills.trained
@@ -44,7 +44,7 @@ choices:
44
44
  when: "!('skill.occultism' in skills.chosen)"
45
45
  - { target: skills.trainings, op: add, value: 1 }
46
46
  grants:
47
- - { item: feats.skill.assurance, state: { skill: "'skill.occultism'" } }
47
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.occultism }] } }
48
48
  - id: religion
49
49
  effects:
50
50
  - target: skills.trained
@@ -53,4 +53,4 @@ choices:
53
53
  when: "!('skill.religion' in skills.chosen)"
54
54
  - { target: skills.trainings, op: add, value: 1 }
55
55
  grants:
56
- - { item: feats.skill.assurance, state: { skill: "'skill.religion'" } }
56
+ - { item: feats.skill.assurance, choices: { skill: [{ option: skill.religion }] } }
@@ -9,3 +9,5 @@ effects:
9
9
  value: min(-incoming.amount, self.amount)
10
10
  when: incoming.amount < 0 && 'damage' in incoming.tags
11
11
  scope: applied
12
+ then:
13
+ - { type: removeEffect, entry: self }
@@ -3,12 +3,6 @@ type: class
3
3
  tags: [trait.wizard]
4
4
  fields: { hp: 6 }
5
5
  # Every pick that adds to the spellbook shares `unique: spellbook`, so no spell is added twice.
6
- # Drain Bonded Item's use today is the class copy's state `bondDrained`, a bit per rank drained (1
7
- # for 1st, 2 for 2nd, 4 for 3rd, …), and Linked Focus's `linkedFocusUsed`; daily preparations reset
8
- # both.
9
- state:
10
- bondDrained: { type: integer, default: 0, min: 0, max: 511 }
11
- linkedFocusUsed: { type: boolean, default: false }
12
6
  effects:
13
7
  # The class's trait, for content that reads the class by it (such as Natural Ambition).
14
8
  - { target: class.traits, op: grant, value: { tag: trait.wizard } }
@@ -16,4 +16,6 @@ effects:
16
16
  }
17
17
  - { target: skills.trainings, op: add, value: 2 }
18
18
  grants:
19
- - { item: feats.skill.additional-lore, waivePrerequisites: true }
19
+ - item: feats.skill.additional-lore
20
+ waivePrerequisites: true
21
+ choices: { lore: [{ option: hag }] }
@@ -6,4 +6,4 @@ fields: { level: 2, category: class, archetype: archetypes.gladiator }
6
6
  prerequisites:
7
7
  - { id: impressive-performance, when: '@feats.skill.impressive-performance in feats.held' }
8
8
  grants:
9
- - { item: feats.skill.additional-lore }
9
+ - { item: feats.skill.additional-lore, choices: { lore: [{ option: gladiatorial }] } }
@@ -7,3 +7,9 @@ prerequisites:
7
7
  - { id: scout-dedication, when: '@feats.archetype.scout.scout-dedication in feats.held' }
8
8
  grants:
9
9
  - { item: feats.skill.terrain-stalker, waivePrerequisites: true }
10
+ # The second Terrain Stalker is written out as the feat's own terrain choice: a second grant of
11
+ # the feat would share the first's picks. Terrain Stalker has no effects beyond its terrain.
12
+ choices:
13
+ - id: terrain
14
+ unique: terrain-stalker
15
+ from: { values: [rubble, snow, underbrush] }
@@ -15,6 +15,8 @@ effects:
15
15
  - target: { fields: { where: "'archetype-extra.at10' in item.tags" } }
16
16
  op: grant
17
17
  value: { item: feats.fighter.quick-shield-block }
18
+ # Additional Lore for Warfare Lore is written out: a second grant of the feat would share the
19
+ # first's picks.
18
20
  - {
19
21
  target: skills.trained,
20
22
  op: grant,
@@ -26,4 +28,4 @@ effects:
26
28
  op: add
27
29
  value: '(level >= 3 ? 1 : 0) + (level >= 7 ? 1 : 0) + (level >= 15 ? 1 : 0)'
28
30
  grants:
29
- - item: feats.skill.additional-lore
31
+ - { item: feats.skill.additional-lore, choices: { lore: [{ option: sailing }] } }
@@ -655,6 +655,18 @@ choices:
655
655
  - target: skills.lore.vampire.rank
656
656
  op: add
657
657
  value: '(level >= 3 ? 1 : 0) + (level >= 7 ? 1 : 0) + (level >= 15 ? 1 : 0)'
658
+ - id: hag
659
+ effects:
660
+ - {
661
+ target: skills.trained,
662
+ op: grant,
663
+ value: { tag: skill.lore.hag },
664
+ when: "!('skill.lore.hag' in skills.chosen)",
665
+ }
666
+ - { target: skills.trainings, op: add, value: 1 }
667
+ - target: skills.lore.hag.rank
668
+ op: add
669
+ value: '(level >= 3 ? 1 : 0) + (level >= 7 ? 1 : 0) + (level >= 15 ? 1 : 0)'
658
670
  - id: custom1
659
671
  effects:
660
672
  - {
@@ -4,40 +4,18 @@ tags: [trait.fortune]
4
4
  fields: { level: 1, category: skill, skills: [skill] }
5
5
  repeatable: true
6
6
 
7
- # Content that grants Assurance for a skill it names passes it as the grant's `skill` state, and the
8
- # choice isn't asked.
9
- state:
10
- skill: { type: string, default: '' }
11
- effects:
12
- - {
13
- target: assurance.skills,
14
- op: grant,
15
- value: { formula: self.skill },
16
- when: "has(self.skill) && self.skill != ''",
17
- }
7
+ # Any skill, or a Lore the character is trained in. Content that grants Assurance for a skill it
8
+ # names presets the choice.
18
9
  choices:
19
10
  - id: skill
20
- when: "!has(self.skill) || self.skill == ''"
21
11
  from:
22
12
  values:
23
- [
24
- skill.acrobatics,
25
- skill.arcana,
26
- skill.athletics,
27
- skill.crafting,
28
- skill.deception,
29
- skill.diplomacy,
30
- skill.intimidation,
31
- skill.medicine,
32
- skill.nature,
33
- skill.occultism,
34
- skill.performance,
35
- skill.religion,
36
- skill.society,
37
- skill.stealth,
38
- skill.survival,
39
- skill.thievery,
40
- ]
13
+ formula: >-
14
+ ['skill.acrobatics', 'skill.arcana', 'skill.athletics', 'skill.crafting',
15
+ 'skill.deception', 'skill.diplomacy', 'skill.intimidation', 'skill.medicine',
16
+ 'skill.nature', 'skill.occultism', 'skill.performance', 'skill.religion',
17
+ 'skill.society', 'skill.stealth', 'skill.survival', 'skill.thievery']
18
+ + sortList(skills.trained + skills.chosen)
41
19
  effects:
42
20
  - { target: assurance.skills, op: grant, value: { formula: pick.value } }
43
21
 
@@ -8,4 +8,5 @@ prerequisites:
8
8
  when: 'skills.stealth.rank >= 1'
9
9
  choices:
10
10
  - id: terrain
11
+ unique: terrain-stalker
11
12
  from: { values: [rubble, snow, underbrush] }
@@ -1,8 +1,12 @@
1
1
  id: features.wizard.arcane-bond
2
2
  type: feature
3
3
  fields: { level: 1 }
4
- # The ranks drained today are the class copy's `bondDrained` (bit `2^(rank - 1)` each). With
5
- # Improved Familiar Attunement this is Drain Familiar.
4
+ # The ranks drained today are its `bondDrained` (bit `2^(rank - 1)` each), and Linked Focus's use
5
+ # its `linkedFocusUsed`; daily preparations reset both. With Improved Familiar Attunement this is
6
+ # Drain Familiar.
7
+ state:
8
+ bondDrained: { type: integer, default: 0, min: 0, max: 511 }
9
+ linkedFocusUsed: { type: boolean, default: false }
6
10
  actions:
7
11
  - id: drain-bonded-item
8
12
  tags: [class-action, spell]
@@ -30,7 +34,7 @@ actions:
30
34
  kind: changes
31
35
  changes:
32
36
  - type: adjustState
33
- entry: self
37
+ grant: self
34
38
  key: bondDrained
35
39
  by: '[1, 2, 4, 8, 16, 32, 64, 128, 256][steps.spell.self.rank - 1]'
36
40
  - id: linked
@@ -40,7 +44,7 @@ actions:
40
44
  && steps.spell.item.id in spells.curriculum && focus.spent > 0
41
45
  changes:
42
46
  - { type: adjust, field: focus.spent, by: -1 }
43
- - { type: setState, entry: self, key: linkedFocusUsed, value: true }
47
+ - { type: setState, grant: self, key: linkedFocusUsed, value: true }
44
48
  - id: result
45
49
  kind: outcome
46
50
  result: "'drained'"
@@ -2,5 +2,7 @@ id: heritages.deep-orc
2
2
  type: heritage
3
3
  fields: { ancestry: ancestries.orc }
4
4
  grants:
5
- - { item: feats.skill.terrain-expertise, waivePrerequisites: true }
5
+ - item: feats.skill.terrain-expertise
6
+ waivePrerequisites: true
7
+ choices: { terrain: [{ option: underground }] }
6
8
  - { item: feats.skill.combat-climber, waivePrerequisites: true }
@@ -2,4 +2,6 @@ id: heritages.woodstalker-lizardfolk
2
2
  type: heritage
3
3
  fields: { ancestry: ancestries.lizardfolk }
4
4
  grants:
5
- - { item: feats.skill.terrain-stalker, waivePrerequisites: true }
5
+ - item: feats.skill.terrain-stalker
6
+ waivePrerequisites: true
7
+ choices: { terrain: [{ option: underbrush }] }
@@ -12,3 +12,5 @@ effects:
12
12
  value: min(-incoming.amount, 8 + attributes.str.mod + 2 * (self.rank - 4))
13
13
  when: incoming.amount < 0
14
14
  scope: applied
15
+ then:
16
+ - { type: removeEffect, entry: self }
@@ -16,3 +16,5 @@ effects:
16
16
  value: min(-incoming.amount, 15 + 5 * (self.rank - 4))
17
17
  when: incoming.amount < 0 && ('damage.' + self.damageType) in incoming.tags
18
18
  scope: applied
19
+ then:
20
+ - { type: removeEffect, entry: self }
@@ -7,6 +7,10 @@ fields:
7
7
  duration: minutes
8
8
  durationAmount: 1
9
9
  applyTo: self
10
+ # `blocked` is the Hit Points the shield has lost to Shield Block; at its Hit Points it is
11
+ # destroyed and the spell ends.
12
+ state:
13
+ blocked: { type: integer, default: 0, min: 0 }
10
14
  effects:
11
15
  - target:
12
16
  incoming:
@@ -17,3 +21,30 @@ effects:
17
21
  value: min(-incoming.amount, 5 + 5 * floor((self.rank - 4) / 2))
18
22
  when: incoming.amount < 0
19
23
  scope: applied
24
+ - target: { fields: { where: "'ac' in item.tags" } }
25
+ op: add
26
+ value: 1
27
+ stackKey: circumstance-bonus
28
+ when: shield.raised
29
+ scope: applied
30
+ - id: block
31
+ target: { incoming: { fields: [hp.current], tags: [damage] } }
32
+ op: add
33
+ value: min(10, -incoming.amount)
34
+ when: situational.fireShieldBlock && incoming.amount < 0
35
+ scope: applied
36
+ then:
37
+ - type: adjustState
38
+ entry: self
39
+ key: blocked
40
+ by: max(0, -incoming.amount - 10)
41
+ - id: destroyed
42
+ target: { incoming: { fields: [hp.current], tags: [damage] } }
43
+ op: add
44
+ value: 0
45
+ when: >-
46
+ situational.fireShieldBlock && incoming.amount < 0
47
+ && self.blocked + max(0, -incoming.amount - 10) >= 40 + 10 * floor((self.rank - 4) / 2)
48
+ scope: applied
49
+ then:
50
+ - { type: removeEffect, entry: self }
@@ -17,3 +17,5 @@ effects:
17
17
  value: min(-incoming.amount, 15 + 5 * floor((self.rank - 4) / 2))
18
18
  when: incoming.amount < 0
19
19
  scope: applied
20
+ then:
21
+ - { type: removeEffect, entry: self }
@@ -26,3 +26,5 @@ effects:
26
26
  value: min(5 + 5 * floor((self.rank - 1) / 2), -incoming.amount)
27
27
  when: situational.shieldSpellBlock && incoming.amount < 0
28
28
  scope: applied
29
+ then:
30
+ - { type: removeEffect, entry: self }