You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improvements to NPC Parser, Items, and general bug fixes. Also adds the user guide. (#133)
* Handle missing backstabDamage.
Placeholder for backstabDamage matches the default damage.
Closes#117.
* Add page numbers to spell item sheets.
Closes#116.
* Add HD to upper level and zero sheets. Tweak HD style to suit.
HD is now a common attribute, defaulting to 1d4 for PCs and 1d6 for
NPCs.
* Implement rollable hit dice and draggable hit dice macros.
Closes#50.
* Support ability modifiers between 0 and 3.
Closes#119.
* Move NPC import to the Actors Directory, and create the actor in the
process.
Support automatically naming actors (from the statline) or by adding
e.g. 'Name: Dave' to a Purple Sorcerer Plain Text character.
Closes#120.
* Support importing multiple actors from JSON data.
Support importing actors directly to a folder.
* Support importing multiple zero level or upper level characters as JSON
or Plain Text.
* Handle importing multiple NPCs.
* Rework actor import into a FormApplication to improve layout and
flexibility.
* Tests for new actor parser output and for multiple actors.
* Register sheets only for Player type actors.
* Enable Compute AC for import PCs and guess at a sheet class.
* Add a value row to Weapons, Equipment (covers Ammunition and Mounts
also), and Armor sheets.
Closes#96.
* Add Weight to Armor, Weapons, and Treasure sheets.
Closes#69.
* Use non-greedy match to parse NPC names so we never go past the first
colon.
Closes#16.
* Begin refactor to split weapon attack rolls from damage rolls (and
potentially crit/fumble rolls).
Refactor useStandardDiceRoller setting lookup into the sheet class,
storing the result in an options object passed to all the attack related
methods.
* Separate attack rolls from damage rolls, and both from the presentation.
* Handle invalid to hit or damage formulae gracefully.
Closes#25.
* Remove spurious parenthesis from the attack roll card.
* Roll crits and fumbles at the correct time for both attack roll flows.
Needs futher refactor on crits and fumbles similar to attack and damage
rolls.
* Fix standard card path crit and fumble rolls.
* Restore Backstab locstring.
* Restore the old name of rollWeaponAttack to support legacy macros.
Formatting fixes.
* Move the check for useStandardDiceRoller to keep weapon roll macros
behaving correctly.
* Handle special attacks in NPC weapon parser. Anything starting with a
number has zero damage, but the damage string is copied into the weapon
Summary for reference.
Closes#6.
* Detect if Roll.validate is present and fallback (for pre 0.7.x support).
* Update system.json for v0.21.
* Point at the preview branch's manifest with a preview release.
* First draft DCC User Guide
* Fix system.json
* Rename the user guide pack and fix the table of contents.
* Expose createActors from the parser module and return the actors.
* Tweak actor import UI and amend userguide to match.
* Update manifest and download urls.
* Bump template version.
Co-authored-by: Christian Ovsenik <[email protected]>
constparsedNPC=parseNPC('Very long, the power super-snake: Init +0; Atk bite +6 melee; Dmg 1d8;\r\n AC 13; HP 21; MV 20’; Act 1d20; SV Fort +8, Ref +4, Will +4; AL L.')
8
+
constparsedNPC=parseNPCs('Very long, the power super-snake: Init +0; Atk bite +6 melee; Dmg 1d8;\r\n AC 13; HP 21; MV 20’; Act 1d20; SV Fort +8, Ref +4, Will +4; AL L.')
9
9
constexpected={
10
10
name: 'Very long, the power super-snake',
11
11
'data.attributes.init.value': '+0',
@@ -31,12 +31,12 @@ test('super snake', () => {
31
31
}
32
32
]
33
33
}
34
-
expect(parsedNPC).toMatchObject(expected)
34
+
expect(parsedNPC).toMatchObject([expected])
35
35
})
36
36
37
37
/* Test dry pile of bones */
38
38
test('pile of bones',()=>{
39
-
constparsedNPC=parseNPC('Seven items of dry stuff: Init -2; Atk bite +0 melee; Dmg 1d4-1; AC 8; HP 3; MV 5’;\r\n Act 1d20; SV Fort +0, Ref -4, Will +1; AL C.')
39
+
constparsedNPC=parseNPCs('Seven items of dry stuff: Init -2; Atk bite +0 melee; Dmg 1d4-1; AC 8; HP 3; MV 5’;\r\n Act 1d20; SV Fort +0, Ref -4, Will +1; AL C.')
40
40
constexpected={
41
41
name: 'Seven items of dry stuff',
42
42
'data.attributes.init.value': '-2',
@@ -60,12 +60,12 @@ test('pile of bones', () => {
60
60
}
61
61
]
62
62
}
63
-
expect(parsedNPC).toMatchObject(expected)
63
+
expect(parsedNPC).toMatchObject([expected])
64
64
})
65
65
66
66
/* Test orcs */
67
67
test('orcs',()=>{
68
-
constparsedNPC=parseNPC('Cute-Infused Orcs (3): Init +2; Atk claw +1 melee (1d4) or spear +1 melee (1d8); AC 15; HD 2d8+2; hp 13 each; MV 30’; Act 1d20; SP none; SV Fort +3, Ref +0, Will -1; AL C.')
68
+
constparsedNPC=parseNPCs('Cute-Infused Orcs (3): Init +2; Atk claw +1 melee (1d4) or spear +1 melee (1d8); AC 15; HD 2d8+2; hp 13 each; MV 30’; Act 1d20; SP none; SV Fort +3, Ref +0, Will -1; AL C.')
69
69
constexpected={
70
70
name: 'Cute-Infused Orcs',
71
71
'data.attributes.init.value': '+2',
@@ -103,12 +103,12 @@ test('orcs', () => {
103
103
}
104
104
]
105
105
}
106
-
expect(parsedNPC).toMatchObject(expected)
106
+
expect(parsedNPC).toMatchObject([expected])
107
107
})
108
108
109
109
/* Test spider */
110
110
test('spider',()=>{
111
-
constparsedNPC=parseNPC('Xformed, Unicorn-Filled Spider: Init +1; Atk bite +2 melee (1d4 plus poison) or web +4 ranged (restrained, 20’ range); AC 13; HD 2d12 +2; hp 20; MV 30’ or climb 30’; Act 1d20; SP poison (DC 14 Fort save or additional 3d4 damage and lose 1 point of Strength, 1d4 damage if successful), create web, filled with bats; SV Fort +2, Ref +4, Will +0; AL N.\n')
111
+
constparsedNPC=parseNPCs('Xformed, Unicorn-Filled Spider: Init +1; Atk bite +2 melee (1d4 plus poison) or web +4 ranged (restrained, 20’ range); AC 13; HD 2d12 +2; hp 20; MV 30’ or climb 30’; Act 1d20; SP poison (DC 14 Fort save or additional 3d4 damage and lose 1 point of Strength, 1d4 damage if successful), create web, filled with bats; SV Fort +2, Ref +4, Will +0; AL N.\n')
112
112
constexpected={
113
113
name: 'Xformed, Unicorn-Filled Spider',
114
114
'data.attributes.init.value': '+1',
@@ -140,19 +140,21 @@ test('spider', () => {
140
140
type: 'weapon',
141
141
data: {
142
142
toHit: '+4',
143
-
melee: false
144
-
// damage": '0', //@TODO: change damage to 0 when there is no die roll
145
-
// description: { value: 'restrained, 20’ range' } // @TODO: Parse out this special
143
+
melee: false,
144
+
damage: '0',
145
+
description: {
146
+
summary: 'restrained, 20’ range'
147
+
}
146
148
}
147
149
}
148
150
]
149
151
}
150
-
expect(parsedNPC).toMatchObject(expected)
152
+
expect(parsedNPC).toMatchObject([expected])
151
153
})
152
154
153
155
/* Test wetad */
154
156
test('wedad',()=>{
155
-
constparsedNPC=parseNPC('Gerieah (in her tree): Init +1; Atk tree limb slam +5 melee (1d10); AC 15;\n HD 4d10; hp 30; MV none; Act 1d20; SP takes 2x damage from fire, can attack targets up to 20’ away with tree limbs; SV Fort +6, Ref -2, Will +4; AL N.')
157
+
constparsedNPC=parseNPCs('Gerieah (in her tree): Init +1; Atk tree limb slam +5 melee (1d10); AC 15;\n HD 4d10; hp 30; MV none; Act 1d20; SP takes 2x damage from fire, can attack targets up to 20’ away with tree limbs; SV Fort +6, Ref -2, Will +4; AL N.')
156
158
constexpected={
157
159
name: 'Gerieah (in her tree)',
158
160
'data.attributes.init.value': '+1',
@@ -180,12 +182,45 @@ test('wedad', () => {
180
182
}
181
183
]
182
184
}
183
-
expect(parsedNPC).toMatchObject(expected)
185
+
expect(parsedNPC).toMatchObject([expected])
186
+
})
187
+
188
+
/* Test smultist */
189
+
test('smultist',()=>{
190
+
constparsedNPC=parseNPCs('Green-robed smultist (1): Init +4; Atk dagger +5 melee (1d4+3); AC 11; HD 5d4+5; hp 21; MV 20’; SP 3d6 control check, able to cast arms of the angel, squid-mass (when killed, an squid-mass emerges; see stats below); Act 1d20; SV Fort +3, Ref +4, Will +0; AL C. Equipment: bird-shaped talisman of gold tied on a leather thong (worth 10 gp; see level 3).')
191
+
constexpected={
192
+
name: 'Green-robed smultist',
193
+
'data.attributes.init.value': '+4',
194
+
'data.attributes.ac.value': '11',
195
+
'data.attributes.hitDice.value': '5d4+5',
196
+
'data.attributes.hp.value': '21',
197
+
'data.attributes.hp.max': '21',
198
+
'data.attributes.speed.value': '20’',
199
+
'data.attributes.special.value': '3d6 control check, able to cast arms of the angel, squid-mass (when killed, an squid-mass emerges',// @TODO: Is it worth finding a way to ignore colons inside brackets?
200
+
'data.config.actionDice': '1d20',
201
+
'data.saves.frt.value': '+3',
202
+
'data.saves.ref.value': '+4',
203
+
'data.saves.wil.value': '+0',
204
+
'data.details.alignment': 'c',
205
+
items: [
206
+
{
207
+
name: 'dagger',
208
+
type: 'weapon',
209
+
data: {
210
+
toHit: '+5',
211
+
damage: '1d4+3',
212
+
description: {value: ''},
213
+
melee: true
214
+
}
215
+
}
216
+
]
217
+
}
218
+
expect(parsedNPC).toMatchObject([expected])
184
219
})
185
220
186
221
/* Test short statline */
187
222
test('shortstats',()=>{
188
-
constparsedNPC=parseNPC('Stunty, the short and muddled: Init +1; Atk kick +2 melee (1d3); AC 15;\n hp 4; Act 1d20; SV Ref +6, Fort -2, Will +4.')
223
+
constparsedNPC=parseNPCs('Stunty, the short and muddled: Init +1; Atk kick +2 melee (1d3); AC 15;\n hp 4; Act 1d20; SV Ref +6, Fort -2, Will +4.')
189
224
constexpected={
190
225
name: 'Stunty, the short and muddled',
191
226
'data.attributes.init.value': '+1',
@@ -213,12 +248,12 @@ test('shortstats', () => {
213
248
}
214
249
]
215
250
}
216
-
expect(parsedNPC).toMatchObject(expected)
251
+
expect(parsedNPC).toMatchObject([expected])
217
252
})
218
253
219
254
/* Test the bad guy's familiar with a minimal stat line */
220
255
test('familiar',()=>{
221
-
constparsedNPC=parseNPC('The bad guy\'s familiar: Atk claw +3 melee (1d4), AC 15, HP 2.')
256
+
constparsedNPC=parseNPCs('The bad guy\'s familiar: Atk claw +3 melee (1d4), AC 15, HP 2.')
222
257
constexpected={
223
258
name: 'The bad guy\'s familiar',
224
259
'data.attributes.init.value': '+0',
@@ -246,12 +281,12 @@ test('familiar', () => {
246
281
}
247
282
]
248
283
}
249
-
expect(parsedNPC).toMatchObject(expected)
284
+
expect(parsedNPC).toMatchObject([expected])
250
285
})
251
286
252
287
/* Test damage modifiers */
253
288
test('bonusguy',()=>{
254
-
constparsedNPC=parseNPC('Bonus Guy: Init -1; Atk big club +3 melee (1d4+2) or small club -2 melee (1d4 - 3); AC 13; HD 1d8+2; MV 30’; Act 1d20; SV Fort +2, Ref +1, Will -2; AL C.')
289
+
constparsedNPC=parseNPCs('Bonus Guy: Init -1; Atk big club +3 melee (1d4+2) or small club -2 melee (1d4 - 3); AC 13; HD 1d8+2; MV 30’; Act 1d20; SV Fort +2, Ref +1, Will -2; AL C.')
0 commit comments