@opencharacter/5e-srd-5.1 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.
- package/README.md +7 -6
- package/content/classes/warlock.yaml +0 -7
- package/content/features/druid/natural-recovery.yaml +23 -45
- package/content/features/wizard/arcane-recovery.yaml +22 -67
- package/content/invocations/bewitching-whispers.yaml +9 -2
- package/content/invocations/dreadful-word.yaml +9 -2
- package/content/invocations/eldritch-spear.yaml +3 -2
- package/content/invocations/minions-of-chaos.yaml +9 -2
- package/content/invocations/mire-the-mind.yaml +9 -2
- package/content/invocations/sculptor-of-flesh.yaml +9 -2
- package/content/invocations/sign-of-ill-omen.yaml +9 -2
- package/content/invocations/thief-of-five-fates.yaml +9 -2
- package/content/races/half-orc.yaml +0 -2
- package/content/races/tiefling.yaml +0 -3
- package/content/spells/death-ward.yaml +11 -0
- package/content/spells/eldritch-blast.yaml +1 -1
- package/content/templates/eldritch-spear.yaml +4 -0
- package/content/traits/infernal-legacy.yaml +11 -2
- package/content/traits/relentless-endurance.yaml +5 -10
- package/dist/i18n/en.js +1 -1
- package/dist/i18n/en.json +24 -23
- package/dist/index.js +1 -1
- package/dist/release.json +1341 -2227
- package/i18n/en.yaml +24 -23
- package/pack.yaml +2 -2
- package/package.json +2 -2
- package/rules/classes.yaml +0 -1
- package/rules/combat.yaml +5 -0
- package/rules/content-types.yaml +3 -0
- package/rules/creation.yaml +6 -2
- package/rules/display.yaml +0 -6
- package/rules/monsters.yaml +1 -1
- package/rules/rest.yaml +13 -50
- package/rules/spellcasting.yaml +5 -0
- package/upgrades/0.1.0-to-0.2.0.yaml +62 -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.
|
|
31
|
+
specVersion: '0.2.0',
|
|
32
32
|
id: 'new-character',
|
|
33
|
-
packs: [{ id: '5e-srd-5.1', version: '0.
|
|
33
|
+
packs: [{ id: '5e-srd-5.1', version: '0.2.0' }],
|
|
34
34
|
creating: true,
|
|
35
35
|
};
|
|
36
36
|
const created = startAction(ruleset, blank, {
|
|
@@ -57,7 +57,7 @@ the [guides](https://opencharacterformat.org/guides/) explain each call.
|
|
|
57
57
|
- **Modeled:** abilities, skills and saves; creation (guided, random, point buy, standard
|
|
58
58
|
array, rolled) and leveling to 20 with multiclassing; the nine races, the acolyte and the
|
|
59
59
|
Grappler feat; all twelve classes and their SRD subclasses, feature by feature; all 319
|
|
60
|
-
spells (slots, Pact Magic, damage, healing, saves, conditions, and
|
|
60
|
+
spells (slots, Pact Magic, damage, healing, saves, conditions, and 31 spells' effects on the
|
|
61
61
|
creature they are cast on); weapons, armor, gear, tools, mounts and vehicles; the SRD magic
|
|
62
62
|
items; conditions and diseases; combat, damage, resting and death saves; all 322 monsters,
|
|
63
63
|
with their attacks, legendary actions, spellcasting and forms. Details in
|
|
@@ -250,12 +250,13 @@ Where the SRD is unclear or silent, the pack reads it this way:
|
|
|
250
250
|
- **Races and backgrounds:** the nine SRD races, four subraces and ten draconic ancestries, the
|
|
251
251
|
Acolyte and the Grappler feat.
|
|
252
252
|
- **Classes:** all twelve classes and their twelve SRD subclasses, feature by feature. Uses
|
|
253
|
-
until a rest are state on the class copy
|
|
253
|
+
until a rest are state on the class copy (an invocation's on its pick, the breath weapon's
|
|
254
|
+
`used` on the draconic ancestry pick, a racial trait's in its saved grant state); per-roll bonuses are situational choices; lasting
|
|
254
255
|
effects are boolean inputs; once per turn is the app's.
|
|
255
256
|
- **Spellcasting:** all 319 SRD spells as mechanics (level, school, class lists, casting time,
|
|
256
257
|
range, components, duration, attack or save, damage and healing); class DCs and attack bonuses;
|
|
257
258
|
spell slots by the multiclass table; Pact Magic; `cast-spell` with upcasting and cantrip
|
|
258
|
-
scaling; concentration;
|
|
259
|
+
scaling; concentration; 31 spells whose effects apply to their target's sheet; racial spells;
|
|
259
260
|
subclass spells; the wizard's spellbook (a spell only in the book is cast only as a ritual).
|
|
260
261
|
- **Equipment:** every SRD weapon and armor, 135 gear items, 7 equipment packs, 35 tools, 8
|
|
261
262
|
mounts and 11 vehicles, with cost (gp) and weight (lb) per unit. Extradimensional containers
|
|
@@ -271,7 +272,7 @@ Where the SRD is unclear or silent, the pack reads it this way:
|
|
|
271
272
|
## Limitations
|
|
272
273
|
|
|
273
274
|
Of the 152 class and subclass features, 8 have no mechanics, and 63 of the 318 magic items are
|
|
274
|
-
text. Of the 319 spells,
|
|
275
|
+
text. Of the 319 spells, 200 do nothing on the sheet beyond spending the slot: what they do is
|
|
275
276
|
their SRD text, for the app and the table (detection, illusions, summoning, movement, utility).
|
|
276
277
|
|
|
277
278
|
- **The app's:** turns and action economy (Cunning Action, Fast Hands, Vanish, Persistent Rage,
|
|
@@ -10,13 +10,6 @@ state:
|
|
|
10
10
|
eldritchMasterUsed: { type: boolean, default: false }
|
|
11
11
|
darkOnesOwnLuckUsed: { type: boolean, default: false }
|
|
12
12
|
hurlThroughHellUsed: { type: boolean, default: false }
|
|
13
|
-
bewitchingWhispersUsed: { type: boolean, default: false }
|
|
14
|
-
dreadfulWordUsed: { type: boolean, default: false }
|
|
15
|
-
minionsOfChaosUsed: { type: boolean, default: false }
|
|
16
|
-
mireTheMindUsed: { type: boolean, default: false }
|
|
17
|
-
sculptorOfFleshUsed: { type: boolean, default: false }
|
|
18
|
-
signOfIllOmenUsed: { type: boolean, default: false }
|
|
19
|
-
thiefOfFiveFatesUsed: { type: boolean, default: false }
|
|
20
13
|
prerequisites:
|
|
21
14
|
- id: multiclass
|
|
22
15
|
when: (self.startingClass && self.level == level.total) || item.id in multiclass.qualified
|
|
@@ -3,56 +3,34 @@ type: feature
|
|
|
3
3
|
actions:
|
|
4
4
|
- id: natural-recovery
|
|
5
5
|
tags: [feature]
|
|
6
|
-
results: [recovered
|
|
7
|
-
available:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
level3: { type: integer, optional: true, min: 0 }
|
|
12
|
-
level4: { type: integer, optional: true, min: 0 }
|
|
13
|
-
level5: { type: integer, optional: true, min: 0 }
|
|
6
|
+
results: [recovered]
|
|
7
|
+
available: >-
|
|
8
|
+
!self.naturalRecoveryUsed
|
|
9
|
+
&& spellSlots.level1.used + spellSlots.level2.used + spellSlots.level3.used
|
|
10
|
+
+ spellSlots.level4.used + spellSlots.level5.used > 0
|
|
14
11
|
steps:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
limit: ceil(self.level / 2)
|
|
12
|
+
# One spent slot per pick, of 5th level or lower, while the levels fit under half the
|
|
13
|
+
# druid level.
|
|
14
|
+
- id: slots
|
|
15
|
+
kind: choice
|
|
16
|
+
options:
|
|
17
|
+
values: [1, 2, 3, 4, 5]
|
|
18
|
+
where: >-
|
|
19
|
+
picks < fieldOf('spellSlots.level{slot}.used', value)
|
|
20
|
+
&& value + sumList(steps.slots.picked, indexOf(['1', '2', '3', '4', '5'], x) + 1)
|
|
21
|
+
<= ceil(self.level / 2)
|
|
22
|
+
repeat: { max: ceil(self.level / 2), min: 1 }
|
|
23
|
+
prefer: value
|
|
24
|
+
changes:
|
|
25
|
+
- type: adjust
|
|
26
|
+
field: { formula: "'spellSlots.level' + string(picked.value) + '.used'" }
|
|
27
|
+
by: -1
|
|
32
28
|
- id: recover
|
|
33
29
|
kind: changes
|
|
34
30
|
changes:
|
|
35
|
-
- type: set
|
|
36
|
-
field: spellSlots.level1.used
|
|
37
|
-
value: max(0, spellSlots.level1.used - flags.l1)
|
|
38
|
-
when: flags.l1 > 0
|
|
39
|
-
- type: set
|
|
40
|
-
field: spellSlots.level2.used
|
|
41
|
-
value: max(0, spellSlots.level2.used - flags.l2)
|
|
42
|
-
when: flags.l2 > 0
|
|
43
|
-
- type: set
|
|
44
|
-
field: spellSlots.level3.used
|
|
45
|
-
value: max(0, spellSlots.level3.used - flags.l3)
|
|
46
|
-
when: flags.l3 > 0
|
|
47
|
-
- type: set
|
|
48
|
-
field: spellSlots.level4.used
|
|
49
|
-
value: max(0, spellSlots.level4.used - flags.l4)
|
|
50
|
-
when: flags.l4 > 0
|
|
51
|
-
- type: set
|
|
52
|
-
field: spellSlots.level5.used
|
|
53
|
-
value: max(0, spellSlots.level5.used - flags.l5)
|
|
54
|
-
when: flags.l5 > 0
|
|
55
31
|
- { type: setState, entry: self, key: naturalRecoveryUsed, value: true }
|
|
56
32
|
- id: result
|
|
57
33
|
kind: outcome
|
|
58
34
|
result: "'recovered'"
|
|
35
|
+
data:
|
|
36
|
+
levels: sumList(steps.slots.picked, indexOf(['1', '2', '3', '4', '5'], x) + 1)
|
|
@@ -3,79 +3,34 @@ type: feature
|
|
|
3
3
|
actions:
|
|
4
4
|
- id: arcane-recovery
|
|
5
5
|
tags: [feature]
|
|
6
|
-
results: [
|
|
7
|
-
available:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
level3: { type: integer, optional: true }
|
|
12
|
-
level4: { type: integer, optional: true }
|
|
13
|
-
level5: { type: integer, optional: true }
|
|
6
|
+
results: [recovered]
|
|
7
|
+
available: >-
|
|
8
|
+
!self.arcaneRecoveryUsed
|
|
9
|
+
&& spellSlots.level1.used + spellSlots.level2.used + spellSlots.level3.used
|
|
10
|
+
+ spellSlots.level4.used + spellSlots.level5.used > 0
|
|
14
11
|
steps:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- id: tooMany
|
|
32
|
-
kind: outcome
|
|
33
|
-
when: >-
|
|
34
|
-
flags.levels == 0 || flags.levels > ceil(self.level / 2)
|
|
35
|
-
|| flags.level1 < 0 || flags.level1 > spellSlots.level1.used
|
|
36
|
-
|| flags.level2 < 0 || flags.level2 > spellSlots.level2.used
|
|
37
|
-
|| flags.level3 < 0 || flags.level3 > spellSlots.level3.used
|
|
38
|
-
|| flags.level4 < 0 || flags.level4 > spellSlots.level4.used
|
|
39
|
-
|| flags.level5 < 0 || flags.level5 > spellSlots.level5.used
|
|
40
|
-
result: "'too-many'"
|
|
41
|
-
data:
|
|
42
|
-
maxLevels: ceil(self.level / 2)
|
|
12
|
+
# One spent slot per pick, of 5th level or lower, while the levels fit under half the
|
|
13
|
+
# wizard level.
|
|
14
|
+
- id: slots
|
|
15
|
+
kind: choice
|
|
16
|
+
options:
|
|
17
|
+
values: [1, 2, 3, 4, 5]
|
|
18
|
+
where: >-
|
|
19
|
+
picks < fieldOf('spellSlots.level{slot}.used', value)
|
|
20
|
+
&& value + sumList(steps.slots.picked, indexOf(['1', '2', '3', '4', '5'], x) + 1)
|
|
21
|
+
<= ceil(self.level / 2)
|
|
22
|
+
repeat: { max: ceil(self.level / 2), min: 1 }
|
|
23
|
+
prefer: value
|
|
24
|
+
changes:
|
|
25
|
+
- type: adjust
|
|
26
|
+
field: { formula: "'spellSlots.level' + string(picked.value) + '.used'" }
|
|
27
|
+
by: -1
|
|
43
28
|
- id: recover
|
|
44
29
|
kind: changes
|
|
45
30
|
changes:
|
|
46
31
|
- { type: setState, entry: self, key: arcaneRecoveryUsed, value: true }
|
|
47
|
-
- {
|
|
48
|
-
type: adjust,
|
|
49
|
-
field: spellSlots.level1.used,
|
|
50
|
-
by: -flags.level1,
|
|
51
|
-
when: flags.level1 > 0,
|
|
52
|
-
}
|
|
53
|
-
- {
|
|
54
|
-
type: adjust,
|
|
55
|
-
field: spellSlots.level2.used,
|
|
56
|
-
by: -flags.level2,
|
|
57
|
-
when: flags.level2 > 0,
|
|
58
|
-
}
|
|
59
|
-
- {
|
|
60
|
-
type: adjust,
|
|
61
|
-
field: spellSlots.level3.used,
|
|
62
|
-
by: -flags.level3,
|
|
63
|
-
when: flags.level3 > 0,
|
|
64
|
-
}
|
|
65
|
-
- {
|
|
66
|
-
type: adjust,
|
|
67
|
-
field: spellSlots.level4.used,
|
|
68
|
-
by: -flags.level4,
|
|
69
|
-
when: flags.level4 > 0,
|
|
70
|
-
}
|
|
71
|
-
- {
|
|
72
|
-
type: adjust,
|
|
73
|
-
field: spellSlots.level5.used,
|
|
74
|
-
by: -flags.level5,
|
|
75
|
-
when: flags.level5 > 0,
|
|
76
|
-
}
|
|
77
32
|
- id: result
|
|
78
33
|
kind: outcome
|
|
79
34
|
result: "'recovered'"
|
|
80
35
|
data:
|
|
81
|
-
levels:
|
|
36
|
+
levels: sumList(steps.slots.picked, indexOf(['1', '2', '3', '4', '5'], x) + 1)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.bewitching-whispers
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
prerequisites:
|
|
4
6
|
- id: level
|
|
5
7
|
when: self.level >= 7
|
|
@@ -12,9 +14,14 @@ effects:
|
|
|
12
14
|
op: option
|
|
13
15
|
when: >-
|
|
14
16
|
action.item.id == @spells.compulsion && flags.slot == pactSlots.level
|
|
15
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
17
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
16
18
|
value:
|
|
17
19
|
id: invocation
|
|
18
20
|
changes:
|
|
19
21
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
20
|
-
- {
|
|
22
|
+
- {
|
|
23
|
+
type: setState,
|
|
24
|
+
picks: { where: 'item.id == @invocations.bewitching-whispers' },
|
|
25
|
+
key: used,
|
|
26
|
+
value: true,
|
|
27
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.dreadful-word
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
prerequisites:
|
|
4
6
|
- id: level
|
|
5
7
|
when: self.level >= 7
|
|
@@ -12,9 +14,14 @@ effects:
|
|
|
12
14
|
op: option
|
|
13
15
|
when: >-
|
|
14
16
|
action.item.id == @spells.confusion && flags.slot == pactSlots.level
|
|
15
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
17
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
16
18
|
value:
|
|
17
19
|
id: invocation
|
|
18
20
|
changes:
|
|
19
21
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
20
|
-
- {
|
|
22
|
+
- {
|
|
23
|
+
type: setState,
|
|
24
|
+
picks: { where: 'item.id == @invocations.dreadful-word' },
|
|
25
|
+
key: used,
|
|
26
|
+
value: true,
|
|
27
|
+
}
|
|
@@ -3,5 +3,6 @@ type: invocation
|
|
|
3
3
|
prerequisites:
|
|
4
4
|
- id: spell
|
|
5
5
|
when: '@spells.eldritch-blast in spells.warlock'
|
|
6
|
-
|
|
7
|
-
-
|
|
6
|
+
keepsTemplates:
|
|
7
|
+
- template: templates.eldritch-spear
|
|
8
|
+
content: { type: spell, where: 'item.id == @spells.eldritch-blast' }
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.minions-of-chaos
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
prerequisites:
|
|
4
6
|
- id: level
|
|
5
7
|
when: self.level >= 9
|
|
@@ -12,9 +14,14 @@ effects:
|
|
|
12
14
|
op: option
|
|
13
15
|
when: >-
|
|
14
16
|
action.item.id == @spells.conjure-elemental && flags.slot == pactSlots.level
|
|
15
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
17
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
16
18
|
value:
|
|
17
19
|
id: invocation
|
|
18
20
|
changes:
|
|
19
21
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
20
|
-
- {
|
|
22
|
+
- {
|
|
23
|
+
type: setState,
|
|
24
|
+
picks: { where: 'item.id == @invocations.minions-of-chaos' },
|
|
25
|
+
key: used,
|
|
26
|
+
value: true,
|
|
27
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.mire-the-mind
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
prerequisites:
|
|
4
6
|
- id: level
|
|
5
7
|
when: self.level >= 5
|
|
@@ -12,9 +14,14 @@ effects:
|
|
|
12
14
|
op: option
|
|
13
15
|
when: >-
|
|
14
16
|
action.item.id == @spells.slow && flags.slot == pactSlots.level
|
|
15
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
17
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
16
18
|
value:
|
|
17
19
|
id: invocation
|
|
18
20
|
changes:
|
|
19
21
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
20
|
-
- {
|
|
22
|
+
- {
|
|
23
|
+
type: setState,
|
|
24
|
+
picks: { where: 'item.id == @invocations.mire-the-mind' },
|
|
25
|
+
key: used,
|
|
26
|
+
value: true,
|
|
27
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.sculptor-of-flesh
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
prerequisites:
|
|
4
6
|
- id: level
|
|
5
7
|
when: self.level >= 7
|
|
@@ -12,9 +14,14 @@ effects:
|
|
|
12
14
|
op: option
|
|
13
15
|
when: >-
|
|
14
16
|
action.item.id == @spells.polymorph && flags.slot == pactSlots.level
|
|
15
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
17
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
16
18
|
value:
|
|
17
19
|
id: invocation
|
|
18
20
|
changes:
|
|
19
21
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
20
|
-
- {
|
|
22
|
+
- {
|
|
23
|
+
type: setState,
|
|
24
|
+
picks: { where: 'item.id == @invocations.sculptor-of-flesh' },
|
|
25
|
+
key: used,
|
|
26
|
+
value: true,
|
|
27
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.sign-of-ill-omen
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
prerequisites:
|
|
4
6
|
- id: level
|
|
5
7
|
when: self.level >= 5
|
|
@@ -12,9 +14,14 @@ effects:
|
|
|
12
14
|
op: option
|
|
13
15
|
when: >-
|
|
14
16
|
action.item.id == @spells.bestow-curse && flags.slot == pactSlots.level
|
|
15
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
17
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
16
18
|
value:
|
|
17
19
|
id: invocation
|
|
18
20
|
changes:
|
|
19
21
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
20
|
-
- {
|
|
22
|
+
- {
|
|
23
|
+
type: setState,
|
|
24
|
+
picks: { where: 'item.id == @invocations.sign-of-ill-omen' },
|
|
25
|
+
key: used,
|
|
26
|
+
value: true,
|
|
27
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
id: invocations.thief-of-five-fates
|
|
2
2
|
type: invocation
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
grants:
|
|
4
6
|
- { item: spells.bane }
|
|
5
7
|
effects:
|
|
@@ -9,9 +11,14 @@ effects:
|
|
|
9
11
|
op: option
|
|
10
12
|
when: >-
|
|
11
13
|
action.item.id == @spells.bane && flags.slot == pactSlots.level
|
|
12
|
-
&& pactSlots.used < pactSlots.max && !self.
|
|
14
|
+
&& pactSlots.used < pactSlots.max && !self.used
|
|
13
15
|
value:
|
|
14
16
|
id: invocation
|
|
15
17
|
changes:
|
|
16
18
|
- { type: adjust, field: pactSlots.used, by: 1 }
|
|
17
|
-
- {
|
|
19
|
+
- {
|
|
20
|
+
type: setState,
|
|
21
|
+
picks: { where: 'item.id == @invocations.thief-of-five-fates' },
|
|
22
|
+
key: used,
|
|
23
|
+
value: true,
|
|
24
|
+
}
|
|
@@ -3,9 +3,6 @@ type: race
|
|
|
3
3
|
fields:
|
|
4
4
|
speed: 30
|
|
5
5
|
size: medium
|
|
6
|
-
state:
|
|
7
|
-
hellishRebukeUsed: { type: boolean, default: false }
|
|
8
|
-
darknessUsed: { type: boolean, default: false }
|
|
9
6
|
effects:
|
|
10
7
|
- { target: abilities.int.base, op: add, value: 1 }
|
|
11
8
|
- { target: abilities.cha.base, op: add, value: 2 }
|
|
@@ -11,5 +11,16 @@ fields:
|
|
|
11
11
|
material: false
|
|
12
12
|
durationUnit: hour
|
|
13
13
|
durationAmount: 8
|
|
14
|
+
applied: true
|
|
14
15
|
actions:
|
|
15
16
|
- use: cast-spell
|
|
17
|
+
effects:
|
|
18
|
+
- id: ward
|
|
19
|
+
target: { incoming: { fields: [hp.current], tags: [damage] } }
|
|
20
|
+
op: atLeast
|
|
21
|
+
value: -(hp.current + hp.temp - 1)
|
|
22
|
+
when: hp.current > 0 && hp.current + hp.temp + incoming.amount <= 0
|
|
23
|
+
scope: applied
|
|
24
|
+
duration: { amount: 8, unit: hour }
|
|
25
|
+
then:
|
|
26
|
+
- { type: removeEffect, entry: self }
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
id: traits.infernal-legacy
|
|
2
2
|
type: trait
|
|
3
|
+
state:
|
|
4
|
+
hellishRebukeUsed: { type: boolean, default: false }
|
|
5
|
+
darknessUsed: { type: boolean, default: false }
|
|
3
6
|
# The option casts at 2nd level with Charisma (`slot` and `castAbility`), whatever slot the app
|
|
4
7
|
# passed and even when a class knows the spell. A spell no class knows is also in spells.limited, so
|
|
5
8
|
# no slot is offered for it.
|
|
@@ -41,7 +44,10 @@ effects:
|
|
|
41
44
|
id: hellish-rebuke
|
|
42
45
|
flags: { slot: 2, castAbility: "'cha'" }
|
|
43
46
|
changes:
|
|
44
|
-
-
|
|
47
|
+
- type: setState
|
|
48
|
+
grants: { where: 'item.id == @traits.infernal-legacy' }
|
|
49
|
+
key: hellishRebukeUsed
|
|
50
|
+
value: true
|
|
45
51
|
- target: { choices: [spell-cost] }
|
|
46
52
|
op: option
|
|
47
53
|
when: >-
|
|
@@ -50,7 +56,10 @@ effects:
|
|
|
50
56
|
id: darkness
|
|
51
57
|
flags: { slot: 2, castAbility: "'cha'" }
|
|
52
58
|
changes:
|
|
53
|
-
-
|
|
59
|
+
- type: setState
|
|
60
|
+
grants: { where: 'item.id == @traits.infernal-legacy' }
|
|
61
|
+
key: darknessUsed
|
|
62
|
+
value: true
|
|
54
63
|
grants:
|
|
55
64
|
- item: spells.thaumaturgy
|
|
56
65
|
- item: spells.hellish-rebuke
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
id: traits.relentless-endurance
|
|
2
2
|
type: trait
|
|
3
|
+
state:
|
|
4
|
+
used: { type: boolean, default: false }
|
|
3
5
|
followUps:
|
|
4
6
|
- id: relentless-endurance
|
|
5
7
|
becomes: hp.current == 0
|
|
6
|
-
when:
|
|
7
|
-
countCopies(has(copy.state.relentlessEnduranceUsed)
|
|
8
|
-
&& !copy.state.relentlessEnduranceUsed) > 0
|
|
8
|
+
when: '!self.used'
|
|
9
9
|
action: relentless-endurance
|
|
10
10
|
actions:
|
|
11
11
|
- id: relentless-endurance
|
|
12
12
|
tags: [feature]
|
|
13
13
|
results: [endured]
|
|
14
|
-
available:
|
|
15
|
-
hp.current == 0 && countCopies(has(copy.state.relentlessEnduranceUsed)
|
|
16
|
-
&& !copy.state.relentlessEnduranceUsed) > 0
|
|
14
|
+
available: hp.current == 0 && !self.used
|
|
17
15
|
steps:
|
|
18
16
|
- id: endure
|
|
19
17
|
kind: changes
|
|
20
18
|
changes:
|
|
21
19
|
- { type: set, field: hp.current, value: 1 }
|
|
22
|
-
- type: setState
|
|
23
|
-
copies: { type: race, where: has(self.relentlessEnduranceUsed) }
|
|
24
|
-
key: relentlessEnduranceUsed
|
|
25
|
-
value: true
|
|
20
|
+
- { type: setState, grant: self, key: used, value: true }
|
|
26
21
|
- id: result
|
|
27
22
|
kind: outcome
|
|
28
23
|
result: "'endured'"
|