coh-content-db 2.0.0-rc.2 → 2.0.0-rc.21
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/.editorconfig +10 -11
- package/.github/workflows/build.yml +4 -2
- package/.github/workflows/pull-request.yml +1 -1
- package/.github/workflows/release.yml +1 -1
- package/CHANGELOG.md +47 -0
- package/README.md +77 -32
- package/dist/coh-content-db.d.ts +755 -290
- package/dist/coh-content-db.js +1028 -358
- package/dist/coh-content-db.js.map +1 -1
- package/dist/coh-content-db.mjs +998 -349
- package/dist/coh-content-db.mjs.map +1 -1
- package/eslint.config.mjs +1 -0
- package/jest.config.mjs +1 -0
- package/package.json +14 -14
- package/src/main/api/alignment.ts +18 -2
- package/src/main/api/badge-data.ts +29 -51
- package/src/main/api/badge-requirement-data.ts +64 -0
- package/src/main/api/badge-requirement-type.ts +32 -0
- package/src/main/api/badge-type.ts +15 -15
- package/src/main/api/bundle-data.ts +47 -0
- package/src/main/api/bundle-header-data.ts +44 -0
- package/src/main/api/contact-data.ts +49 -0
- package/src/main/api/enhancement-category.ts +26 -26
- package/src/main/api/level-range-data.ts +4 -0
- package/src/main/api/location-data.ts +28 -0
- package/src/main/api/markdown-string.ts +4 -0
- package/src/main/api/mission-data.ts +57 -0
- package/src/main/api/mission-flashback-data.ts +31 -0
- package/src/main/api/mission-type.ts +2 -0
- package/src/main/api/morality.ts +49 -0
- package/src/main/api/set-title-data.ts +4 -0
- package/src/main/api/sex.ts +8 -1
- package/src/main/api/variant-context.ts +11 -0
- package/src/main/api/variant-data.ts +22 -0
- package/src/main/api/zone-data.ts +44 -0
- package/src/main/api/zone-type.ts +59 -0
- package/src/main/db/abstract-index.ts +37 -0
- package/src/main/db/alignment-list.ts +54 -0
- package/src/main/db/badge-index.ts +83 -0
- package/src/main/db/badge-requirement.ts +81 -0
- package/src/main/db/badge-search-options.ts +52 -0
- package/src/main/db/badge.ts +97 -74
- package/src/main/db/bundle-header.ts +52 -0
- package/src/main/db/coh-content-database.ts +123 -14
- package/src/main/db/contact.ts +63 -0
- package/src/main/db/level-range.ts +15 -0
- package/src/main/db/location.ts +30 -0
- package/src/main/db/mission.ts +108 -0
- package/src/main/db/morality-list.ts +99 -0
- package/src/main/db/paged.ts +11 -0
- package/src/main/db/set-title-ids.ts +10 -0
- package/src/main/db/variants.ts +84 -0
- package/src/main/db/zone.ts +57 -0
- package/src/main/index.ts +33 -18
- package/src/main/util/coalesce-to-array.ts +13 -0
- package/src/main/util/links.ts +104 -0
- package/src/main/util/to-date.ts +9 -0
- package/src/test/api/alignment.test.ts +38 -4
- package/src/test/api/badge-data.fixture.ts +2 -15
- package/src/test/api/badge-data.test.ts +5 -4
- package/src/test/api/badge-requirement-data.fixture.ts +7 -0
- package/src/test/api/badge-requirement-type.test.ts +31 -0
- package/src/test/api/badge-type.test.ts +5 -5
- package/src/test/api/bundle-data.fixture.ts +7 -0
- package/src/test/api/bundle-header-data.fixture.ts +8 -0
- package/src/test/api/contact-data.fixture.ts +7 -0
- package/src/test/api/enhancement-category.test.ts +5 -5
- package/src/test/api/mission-data.fixture.ts +12 -0
- package/src/test/api/morality.test.ts +31 -0
- package/src/test/api/sex.test.ts +33 -1
- package/src/test/api/zone-data.fixture.ts +9 -0
- package/src/test/db/abstract-index.test.ts +55 -0
- package/src/test/db/alignment-list.test.ts +200 -0
- package/src/test/db/badge-index.test.ts +653 -0
- package/src/test/db/badge-requirement.test.ts +145 -0
- package/src/test/db/badge.test.ts +416 -14
- package/src/test/db/bundle-header.test.ts +89 -0
- package/src/test/db/coh-content-database.test.ts +265 -24
- package/src/test/db/contact.test.ts +98 -0
- package/src/test/db/level-range.test.ts +47 -0
- package/src/test/db/location.test.ts +51 -0
- package/src/test/db/mission.test.ts +173 -0
- package/src/test/db/morality-list.test.ts +457 -0
- package/src/test/db/set-title-ids.test.ts +19 -0
- package/src/test/db/variants.test.ts +188 -0
- package/src/test/db/zone.test.ts +81 -0
- package/src/test/integration.test.ts +16 -0
- package/src/test/util/coalese-to-array.test.ts +17 -0
- package/src/test/util/links.test.ts +149 -0
- package/src/test/util/to-date.test.ts +15 -0
- package/src/main/api/alternate-data.ts +0 -22
- package/src/main/api/badge-partial-data.ts +0 -65
- package/src/main/api/badge-partial-type.ts +0 -8
- package/src/main/api/change.ts +0 -14
- package/src/main/api/game-map-data.ts +0 -26
- package/src/main/api/plaque-type.ts +0 -6
- package/src/main/api/server-group-data.ts +0 -65
- package/src/main/api/vidiot-map-data.ts +0 -18
- package/src/main/api/vidiot-map-point-of-interest-data.ts +0 -30
- package/src/main/changelog.ts +0 -20
- package/src/main/db/alternates.ts +0 -81
- package/src/main/db/badge-partial.ts +0 -35
- package/src/main/db/game-map.ts +0 -33
- package/src/main/db/server-group.ts +0 -112
- package/src/main/db/vidiot-map-point-of-interest.ts +0 -40
- package/src/main/db/vidiot-map.ts +0 -25
- package/src/main/util.ts +0 -17
- package/src/test/api/badge-partial-data.fixture.ts +0 -17
- package/src/test/api/badge-partial-type.test.ts +0 -31
- package/src/test/api/game-map-data.fixture.ts +0 -10
- package/src/test/api/plaque-type.test.ts +0 -31
- package/src/test/api/server-group-data.fixture.ts +0 -23
- package/src/test/api/server-group-data.test.ts +0 -15
- package/src/test/api/vidiot-map-point-of-interest.fixture.ts +0 -10
- package/src/test/api/vidiot-map.fixture.ts +0 -9
- package/src/test/changelog.test.ts +0 -36
- package/src/test/db/alternates.test.ts +0 -223
- package/src/test/db/server-group.test.ts +0 -124
- package/src/test/index.test.ts +0 -10
- package/src/test/util.test.ts +0 -39
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ArchetypeData } from './archetype-data'
|
|
2
|
+
import { ZoneData } from './zone-data'
|
|
3
|
+
import { BadgeData } from './badge-data'
|
|
4
|
+
import { ContactData } from './contact-data'
|
|
5
|
+
import { MissionData } from './mission-data'
|
|
6
|
+
import { BundleHeaderData } from './bundle-header-data'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A bundle of game data from a forked instance of the game, such as Homecoming (https://forums.homecomingservers.com/).
|
|
10
|
+
*/
|
|
11
|
+
export interface BundleData {
|
|
12
|
+
/**
|
|
13
|
+
* Bundle header.
|
|
14
|
+
*/
|
|
15
|
+
readonly header: BundleHeaderData
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* List of the game server names in this fork.
|
|
19
|
+
* Torchbearer, Excelsior, etc.
|
|
20
|
+
*/
|
|
21
|
+
readonly servers?: string[]
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* List of archetypes available in this fork.
|
|
25
|
+
*/
|
|
26
|
+
readonly archetypes?: ArchetypeData[]
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* List of zones supported by this fork.
|
|
30
|
+
*/
|
|
31
|
+
readonly zones?: ZoneData[]
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* List of contacts available in this fork.
|
|
35
|
+
*/
|
|
36
|
+
readonly contacts?: ContactData[]
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* List of missions available in this fork.
|
|
40
|
+
*/
|
|
41
|
+
readonly missions?: MissionData[]
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* List of badges available on this fork.
|
|
45
|
+
*/
|
|
46
|
+
readonly badges?: BadgeData[]
|
|
47
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Link } from './link'
|
|
2
|
+
import { MarkdownString } from './markdown-string'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Metadata about a content bundle.
|
|
6
|
+
*/
|
|
7
|
+
export interface BundleHeaderData {
|
|
8
|
+
/**
|
|
9
|
+
* Name of the fork this bundle contains data for.
|
|
10
|
+
*/
|
|
11
|
+
readonly name: string
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Version number for this data package.
|
|
15
|
+
*/
|
|
16
|
+
readonly version: string
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The time this bundle was last updated.
|
|
20
|
+
*
|
|
21
|
+
* Must be an ISO-8601 string in UTC.
|
|
22
|
+
*/
|
|
23
|
+
readonly lastUpdateTime: string
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Description of the fork.
|
|
27
|
+
*/
|
|
28
|
+
readonly description?: MarkdownString
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Url for the repository where the bundle is maintained.
|
|
32
|
+
*/
|
|
33
|
+
readonly repositoryUrl?: string
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Url for the location of the changelog.
|
|
37
|
+
*/
|
|
38
|
+
readonly changelogUrl?: string
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* List of external links. Wiki, forums, etc.
|
|
42
|
+
*/
|
|
43
|
+
readonly links?: Link[]
|
|
44
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Link } from './link'
|
|
2
|
+
import { MarkdownString } from './markdown-string'
|
|
3
|
+
import { LocationData } from './location-data'
|
|
4
|
+
import { MoralityExtended } from './morality'
|
|
5
|
+
import { LevelRangeData } from './level-range-data'
|
|
6
|
+
|
|
7
|
+
export interface ContactData {
|
|
8
|
+
/**
|
|
9
|
+
* Unique key used to reference this contact.
|
|
10
|
+
*
|
|
11
|
+
* Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
|
|
12
|
+
*/
|
|
13
|
+
readonly key: string
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The name of this contact.
|
|
17
|
+
*/
|
|
18
|
+
readonly name: string
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The contact's title.
|
|
22
|
+
*/
|
|
23
|
+
readonly title?: string
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The character moralities that this contact will interact with.
|
|
27
|
+
*/
|
|
28
|
+
readonly morality?: MoralityExtended | MoralityExtended[]
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The location of this contact.
|
|
32
|
+
*/
|
|
33
|
+
readonly location?: LocationData
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The level range this contact will offer missions for.
|
|
37
|
+
*/
|
|
38
|
+
readonly levelRange?: LevelRangeData
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Freeform notes or tips about the contact.
|
|
42
|
+
*/
|
|
43
|
+
readonly notes?: MarkdownString
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* List of external links. Wiki, forums, etc.
|
|
47
|
+
*/
|
|
48
|
+
readonly links?: Link[]
|
|
49
|
+
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
export const ENHANCEMENT_CATEGORY = [
|
|
2
|
-
'
|
|
3
|
-
'
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
2
|
+
'defense-debuff',
|
|
3
|
+
'to-hit-debuff',
|
|
4
|
+
'taunt',
|
|
5
|
+
'confuse',
|
|
6
|
+
'healing',
|
|
7
|
+
'defense-buff',
|
|
8
|
+
'resist-damage',
|
|
9
|
+
'intangibility',
|
|
10
|
+
'sleep',
|
|
11
|
+
'slow',
|
|
12
|
+
'hold',
|
|
13
|
+
'stun',
|
|
14
|
+
'immobilize',
|
|
15
|
+
'fear',
|
|
16
|
+
'endurance-modification',
|
|
17
|
+
'endurance-reduction',
|
|
18
|
+
'recharge-reduction',
|
|
19
|
+
'interrupt-duration',
|
|
20
|
+
'accuracy',
|
|
21
|
+
'to-hit-buff',
|
|
22
|
+
'damage',
|
|
23
|
+
'knockback',
|
|
24
|
+
'run-speed',
|
|
25
|
+
'jump',
|
|
26
|
+
'fly-speed',
|
|
27
|
+
'range',
|
|
28
28
|
] as const
|
|
29
29
|
|
|
30
30
|
export type EnhancementCategory = typeof ENHANCEMENT_CATEGORY[number]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface LocationData {
|
|
2
|
+
/**
|
|
3
|
+
* Key of the {@link Zone} that the location references.
|
|
4
|
+
*/
|
|
5
|
+
readonly zoneKey?: string
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* In-game `/loc` coordinates of the location.
|
|
9
|
+
*/
|
|
10
|
+
readonly coords?: Coords
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The type of icon to use if the location appears on a map. (Typically the Vidiot map icon).
|
|
14
|
+
*/
|
|
15
|
+
readonly icon?: LocationIcon
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The text that should appear in the location icon. (Typically a number or symbol from the Vidiot map).
|
|
19
|
+
*/
|
|
20
|
+
readonly iconText?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Coordinates as they appear using the in-game `/loc` command.
|
|
25
|
+
*/
|
|
26
|
+
export type Coords = [number, number, number]
|
|
27
|
+
|
|
28
|
+
export type LocationIcon = 'badge' | 'plaque' | 'pedestal' | 'object'
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Link } from './link'
|
|
2
|
+
import { MarkdownString } from './markdown-string'
|
|
3
|
+
import { MissionType } from './mission-type'
|
|
4
|
+
import { MoralityExtended } from './morality'
|
|
5
|
+
import { LevelRangeData } from './level-range-data'
|
|
6
|
+
import { MissionFlashbackData } from './mission-flashback-data'
|
|
7
|
+
|
|
8
|
+
export interface MissionData {
|
|
9
|
+
/**
|
|
10
|
+
* Unique key used to reference this mission.
|
|
11
|
+
*
|
|
12
|
+
* Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
|
|
13
|
+
*/
|
|
14
|
+
readonly key: string
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The name of the mission as it appears from the contact.
|
|
18
|
+
*
|
|
19
|
+
* The name may be different when viewed in Ouroboros as a Flashback.
|
|
20
|
+
*/
|
|
21
|
+
readonly name: string
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The type of mission... Story arc, task force, trial, etc.
|
|
25
|
+
*/
|
|
26
|
+
readonly type: MissionType
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The character moralities that may accept the mission.
|
|
30
|
+
*/
|
|
31
|
+
readonly morality?: MoralityExtended | MoralityExtended[]
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The keys of any contacts that provide this mission.
|
|
35
|
+
*/
|
|
36
|
+
readonly contactKeys?: string | string[]
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The level range this mission is available for.
|
|
40
|
+
*/
|
|
41
|
+
readonly levelRange?: LevelRangeData
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Freeform notes or tips about the mission.
|
|
45
|
+
*/
|
|
46
|
+
readonly notes?: MarkdownString
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* List of external links. Wiki, forums, etc.
|
|
50
|
+
*/
|
|
51
|
+
readonly links?: Link[]
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* If the mission is available in Ouroboros as a Flashback.
|
|
55
|
+
*/
|
|
56
|
+
readonly flashback?: MissionFlashbackData
|
|
57
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { MarkdownString } from './markdown-string'
|
|
2
|
+
import { MoralityExtended } from './morality'
|
|
3
|
+
import { LevelRangeData } from './level-range-data'
|
|
4
|
+
|
|
5
|
+
export interface MissionFlashbackData {
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The id of the mission as seen in the Flashback menu, i.e. '14.01'.
|
|
9
|
+
*/
|
|
10
|
+
readonly id: string
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The level range this mission appears under as a Flashback.
|
|
14
|
+
*/
|
|
15
|
+
readonly levelRange?: LevelRangeData
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The name as it appears in the Flashback list. Leave undefined if the same as the base mission.
|
|
19
|
+
*/
|
|
20
|
+
readonly name?: string
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The character moralities that the mission will appear for in the Flashback list. Leave undefined if the same as the base mission.
|
|
24
|
+
*/
|
|
25
|
+
readonly morality?: MoralityExtended | MoralityExtended[]
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Freeform notes or tips about the Flashback version of the mission.
|
|
29
|
+
*/
|
|
30
|
+
readonly notes?: MarkdownString
|
|
31
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Alignment } from './alignment'
|
|
2
|
+
|
|
3
|
+
export const MORALITY = ['hero', 'vigilante', 'villain', 'rogue', 'resistance', 'loyalist'] as const
|
|
4
|
+
export const MORALITY_EXTENDED = [
|
|
5
|
+
...MORALITY,
|
|
6
|
+
/**
|
|
7
|
+
* Any of the Primal Earth moralities - Hero, Vigilante, Villain, Rogue.
|
|
8
|
+
*/
|
|
9
|
+
'primal',
|
|
10
|
+
/**
|
|
11
|
+
* Either of the Praetorian Earth moralities - Resistance or Loyalist.
|
|
12
|
+
*/
|
|
13
|
+
'praetorian',
|
|
14
|
+
/**
|
|
15
|
+
* The moralities that roll up to the Hero {@link Alignment} - Hero and Vigilante.
|
|
16
|
+
*/
|
|
17
|
+
'heroic',
|
|
18
|
+
/**
|
|
19
|
+
* The moralities that roll up to the Villain {@link Alignment} - Villain and Rogue.
|
|
20
|
+
*/
|
|
21
|
+
'villainous',
|
|
22
|
+
/**
|
|
23
|
+
* Moralities with access to Paragon City - Hero, Vigilante and Rogue.
|
|
24
|
+
*/
|
|
25
|
+
'paragon-city-access',
|
|
26
|
+
/**
|
|
27
|
+
* Moralities with access to the Rogue Isles - Villain, Rogue and Vigilante.
|
|
28
|
+
*/
|
|
29
|
+
'rogue-isles-access',
|
|
30
|
+
/**
|
|
31
|
+
* All the moralities.
|
|
32
|
+
*/
|
|
33
|
+
'all',
|
|
34
|
+
] as const
|
|
35
|
+
export type Morality = typeof MORALITY[number]
|
|
36
|
+
export type MoralityExtended = typeof MORALITY_EXTENDED[number]
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Maps a morality to the underlying alignment
|
|
40
|
+
*/
|
|
41
|
+
export const MoralityMap: Record<Morality | Alignment, Alignment> = {
|
|
42
|
+
hero: 'hero',
|
|
43
|
+
vigilante: 'hero',
|
|
44
|
+
villain: 'villain',
|
|
45
|
+
rogue: 'villain',
|
|
46
|
+
loyalist: 'praetorian',
|
|
47
|
+
resistance: 'praetorian',
|
|
48
|
+
praetorian: 'praetorian',
|
|
49
|
+
}
|
package/src/main/api/sex.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
export const SEX = ['M', 'F'] as const
|
|
2
|
-
|
|
3
2
|
export type Sex = typeof SEX[number]
|
|
3
|
+
|
|
4
|
+
const SEX_ORDER = Object.fromEntries(SEX.map((x, index) => [x, index]))
|
|
5
|
+
|
|
6
|
+
export function compareSex(a?: Sex, b?: Sex): number {
|
|
7
|
+
const orderA = a ? SEX_ORDER[a] : -1
|
|
8
|
+
const orderB = b ? SEX_ORDER[b] : -1
|
|
9
|
+
return orderA - orderB
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Sex } from './sex'
|
|
2
|
+
import { Morality } from './morality'
|
|
3
|
+
import { Alignment } from './alignment'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* For badges, aspects like the name, icon, or badge text can vary depending on context, such as the alignment or sex of the character.
|
|
7
|
+
*/
|
|
8
|
+
export interface VariantContext {
|
|
9
|
+
readonly morality?: Morality | Alignment
|
|
10
|
+
readonly sex?: Sex
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Sex } from './sex'
|
|
2
|
+
import { Alignment } from './alignment'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Some badge values differ based on the alignment or sex of a character.
|
|
6
|
+
*/
|
|
7
|
+
export interface VariantData<V> {
|
|
8
|
+
/**
|
|
9
|
+
* The character alignment this variant applies to.
|
|
10
|
+
*/
|
|
11
|
+
readonly alignment?: Alignment
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The character sex this variant applies to.
|
|
15
|
+
*/
|
|
16
|
+
readonly sex?: Sex
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The value for this combination.
|
|
20
|
+
*/
|
|
21
|
+
readonly value: V
|
|
22
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Link } from './link'
|
|
2
|
+
import { MoralityExtended } from './morality'
|
|
3
|
+
import { ZoneType } from './zone-type'
|
|
4
|
+
import { MarkdownString } from './markdown-string'
|
|
5
|
+
import { LevelRangeData } from './level-range-data'
|
|
6
|
+
|
|
7
|
+
export interface ZoneData {
|
|
8
|
+
/**
|
|
9
|
+
* Unique key used to reference this zone.
|
|
10
|
+
*
|
|
11
|
+
* Keys must be unique and can only contain lowercase letters, numbers and hyphens (`-`).
|
|
12
|
+
*/
|
|
13
|
+
readonly key: string
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The name of the zone as it appears in-game.
|
|
17
|
+
*/
|
|
18
|
+
readonly name: string
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The type of zone.
|
|
22
|
+
*/
|
|
23
|
+
readonly type: ZoneType
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The character moralities that this zone is accessible by.
|
|
27
|
+
*/
|
|
28
|
+
readonly morality?: MoralityExtended | MoralityExtended[]
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The level range this zone is recommended for.
|
|
32
|
+
*/
|
|
33
|
+
readonly levelRange?: LevelRangeData
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Freeform notes or tips about the zone.
|
|
37
|
+
*/
|
|
38
|
+
readonly notes?: MarkdownString
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* List of external links. Wiki, forums, etc.
|
|
42
|
+
*/
|
|
43
|
+
readonly links?: Link[]
|
|
44
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export const ZONE_TYPE = [
|
|
2
|
+
/**
|
|
3
|
+
* The standard zone type, even if not technically occurring in the 'City' proper.
|
|
4
|
+
*/
|
|
5
|
+
'city',
|
|
6
|
+
/**
|
|
7
|
+
* An Ouroboros flashback to a zone as it was in a previous era.
|
|
8
|
+
*/
|
|
9
|
+
'echo',
|
|
10
|
+
/**
|
|
11
|
+
* Tutorial zon, usually inaccessible after leaving.
|
|
12
|
+
*/
|
|
13
|
+
'tutorial',
|
|
14
|
+
/**
|
|
15
|
+
* Trial zones, like the Abandoned Sewers trial.
|
|
16
|
+
*/
|
|
17
|
+
'trial',
|
|
18
|
+
/**
|
|
19
|
+
* Hazard zones like the Hollows.
|
|
20
|
+
*/
|
|
21
|
+
'hazard',
|
|
22
|
+
/**
|
|
23
|
+
* Mayhem mission zones.
|
|
24
|
+
*/
|
|
25
|
+
'mayhem',
|
|
26
|
+
/**
|
|
27
|
+
* Safeguard mission zones.
|
|
28
|
+
*/
|
|
29
|
+
'safeguard',
|
|
30
|
+
/**
|
|
31
|
+
* Exists inside a mission not covered by the other types.
|
|
32
|
+
*/
|
|
33
|
+
'mission',
|
|
34
|
+
/**
|
|
35
|
+
* Incarnate trial zones.
|
|
36
|
+
*/
|
|
37
|
+
'incarnate',
|
|
38
|
+
/**
|
|
39
|
+
* Cooprative zones where Heroes and Villains can team up for PvE content.
|
|
40
|
+
*/
|
|
41
|
+
'co-op',
|
|
42
|
+
/**
|
|
43
|
+
* PvP zones like Bloody Bay.
|
|
44
|
+
*/
|
|
45
|
+
'pvp',
|
|
46
|
+
/**
|
|
47
|
+
* Located in an arena PvP map.
|
|
48
|
+
*/
|
|
49
|
+
'arena',
|
|
50
|
+
/**
|
|
51
|
+
* A building, usually contained within another zone, like the AE buildings.
|
|
52
|
+
*/
|
|
53
|
+
'building',
|
|
54
|
+
/**
|
|
55
|
+
* Stuff like the (Phone only) zone.
|
|
56
|
+
*/
|
|
57
|
+
'other',
|
|
58
|
+
] as const
|
|
59
|
+
export type ZoneType = typeof ZONE_TYPE[number]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
type KeysOfType<T, V> = { [P in keyof T]: T[P] extends V ? P : never }[keyof T]
|
|
2
|
+
|
|
3
|
+
export class AbstractIndex<T> {
|
|
4
|
+
protected _values: T[] = []
|
|
5
|
+
protected _hashTable: Record<string, T> = {}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create a new index.
|
|
9
|
+
* @param keyField The field of the values that will act as the key.
|
|
10
|
+
* @param values Values to index.
|
|
11
|
+
*/
|
|
12
|
+
constructor(keyField: KeysOfType<T, string>, values: T[] | undefined) {
|
|
13
|
+
this._values = values ?? []
|
|
14
|
+
this._hashTable = {}
|
|
15
|
+
for (const value of this.values) {
|
|
16
|
+
const key = value[keyField] as string
|
|
17
|
+
if (this._hashTable[key] !== undefined) throw new Error(`Duplicate key [${key}]`)
|
|
18
|
+
this._hashTable[key] = value
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Return all indexed values
|
|
24
|
+
*/
|
|
25
|
+
get values(): T[] {
|
|
26
|
+
return this._values
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get a value from the index
|
|
31
|
+
* @param key Key string
|
|
32
|
+
*/
|
|
33
|
+
get(key: string | undefined): T | undefined {
|
|
34
|
+
if (!key) return undefined
|
|
35
|
+
return this._hashTable[key]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ALIGNMENT, Alignment, AlignmentExtended } from '../api/alignment'
|
|
2
|
+
|
|
3
|
+
export class AlignmentList {
|
|
4
|
+
readonly #items: Set<Alignment>
|
|
5
|
+
|
|
6
|
+
readonly hero: boolean
|
|
7
|
+
readonly villain: boolean
|
|
8
|
+
readonly praetorian: boolean
|
|
9
|
+
|
|
10
|
+
readonly primal: boolean
|
|
11
|
+
readonly all: boolean
|
|
12
|
+
|
|
13
|
+
constructor(items?: AlignmentExtended[]) {
|
|
14
|
+
const set = new Set(items ?? [...ALIGNMENT])
|
|
15
|
+
this.hero = set.has('hero') || set.has('primal') || set.has('all')
|
|
16
|
+
this.villain = set.has('villain') || set.has('primal') || set.has('all')
|
|
17
|
+
this.praetorian = set.has('praetorian') || set.has('all')
|
|
18
|
+
|
|
19
|
+
this.primal = this.hero && this.villain
|
|
20
|
+
this.all = this.hero && this.villain && this.praetorian
|
|
21
|
+
|
|
22
|
+
this.#items = new Set()
|
|
23
|
+
if (this.hero) this.#items.add('hero')
|
|
24
|
+
if (this.villain) this.#items.add('villain')
|
|
25
|
+
if (this.praetorian) this.#items.add('praetorian')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get items(): Alignment[] {
|
|
29
|
+
return [...this.#items]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
has(alignment?: AlignmentExtended): boolean {
|
|
33
|
+
switch (alignment) {
|
|
34
|
+
case 'hero': {
|
|
35
|
+
return this.hero
|
|
36
|
+
}
|
|
37
|
+
case 'villain': {
|
|
38
|
+
return this.villain
|
|
39
|
+
}
|
|
40
|
+
case 'praetorian': {
|
|
41
|
+
return this.praetorian
|
|
42
|
+
}
|
|
43
|
+
case 'primal' : {
|
|
44
|
+
return this.primal
|
|
45
|
+
}
|
|
46
|
+
case 'all': {
|
|
47
|
+
return this.all
|
|
48
|
+
}
|
|
49
|
+
default: {
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|