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 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 + 1 ? pp : cc.name.length + 1, c.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:**\`- ${child.name.padEnd(nameLength - 1)} ▏${child.alias.padEnd(3)} ▏${hhp} \`** ${hpBar(child.hp, child.maxhp)} `));
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
- const input = yield new Promise((resolve) => (rl.question('>', resolve)));
226
- const hpmod = input.match(/([^\d+-]+)\s*([+-]?\d+)/);
227
- if (hpmod) {
228
- const file = yield promises_1.default.readFile(argument, { encoding: 'utf-8' });
229
- const tracker = (0, app_1.parseTracker)(file);
230
- const index = tracker.findIndex((c) => c.alias === hpmod[1]);
231
- if (index >= 0) {
232
- let hp = tracker[index].hp;
233
- let thp = tracker[index].temphp;
234
- if (hpmod[2].match(/^[+-]/)) {
235
- const delta = parseInt(hpmod[2]);
236
- if (delta < 0) {
237
- thp += delta;
238
- hp += Math.min(thp, 0);
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 += delta;
246
+ return { command: 'set-hp', tag: match[1], value: parseInt(match[2]) };
242
247
  }
243
248
  }
244
- else {
245
- hp = parseInt(hpmod[2]);
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
- tracker[index].temphp = Math.max(0, thp);
248
- tracker[index].hp = Math.min(tracker[index].maxhp, Math.max(0, hp));
249
- yield promises_1.default.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' });
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 thpmod = input.match(/(\S+)\s+[tT]\s*([+-]?\d+)/);
253
- if (thpmod) {
254
- const file = yield promises_1.default.readFile(argument, { encoding: 'utf-8' });
255
- const tracker = (0, app_1.parseTracker)(file);
256
- const index = tracker.findIndex((c) => c.alias === thpmod[1]);
257
- if (index >= 0) {
258
- let thp = tracker[index].temphp;
259
- if (thpmod[2].match(/^[+-]/)) {
260
- thp += parseInt(thpmod[2]);
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
- else {
263
- thp = parseInt(thpmod[2]);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pf2e-sage-stats",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "An RPG Sage's .tsv stat generation tool",
5
5
  "main": "dist/index.js",
6
6
  "author": "ikariott@gmail.com",
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 + 1 ? pp : cc.name.length + 1, c.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:**\`- ${child.name.padEnd(nameLength - 1)} ▏${child.alias.padEnd(3)} ▏${hhp} \`** ${hpBar(child.hp, child.maxhp)} `
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
- const input = await new Promise<string>((resolve) => (
218
- rl.question('>', resolve)
217
+ let input = await new Promise<string>((resolve) => (
218
+ rl.question('> ', resolve)
219
219
  ));
220
220
 
221
- const hpmod = input.match(/([^\d+-]+)\s*([+-]?\d+)/);
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
- if (hpmod) {
224
- const file = await fs.readFile(argument, { encoding: 'utf-8' });
285
+ const match = input.match(command.regex);
225
286
 
226
- const tracker = parseTracker(file);
287
+ if (!match) {
288
+ break;
289
+ }
227
290
 
228
- const index = tracker.findIndex((c) => c.alias === hpmod[1])
291
+ const action = command.map(match);
229
292
 
230
- if (index >= 0) {
231
- let hp = tracker[index].hp;
232
- let thp = tracker[index].temphp;
293
+ input = input.slice(match[0].length);
233
294
 
234
- if (hpmod[2].match(/^[+-]/)) {
235
- const delta = parseInt(hpmod[2])
295
+ actions.push(action)
296
+ }
236
297
 
237
- if (delta < 0) {
238
- thp += delta;
239
- hp += Math.min(thp, 0)
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
- hp += delta;
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
- tracker[index].temphp = Math.max(0, thp)
248
- tracker[index].hp = Math.min(tracker[index].maxhp, Math.max(0, hp))
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
- await fs.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' })
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
- const thpmod = input.match(/(\S+)\s+[tT]\s*([+-]?\d+)/);
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
- if (thpmod) {
257
- const file = await fs.readFile(argument, { encoding: 'utf-8' });
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
- const tracker = parseTracker(file);
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
- const index = tracker.findIndex((c) => c.alias === thpmod[1])
399
+ if (item) {
400
+ let hp = item.hp;
401
+ let thp = item.temphp;
262
402
 
263
- if (index >= 0) {
264
- let thp = tracker[index].temphp;
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
- if (thpmod[2].match(/^[+-]/)) {
267
- thp += parseInt(thpmod[2]);
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
- tracker[index].temphp = Math.max(0, thp)
273
-
274
- await fs.writeFile(argument, JSON.stringify(tracker, undefined, 2), { encoding: 'utf-8' })
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
@@ -1,5 +0,0 @@
1
- ## Status: Player Characters
2
- Асотил (64/64 HP):
3
- Брон (24/24 HP):
4
- Нтаанди (20/20 HP):
5
- Перитон (22/22 HP):
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
- ]