pf2e-sage-stats 0.2.4 → 0.2.6
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 +48 -34
- package/dist/app.js +60 -37
- package/dist/index.js +306 -44
- package/package.json +6 -2
- package/src/app.ts +97 -40
- package/src/index.ts +334 -47
- package/status.txt +0 -5
- package/tracker.json +0 -62
package/src/index.ts
CHANGED
|
@@ -4,10 +4,11 @@ import { Command } from 'commander';
|
|
|
4
4
|
import fs from 'fs/promises';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import readline from 'readline';
|
|
7
|
+
import clipboardy from 'clipboardy';
|
|
7
8
|
|
|
8
9
|
import pack from '../package.json';
|
|
9
10
|
|
|
10
|
-
import { sortFolder, formatCommand, formatJSON, formatTSV, fromatMap, parseJSON, parseStatblock, stub,
|
|
11
|
+
import { sortFolder, formatCommand, formatJSON, formatTSV, fromatMap, parseJSON, parseStatblock, stub, flatMap, formatTable, formatHP, newtracker, parseTracker, formatTracker, screenPlay, diceMap } from './app';
|
|
11
12
|
|
|
12
13
|
const program = new Command(pack.name);
|
|
13
14
|
|
|
@@ -57,27 +58,41 @@ program.command('sort')
|
|
|
57
58
|
console.log(await sortFolder());
|
|
58
59
|
});
|
|
59
60
|
|
|
61
|
+
program.command('convert')
|
|
62
|
+
.description('Convert a discord export file into a txt log')
|
|
63
|
+
.argument('<file>', 'input file')
|
|
64
|
+
.option('-o, --output <file>', 'output file')
|
|
65
|
+
.action(async (argument, option) => {
|
|
66
|
+
const file = await fs.readFile(argument, { encoding: 'utf-8' });
|
|
67
|
+
|
|
68
|
+
if (option.output) {
|
|
69
|
+
await fs.writeFile(option.output, screenPlay(file), { encoding: 'utf-8' })
|
|
70
|
+
} else {
|
|
71
|
+
console.log(screenPlay(file));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
60
75
|
program.command('flat')
|
|
61
76
|
.description('Generte a special flat npc tsv')
|
|
62
77
|
.option('-n, --name <string>', 'npc name')
|
|
63
78
|
.option('-o, --output <file>', 'output json')
|
|
64
79
|
.action(async (option) => {
|
|
65
80
|
if (option.output) {
|
|
66
|
-
await fs.writeFile(option.output, fromatMap(option.name ?? 'flat',
|
|
81
|
+
await fs.writeFile(option.output, fromatMap(option.name ?? 'flat', flatMap), { encoding: 'utf-8' })
|
|
67
82
|
} else {
|
|
68
|
-
console.log(fromatMap(option.name ?? 'flat',
|
|
83
|
+
console.log(fromatMap(option.name ?? 'flat', flatMap));
|
|
69
84
|
}
|
|
70
85
|
});
|
|
71
86
|
|
|
72
|
-
program.command('
|
|
73
|
-
.description('Generte a special
|
|
87
|
+
program.command('dice')
|
|
88
|
+
.description('Generte a special dice npc tsv')
|
|
74
89
|
.option('-n, --name <string>', 'npc name')
|
|
75
90
|
.option('-o, --output <file>', 'output json')
|
|
76
91
|
.action(async (option) => {
|
|
77
92
|
if (option.output) {
|
|
78
|
-
await fs.writeFile(option.output, fromatMap(option.name ?? '
|
|
93
|
+
await fs.writeFile(option.output, fromatMap(option.name ?? 'dice', diceMap), { encoding: 'utf-8' })
|
|
79
94
|
} else {
|
|
80
|
-
console.log(fromatMap(option.name ?? '
|
|
95
|
+
console.log(fromatMap(option.name ?? 'dice', diceMap));
|
|
81
96
|
}
|
|
82
97
|
});
|
|
83
98
|
|
|
@@ -119,7 +134,6 @@ program.command('tsv')
|
|
|
119
134
|
.argument('<file>', 'input json')
|
|
120
135
|
.option('-o, --output <file>', 'output tsv')
|
|
121
136
|
.option('-s, --secretDC', 'produce secret DCs')
|
|
122
|
-
.option('-r, --recallDC', 'produce recall DCs')
|
|
123
137
|
.option('-d, --defaultSkills', 'produce values for untrained skills')
|
|
124
138
|
.action(async (argument, option) => {
|
|
125
139
|
const file = await fs.readFile(argument, { encoding: 'utf-8' });
|
|
@@ -128,7 +142,7 @@ program.command('tsv')
|
|
|
128
142
|
|
|
129
143
|
const output = option.output ? option.output : path.join(path.parse(argument).dir, path.parse(argument).name + '.tsv');
|
|
130
144
|
|
|
131
|
-
await fs.writeFile(output, formatTSV(stats, option.secretDC, option.defaultSkills
|
|
145
|
+
await fs.writeFile(output, formatTSV(stats, option.secretDC, option.defaultSkills), { encoding: 'utf-8' });
|
|
132
146
|
});
|
|
133
147
|
|
|
134
148
|
program.command('command')
|
|
@@ -136,7 +150,6 @@ program.command('command')
|
|
|
136
150
|
.argument('<file>', 'input json')
|
|
137
151
|
.option('-o, --output <file>', 'output txt')
|
|
138
152
|
.option('-s, --secretDC', 'produce secret DCs')
|
|
139
|
-
.option('-r, --recallDC', 'produce recall DCs')
|
|
140
153
|
.option('-d, --defaultSkills', 'produce values for untrained skills')
|
|
141
154
|
.action(async (argument, option) => {
|
|
142
155
|
const file = await fs.readFile(argument, { encoding: 'utf-8' });
|
|
@@ -145,7 +158,7 @@ program.command('command')
|
|
|
145
158
|
|
|
146
159
|
const output = option.output ? option.output : path.join(path.parse(argument).dir, path.parse(argument).name + '-command.txt');
|
|
147
160
|
|
|
148
|
-
await fs.writeFile(output, formatCommand(stats, option.secretDC, option.defaultSkills
|
|
161
|
+
await fs.writeFile(output, formatCommand(stats, option.secretDC, option.defaultSkills), { encoding: 'utf-8' });
|
|
149
162
|
});
|
|
150
163
|
|
|
151
164
|
program.command('newtracker')
|
|
@@ -193,7 +206,10 @@ program.command('track')
|
|
|
193
206
|
await fs.writeFile(option.output, formatTracker(tracker), { encoding: 'utf-8' })
|
|
194
207
|
} else {
|
|
195
208
|
console.clear();
|
|
196
|
-
|
|
209
|
+
|
|
210
|
+
const track = formatTracker(tracker);
|
|
211
|
+
clipboardy.writeSync(track)
|
|
212
|
+
console.log(track);
|
|
197
213
|
}
|
|
198
214
|
}
|
|
199
215
|
|
|
@@ -214,66 +230,337 @@ program.command('track')
|
|
|
214
230
|
while (true) {
|
|
215
231
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
216
232
|
|
|
217
|
-
|
|
233
|
+
let input = await new Promise<string>((resolve) => (
|
|
218
234
|
rl.question('> ', resolve)
|
|
219
235
|
));
|
|
220
236
|
|
|
221
|
-
const
|
|
237
|
+
const commands = [{
|
|
238
|
+
regex: /^\s*[bB]\s*(\d+)/,
|
|
239
|
+
map: (match: RegExpMatchArray) => ({ command: 'block' as const, index: parseInt(match[1], 10) })
|
|
240
|
+
}, {
|
|
241
|
+
regex: /^\s*reset/i,
|
|
242
|
+
map: () => ({ command: 'reset' as const })
|
|
243
|
+
}, {
|
|
244
|
+
regex: /^\s*heal/i,
|
|
245
|
+
map: () => ({ command: 'heal' as const })
|
|
246
|
+
}, {
|
|
247
|
+
regex: /^\s*exit/i,
|
|
248
|
+
map: () => ({ command: 'exit' as const })
|
|
249
|
+
}, {
|
|
250
|
+
regex: /^\s*([^\d\s+-]+)\s*([+-]?\d+)/,
|
|
251
|
+
map: (match: RegExpMatchArray) => {
|
|
252
|
+
if (match[2].match(/^[+-]/)) {
|
|
253
|
+
return { command: 'mod-hp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
254
|
+
} else {
|
|
255
|
+
return { command: 'set-hp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}, {
|
|
259
|
+
regex: /^\s*(\S+)\s+[tT]\s*([+-]?\d+)/,
|
|
260
|
+
map: (match: RegExpMatchArray) => {
|
|
261
|
+
if (match[2].match(/^[+-]/)) {
|
|
262
|
+
return { command: 'mod-thp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
263
|
+
} else {
|
|
264
|
+
return { command: 'set-thp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}, {
|
|
268
|
+
regex: /^\s*(\S+)\s+[iI]\s*([+-]?\d+)/,
|
|
269
|
+
map: (match: RegExpMatchArray) => {
|
|
270
|
+
if (match[2].match(/^[+-]/)) {
|
|
271
|
+
return { command: 'mod-init' as const, tag: match[1], value: parseInt(match[2]) };
|
|
272
|
+
} else {
|
|
273
|
+
return { command: 'set-init' as const, tag: match[1], value: parseInt(match[2]) };
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
}, {
|
|
277
|
+
regex: /^\s*(\S+)\s+[sS]?\s*=?"([^"]*)"/,
|
|
278
|
+
map: (match: RegExpMatchArray) => {
|
|
279
|
+
return { command: 'set-conditions' as const, tag: match[1], value: match[2] };
|
|
280
|
+
},
|
|
281
|
+
}, {
|
|
282
|
+
regex: /^\s*(\S+)\s+[sS]?\s*\+"([^"]*)"/,
|
|
283
|
+
map: (match: RegExpMatchArray) => {
|
|
284
|
+
return { command: 'add-conditions' as const, tag: match[1], value: match[2] };
|
|
285
|
+
},
|
|
286
|
+
}, {
|
|
287
|
+
regex: /^\s*(\S+)\s+[sS]?\s*-"([^"]*)"/,
|
|
288
|
+
map: (match: RegExpMatchArray) => {
|
|
289
|
+
return { command: 'rem-conditions' as const, tag: match[1], value: match[2] };
|
|
290
|
+
},
|
|
291
|
+
}, {
|
|
292
|
+
regex: /^\s*(\S+)\s+[sS]?\s*\+\+"([^"]*)"/,
|
|
293
|
+
map: (match: RegExpMatchArray) => {
|
|
294
|
+
return { command: 'inc-conditions' as const, tag: match[1], value: match[2] };
|
|
295
|
+
},
|
|
296
|
+
}, {
|
|
297
|
+
regex: /^\s*(\S+)\s+[sS]?\s*--"([^"]*)"/,
|
|
298
|
+
map: (match: RegExpMatchArray) => {
|
|
299
|
+
return { command: 'dec-conditions' as const, tag: match[1], value: match[2] };
|
|
300
|
+
},
|
|
301
|
+
}, {
|
|
302
|
+
regex: /^\s*(\S+)\s+[cC]/,
|
|
303
|
+
map: (match: RegExpMatchArray) => ({ command: 'check' as const, tag: match[1] }),
|
|
304
|
+
}, {
|
|
305
|
+
regex: /^\s*(\S+)\s+[aA]/,
|
|
306
|
+
map: (match: RegExpMatchArray) => ({ command: 'arrow' as const, tag: match[1] }),
|
|
307
|
+
}, {
|
|
308
|
+
regex: /^\s*(\S+)\s+[eE]/,
|
|
309
|
+
map: (match: RegExpMatchArray) => ({ command: 'empty' as const, tag: match[1] }),
|
|
310
|
+
}, {
|
|
311
|
+
regex: /^\s*(\S+)\s+[xX]/,
|
|
312
|
+
map: (match: RegExpMatchArray) => ({ command: 'cross' as const, tag: match[1] }),
|
|
313
|
+
}, {
|
|
314
|
+
regex: /^\s*(\S+)\s+[dD]/,
|
|
315
|
+
map: (match: RegExpMatchArray) => ({ command: 'delete' as const, tag: match[1] }),
|
|
316
|
+
}, {
|
|
317
|
+
regex: /^\s*(\S+)\s+[wW]/,
|
|
318
|
+
map: (match: RegExpMatchArray) => ({ command: 'wait' as const, tag: match[1] }),
|
|
319
|
+
}];
|
|
320
|
+
|
|
321
|
+
const actions: ReturnType<typeof commands[number]['map']>[] = [];
|
|
322
|
+
|
|
323
|
+
while (true) {
|
|
324
|
+
const command = commands.find((c) => input.match(c.regex));
|
|
325
|
+
|
|
326
|
+
if (!command) {
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const match = input.match(command.regex);
|
|
222
331
|
|
|
223
|
-
|
|
224
|
-
|
|
332
|
+
if (!match) {
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
225
335
|
|
|
226
|
-
const
|
|
336
|
+
const action = command.map(match);
|
|
227
337
|
|
|
228
|
-
|
|
338
|
+
input = input.slice(match[0].length);
|
|
229
339
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
let thp = tracker[index].temphp;
|
|
340
|
+
actions.push(action)
|
|
341
|
+
}
|
|
233
342
|
|
|
234
|
-
|
|
235
|
-
const delta = parseInt(hpmod[2])
|
|
343
|
+
const file = await fs.readFile(argument, { encoding: 'utf-8' });
|
|
236
344
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
345
|
+
let tracker = parseTracker(file);
|
|
346
|
+
|
|
347
|
+
for (const action of actions) {
|
|
348
|
+
if (action.command === 'block') {
|
|
349
|
+
const sorted = [...tracker].sort((a, b) => (a.init === b.init) ? (b.foe ? 1 : 0) - (a.foe ? 1 : 0) : b.init - a.init);
|
|
350
|
+
|
|
351
|
+
const blocks = [[sorted[0]]];
|
|
352
|
+
|
|
353
|
+
for (let i=1; i < sorted.length; ++i) {
|
|
354
|
+
if (sorted[i].foe === blocks[blocks.length-1][0].foe) {
|
|
355
|
+
blocks[blocks.length-1].push(sorted[i])
|
|
240
356
|
} else {
|
|
241
|
-
|
|
357
|
+
blocks.push([sorted[i]])
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
for (let i=0; i < blocks.length; ++i) {
|
|
362
|
+
if (i < action.index) {
|
|
363
|
+
blocks[i].forEach((b) => b.state = 'check')
|
|
364
|
+
} else if (i === action.index) {
|
|
365
|
+
blocks[i].forEach((b) => b.state = 'arrow')
|
|
366
|
+
} else {
|
|
367
|
+
blocks[i].forEach((b) => b.state = 'empty')
|
|
242
368
|
}
|
|
243
|
-
} else {
|
|
244
|
-
hp = parseInt(hpmod[2]);
|
|
245
369
|
}
|
|
370
|
+
} else if (action.command === 'wait') {
|
|
371
|
+
const sorted = [...tracker].sort((a, b) => (a.init === b.init) ? (b.foe ? 1 : 0) - (a.foe ? 1 : 0) : b.init - a.init);
|
|
246
372
|
|
|
247
|
-
|
|
248
|
-
tracker[index].hp = Math.min(tracker[index].maxhp, Math.max(0, hp))
|
|
373
|
+
const blocks = [[sorted[0]]];
|
|
249
374
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
375
|
+
for (let i=1; i < sorted.length; ++i) {
|
|
376
|
+
if (sorted[i].foe === blocks[blocks.length-1][0].foe) {
|
|
377
|
+
blocks[blocks.length-1].push(sorted[i])
|
|
378
|
+
} else {
|
|
379
|
+
blocks.push([sorted[i]])
|
|
380
|
+
}
|
|
381
|
+
}
|
|
253
382
|
|
|
254
|
-
|
|
383
|
+
const blockIndex = blocks.findIndex((b) => b.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag))
|
|
384
|
+
const block = blocks[blockIndex + 1]
|
|
385
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
255
386
|
|
|
256
|
-
|
|
257
|
-
|
|
387
|
+
if (block && item) {
|
|
388
|
+
item.init = (block[block.length - 1]?.init ?? 0) - 1;
|
|
389
|
+
}
|
|
390
|
+
} else if (action.command === 'check') {
|
|
391
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
258
392
|
|
|
259
|
-
|
|
393
|
+
if (item) {
|
|
394
|
+
item.state = "check"
|
|
395
|
+
}
|
|
396
|
+
} else if (action.command === 'arrow') {
|
|
397
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
260
398
|
|
|
261
|
-
|
|
399
|
+
if (item) {
|
|
400
|
+
item.state = "arrow"
|
|
401
|
+
}
|
|
402
|
+
} else if (action.command === 'empty') {
|
|
403
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
262
404
|
|
|
263
|
-
|
|
264
|
-
|
|
405
|
+
if (item) {
|
|
406
|
+
item.state = "empty"
|
|
407
|
+
}
|
|
408
|
+
} else if (action.command === 'cross') {
|
|
409
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
265
410
|
|
|
266
|
-
if (
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
|
|
411
|
+
if (item) {
|
|
412
|
+
item.state = "cross"
|
|
413
|
+
}
|
|
414
|
+
} else if (action.command === 'delete') {
|
|
415
|
+
tracker = tracker.filter((c) => !(c.id === action.tag || c.alias === action.tag || c.name == action.tag)).map((p) => ({
|
|
416
|
+
...p,
|
|
417
|
+
children: p.children.filter((c) => !(c.id === action.tag || c.alias === action.tag || c.name == action.tag)),
|
|
418
|
+
}))
|
|
419
|
+
} else if (action.command === 'exit') {
|
|
420
|
+
process.exit(0)
|
|
421
|
+
} else if (action.command === 'heal') {
|
|
422
|
+
tracker.forEach((char) => {
|
|
423
|
+
char.hp = char.maxhp
|
|
424
|
+
|
|
425
|
+
char.children.forEach((child) => {
|
|
426
|
+
child.hp = child.maxhp
|
|
427
|
+
})
|
|
428
|
+
})
|
|
429
|
+
} else if (action.command === 'reset') {
|
|
430
|
+
tracker.forEach((char) => {
|
|
431
|
+
char.state = 'empty'
|
|
432
|
+
})
|
|
433
|
+
} else if (action.command === 'set-thp') {
|
|
434
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
435
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
if (item) {
|
|
439
|
+
item.temphp = Math.max(0, action.value)
|
|
440
|
+
}
|
|
441
|
+
} else if (action.command === 'set-hp') {
|
|
442
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
443
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
if (item) {
|
|
447
|
+
item.hp = Math.min(item.maxhp, Math.max(0, action.value))
|
|
448
|
+
}
|
|
449
|
+
} else if (action.command === 'set-init') {
|
|
450
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
451
|
+
|
|
452
|
+
if (item) {
|
|
453
|
+
item.init = Math.max(0, action.value)
|
|
454
|
+
}
|
|
455
|
+
} else if (action.command === 'set-conditions') {
|
|
456
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
457
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
if (item) {
|
|
461
|
+
item.conditions = action.value.trim()
|
|
462
|
+
}
|
|
463
|
+
} else if (action.command === 'add-conditions') {
|
|
464
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
465
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
if (item) {
|
|
469
|
+
const conditions = [...item.conditions.split(',').map((c) => c.toLowerCase().trim()).filter((c) => c.length), action.value.toLowerCase().trim()];
|
|
470
|
+
|
|
471
|
+
item.conditions = conditions.join(', ')
|
|
472
|
+
}
|
|
473
|
+
} else if (action.command === 'rem-conditions') {
|
|
474
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
475
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
if (item) {
|
|
479
|
+
const conditions = item.conditions.split(',').map((c) => c.toLowerCase().trim()).filter((c) => c.length).filter((c) => !c.includes(action.value.toLowerCase().trim()));
|
|
480
|
+
|
|
481
|
+
item.conditions = conditions.join(', ')
|
|
482
|
+
}
|
|
483
|
+
} else if (action.command === 'inc-conditions') {
|
|
484
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
485
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
if (item) {
|
|
489
|
+
const conditions = item.conditions.split(',').map((c) => c.toLowerCase().trim()).filter((c) => c.length).map((c) => {
|
|
490
|
+
if (c.includes(action.value.toLowerCase().trim())) {
|
|
491
|
+
const match = c.match(/(.*)\s+(\d+)/);
|
|
492
|
+
|
|
493
|
+
if (match && match[1] && match[2]) {
|
|
494
|
+
return `${match[1].trim()} ${parseInt(match[2]) + 1}`
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return c;
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
item.conditions = conditions.join(', ')
|
|
502
|
+
}
|
|
503
|
+
} else if (action.command === 'dec-conditions') {
|
|
504
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
505
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
if (item) {
|
|
509
|
+
const conditions = item.conditions.split(',').map((c) => c.toLowerCase().trim()).filter((c) => c.length).map((c) => {
|
|
510
|
+
if (c.includes(action.value.toLowerCase().trim())) {
|
|
511
|
+
const match = c.match(/(.*)\s+(\d+)/);
|
|
512
|
+
|
|
513
|
+
if (match && match[1] && match[2]) {
|
|
514
|
+
if (parseInt(match[2]) > 1) {
|
|
515
|
+
return `${match[1].trim()} ${parseInt(match[2]) - 1}`
|
|
516
|
+
} else {
|
|
517
|
+
return match[1].trim()
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return c;
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
item.conditions = conditions.join(', ')
|
|
526
|
+
}
|
|
527
|
+
} else if (action.command === 'mod-thp') {
|
|
528
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
529
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
if (item) {
|
|
533
|
+
item.temphp = Math.max(0, item.temphp + action.value)
|
|
270
534
|
}
|
|
535
|
+
} else if (action.command === 'mod-hp') {
|
|
536
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
537
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
538
|
+
)
|
|
271
539
|
|
|
272
|
-
|
|
540
|
+
if (item) {
|
|
541
|
+
let hp = item.hp;
|
|
542
|
+
let thp = item.temphp;
|
|
273
543
|
|
|
274
|
-
|
|
544
|
+
if (action.value < 0) {
|
|
545
|
+
thp += action.value;
|
|
546
|
+
hp += Math.min(thp, 0)
|
|
547
|
+
} else {
|
|
548
|
+
hp += action.value;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
item.temphp = Math.max(0, thp)
|
|
552
|
+
item.hp = Math.min(item.maxhp, Math.max(0, hp))
|
|
553
|
+
}
|
|
554
|
+
} else if (action.command === 'mod-init') {
|
|
555
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
556
|
+
|
|
557
|
+
if (item) {
|
|
558
|
+
item.init = Math.max(0, item.init + action.value)
|
|
559
|
+
}
|
|
275
560
|
}
|
|
276
561
|
}
|
|
562
|
+
|
|
563
|
+
await fs.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' })
|
|
277
564
|
}
|
|
278
565
|
})(),
|
|
279
566
|
])
|
package/status.txt
DELETED
package/tracker.json
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"init": 19,
|
|
4
|
-
"foe": false,
|
|
5
|
-
"state": "empty",
|
|
6
|
-
"name": "Перитон",
|
|
7
|
-
"alias": "pe",
|
|
8
|
-
"hp": 22,
|
|
9
|
-
"temphp": 0,
|
|
10
|
-
"maxhp": 22,
|
|
11
|
-
"conditions": "",
|
|
12
|
-
"children": []
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"init": 21,
|
|
16
|
-
"foe": false,
|
|
17
|
-
"state": "empty",
|
|
18
|
-
"name": "Асотил",
|
|
19
|
-
"alias": "as",
|
|
20
|
-
"hp": 64,
|
|
21
|
-
"temphp": 0,
|
|
22
|
-
"maxhp": 64,
|
|
23
|
-
"conditions": "",
|
|
24
|
-
"children": []
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"init": 19,
|
|
28
|
-
"foe": true,
|
|
29
|
-
"state": "empty",
|
|
30
|
-
"name": "Псина",
|
|
31
|
-
"alias": "hnd",
|
|
32
|
-
"hp": 70,
|
|
33
|
-
"temphp": 0,
|
|
34
|
-
"maxhp": 80,
|
|
35
|
-
"conditions": "-1 to AC and saves",
|
|
36
|
-
"children": []
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"init": 18,
|
|
40
|
-
"foe": false,
|
|
41
|
-
"state": "empty",
|
|
42
|
-
"name": "Брон",
|
|
43
|
-
"alias": "br",
|
|
44
|
-
"hp": 24,
|
|
45
|
-
"temphp": 0,
|
|
46
|
-
"maxhp": 24,
|
|
47
|
-
"conditions": "hidden",
|
|
48
|
-
"children": []
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"init": 25,
|
|
52
|
-
"foe": false,
|
|
53
|
-
"state": "arrow",
|
|
54
|
-
"name": "Нтаанди",
|
|
55
|
-
"alias": "nt",
|
|
56
|
-
"hp": 13,
|
|
57
|
-
"temphp": 0,
|
|
58
|
-
"maxhp": 20,
|
|
59
|
-
"conditions": "",
|
|
60
|
-
"children": []
|
|
61
|
-
}
|
|
62
|
-
]
|