pf2e-sage-stats 0.2.3 → 0.2.5
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/dist/app.js +7 -2
- package/dist/index.js +173 -33
- package/package.json +1 -1
- package/src/app.ts +7 -2
- package/src/index.ts +183 -37
- package/status.txt +0 -5
- package/tracker.json +0 -62
package/dist/app.js
CHANGED
|
@@ -182,6 +182,7 @@ exports.stub = {
|
|
|
182
182
|
const childSchema = zod_1.default.object({
|
|
183
183
|
name: zod_1.default.string().default(""),
|
|
184
184
|
alias: zod_1.default.string().default(""),
|
|
185
|
+
id: zod_1.default.string().default(""),
|
|
185
186
|
hp: zod_1.default.coerce.number().default(0),
|
|
186
187
|
temphp: zod_1.default.coerce.number().default(0),
|
|
187
188
|
maxhp: zod_1.default.coerce.number().default(10),
|
|
@@ -193,6 +194,7 @@ const charSchema = zod_1.default.object({
|
|
|
193
194
|
state: zod_1.default.union([zod_1.default.literal('empty'), zod_1.default.literal('arrow'), zod_1.default.literal('check'), zod_1.default.literal('cross')]).default('empty'),
|
|
194
195
|
name: zod_1.default.string().default(""),
|
|
195
196
|
alias: zod_1.default.string().default(""),
|
|
197
|
+
id: zod_1.default.string().default(""),
|
|
196
198
|
hp: zod_1.default.coerce.number().default(0),
|
|
197
199
|
temphp: zod_1.default.coerce.number().default(0),
|
|
198
200
|
maxhp: zod_1.default.coerce.number().default(10),
|
|
@@ -293,6 +295,7 @@ const locateStrikes = (statblock, alias) => {
|
|
|
293
295
|
.replace(/\s+/g, ' ')
|
|
294
296
|
.replace(bps, (m) => m.toUpperCase())
|
|
295
297
|
.replace(/1d/, 'd')
|
|
298
|
+
.replace(/jousting\s+d\d+/g, 'jousting')
|
|
296
299
|
.trim();
|
|
297
300
|
const _dice = dice
|
|
298
301
|
.replace(/\s+/g, ' ')
|
|
@@ -300,6 +303,8 @@ const locateStrikes = (statblock, alias) => {
|
|
|
300
303
|
.replace(/Fire/, 'fire')
|
|
301
304
|
.replace(/Cold/, 'cold')
|
|
302
305
|
.replace(/Electricity/, 'electricity')
|
|
306
|
+
.replace(/Sonic/, 'sonic')
|
|
307
|
+
.replace(/Spirit/, 'spirit')
|
|
303
308
|
.trim();
|
|
304
309
|
const twoHand = _traits.match(/(two-hand|two-handed)\s+(d\d+)/);
|
|
305
310
|
if (twoHand && twoHand[2]) {
|
|
@@ -546,7 +551,7 @@ const newtracker = (status) => {
|
|
|
546
551
|
exports.newtracker = newtracker;
|
|
547
552
|
const formatTracker = (tracker) => {
|
|
548
553
|
const nameLength = tracker.reduce((p, c) => {
|
|
549
|
-
const length = c.children.reduce((pp, cc) => pp > cc.name.length
|
|
554
|
+
const length = c.children.reduce((pp, cc) => pp > cc.name.length ? pp : cc.name.length, c.name.length);
|
|
550
555
|
return p > length ? p : length;
|
|
551
556
|
}, 0);
|
|
552
557
|
const hpLength = tracker.reduce((p, c) => {
|
|
@@ -583,7 +588,7 @@ const formatTracker = (tracker) => {
|
|
|
583
588
|
}
|
|
584
589
|
for (const child of char.children) {
|
|
585
590
|
const hhp = char.foe ? (`-${child.maxhp - child.hp}${child.temphp > 0 ? `+${child.temphp}` : ''}`.padStart(hpLength)) : (`${child.hp}${child.temphp > 0 ? `+${child.temphp}` : ''}/${child.maxhp}`.padStart(hpLength));
|
|
586
|
-
ls.push((`:smallnode
|
|
591
|
+
ls.push((`:smallnode:**\` ${child.name.padEnd(nameLength)} ▏${child.alias.padEnd(3)} ▏${hhp} \`** ${hpBar(child.hp, child.maxhp)} `));
|
|
587
592
|
if (child.conditions.length > 0) {
|
|
588
593
|
ls.push(`-# ${child.conditions}`);
|
|
589
594
|
}
|
package/dist/index.js
CHANGED
|
@@ -216,56 +216,196 @@ program.command('track')
|
|
|
216
216
|
}
|
|
217
217
|
}))(),
|
|
218
218
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
219
|
+
var _a, _b, _c, _d, _e;
|
|
219
220
|
const rl = readline_1.default.createInterface({
|
|
220
221
|
input: process.stdin,
|
|
221
222
|
output: process.stdout
|
|
222
223
|
});
|
|
223
224
|
while (true) {
|
|
224
225
|
yield new Promise((resolve) => setTimeout(resolve, 500));
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
226
|
+
let input = yield new Promise((resolve) => (rl.question('> ', resolve)));
|
|
227
|
+
const commands = [{
|
|
228
|
+
regex: /^\s*[bB]\s*(\d+)/,
|
|
229
|
+
map: (match) => ({ command: 'block', index: parseInt(match[1], 10) })
|
|
230
|
+
}, {
|
|
231
|
+
regex: /^\s*reset/i,
|
|
232
|
+
map: () => ({ command: 'reset' })
|
|
233
|
+
}, {
|
|
234
|
+
regex: /^\s*heal/i,
|
|
235
|
+
map: () => ({ command: 'heal' })
|
|
236
|
+
}, {
|
|
237
|
+
regex: /^\s*exit/i,
|
|
238
|
+
map: () => ({ command: 'exit' })
|
|
239
|
+
}, {
|
|
240
|
+
regex: /^\s*([^\d\s+-]+)\s*([+-]?\d+)/,
|
|
241
|
+
map: (match) => {
|
|
242
|
+
if (match[2].match(/^[+-]/)) {
|
|
243
|
+
return { command: 'mod-hp', tag: match[1], value: parseInt(match[2]) };
|
|
239
244
|
}
|
|
240
245
|
else {
|
|
241
|
-
hp
|
|
246
|
+
return { command: 'set-hp', tag: match[1], value: parseInt(match[2]) };
|
|
242
247
|
}
|
|
243
248
|
}
|
|
244
|
-
|
|
245
|
-
|
|
249
|
+
}, {
|
|
250
|
+
regex: /^\s*(\S+)\s+[tT]\s*([+-]?\d+)/,
|
|
251
|
+
map: (match) => {
|
|
252
|
+
if (match[2].match(/^[+-]/)) {
|
|
253
|
+
return { command: 'mod-thp', tag: match[1], value: parseInt(match[2]) };
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
return { command: 'set-thp', tag: match[1], value: parseInt(match[2]) };
|
|
257
|
+
}
|
|
246
258
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
259
|
+
}, {
|
|
260
|
+
regex: /^\s*(\S+)\s+[iI]\s*([+-]?\d+)/,
|
|
261
|
+
map: (match) => {
|
|
262
|
+
if (match[2].match(/^[+-]/)) {
|
|
263
|
+
return { command: 'mod-init', tag: match[1], value: parseInt(match[2]) };
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
return { command: 'set-init', tag: match[1], value: parseInt(match[2]) };
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
}, {
|
|
270
|
+
regex: /^\s*(\S+)\s+[sS]\s*"(.*)"/,
|
|
271
|
+
map: (match) => {
|
|
272
|
+
return { command: 'set-conditions', tag: match[1], value: match[2] };
|
|
273
|
+
},
|
|
274
|
+
}, {
|
|
275
|
+
regex: /^\s*(\S+)\s+[cC]/,
|
|
276
|
+
map: (match) => ({ command: 'check', tag: match[1] }),
|
|
277
|
+
}, {
|
|
278
|
+
regex: /^\s*(\S+)\s+[aA]/,
|
|
279
|
+
map: (match) => ({ command: 'arrow', tag: match[1] }),
|
|
280
|
+
}, {
|
|
281
|
+
regex: /^\s*(\S+)\s+[dD]/,
|
|
282
|
+
map: (match) => ({ command: 'delete', tag: match[1] }),
|
|
283
|
+
}];
|
|
284
|
+
const actions = [];
|
|
285
|
+
while (true) {
|
|
286
|
+
const command = commands.find((c) => input.match(c.regex));
|
|
287
|
+
if (!command) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
const match = input.match(command.regex);
|
|
291
|
+
if (!match) {
|
|
292
|
+
break;
|
|
250
293
|
}
|
|
294
|
+
const action = command.map(match);
|
|
295
|
+
input = input.slice(match[0].length);
|
|
296
|
+
actions.push(action);
|
|
251
297
|
}
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
let
|
|
259
|
-
|
|
260
|
-
|
|
298
|
+
const file = yield promises_1.default.readFile(argument, { encoding: 'utf-8' });
|
|
299
|
+
let tracker = (0, app_1.parseTracker)(file);
|
|
300
|
+
for (const action of actions) {
|
|
301
|
+
if (action.command === 'block') {
|
|
302
|
+
const sorted = [...tracker].sort((a, b) => (a.init === b.init) ? (b.foe ? 1 : 0) - (a.foe ? 1 : 0) : b.init - a.init);
|
|
303
|
+
const blocks = [[sorted[0]]];
|
|
304
|
+
for (let i = 1; i < sorted.length; ++i) {
|
|
305
|
+
if (sorted[i].foe === blocks[blocks.length - 1][0].foe) {
|
|
306
|
+
blocks[blocks.length - 1].push(sorted[i]);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
blocks.push([sorted[i]]);
|
|
310
|
+
}
|
|
261
311
|
}
|
|
262
|
-
|
|
263
|
-
|
|
312
|
+
for (let i = 0; i < blocks.length; ++i) {
|
|
313
|
+
if (i < action.index) {
|
|
314
|
+
blocks[i].forEach((b) => b.state = 'check');
|
|
315
|
+
}
|
|
316
|
+
else if (i === action.index) {
|
|
317
|
+
blocks[i].forEach((b) => b.state = 'arrow');
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
blocks[i].forEach((b) => b.state = 'empty');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
else if (action.command === 'check') {
|
|
325
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag);
|
|
326
|
+
if (item) {
|
|
327
|
+
item.state = "check";
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else if (action.command === 'arrow') {
|
|
331
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag);
|
|
332
|
+
if (item) {
|
|
333
|
+
item.state = "arrow";
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else if (action.command === 'delete') {
|
|
337
|
+
tracker = tracker.filter((c) => !(c.id === action.tag || c.alias === action.tag || c.name == action.tag)).map((p) => (Object.assign(Object.assign({}, p), { children: p.children.filter((c) => !(c.id === action.tag || c.alias === action.tag || c.name == action.tag)) })));
|
|
338
|
+
}
|
|
339
|
+
else if (action.command === 'exit') {
|
|
340
|
+
process.exit(0);
|
|
341
|
+
}
|
|
342
|
+
else if (action.command === 'heal') {
|
|
343
|
+
tracker.forEach((char) => {
|
|
344
|
+
char.hp = char.maxhp;
|
|
345
|
+
char.children.forEach((child) => {
|
|
346
|
+
child.hp = child.maxhp;
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
else if (action.command === 'reset') {
|
|
351
|
+
tracker.forEach((char) => {
|
|
352
|
+
char.state = 'empty';
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
else if (action.command === 'set-thp') {
|
|
356
|
+
const item = (_a = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)) !== null && _a !== void 0 ? _a : (tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag));
|
|
357
|
+
if (item) {
|
|
358
|
+
item.temphp = Math.max(0, action.value);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else if (action.command === 'set-hp') {
|
|
362
|
+
const item = (_b = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)) !== null && _b !== void 0 ? _b : (tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag));
|
|
363
|
+
if (item) {
|
|
364
|
+
item.hp = Math.min(item.maxhp, Math.max(0, action.value));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else if (action.command === 'set-init') {
|
|
368
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag);
|
|
369
|
+
if (item) {
|
|
370
|
+
item.init = Math.max(0, action.value);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else if (action.command === 'set-conditions') {
|
|
374
|
+
const item = (_c = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)) !== null && _c !== void 0 ? _c : (tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag));
|
|
375
|
+
if (item) {
|
|
376
|
+
item.conditions = action.value;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
else if (action.command === 'mod-thp') {
|
|
380
|
+
const item = (_d = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)) !== null && _d !== void 0 ? _d : (tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag));
|
|
381
|
+
if (item) {
|
|
382
|
+
item.temphp = Math.max(0, item.temphp + action.value);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
else if (action.command === 'mod-hp') {
|
|
386
|
+
const item = (_e = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)) !== null && _e !== void 0 ? _e : (tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag));
|
|
387
|
+
if (item) {
|
|
388
|
+
let hp = item.hp;
|
|
389
|
+
let thp = item.temphp;
|
|
390
|
+
if (action.value < 0) {
|
|
391
|
+
thp += action.value;
|
|
392
|
+
hp += Math.min(thp, 0);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
hp += action.value;
|
|
396
|
+
}
|
|
397
|
+
item.temphp = Math.max(0, thp);
|
|
398
|
+
item.hp = Math.min(item.maxhp, Math.max(0, hp));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else if (action.command === 'mod-init') {
|
|
402
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag);
|
|
403
|
+
if (item) {
|
|
404
|
+
item.init = Math.max(0, item.init + action.value);
|
|
264
405
|
}
|
|
265
|
-
tracker[index].temphp = Math.max(0, thp);
|
|
266
|
-
yield promises_1.default.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' });
|
|
267
406
|
}
|
|
268
407
|
}
|
|
408
|
+
yield promises_1.default.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' });
|
|
269
409
|
}
|
|
270
410
|
}))(),
|
|
271
411
|
]);
|
package/package.json
CHANGED
package/src/app.ts
CHANGED
|
@@ -172,6 +172,7 @@ export const stub: Required<Schema> = {
|
|
|
172
172
|
const childSchema = zod.object({
|
|
173
173
|
name: zod.string().default(""),
|
|
174
174
|
alias: zod.string().default(""),
|
|
175
|
+
id: zod.string().default(""),
|
|
175
176
|
hp: zod.coerce.number().default(0),
|
|
176
177
|
temphp: zod.coerce.number().default(0),
|
|
177
178
|
maxhp: zod.coerce.number().default(10),
|
|
@@ -186,6 +187,7 @@ const charSchema = zod.object({
|
|
|
186
187
|
state: zod.union([zod.literal('empty'), zod.literal('arrow'), zod.literal('check'), zod.literal('cross')]).default('empty'),
|
|
187
188
|
name: zod.string().default(""),
|
|
188
189
|
alias: zod.string().default(""),
|
|
190
|
+
id: zod.string().default(""),
|
|
189
191
|
hp: zod.coerce.number().default(0),
|
|
190
192
|
temphp: zod.coerce.number().default(0),
|
|
191
193
|
maxhp: zod.coerce.number().default(10),
|
|
@@ -320,6 +322,7 @@ const locateStrikes = (statblock: string, alias: string): Record<string, Schema[
|
|
|
320
322
|
.replace(/\s+/g, ' ')
|
|
321
323
|
.replace(bps, (m) => m.toUpperCase())
|
|
322
324
|
.replace(/1d/, 'd')
|
|
325
|
+
.replace(/jousting\s+d\d+/g, 'jousting')
|
|
323
326
|
.trim();
|
|
324
327
|
|
|
325
328
|
const _dice = dice
|
|
@@ -328,6 +331,8 @@ const locateStrikes = (statblock: string, alias: string): Record<string, Schema[
|
|
|
328
331
|
.replace(/Fire/, 'fire')
|
|
329
332
|
.replace(/Cold/, 'cold')
|
|
330
333
|
.replace(/Electricity/, 'electricity')
|
|
334
|
+
.replace(/Sonic/, 'sonic')
|
|
335
|
+
.replace(/Spirit/, 'spirit')
|
|
331
336
|
.trim();
|
|
332
337
|
|
|
333
338
|
const twoHand = _traits.match(/(two-hand|two-handed)\s+(d\d+)/);
|
|
@@ -698,7 +703,7 @@ export const newtracker = (status: string) => {
|
|
|
698
703
|
|
|
699
704
|
export const formatTracker = (tracker: CharSchema[]) => {
|
|
700
705
|
const nameLength = tracker.reduce((p, c) => {
|
|
701
|
-
const length = c.children.reduce((pp, cc) => pp > cc.name.length
|
|
706
|
+
const length = c.children.reduce((pp, cc) => pp > cc.name.length ? pp : cc.name.length, c.name.length);
|
|
702
707
|
|
|
703
708
|
return p > length ? p : length;
|
|
704
709
|
}, 0);
|
|
@@ -769,7 +774,7 @@ export const formatTracker = (tracker: CharSchema[]) => {
|
|
|
769
774
|
);
|
|
770
775
|
|
|
771
776
|
ls.push((
|
|
772
|
-
`:smallnode
|
|
777
|
+
`:smallnode:**\` ${child.name.padEnd(nameLength)} ▏${child.alias.padEnd(3)} ▏${hhp} \`** ${hpBar(child.hp, child.maxhp)} `
|
|
773
778
|
))
|
|
774
779
|
|
|
775
780
|
if (child.conditions.length > 0) {
|
package/src/index.ts
CHANGED
|
@@ -214,66 +214,212 @@ program.command('track')
|
|
|
214
214
|
while (true) {
|
|
215
215
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
rl.question('>', resolve)
|
|
217
|
+
let input = await new Promise<string>((resolve) => (
|
|
218
|
+
rl.question('> ', resolve)
|
|
219
219
|
));
|
|
220
220
|
|
|
221
|
-
const
|
|
221
|
+
const commands = [{
|
|
222
|
+
regex: /^\s*[bB]\s*(\d+)/,
|
|
223
|
+
map: (match: RegExpMatchArray) => ({ command: 'block' as const, index: parseInt(match[1], 10) })
|
|
224
|
+
}, {
|
|
225
|
+
regex: /^\s*reset/i,
|
|
226
|
+
map: () => ({ command: 'reset' as const })
|
|
227
|
+
}, {
|
|
228
|
+
regex: /^\s*heal/i,
|
|
229
|
+
map: () => ({ command: 'heal' as const })
|
|
230
|
+
}, {
|
|
231
|
+
regex: /^\s*exit/i,
|
|
232
|
+
map: () => ({ command: 'exit' as const })
|
|
233
|
+
}, {
|
|
234
|
+
regex: /^\s*([^\d\s+-]+)\s*([+-]?\d+)/,
|
|
235
|
+
map: (match: RegExpMatchArray) => {
|
|
236
|
+
if (match[2].match(/^[+-]/)) {
|
|
237
|
+
return { command: 'mod-hp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
238
|
+
} else {
|
|
239
|
+
return { command: 'set-hp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}, {
|
|
243
|
+
regex: /^\s*(\S+)\s+[tT]\s*([+-]?\d+)/,
|
|
244
|
+
map: (match: RegExpMatchArray) => {
|
|
245
|
+
if (match[2].match(/^[+-]/)) {
|
|
246
|
+
return { command: 'mod-thp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
247
|
+
} else {
|
|
248
|
+
return { command: 'set-thp' as const, tag: match[1], value: parseInt(match[2]) };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}, {
|
|
252
|
+
regex: /^\s*(\S+)\s+[iI]\s*([+-]?\d+)/,
|
|
253
|
+
map: (match: RegExpMatchArray) => {
|
|
254
|
+
if (match[2].match(/^[+-]/)) {
|
|
255
|
+
return { command: 'mod-init' as const, tag: match[1], value: parseInt(match[2]) };
|
|
256
|
+
} else {
|
|
257
|
+
return { command: 'set-init' as const, tag: match[1], value: parseInt(match[2]) };
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
}, {
|
|
261
|
+
regex: /^\s*(\S+)\s+[sS]\s*"(.*)"/,
|
|
262
|
+
map: (match: RegExpMatchArray) => {
|
|
263
|
+
return { command: 'set-conditions' as const, tag: match[1], value: match[2] };
|
|
264
|
+
},
|
|
265
|
+
}, {
|
|
266
|
+
regex: /^\s*(\S+)\s+[cC]/,
|
|
267
|
+
map: (match: RegExpMatchArray) => ({ command: 'check' as const, tag: match[1] }),
|
|
268
|
+
}, {
|
|
269
|
+
regex: /^\s*(\S+)\s+[aA]/,
|
|
270
|
+
map: (match: RegExpMatchArray) => ({ command: 'arrow' as const, tag: match[1] }),
|
|
271
|
+
}, {
|
|
272
|
+
regex: /^\s*(\S+)\s+[dD]/,
|
|
273
|
+
map: (match: RegExpMatchArray) => ({ command: 'delete' as const, tag: match[1] }),
|
|
274
|
+
}];
|
|
275
|
+
|
|
276
|
+
const actions: ReturnType<typeof commands[number]['map']>[] = [];
|
|
277
|
+
|
|
278
|
+
while (true) {
|
|
279
|
+
const command = commands.find((c) => input.match(c.regex));
|
|
280
|
+
|
|
281
|
+
if (!command) {
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
222
284
|
|
|
223
|
-
|
|
224
|
-
const file = await fs.readFile(argument, { encoding: 'utf-8' });
|
|
285
|
+
const match = input.match(command.regex);
|
|
225
286
|
|
|
226
|
-
|
|
287
|
+
if (!match) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
227
290
|
|
|
228
|
-
const
|
|
291
|
+
const action = command.map(match);
|
|
229
292
|
|
|
230
|
-
|
|
231
|
-
let hp = tracker[index].hp;
|
|
232
|
-
let thp = tracker[index].temphp;
|
|
293
|
+
input = input.slice(match[0].length);
|
|
233
294
|
|
|
234
|
-
|
|
235
|
-
|
|
295
|
+
actions.push(action)
|
|
296
|
+
}
|
|
236
297
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
298
|
+
const file = await fs.readFile(argument, { encoding: 'utf-8' });
|
|
299
|
+
|
|
300
|
+
let tracker = parseTracker(file);
|
|
301
|
+
|
|
302
|
+
for (const action of actions) {
|
|
303
|
+
if (action.command === 'block') {
|
|
304
|
+
const sorted = [...tracker].sort((a, b) => (a.init === b.init) ? (b.foe ? 1 : 0) - (a.foe ? 1 : 0) : b.init - a.init);
|
|
305
|
+
|
|
306
|
+
const blocks = [[sorted[0]]];
|
|
307
|
+
|
|
308
|
+
for (let i=1; i < sorted.length; ++i) {
|
|
309
|
+
if (sorted[i].foe === blocks[blocks.length-1][0].foe) {
|
|
310
|
+
blocks[blocks.length-1].push(sorted[i])
|
|
311
|
+
} else {
|
|
312
|
+
blocks.push([sorted[i]])
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
for (let i=0; i < blocks.length; ++i) {
|
|
317
|
+
if (i < action.index) {
|
|
318
|
+
blocks[i].forEach((b) => b.state = 'check')
|
|
319
|
+
} else if (i === action.index) {
|
|
320
|
+
blocks[i].forEach((b) => b.state = 'arrow')
|
|
240
321
|
} else {
|
|
241
|
-
|
|
322
|
+
blocks[i].forEach((b) => b.state = 'empty')
|
|
242
323
|
}
|
|
243
|
-
} else {
|
|
244
|
-
hp = parseInt(hpmod[2]);
|
|
245
324
|
}
|
|
325
|
+
} else if (action.command === 'check') {
|
|
326
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
246
327
|
|
|
247
|
-
|
|
248
|
-
|
|
328
|
+
if (item) {
|
|
329
|
+
item.state = "check"
|
|
330
|
+
}
|
|
331
|
+
} else if (action.command === 'arrow') {
|
|
332
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
249
333
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
334
|
+
if (item) {
|
|
335
|
+
item.state = "arrow"
|
|
336
|
+
}
|
|
337
|
+
} else if (action.command === 'delete') {
|
|
338
|
+
tracker = tracker.filter((c) => !(c.id === action.tag || c.alias === action.tag || c.name == action.tag)).map((p) => ({
|
|
339
|
+
...p,
|
|
340
|
+
children: p.children.filter((c) => !(c.id === action.tag || c.alias === action.tag || c.name == action.tag)),
|
|
341
|
+
}))
|
|
342
|
+
} else if (action.command === 'exit') {
|
|
343
|
+
process.exit(0)
|
|
344
|
+
} else if (action.command === 'heal') {
|
|
345
|
+
tracker.forEach((char) => {
|
|
346
|
+
char.hp = char.maxhp
|
|
347
|
+
|
|
348
|
+
char.children.forEach((child) => {
|
|
349
|
+
child.hp = child.maxhp
|
|
350
|
+
})
|
|
351
|
+
})
|
|
352
|
+
} else if (action.command === 'reset') {
|
|
353
|
+
tracker.forEach((char) => {
|
|
354
|
+
char.state = 'empty'
|
|
355
|
+
})
|
|
356
|
+
} else if (action.command === 'set-thp') {
|
|
357
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
358
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
if (item) {
|
|
362
|
+
item.temphp = Math.max(0, action.value)
|
|
363
|
+
}
|
|
364
|
+
} else if (action.command === 'set-hp') {
|
|
365
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
366
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
if (item) {
|
|
370
|
+
item.hp = Math.min(item.maxhp, Math.max(0, action.value))
|
|
371
|
+
}
|
|
372
|
+
} else if (action.command === 'set-init') {
|
|
373
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
253
374
|
|
|
254
|
-
|
|
375
|
+
if (item) {
|
|
376
|
+
item.init = Math.max(0, action.value)
|
|
377
|
+
}
|
|
378
|
+
} else if (action.command === 'set-conditions') {
|
|
379
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
380
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
381
|
+
)
|
|
255
382
|
|
|
256
|
-
|
|
257
|
-
|
|
383
|
+
if (item) {
|
|
384
|
+
item.conditions = action.value
|
|
385
|
+
}
|
|
386
|
+
} else if (action.command === 'mod-thp') {
|
|
387
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
388
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
389
|
+
)
|
|
258
390
|
|
|
259
|
-
|
|
391
|
+
if (item) {
|
|
392
|
+
item.temphp = Math.max(0, item.temphp + action.value)
|
|
393
|
+
}
|
|
394
|
+
} else if (action.command === 'mod-hp') {
|
|
395
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag) ?? (
|
|
396
|
+
tracker.flatMap((c) => c.children).find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
397
|
+
)
|
|
260
398
|
|
|
261
|
-
|
|
399
|
+
if (item) {
|
|
400
|
+
let hp = item.hp;
|
|
401
|
+
let thp = item.temphp;
|
|
262
402
|
|
|
263
|
-
|
|
264
|
-
|
|
403
|
+
if (action.value < 0) {
|
|
404
|
+
thp += action.value;
|
|
405
|
+
hp += Math.min(thp, 0)
|
|
406
|
+
} else {
|
|
407
|
+
hp += action.value;
|
|
408
|
+
}
|
|
265
409
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
} else {
|
|
269
|
-
thp = parseInt(thpmod[2]);
|
|
410
|
+
item.temphp = Math.max(0, thp)
|
|
411
|
+
item.hp = Math.min(item.maxhp, Math.max(0, hp))
|
|
270
412
|
}
|
|
413
|
+
} else if (action.command === 'mod-init') {
|
|
414
|
+
const item = tracker.find((c) => c.id === action.tag || c.alias === action.tag || c.name == action.tag)
|
|
271
415
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
416
|
+
if (item) {
|
|
417
|
+
item.init = Math.max(0, item.init + action.value)
|
|
418
|
+
}
|
|
275
419
|
}
|
|
276
420
|
}
|
|
421
|
+
|
|
422
|
+
await fs.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' })
|
|
277
423
|
}
|
|
278
424
|
})(),
|
|
279
425
|
])
|
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
|
-
]
|