coh-content-db 2.0.0-rc.5 → 2.0.0-rc.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.
Files changed (51) hide show
  1. package/README.md +4 -4
  2. package/dist/coh-content-db.d.ts +203 -156
  3. package/dist/coh-content-db.js +263 -197
  4. package/dist/coh-content-db.js.map +1 -1
  5. package/dist/coh-content-db.mjs +256 -191
  6. package/dist/coh-content-db.mjs.map +1 -1
  7. package/package.json +1 -1
  8. package/src/main/api/badge-data.ts +16 -9
  9. package/src/main/api/{badge-partial-data.ts → badge-requirement-data.ts} +24 -8
  10. package/src/main/api/badge-requirement-type.ts +11 -0
  11. package/src/main/api/contact-data.ts +46 -0
  12. package/src/main/api/content-bundle.ts +10 -4
  13. package/src/main/api/zone-data.ts +20 -0
  14. package/src/main/changelog.ts +5 -1
  15. package/src/main/db/badge-index.ts +17 -11
  16. package/src/main/db/{badge-partial.ts → badge-requirement.ts} +30 -11
  17. package/src/main/db/badge-search-options.ts +2 -2
  18. package/src/main/db/badge.ts +48 -36
  19. package/src/main/db/bundle-metadata.ts +3 -3
  20. package/src/main/db/coh-content-database.ts +51 -18
  21. package/src/main/db/contact.ts +59 -0
  22. package/src/main/db/zone.ts +28 -0
  23. package/src/main/index.ts +8 -10
  24. package/src/main/util.ts +44 -13
  25. package/src/test/api/badge-data.fixture.ts +9 -7
  26. package/src/test/api/badge-requirement-data.fixture.ts +17 -0
  27. package/src/test/api/badge-requirement-type.test.ts +31 -0
  28. package/src/test/api/contact-data.fixture.ts +13 -0
  29. package/src/test/api/content-bundle.fixture.ts +2 -2
  30. package/src/test/api/content-bundle.test.ts +1 -1
  31. package/src/test/api/zone-data.fixture.ts +8 -0
  32. package/src/test/db/badge-index.test.ts +73 -41
  33. package/src/test/db/badge-requirement.test.ts +180 -0
  34. package/src/test/db/badge.test.ts +190 -15
  35. package/src/test/db/coh-content-database.test.ts +110 -18
  36. package/src/test/db/contact.test.ts +96 -0
  37. package/src/test/db/zone.test.ts +36 -0
  38. package/src/test/index.test.ts +4 -2
  39. package/src/test/util.test.ts +59 -22
  40. package/src/main/api/badge-partial-type.ts +0 -8
  41. package/src/main/api/game-map-data.ts +0 -26
  42. package/src/main/api/vidiot-map-data.ts +0 -18
  43. package/src/main/api/vidiot-map-point-of-interest-data.ts +0 -30
  44. package/src/main/db/game-map.ts +0 -33
  45. package/src/main/db/vidiot-map-point-of-interest.ts +0 -39
  46. package/src/main/db/vidiot-map.ts +0 -25
  47. package/src/test/api/badge-partial-data.fixture.ts +0 -17
  48. package/src/test/api/badge-partial-type.test.ts +0 -31
  49. package/src/test/api/game-map-data.fixture.ts +0 -10
  50. package/src/test/api/vidiot-map-point-of-interest.fixture.ts +0 -10
  51. package/src/test/api/vidiot-map.fixture.ts +0 -9
@@ -2,10 +2,16 @@
2
2
 
3
3
  const ALIGNMENT = ["H", "V", "P"];
4
4
 
5
- const BADGE_PARTIAL_TYPE = [
5
+ const BADGE_REQUIREMENT_TYPE = [
6
6
  "PLAQUE",
7
7
  "BADGE",
8
8
  "INVENTION",
9
+ "MISSION",
10
+ // Complete a mission
11
+ "ARC",
12
+ // Complete a story arc
13
+ "TASK_FORCE",
14
+ // Complete a task force
9
15
  "INVENTION_PLUS_ONE"
10
16
  // Some invention badges require you to build x of two different invention levels, 'plus one of either level'.
11
17
  ];
@@ -64,16 +70,16 @@ const PLAQUE_TYPE = [
64
70
 
65
71
  const SEX = ["M", "F"];
66
72
 
67
- var __defProp$8 = Object.defineProperty;
68
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
69
- var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
73
+ var __defProp$7 = Object.defineProperty;
74
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
75
+ var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
70
76
  class Alignments {
71
77
  constructor(raw) {
72
- __publicField$8(this, "items");
73
- __publicField$8(this, "hero");
74
- __publicField$8(this, "villain");
75
- __publicField$8(this, "praetorian");
76
- __publicField$8(this, "primal");
78
+ __publicField$7(this, "items");
79
+ __publicField$7(this, "hero");
80
+ __publicField$7(this, "villain");
81
+ __publicField$7(this, "praetorian");
82
+ __publicField$7(this, "primal");
77
83
  this.items = raw;
78
84
  this.hero = raw.includes("H");
79
85
  this.villain = raw.includes("V");
@@ -183,198 +189,224 @@ validateKey_fn = function(key) {
183
189
  if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
184
190
  };
185
191
 
186
- var __defProp$7 = Object.defineProperty;
187
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
188
- var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
192
+ var __defProp$6 = Object.defineProperty;
193
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
194
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
189
195
  class Archetype {
190
196
  constructor(data) {
191
- __publicField$7(this, "key");
192
- __publicField$7(this, "name");
193
- __publicField$7(this, "description");
197
+ __publicField$6(this, "key");
198
+ __publicField$6(this, "name");
199
+ __publicField$6(this, "description");
194
200
  this.key = new Key(data.key).value;
195
201
  this.name = data.name;
196
202
  this.description = data.description;
197
203
  }
198
204
  }
199
205
 
200
- var __defProp$6 = Object.defineProperty;
201
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
202
- var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
203
- class BadgePartial {
206
+ var __defProp$5 = Object.defineProperty;
207
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
208
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
209
+ class BadgeRequirement {
204
210
  constructor(data) {
205
211
  /**
206
212
  * Key.
207
213
  */
208
- __publicField$6(this, "key");
214
+ __publicField$5(this, "key");
209
215
  /**
210
- * Type of partial.
216
+ * Type of requirement.
211
217
  */
212
- __publicField$6(this, "type");
218
+ __publicField$5(this, "type");
213
219
  /**
214
- * Map the partial is located on.
220
+ * Zone the requirement is located in.
215
221
  */
216
- __publicField$6(this, "mapKey");
222
+ __publicField$5(this, "zoneKey");
217
223
  /**
218
224
  * /loc coordinates.
219
225
  */
220
- __publicField$6(this, "loc");
226
+ __publicField$5(this, "loc");
221
227
  /**
222
228
  * Is it a wall plaque or a physical monument?
223
229
  */
224
- __publicField$6(this, "plaqueType");
230
+ __publicField$5(this, "plaqueType");
225
231
  /**
226
232
  * Plaque inscription.
227
233
  */
228
- __publicField$6(this, "plaqueInscription");
234
+ __publicField$5(this, "plaqueInscription");
235
+ /**
236
+ * The number or letter the plaque appears as on Vidiot Maps.
237
+ */
238
+ __publicField$5(this, "vidiotMapKey");
239
+ /**
240
+ * The key of the badge for this requirement.
241
+ */
242
+ __publicField$5(this, "badgeKey");
229
243
  /**
230
- * The number or letter the partial appears as on Vidiot Maps.
244
+ * Mission name.
231
245
  */
232
- __publicField$6(this, "vidiotMapKey");
246
+ __publicField$5(this, "missionName");
233
247
  /**
234
- * The badge required for this partial.
248
+ * {@link Contact} key for the story arc.
235
249
  */
236
- __publicField$6(this, "badgeKey");
250
+ __publicField$5(this, "contactKey");
237
251
  /**
238
252
  * Level of the invention required.
239
253
  */
240
- __publicField$6(this, "inventionLevel");
254
+ __publicField$5(this, "inventionLevel");
241
255
  /**
242
256
  * The types of enhancements required to be crafted.
243
257
  */
244
- __publicField$6(this, "inventionTypes");
258
+ __publicField$5(this, "inventionTypes");
245
259
  /**
246
260
  * Number of invention crafts required.
247
261
  */
248
- __publicField$6(this, "inventionCount");
262
+ __publicField$5(this, "inventionCount");
249
263
  /**
250
264
  * Any additional notes.
251
265
  */
252
- __publicField$6(this, "notes");
266
+ __publicField$5(this, "notes");
267
+ /**
268
+ * List of external links. Wiki, forums, etc.
269
+ */
270
+ __publicField$5(this, "links");
253
271
  this.key = new Key(data.key).value;
254
272
  this.type = data.type;
255
- this.mapKey = data.mapKey;
273
+ this.zoneKey = data.zoneKey;
256
274
  this.loc = data.loc;
257
275
  this.plaqueType = data.plaqueType;
258
276
  this.plaqueInscription = data.plaqueInscription;
259
277
  this.vidiotMapKey = data.vidiotMapKey;
260
278
  this.badgeKey = data.badgeKey;
279
+ this.missionName = data.missionName;
280
+ this.contactKey = data.contactKey;
261
281
  this.inventionLevel = data.inventionLevel;
262
282
  this.inventionTypes = data.inventionTypes;
263
283
  this.inventionCount = data.inventionCount;
264
284
  this.notes = data.notes;
285
+ this.links = data.links ?? [];
265
286
  }
266
287
  }
267
288
 
268
- var __defProp$5 = Object.defineProperty;
289
+ var __defProp$4 = Object.defineProperty;
269
290
  var __typeError$2 = (msg) => {
270
291
  throw TypeError(msg);
271
292
  };
272
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
273
- var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
293
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
294
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
274
295
  var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
275
296
  var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
276
297
  var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
277
- var _partialsIndex;
298
+ var _requirementsIndex;
278
299
  class Badge {
279
- constructor(data) {
280
- __privateAdd$2(this, _partialsIndex, {});
300
+ constructor(badgeData) {
301
+ __privateAdd$2(this, _requirementsIndex, {});
281
302
  /**
282
303
  * The database key for this badge.
283
304
  */
284
- __publicField$5(this, "key");
305
+ __publicField$4(this, "key");
285
306
  /**
286
307
  * The type of badge.
287
308
  */
288
- __publicField$5(this, "type");
309
+ __publicField$4(this, "type");
289
310
  /**
290
311
  * The name of this badge.
291
312
  *
292
313
  * May vary by character sex or alignment.
293
314
  */
294
- __publicField$5(this, "name");
315
+ __publicField$4(this, "name");
295
316
  /**
296
317
  * The character alignments that this badge is available to.
297
318
  */
298
- __publicField$5(this, "alignment");
319
+ __publicField$4(this, "alignment");
299
320
  /**
300
321
  * The badge text as it appears in-game. May vary by character sex or alignment.
301
322
  */
302
- __publicField$5(this, "badgeText");
323
+ __publicField$4(this, "badgeText");
303
324
  /**
304
- * Description of how to acquire the badge.
325
+ * Short description of how to acquire the badge. Detailed instructions will be in the notes field.
305
326
  */
306
- __publicField$5(this, "acquisition");
327
+ __publicField$4(this, "acquisition");
307
328
  /**
308
329
  * Absolute URL to this badge's icon.
309
330
  *
310
331
  * May vary by character sex or alignment.
311
332
  */
312
- __publicField$5(this, "icon");
333
+ __publicField$4(this, "icon");
313
334
  /**
314
335
  * Freeform notes or tips about the badge.
315
336
  */
316
- __publicField$5(this, "notes");
337
+ __publicField$4(this, "notes");
317
338
  /**
318
- * List of external links for this Badge. Wiki, forums, etc.
339
+ * List of external links. Wiki, forums, etc.
319
340
  */
320
- __publicField$5(this, "links");
341
+ __publicField$4(this, "links");
321
342
  /**
322
- * For exploration badges, the key of the {@link GameMap} that this badge is found on.
343
+ * For exploration badges, the key of the {@link Zone} that this badge is found on.
323
344
  */
324
- __publicField$5(this, "mapKey");
345
+ __publicField$4(this, "zoneKey");
325
346
  /**
326
- * For exploration badges, the `/loc` coordinates of the badge on the in-game map.
347
+ * For exploration badges, the `/loc` coordinates of the badge.
327
348
  */
328
- __publicField$5(this, "loc");
349
+ __publicField$4(this, "loc");
329
350
  /**
330
- * For badges that appear on a Vidiot Map, the number or letter the badge appears as.
351
+ * For plaques that appear on a Vidiot Map, the number or letter the badge appears as.
331
352
  */
332
- __publicField$5(this, "vidiotMapKey");
353
+ __publicField$4(this, "vidiotMapKey");
333
354
  /**
334
355
  * ID used with the in-game `/settitle` command to apply the badge.
335
356
  */
336
- __publicField$5(this, "setTitle");
357
+ __publicField$4(this, "setTitle");
337
358
  /**
338
359
  * A description of the effect the badge will have, such as a buff or granting a temporary power.
339
360
  */
340
- __publicField$5(this, "effect");
361
+ __publicField$4(this, "effect");
341
362
  /**
342
- * A list of requirements for badges that have partial fulfilment steps, such as visiting plaques for history badges, or collecting other badges for meta-badges like accolades.
363
+ * Represents the layered requirements for badges with multiple fulfillment steps,
364
+ * such as visiting plaques for history badges or collecting other badges.
365
+ *
366
+ * The outer array represents groups of requirements evaluated with OR logic —
367
+ * fulfilling any group satisfies the badge.
368
+ *
369
+ * Each inner array represents individual requirements evaluated with AND logic —
370
+ * all conditions in the group must be met.
343
371
  */
344
- __publicField$5(this, "partials");
372
+ __publicField$4(this, "requirements");
345
373
  /**
346
374
  * Some badges are not included in the badge total count... such as Flames of Prometheus, which can be removed by redeeming it for a Notice of the Well.
347
375
  */
348
- __publicField$5(this, "ignoreInTotals");
349
- this.key = new Key(data.key).value;
350
- this.type = data.type;
351
- this.name = new Alternates(data.name);
352
- this.alignment = new Alignments(data.alignment);
353
- this.badgeText = new Alternates(data.badgeText ?? []);
354
- this.acquisition = data.acquisition;
355
- this.icon = new Alternates(data.icon ?? []);
356
- this.notes = data.notes;
357
- this.links = data.links;
358
- this.mapKey = data.mapKey;
359
- this.loc = data.loc;
360
- this.effect = data.effect;
361
- this.vidiotMapKey = data.vidiotMapKey;
362
- this.setTitle = data.setTitle;
363
- this.ignoreInTotals = data.ignoreInTotals ?? false;
364
- this.partials = data.partials?.map((data2) => {
365
- if (__privateGet$2(this, _partialsIndex)[data2.key] !== void 0) throw new Error(`Duplicate badge partial key [${data2.key}]`);
366
- const badge = new BadgePartial(data2);
367
- __privateGet$2(this, _partialsIndex)[badge.key] = badge;
368
- return badge;
376
+ __publicField$4(this, "ignoreInTotals");
377
+ this.key = new Key(badgeData.key).value;
378
+ this.type = badgeData.type;
379
+ this.name = new Alternates(badgeData.name);
380
+ this.alignment = new Alignments(badgeData.alignment);
381
+ this.badgeText = new Alternates(badgeData.badgeText ?? []);
382
+ this.acquisition = badgeData.acquisition;
383
+ this.icon = new Alternates(badgeData.icon ?? []);
384
+ this.notes = badgeData.notes;
385
+ this.links = badgeData.links ?? [];
386
+ this.zoneKey = badgeData.zoneKey;
387
+ this.loc = badgeData.loc;
388
+ this.effect = badgeData.effect;
389
+ this.vidiotMapKey = badgeData.vidiotMapKey;
390
+ this.setTitle = badgeData.setTitle;
391
+ this.ignoreInTotals = badgeData.ignoreInTotals ?? false;
392
+ this.requirements = badgeData.requirements?.map((groups, index) => {
393
+ const existingKeysInGroup = /* @__PURE__ */ new Set();
394
+ return groups.map((requirementData) => {
395
+ if (existingKeysInGroup.has(requirementData.key)) throw new Error(`Duplicate badge requirement key [${badgeData.key}:${requirementData.key}] in group [${index + 1}]`);
396
+ existingKeysInGroup.add(requirementData.key);
397
+ const badge = new BadgeRequirement(requirementData);
398
+ __privateGet$2(this, _requirementsIndex)[badge.key] = badge;
399
+ return badge;
400
+ });
369
401
  });
370
402
  }
371
- getPartial(key) {
372
- const result = __privateGet$2(this, _partialsIndex)[key];
373
- if (result === void 0) throw new Error(`Unknown badge partial key [${key}]`);
403
+ getRequirement(key) {
404
+ const result = __privateGet$2(this, _requirementsIndex)[key];
405
+ if (result === void 0) throw new Error(`Unknown badge requirement key [${key}]`);
374
406
  return result;
375
407
  }
376
408
  }
377
- _partialsIndex = new WeakMap();
409
+ _requirementsIndex = new WeakMap();
378
410
 
379
411
  var __typeError$1 = (msg) => {
380
412
  throw TypeError(msg);
@@ -384,15 +416,15 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
384
416
  var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
385
417
  var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
386
418
  var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
387
- var _badges, _badgeIndex$1, _mapOrder, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
419
+ var _badges, _badgeIndex$1, _zoneOrder, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
388
420
  class BadgeIndex {
389
- constructor(badges, maps) {
421
+ constructor(badges, zones) {
390
422
  __privateAdd$1(this, _BadgeIndex_instances);
391
423
  __privateAdd$1(this, _badges, []);
392
424
  __privateAdd$1(this, _badgeIndex$1, {});
393
- __privateAdd$1(this, _mapOrder, {});
394
- __privateSet$1(this, _mapOrder, Object.fromEntries(
395
- maps?.sort((a, b) => a.name.localeCompare(b.name))?.map((x, index) => [x.key, index]) ?? []
425
+ __privateAdd$1(this, _zoneOrder, {});
426
+ __privateSet$1(this, _zoneOrder, Object.fromEntries(
427
+ zones?.sort((a, b) => a.name.localeCompare(b.name))?.map((x, index) => [x.key, index]) ?? []
396
428
  ));
397
429
  __privateSet$1(this, _badges, badges);
398
430
  for (const badge of badges) {
@@ -405,29 +437,34 @@ class BadgeIndex {
405
437
  if (result === void 0) throw new Error(`Unknown badge key [${key}]`);
406
438
  return result;
407
439
  }
440
+ badgeExists(key) {
441
+ return !!__privateGet$1(this, _badgeIndex$1)[key];
442
+ }
408
443
  searchBadges(options) {
409
444
  const filtered = options?.query || options?.filter ? __privateGet$1(this, _badges).filter((badge) => __privateMethod(this, _BadgeIndex_instances, satisfiesQueryPredicate_fn).call(this, badge, options?.query) && __privateMethod(this, _BadgeIndex_instances, satisfiesFilterPredicate_fn).call(this, badge, options?.filter)) : __privateGet$1(this, _badges);
410
- const paged = options?.pageSize ? filtered.slice(((options?.page ?? 1) - 1) * options.pageSize, (options?.page ?? 1) * options?.pageSize) : filtered;
445
+ const totalPages = options?.pageSize ? Math.ceil(filtered.length / options?.pageSize) : 1;
446
+ const page = Math.max(1, Math.min(totalPages, options?.page ?? 1));
447
+ const paged = options?.pageSize ? filtered.slice((page - 1) * options.pageSize, page * options?.pageSize) : filtered;
411
448
  const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, paged, options?.sort);
412
449
  return {
413
450
  items: sorted,
414
- page: options?.page ?? 1,
451
+ page,
415
452
  pageSize: options?.pageSize,
416
453
  totalItems: filtered.length,
417
- totalPages: options?.pageSize ? Math.ceil(filtered.length / options?.pageSize) : 1
454
+ totalPages
418
455
  };
419
456
  }
420
457
  }
421
458
  _badges = new WeakMap();
422
459
  _badgeIndex$1 = new WeakMap();
423
- _mapOrder = new WeakMap();
460
+ _zoneOrder = new WeakMap();
424
461
  _BadgeIndex_instances = new WeakSet();
425
462
  satisfiesQueryPredicate_fn = function(badge, query) {
426
463
  const queryString = query?.str?.toLowerCase() ?? "";
427
464
  return !!((query?.on?.name ?? true) && badge.name.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.badgeText && badge.badgeText.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.acquisition && badge.acquisition?.toLowerCase().includes(queryString) || query?.on?.effect && badge.effect?.toLowerCase().includes(queryString) || query?.on?.notes && badge.notes?.toLowerCase().includes(queryString) || query?.on?.setTitle && (badge.setTitle?.id?.toString().includes(queryString) || badge.setTitle?.praetorianId?.toString().includes(queryString)));
428
465
  };
429
466
  satisfiesFilterPredicate_fn = function(badge, filter) {
430
- return (!filter?.type || badge.type === filter.type) && (!filter?.mapKey || badge.mapKey === filter.mapKey) && (!filter?.alignment || badge.alignment.items.includes(filter.alignment));
467
+ return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.alignment || badge.alignment.items.includes(filter.alignment));
431
468
  };
432
469
  sort_fn = function(badges, sort) {
433
470
  if (!sort) return badges;
@@ -435,8 +472,8 @@ sort_fn = function(badges, sort) {
435
472
  if (!sort.by || sort.by === "CANONICAL") return sort.dir === "DESC" ? badges.reverse() : badges;
436
473
  if (sort.by === "BADGE_NAME") return ascending ? badges.sort((a, b) => a.name.default?.value.localeCompare(b.name.default?.value ?? "") ?? 0) : badges.sort((a, b) => b.name.default?.value.localeCompare(a.name.default?.value ?? "") ?? 0);
437
474
  return badges.sort((a, b) => {
438
- const aIndex = __privateGet$1(this, _mapOrder)[a.mapKey ?? ""];
439
- const bIndex = __privateGet$1(this, _mapOrder)[b.mapKey ?? ""];
475
+ const aIndex = __privateGet$1(this, _zoneOrder)[a.zoneKey ?? ""];
476
+ const bIndex = __privateGet$1(this, _zoneOrder)[b.zoneKey ?? ""];
440
477
  if (aIndex === bIndex) return 0;
441
478
  if (aIndex === void 0) return ascending ? 1 : -1;
442
479
  if (bIndex === void 0) return ascending ? -1 : 1;
@@ -444,31 +481,31 @@ sort_fn = function(badges, sort) {
444
481
  });
445
482
  };
446
483
 
447
- var __defProp$4 = Object.defineProperty;
448
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
449
- var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
484
+ var __defProp$3 = Object.defineProperty;
485
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
486
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
450
487
  class BundleMetadata {
451
488
  constructor(bundle) {
452
489
  /**
453
- * Name of the server group.
490
+ * Name of the content bundle.
454
491
  */
455
- __publicField$4(this, "name");
492
+ __publicField$3(this, "name");
456
493
  /**
457
- * Description of the server group.
494
+ * Description of the fork.
458
495
  */
459
- __publicField$4(this, "description");
496
+ __publicField$3(this, "description");
460
497
  /**
461
498
  * Repository where the db content package is maintained.
462
499
  */
463
- __publicField$4(this, "repository");
500
+ __publicField$3(this, "repository");
464
501
  /**
465
- * List of external links for this Server Group. Wiki, forums, etc.
502
+ * List of external links. Wiki, forums, etc.
466
503
  */
467
- __publicField$4(this, "links");
504
+ __publicField$3(this, "links");
468
505
  /**
469
506
  * Change log for this data package.
470
507
  */
471
- __publicField$4(this, "changelog");
508
+ __publicField$3(this, "changelog");
472
509
  this.name = bundle.name;
473
510
  this.description = bundle.description;
474
511
  this.repository = bundle.repository;
@@ -477,89 +514,78 @@ class BundleMetadata {
477
514
  }
478
515
  }
479
516
 
480
- var __defProp$3 = Object.defineProperty;
481
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
482
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
483
- class VidiotMapPointOfInterest {
484
- constructor(data) {
485
- /**
486
- * The pixel-space position of the PoI on the map graphic.
487
- *
488
- * Screen-space, pixels from top-left `[0, 0]`.
489
- */
490
- __publicField$3(this, "pos");
491
- /**
492
- * Freeform notes about the PoI.
493
- */
494
- __publicField$3(this, "notes");
495
- /**
496
- * If the POI is a zone transfer, the map it transfers to.
497
- */
498
- __publicField$3(this, "mapKey");
499
- /**
500
- * If the POI is a badge, the badge.
501
- */
502
- __publicField$3(this, "badgeKey");
503
- /**
504
- * If the POI is a partial for a badge, the partial key.
505
- */
506
- __publicField$3(this, "badgePartialKey");
507
- this.pos = data.pos;
508
- this.notes = data.notes;
509
- this.mapKey = data.mapKey;
510
- this.badgeKey = data.badgeKey;
511
- this.badgePartialKey = data.badgePartialKey;
512
- }
513
- }
514
-
515
517
  var __defProp$2 = Object.defineProperty;
516
518
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
517
519
  var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
518
- class VidiotMap {
520
+ class Zone {
519
521
  constructor(data) {
520
522
  /**
521
- * URL of the map image.
523
+ * Unique key used to reference this zone.
524
+ *
525
+ * Keys can only contain lowercase letters, numbers and hyphens (`-`).
522
526
  */
523
- __publicField$2(this, "imageUrl");
527
+ __publicField$2(this, "key");
524
528
  /**
525
- * Name to display for the Vidiot map.
529
+ * The name of the zone as it appears in-game.
526
530
  */
527
531
  __publicField$2(this, "name");
528
532
  /**
529
- * List of Points of Interest labelled on the image.
533
+ * List of external links. Wiki, forums, etc.
530
534
  */
531
- __publicField$2(this, "pointsOfInterest");
532
- this.imageUrl = data.imageUrl;
535
+ __publicField$2(this, "links");
536
+ this.key = new Key(data.key).value;
533
537
  this.name = data.name;
534
- this.pointsOfInterest = data.pointsOfInterest?.map((data2) => new VidiotMapPointOfInterest(data2));
538
+ this.links = data.links ?? [];
535
539
  }
536
540
  }
537
541
 
538
542
  var __defProp$1 = Object.defineProperty;
539
543
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
540
544
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
541
- class GameMap {
542
- constructor(data) {
545
+ class Contact {
546
+ constructor(contactData) {
543
547
  /**
544
- * The database key for this map.
548
+ * Unique key used to reference this contact.
549
+ *
550
+ * Keys can only contain lowercase letters, numbers and hyphens (`-`).
545
551
  */
546
552
  __publicField$1(this, "key");
547
553
  /**
548
- * The name of the map as it appears in-game.
554
+ * The name of this contact.
549
555
  */
550
556
  __publicField$1(this, "name");
551
557
  /**
552
- * List of external links for this Map. Wiki, forums, etc.
558
+ * The contact's title.
553
559
  */
554
- __publicField$1(this, "links");
560
+ __publicField$1(this, "title");
555
561
  /**
556
- * List of Vidiot Map assets for this map.
562
+ * The zone this character is located in.
557
563
  */
558
- __publicField$1(this, "vidiotMaps");
559
- this.key = new Key(data.key).value;
560
- this.name = data.name;
561
- this.links = data.links;
562
- this.vidiotMaps = data.vidiotMaps?.map((data2) => new VidiotMap(data2));
564
+ __publicField$1(this, "zoneKey");
565
+ /**
566
+ * The `/loc` coordinates of the contact.
567
+ */
568
+ __publicField$1(this, "loc");
569
+ /**
570
+ * The level range this contact will offer missions for.
571
+ */
572
+ __publicField$1(this, "levelRange");
573
+ /**
574
+ * Freeform notes or tips about the contact.
575
+ */
576
+ __publicField$1(this, "notes");
577
+ /**
578
+ * List of external links. Wiki, forums, etc.
579
+ */
580
+ __publicField$1(this, "links");
581
+ this.key = new Key(contactData.key).value;
582
+ this.name = contactData.name;
583
+ this.title = contactData.title;
584
+ this.zoneKey = contactData.zoneKey;
585
+ this.loc = contactData.loc;
586
+ this.levelRange = contactData.levelRange;
587
+ this.notes = contactData.notes;
588
+ this.links = contactData.links ?? [];
563
589
  }
564
590
  }
565
591
 
@@ -573,7 +599,7 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
573
599
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
574
600
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
575
601
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
576
- var _archetypeIndex, _mapIndex, _badgeIndex;
602
+ var _archetypeIndex, _zoneIndex, _contactIndex, _badgeIndex;
577
603
  class CohContentDatabase {
578
604
  /**
579
605
  * Initialize the database with a content bundle.
@@ -581,59 +607,85 @@ class CohContentDatabase {
581
607
  */
582
608
  constructor(bundle) {
583
609
  __privateAdd(this, _archetypeIndex, {});
584
- __privateAdd(this, _mapIndex, {});
610
+ __privateAdd(this, _zoneIndex, {});
611
+ __privateAdd(this, _contactIndex, {});
585
612
  __privateAdd(this, _badgeIndex);
586
613
  /**
587
614
  * Metadata about the content bundle.
588
615
  */
589
616
  __publicField(this, "metadata");
590
617
  /**
591
- * List of the game server names in this server group.
618
+ * List of the game server names.
619
+ *
592
620
  * Torchbearer, Excelsior, etc.
593
621
  */
594
622
  __publicField(this, "servers");
595
623
  /**
596
- * List of archetypes available in this server group.
624
+ * List of archetypes.
597
625
  */
598
626
  __publicField(this, "archetypes");
599
627
  /**
600
- * List of game maps supported by this server group.
628
+ * List of game zones.
629
+ */
630
+ __publicField(this, "zones");
631
+ /**
632
+ * List of contacts.
601
633
  */
602
- __publicField(this, "maps");
634
+ __publicField(this, "contacts");
603
635
  /**
604
- * List of badges available on this server group.
636
+ * List of badges.
605
637
  */
606
638
  __publicField(this, "badges");
607
639
  this.metadata = new BundleMetadata(bundle);
608
640
  this.servers = bundle.servers ?? [];
609
641
  this.archetypes = bundle.archetypes?.map((data) => {
610
- if (__privateGet(this, _archetypeIndex)[data.key] !== void 0) throw new Error(`Duplicate archetype key [${data.key}]`);
642
+ if (__privateGet(this, _archetypeIndex)[data.key] !== void 0) throw new Error(`Duplicate archetype key '${data.key}'`);
611
643
  const archetype = new Archetype(data);
612
644
  __privateGet(this, _archetypeIndex)[archetype.key] = archetype;
613
645
  return archetype;
614
646
  }) ?? [];
615
- this.maps = bundle.maps?.map((data) => {
616
- if (__privateGet(this, _mapIndex)[data.key] !== void 0) throw new Error(`Duplicate map key [${data.key}]`);
617
- const map = new GameMap(data);
618
- __privateGet(this, _mapIndex)[map.key] = map;
619
- return map;
647
+ this.zones = bundle.zones?.map((data) => {
648
+ if (__privateGet(this, _zoneIndex)[data.key] !== void 0) throw new Error(`Duplicate zone key '${data.key}'`);
649
+ const zone = new Zone(data);
650
+ __privateGet(this, _zoneIndex)[zone.key] = zone;
651
+ return zone;
652
+ }) ?? [];
653
+ this.contacts = bundle.contacts?.map((data) => {
654
+ if (__privateGet(this, _contactIndex)[data.key] !== void 0) throw new Error(`Duplicate contact key '${data.key}'`);
655
+ const contact = new Contact(data);
656
+ __privateGet(this, _contactIndex)[contact.key] = contact;
657
+ return contact;
620
658
  }) ?? [];
621
659
  this.badges = bundle.badges?.map((data) => new Badge(data)) ?? [];
622
- __privateSet(this, _badgeIndex, new BadgeIndex(this.badges, this.maps));
660
+ __privateSet(this, _badgeIndex, new BadgeIndex(this.badges, this.zones));
623
661
  }
624
662
  getArchetype(key) {
625
663
  const result = __privateGet(this, _archetypeIndex)[key];
626
- if (result === void 0) throw new Error(`Unknown archetype key [${key}]`);
664
+ if (result === void 0) throw new Error(`Unknown archetype key '${key}'`);
627
665
  return result;
628
666
  }
629
- getMap(key) {
630
- const result = __privateGet(this, _mapIndex)[key];
631
- if (result === void 0) throw new Error(`Unknown map key [${key}]`);
667
+ getZone(key) {
668
+ const result = __privateGet(this, _zoneIndex)[key];
669
+ if (result === void 0) throw new Error(`Unknown zone key '${key}'`);
632
670
  return result;
633
671
  }
672
+ getContact(key) {
673
+ const result = __privateGet(this, _contactIndex)[key];
674
+ if (result === void 0) throw new Error(`Unknown contact key '${key}'`);
675
+ return result;
676
+ }
677
+ zoneExists(key) {
678
+ return !!__privateGet(this, _zoneIndex)[key];
679
+ }
680
+ contactExists(key) {
681
+ return !!__privateGet(this, _contactIndex)[key];
682
+ }
634
683
  getBadge(key) {
635
684
  return __privateGet(this, _badgeIndex).getBadge(key);
636
685
  }
686
+ badgeExists(key) {
687
+ return __privateGet(this, _badgeIndex).badgeExists(key);
688
+ }
637
689
  /**
638
690
  * Search, sort and filter the badge list.
639
691
  * This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
@@ -645,7 +697,8 @@ class CohContentDatabase {
645
697
  }
646
698
  }
647
699
  _archetypeIndex = new WeakMap();
648
- _mapIndex = new WeakMap();
700
+ _zoneIndex = new WeakMap();
701
+ _contactIndex = new WeakMap();
649
702
  _badgeIndex = new WeakMap();
650
703
 
651
704
  const CHANGELOG = [
@@ -656,9 +709,13 @@ const CHANGELOG = [
656
709
  * Server groups are now referred to as 'forks'.
657
710
  * Replaced enums with union types.
658
711
  * \`IServerGroupData\` is now \`ContentBundle\` and each database instance is now designed to accept only a single server group.
712
+ * \`GameMap\` is now \`Zone\`.
659
713
  * Removed the \`serverGroup\` property from entities to simplify the object tree given that only a single context can exist per db now.
660
714
  * Added a simple indexing and search function for badge names, text and acquisition info.
661
- * Map and badge references now follow a standard Markdown link format with a \`badge://\` or \`map://\` protocol.
715
+ * Zone and badge references now follow a standard Markdown link format with a \`badge://\` or \`map://\` protocol.
716
+ * Badge partials are now known as badge requirements and support both AND and OR groups of requirements.
717
+ * Removed the \`VidiotMap\` API as it was never used or fleshed out properly.
718
+ * Added support for story arcs to badge requirements including a link to the contact.
662
719
  * Standardized pluralization of some field names (name, icon).
663
720
  * Combined \`settitle\` ids into a single tuple field.
664
721
  * Change from GNU to The Unlicense.
@@ -679,36 +736,45 @@ function badgeLink(target) {
679
736
  const key = typeof target === "string" ? target : target.key;
680
737
  return `[${key}](${badgeUri(target)})`;
681
738
  }
682
- function mapUri(target) {
739
+ function contactUri(target) {
740
+ const key = typeof target === "string" ? target : target.key;
741
+ return `contact://${key}`;
742
+ }
743
+ function contactLink(target) {
744
+ const key = typeof target === "string" ? target : target.key;
745
+ return `[${key}](${contactUri(target)})`;
746
+ }
747
+ function zoneUri(target) {
683
748
  const key = typeof target === "string" ? target : target.key;
684
- return `map://${key}`;
749
+ return `zone://${key}`;
685
750
  }
686
- function mapLink(target) {
751
+ function zoneLink(target) {
687
752
  const key = typeof target === "string" ? target : target.key;
688
- return `[${key}](${mapUri(target)})`;
753
+ return `[${key}](${zoneUri(target)})`;
689
754
  }
690
755
 
691
756
  exports.ALIGNMENT = ALIGNMENT;
692
757
  exports.Alignments = Alignments;
693
758
  exports.Alternates = Alternates;
694
759
  exports.Archetype = Archetype;
695
- exports.BADGE_PARTIAL_TYPE = BADGE_PARTIAL_TYPE;
760
+ exports.BADGE_REQUIREMENT_TYPE = BADGE_REQUIREMENT_TYPE;
696
761
  exports.BADGE_TYPE = BADGE_TYPE;
697
762
  exports.Badge = Badge;
698
763
  exports.BadgeIndex = BadgeIndex;
699
- exports.BadgePartial = BadgePartial;
764
+ exports.BadgeRequirement = BadgeRequirement;
700
765
  exports.BundleMetadata = BundleMetadata;
701
766
  exports.CHANGELOG = CHANGELOG;
702
767
  exports.CohContentDatabase = CohContentDatabase;
768
+ exports.Contact = Contact;
703
769
  exports.ENHANCEMENT_CATEGORY = ENHANCEMENT_CATEGORY;
704
- exports.GameMap = GameMap;
705
770
  exports.Key = Key;
706
771
  exports.PLAQUE_TYPE = PLAQUE_TYPE;
707
772
  exports.SEX = SEX;
708
- exports.VidiotMap = VidiotMap;
709
- exports.VidiotMapPointOfInterest = VidiotMapPointOfInterest;
773
+ exports.Zone = Zone;
710
774
  exports.badgeLink = badgeLink;
711
775
  exports.badgeUri = badgeUri;
712
- exports.mapLink = mapLink;
713
- exports.mapUri = mapUri;
776
+ exports.contactLink = contactLink;
777
+ exports.contactUri = contactUri;
778
+ exports.zoneLink = zoneLink;
779
+ exports.zoneUri = zoneUri;
714
780
  //# sourceMappingURL=coh-content-db.js.map