@lycoristech/azurdata 0.0.1
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/LICENSE +25 -0
- package/README.md +123 -0
- package/data/.gitkeep +0 -0
- package/data/id-map.json +3530 -0
- package/data/ship-list.json +4478 -0
- package/data/ships.json +143282 -0
- package/data/version.json +5 -0
- package/dist/cjs/client/AzurData.js +69 -0
- package/dist/cjs/client/fetcher.js +121 -0
- package/dist/cjs/client/index.js +7 -0
- package/dist/cjs/client/ships.js +80 -0
- package/dist/cjs/config.js +14 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/ingest/files.js +134 -0
- package/dist/cjs/ingest/index.js +18 -0
- package/dist/cjs/ingest/upstream.js +12 -0
- package/dist/cjs/normalize/construction.js +186 -0
- package/dist/cjs/normalize/identity.js +131 -0
- package/dist/cjs/normalize/index.js +25 -0
- package/dist/cjs/normalize/misc.js +31 -0
- package/dist/cjs/normalize/retrofit.js +21 -0
- package/dist/cjs/normalize/ship.js +406 -0
- package/dist/cjs/normalize/skills.js +194 -0
- package/dist/cjs/normalize/skins.js +141 -0
- package/dist/cjs/normalize/slots.js +35 -0
- package/dist/cjs/normalize/stats.js +182 -0
- package/dist/cjs/output/index.js +20 -0
- package/dist/cjs/output/writeIdMap.js +52 -0
- package/dist/cjs/output/writeShipList.js +31 -0
- package/dist/cjs/output/writeShips.js +33 -0
- package/dist/cjs/output/writeVersion.js +23 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/schema/output/index.js +17 -0
- package/dist/cjs/schema/output/ship.js +169 -0
- package/dist/cjs/schema/raw/attributeInfoByType.js +11 -0
- package/dist/cjs/schema/raw/equipDataByType.js +12 -0
- package/dist/cjs/schema/raw/fleetTechGroup.js +10 -0
- package/dist/cjs/schema/raw/fleetTechShipClass.js +15 -0
- package/dist/cjs/schema/raw/fleetTechShipTemplate.js +20 -0
- package/dist/cjs/schema/raw/index.js +38 -0
- package/dist/cjs/schema/raw/shipDataBlueprint.js +11 -0
- package/dist/cjs/schema/raw/shipDataBreakout.js +17 -0
- package/dist/cjs/schema/raw/shipDataByStar.js +10 -0
- package/dist/cjs/schema/raw/shipDataByType.js +13 -0
- package/dist/cjs/schema/raw/shipDataCreateExchange.js +10 -0
- package/dist/cjs/schema/raw/shipDataGroup.js +22 -0
- package/dist/cjs/schema/raw/shipDataStatistics.js +24 -0
- package/dist/cjs/schema/raw/shipDataStrengthen.js +12 -0
- package/dist/cjs/schema/raw/shipDataTemplate.js +26 -0
- package/dist/cjs/schema/raw/shipDataTrans.js +13 -0
- package/dist/cjs/schema/raw/shipSkinTemplate.js +23 -0
- package/dist/cjs/schema/raw/shipSkinWords.js +11 -0
- package/dist/cjs/schema/raw/shopTemplate.js +14 -0
- package/dist/cjs/schema/raw/skillDataDisplay.js +11 -0
- package/dist/cjs/schema/raw/skillDataTemplate.js +17 -0
- package/dist/cjs/schema/raw/transformDataTemplate.js +18 -0
- package/dist/cjs/schema/raw/voiceActorCn.js +11 -0
- package/dist/cjs/translate/enums.js +131 -0
- package/dist/cjs/translate/index.js +19 -0
- package/dist/cjs/translate/lookups.js +63 -0
- package/dist/cjs/translate/strings.js +98 -0
- package/dist/client/AzurData.d.ts +25 -0
- package/dist/client/AzurData.d.ts.map +1 -0
- package/dist/client/AzurData.js +63 -0
- package/dist/client/AzurData.js.map +1 -0
- package/dist/client/fetcher.d.ts +25 -0
- package/dist/client/fetcher.d.ts.map +1 -0
- package/dist/client/fetcher.js +116 -0
- package/dist/client/fetcher.js.map +1 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/ships.d.ts +20 -0
- package/dist/client/ships.d.ts.map +1 -0
- package/dist/client/ships.js +74 -0
- package/dist/client/ships.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/files.d.ts +25 -0
- package/dist/ingest/files.d.ts.map +1 -0
- package/dist/ingest/files.js +108 -0
- package/dist/ingest/files.js.map +1 -0
- package/dist/ingest/index.d.ts +3 -0
- package/dist/ingest/index.d.ts.map +1 -0
- package/dist/ingest/index.js +3 -0
- package/dist/ingest/index.js.map +1 -0
- package/dist/ingest/upstream.d.ts +4 -0
- package/dist/ingest/upstream.d.ts.map +1 -0
- package/dist/ingest/upstream.js +6 -0
- package/dist/ingest/upstream.js.map +1 -0
- package/dist/normalize/construction.d.ts +30 -0
- package/dist/normalize/construction.d.ts.map +1 -0
- package/dist/normalize/construction.js +184 -0
- package/dist/normalize/construction.js.map +1 -0
- package/dist/normalize/identity.d.ts +47 -0
- package/dist/normalize/identity.d.ts.map +1 -0
- package/dist/normalize/identity.js +129 -0
- package/dist/normalize/identity.js.map +1 -0
- package/dist/normalize/index.d.ts +10 -0
- package/dist/normalize/index.d.ts.map +1 -0
- package/dist/normalize/index.js +10 -0
- package/dist/normalize/index.js.map +1 -0
- package/dist/normalize/misc.d.ts +15 -0
- package/dist/normalize/misc.d.ts.map +1 -0
- package/dist/normalize/misc.js +29 -0
- package/dist/normalize/misc.js.map +1 -0
- package/dist/normalize/retrofit.d.ts +14 -0
- package/dist/normalize/retrofit.d.ts.map +1 -0
- package/dist/normalize/retrofit.js +19 -0
- package/dist/normalize/retrofit.js.map +1 -0
- package/dist/normalize/ship.d.ts +67 -0
- package/dist/normalize/ship.d.ts.map +1 -0
- package/dist/normalize/ship.js +369 -0
- package/dist/normalize/ship.js.map +1 -0
- package/dist/normalize/skills.d.ts +20 -0
- package/dist/normalize/skills.d.ts.map +1 -0
- package/dist/normalize/skills.js +192 -0
- package/dist/normalize/skills.js.map +1 -0
- package/dist/normalize/skins.d.ts +14 -0
- package/dist/normalize/skins.d.ts.map +1 -0
- package/dist/normalize/skins.js +139 -0
- package/dist/normalize/skins.js.map +1 -0
- package/dist/normalize/slots.d.ts +14 -0
- package/dist/normalize/slots.d.ts.map +1 -0
- package/dist/normalize/slots.js +33 -0
- package/dist/normalize/slots.js.map +1 -0
- package/dist/normalize/stats.d.ts +19 -0
- package/dist/normalize/stats.d.ts.map +1 -0
- package/dist/normalize/stats.js +180 -0
- package/dist/normalize/stats.js.map +1 -0
- package/dist/output/index.d.ts +5 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +5 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/writeIdMap.d.ts +16 -0
- package/dist/output/writeIdMap.d.ts.map +1 -0
- package/dist/output/writeIdMap.js +47 -0
- package/dist/output/writeIdMap.js.map +1 -0
- package/dist/output/writeShipList.d.ts +9 -0
- package/dist/output/writeShipList.d.ts.map +1 -0
- package/dist/output/writeShipList.js +26 -0
- package/dist/output/writeShipList.js.map +1 -0
- package/dist/output/writeShips.d.ts +15 -0
- package/dist/output/writeShips.d.ts.map +1 -0
- package/dist/output/writeShips.js +28 -0
- package/dist/output/writeShips.js.map +1 -0
- package/dist/output/writeVersion.d.ts +11 -0
- package/dist/output/writeVersion.d.ts.map +1 -0
- package/dist/output/writeVersion.js +18 -0
- package/dist/output/writeVersion.js.map +1 -0
- package/dist/schema/output/index.d.ts +2 -0
- package/dist/schema/output/index.d.ts.map +1 -0
- package/dist/schema/output/index.js +2 -0
- package/dist/schema/output/index.js.map +1 -0
- package/dist/schema/output/ship.d.ts +977 -0
- package/dist/schema/output/ship.d.ts.map +1 -0
- package/dist/schema/output/ship.js +167 -0
- package/dist/schema/output/ship.js.map +1 -0
- package/dist/schema/raw/attributeInfoByType.d.ts +25 -0
- package/dist/schema/raw/attributeInfoByType.d.ts.map +1 -0
- package/dist/schema/raw/attributeInfoByType.js +9 -0
- package/dist/schema/raw/attributeInfoByType.js.map +1 -0
- package/dist/schema/raw/equipDataByType.d.ts +31 -0
- package/dist/schema/raw/equipDataByType.d.ts.map +1 -0
- package/dist/schema/raw/equipDataByType.js +10 -0
- package/dist/schema/raw/equipDataByType.js.map +1 -0
- package/dist/schema/raw/fleetTechGroup.d.ts +19 -0
- package/dist/schema/raw/fleetTechGroup.d.ts.map +1 -0
- package/dist/schema/raw/fleetTechGroup.js +8 -0
- package/dist/schema/raw/fleetTechGroup.js.map +1 -0
- package/dist/schema/raw/fleetTechShipClass.d.ts +49 -0
- package/dist/schema/raw/fleetTechShipClass.d.ts.map +1 -0
- package/dist/schema/raw/fleetTechShipClass.js +13 -0
- package/dist/schema/raw/fleetTechShipClass.js.map +1 -0
- package/dist/schema/raw/fleetTechShipTemplate.d.ts +79 -0
- package/dist/schema/raw/fleetTechShipTemplate.d.ts.map +1 -0
- package/dist/schema/raw/fleetTechShipTemplate.js +18 -0
- package/dist/schema/raw/fleetTechShipTemplate.js.map +1 -0
- package/dist/schema/raw/index.d.ts +23 -0
- package/dist/schema/raw/index.d.ts.map +1 -0
- package/dist/schema/raw/index.js +23 -0
- package/dist/schema/raw/index.js.map +1 -0
- package/dist/schema/raw/shipDataBlueprint.d.ts +25 -0
- package/dist/schema/raw/shipDataBlueprint.d.ts.map +1 -0
- package/dist/schema/raw/shipDataBlueprint.js +9 -0
- package/dist/schema/raw/shipDataBlueprint.js.map +1 -0
- package/dist/schema/raw/shipDataBreakout.d.ts +61 -0
- package/dist/schema/raw/shipDataBreakout.d.ts.map +1 -0
- package/dist/schema/raw/shipDataBreakout.js +15 -0
- package/dist/schema/raw/shipDataBreakout.js.map +1 -0
- package/dist/schema/raw/shipDataByStar.d.ts +19 -0
- package/dist/schema/raw/shipDataByStar.d.ts.map +1 -0
- package/dist/schema/raw/shipDataByStar.js +8 -0
- package/dist/schema/raw/shipDataByStar.js.map +1 -0
- package/dist/schema/raw/shipDataByType.d.ts +37 -0
- package/dist/schema/raw/shipDataByType.d.ts.map +1 -0
- package/dist/schema/raw/shipDataByType.js +11 -0
- package/dist/schema/raw/shipDataByType.js.map +1 -0
- package/dist/schema/raw/shipDataCreateExchange.d.ts +19 -0
- package/dist/schema/raw/shipDataCreateExchange.d.ts.map +1 -0
- package/dist/schema/raw/shipDataCreateExchange.js +8 -0
- package/dist/schema/raw/shipDataCreateExchange.js.map +1 -0
- package/dist/schema/raw/shipDataGroup.d.ts +79 -0
- package/dist/schema/raw/shipDataGroup.d.ts.map +1 -0
- package/dist/schema/raw/shipDataGroup.js +20 -0
- package/dist/schema/raw/shipDataGroup.js.map +1 -0
- package/dist/schema/raw/shipDataStatistics.d.ts +103 -0
- package/dist/schema/raw/shipDataStatistics.d.ts.map +1 -0
- package/dist/schema/raw/shipDataStatistics.js +22 -0
- package/dist/schema/raw/shipDataStatistics.js.map +1 -0
- package/dist/schema/raw/shipDataStrengthen.d.ts +31 -0
- package/dist/schema/raw/shipDataStrengthen.d.ts.map +1 -0
- package/dist/schema/raw/shipDataStrengthen.js +10 -0
- package/dist/schema/raw/shipDataStrengthen.js.map +1 -0
- package/dist/schema/raw/shipDataTemplate.d.ts +115 -0
- package/dist/schema/raw/shipDataTemplate.d.ts.map +1 -0
- package/dist/schema/raw/shipDataTemplate.js +24 -0
- package/dist/schema/raw/shipDataTemplate.js.map +1 -0
- package/dist/schema/raw/shipDataTrans.d.ts +37 -0
- package/dist/schema/raw/shipDataTrans.d.ts.map +1 -0
- package/dist/schema/raw/shipDataTrans.js +11 -0
- package/dist/schema/raw/shipDataTrans.js.map +1 -0
- package/dist/schema/raw/shipSkinTemplate.d.ts +97 -0
- package/dist/schema/raw/shipSkinTemplate.d.ts.map +1 -0
- package/dist/schema/raw/shipSkinTemplate.js +21 -0
- package/dist/schema/raw/shipSkinTemplate.js.map +1 -0
- package/dist/schema/raw/shipSkinWords.d.ts +25 -0
- package/dist/schema/raw/shipSkinWords.d.ts.map +1 -0
- package/dist/schema/raw/shipSkinWords.js +9 -0
- package/dist/schema/raw/shipSkinWords.js.map +1 -0
- package/dist/schema/raw/shopTemplate.d.ts +43 -0
- package/dist/schema/raw/shopTemplate.d.ts.map +1 -0
- package/dist/schema/raw/shopTemplate.js +12 -0
- package/dist/schema/raw/shopTemplate.js.map +1 -0
- package/dist/schema/raw/skillDataDisplay.d.ts +25 -0
- package/dist/schema/raw/skillDataDisplay.d.ts.map +1 -0
- package/dist/schema/raw/skillDataDisplay.js +9 -0
- package/dist/schema/raw/skillDataDisplay.js.map +1 -0
- package/dist/schema/raw/skillDataTemplate.d.ts +61 -0
- package/dist/schema/raw/skillDataTemplate.d.ts.map +1 -0
- package/dist/schema/raw/skillDataTemplate.js +15 -0
- package/dist/schema/raw/skillDataTemplate.js.map +1 -0
- package/dist/schema/raw/transformDataTemplate.d.ts +67 -0
- package/dist/schema/raw/transformDataTemplate.d.ts.map +1 -0
- package/dist/schema/raw/transformDataTemplate.js +16 -0
- package/dist/schema/raw/transformDataTemplate.js.map +1 -0
- package/dist/schema/raw/voiceActorCn.d.ts +25 -0
- package/dist/schema/raw/voiceActorCn.d.ts.map +1 -0
- package/dist/schema/raw/voiceActorCn.js +9 -0
- package/dist/schema/raw/voiceActorCn.js.map +1 -0
- package/dist/translate/enums.d.ts +34 -0
- package/dist/translate/enums.d.ts.map +1 -0
- package/dist/translate/enums.js +126 -0
- package/dist/translate/enums.js.map +1 -0
- package/dist/translate/index.d.ts +4 -0
- package/dist/translate/index.d.ts.map +1 -0
- package/dist/translate/index.js +4 -0
- package/dist/translate/index.js.map +1 -0
- package/dist/translate/lookups.d.ts +37 -0
- package/dist/translate/lookups.d.ts.map +1 -0
- package/dist/translate/lookups.js +61 -0
- package/dist/translate/lookups.js.map +1 -0
- package/dist/translate/strings.d.ts +40 -0
- package/dist/translate/strings.d.ts.map +1 -0
- package/dist/translate/strings.js +92 -0
- package/dist/translate/strings.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeSkills = normalizeSkills;
|
|
4
|
+
const enums_js_1 = require("../translate/enums.js");
|
|
5
|
+
const strings_js_1 = require("../translate/strings.js");
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Internal helpers
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
/**
|
|
10
|
+
* Strip trailing Roman numeral suffix (Ⅰ–Ⅴ or ASCII I/II/III/IV/V) from a skill
|
|
11
|
+
* name, returning just the "root" portion for comparison purposes.
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* "All Out Assault Ⅰ" → "All Out Assault"
|
|
15
|
+
* "All Out Assault Ⅱ" → "All Out Assault"
|
|
16
|
+
* "Smokescreen: Light Cruisers" → "Smokescreen: Light Cruisers"
|
|
17
|
+
* "Burn Order" → "Burn Order"
|
|
18
|
+
*/
|
|
19
|
+
function rootSkillName(name) {
|
|
20
|
+
// Trim Unicode Roman numerals (Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ) and ASCII (I–X variants)
|
|
21
|
+
// at end of string, optionally preceded by a colon/period and more text.
|
|
22
|
+
return name
|
|
23
|
+
.replace(/\s+[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩiIvVxX]+(?:[:.][^\s]*)*\s*$/, "")
|
|
24
|
+
.trim();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a `skill_id` value (number | number[] | undefined) to a number[].
|
|
28
|
+
*/
|
|
29
|
+
function normalizeSkillIdList(raw) {
|
|
30
|
+
if (raw === undefined)
|
|
31
|
+
return [];
|
|
32
|
+
if (Array.isArray(raw))
|
|
33
|
+
return raw;
|
|
34
|
+
return [raw];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the description string for a skill.
|
|
38
|
+
*/
|
|
39
|
+
function buildDescription(skillTemplate, idStr) {
|
|
40
|
+
const row = skillTemplate[idStr];
|
|
41
|
+
if (row === undefined)
|
|
42
|
+
return "";
|
|
43
|
+
const rawDesc = row.desc;
|
|
44
|
+
if (rawDesc === undefined || rawDesc === "")
|
|
45
|
+
return "";
|
|
46
|
+
const substitutions = (0, strings_js_1.extractMaxLevelSubstitutions)(row.desc_add, row.max_level ?? 10);
|
|
47
|
+
return (0, strings_js_1.substitutePlaceholders)(rawDesc, substitutions);
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Main
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
function normalizeSkills(inputs) {
|
|
53
|
+
const { rowIds, en, groupType } = inputs;
|
|
54
|
+
const { template, breakout, skillDataTemplate, skillDataDisplay, trans, transformDataTemplate, } = en;
|
|
55
|
+
// -------------------------------------------------------------------------
|
|
56
|
+
// 1. Resolve the LB3 row ID (the row whose key ends with "4", or last entry).
|
|
57
|
+
// -------------------------------------------------------------------------
|
|
58
|
+
const lb3RowId = rowIds.find((id) => id.endsWith("4")) ?? rowIds[rowIds.length - 1] ?? groupType;
|
|
59
|
+
// -------------------------------------------------------------------------
|
|
60
|
+
// 2. Get the base skill ID list from the LB3 row.
|
|
61
|
+
// -------------------------------------------------------------------------
|
|
62
|
+
const lb3Template = template[lb3RowId];
|
|
63
|
+
const baseSkillIds = lb3Template?.buff_list_display ?? [];
|
|
64
|
+
// -------------------------------------------------------------------------
|
|
65
|
+
// 3. Apply retrofit skill upgrades (if any).
|
|
66
|
+
//
|
|
67
|
+
// TODO: The retrofit skill-upgrade/replace logic is a best-effort
|
|
68
|
+
// approximation. AzurAPI's historical output was inconsistent here; some
|
|
69
|
+
// versions replaced the base skill, others appended. The implementation
|
|
70
|
+
// below attempts a root-name match and replaces when found, otherwise
|
|
71
|
+
// appends. If this causes issues, simplify to just using `baseSkillIds`
|
|
72
|
+
// directly.
|
|
73
|
+
// -------------------------------------------------------------------------
|
|
74
|
+
let finalSkillIds = [...baseSkillIds];
|
|
75
|
+
if (trans !== undefined && transformDataTemplate !== undefined) {
|
|
76
|
+
const transRow = trans[groupType];
|
|
77
|
+
if (transRow !== undefined) {
|
|
78
|
+
// Collect all retrofit skill IDs: from trans.skill_id + each transform node's skill_id
|
|
79
|
+
const retrofitSkillIds = new Set();
|
|
80
|
+
// From the top-level trans row
|
|
81
|
+
const topSkillIds = normalizeSkillIdList(transRow.skill_id);
|
|
82
|
+
for (const sid of topSkillIds) {
|
|
83
|
+
if (sid !== 0)
|
|
84
|
+
retrofitSkillIds.add(sid);
|
|
85
|
+
}
|
|
86
|
+
// From each transform_data_template node referenced in transform_list
|
|
87
|
+
const seenTransformIds = new Set();
|
|
88
|
+
for (const outerList of transRow.transform_list) {
|
|
89
|
+
for (const pair of outerList) {
|
|
90
|
+
const transformId = pair[1];
|
|
91
|
+
if (transformId === undefined || seenTransformIds.has(transformId))
|
|
92
|
+
continue;
|
|
93
|
+
seenTransformIds.add(transformId);
|
|
94
|
+
const tRow = transformDataTemplate[String(transformId)];
|
|
95
|
+
if (tRow === undefined)
|
|
96
|
+
continue;
|
|
97
|
+
const tSkillIds = normalizeSkillIdList(tRow.skill_id);
|
|
98
|
+
for (const sid of tSkillIds) {
|
|
99
|
+
if (sid !== 0)
|
|
100
|
+
retrofitSkillIds.add(sid);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Merge retrofit skills: replace base skill if root names match, else append
|
|
105
|
+
for (const retrofitId of retrofitSkillIds) {
|
|
106
|
+
const retrofitRow = skillDataTemplate[String(retrofitId)];
|
|
107
|
+
if (retrofitRow === undefined)
|
|
108
|
+
continue;
|
|
109
|
+
const retrofitName = retrofitRow.name;
|
|
110
|
+
if (retrofitName === undefined)
|
|
111
|
+
continue;
|
|
112
|
+
const retrofitRoot = rootSkillName(retrofitName);
|
|
113
|
+
// Try to find a base skill with the same root name
|
|
114
|
+
let replaced = false;
|
|
115
|
+
for (let i = 0; i < finalSkillIds.length; i++) {
|
|
116
|
+
const baseId = finalSkillIds[i];
|
|
117
|
+
if (baseId === undefined)
|
|
118
|
+
continue;
|
|
119
|
+
const baseRow = skillDataTemplate[String(baseId)];
|
|
120
|
+
if (baseRow === undefined)
|
|
121
|
+
continue;
|
|
122
|
+
const baseName = baseRow.name;
|
|
123
|
+
if (baseName === undefined)
|
|
124
|
+
continue;
|
|
125
|
+
const baseRoot = rootSkillName(baseName);
|
|
126
|
+
if (baseRoot === retrofitRoot && baseRoot.length > 0) {
|
|
127
|
+
finalSkillIds[i] = retrofitId;
|
|
128
|
+
replaced = true;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!replaced) {
|
|
133
|
+
// No matching base skill — append if not already present
|
|
134
|
+
if (!finalSkillIds.includes(retrofitId)) {
|
|
135
|
+
finalSkillIds.push(retrofitId);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// -------------------------------------------------------------------------
|
|
142
|
+
// 4. Build skill objects.
|
|
143
|
+
// -------------------------------------------------------------------------
|
|
144
|
+
const skills = [];
|
|
145
|
+
for (const skillId of finalSkillIds) {
|
|
146
|
+
const idStr = String(skillId);
|
|
147
|
+
const skillRow = skillDataTemplate[idStr];
|
|
148
|
+
const displayRow = skillDataDisplay[idStr];
|
|
149
|
+
// Resolve name: prefer skill_data_template, fallback to skill_data_display
|
|
150
|
+
let nameEn = skillRow?.name ?? displayRow?.name;
|
|
151
|
+
if (nameEn === undefined || nameEn.trim() === "") {
|
|
152
|
+
// No name at all — skip this skill
|
|
153
|
+
console.warn(`normalizeSkills: skill ID ${skillId} has no name in skill_data_template or skill_data_display — skipping (group_type ${groupType})`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
nameEn = nameEn.trim();
|
|
157
|
+
const type = skillRow?.type ?? 0;
|
|
158
|
+
const color = (0, enums_js_1.skillColor)(type);
|
|
159
|
+
const description = buildDescription(skillDataTemplate, idStr);
|
|
160
|
+
skills.push({
|
|
161
|
+
color,
|
|
162
|
+
names: { en: nameEn },
|
|
163
|
+
description,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// -------------------------------------------------------------------------
|
|
167
|
+
// 5. Build limit breaks.
|
|
168
|
+
//
|
|
169
|
+
// rowIds[0..2] correspond to LB1/LB2/LB3 source rows.
|
|
170
|
+
// The terminal row (index 3, ending in "4") has breakout_view: "None" → skip.
|
|
171
|
+
// -------------------------------------------------------------------------
|
|
172
|
+
// We want the first THREE non-terminal rows: rowIds[0], [1], [2]
|
|
173
|
+
const limitBreaks = [];
|
|
174
|
+
for (let i = 0; i < 3; i++) {
|
|
175
|
+
const rowId = rowIds[i];
|
|
176
|
+
if (rowId === undefined) {
|
|
177
|
+
// Fewer than 3 rows — some ships (e.g. META 4-star ships) may have fewer LB stages
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const breakoutRow = breakout[rowId];
|
|
181
|
+
if (breakoutRow === undefined) {
|
|
182
|
+
// Row missing from breakout table — skip
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const bonuses = (0, strings_js_1.splitLimitBreakBonuses)(breakoutRow.breakout_view);
|
|
186
|
+
limitBreaks.push(bonuses);
|
|
187
|
+
}
|
|
188
|
+
// If all three limit-break arrays are empty/absent, omit the field
|
|
189
|
+
const hasLimitBreaks = limitBreaks.length > 0 && limitBreaks.some((lb) => lb.length > 0);
|
|
190
|
+
return {
|
|
191
|
+
skills,
|
|
192
|
+
limitBreaks: hasLimitBreaks ? limitBreaks : undefined,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeSkins = normalizeSkins;
|
|
4
|
+
const config_js_1 = require("../config.js");
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Internal helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const DEFAULT_BASE_URL = config_js_1.PAINTINGS_URL;
|
|
9
|
+
/**
|
|
10
|
+
* Returns true if l2d_animations is non-empty
|
|
11
|
+
* (Array with length > 0, or object with at least one key).
|
|
12
|
+
*/
|
|
13
|
+
function hasLive2d(l2dAnimations) {
|
|
14
|
+
if (l2dAnimations === undefined || l2dAnimations === null)
|
|
15
|
+
return false;
|
|
16
|
+
if (Array.isArray(l2dAnimations))
|
|
17
|
+
return l2dAnimations.length > 0;
|
|
18
|
+
if (typeof l2dAnimations === "object") {
|
|
19
|
+
return Object.keys(l2dAnimations).length > 0;
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns true if the shop entry's `time` value represents "always"
|
|
25
|
+
* (i.e. the string "always").
|
|
26
|
+
*/
|
|
27
|
+
function isAlwaysAvailable(time) {
|
|
28
|
+
return time === "always";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build the variant images map for a skin painting.
|
|
32
|
+
*
|
|
33
|
+
* Variant mapping:
|
|
34
|
+
* {name}.webp → "default" (base file — the EN version, may be censored)
|
|
35
|
+
* {name}_rw.webp → "censored_nobg" (EN character layer without background)
|
|
36
|
+
* {name}_n.webp → "uncensored" (JP/original version)
|
|
37
|
+
* {name}_n_rw.webp → "uncensored_nobg" (JP character without background)
|
|
38
|
+
* {name}_bj.webp → "background" (background layer only)
|
|
39
|
+
*
|
|
40
|
+
* "censored" is an alias for "default" since the base file IS the EN version.
|
|
41
|
+
*/
|
|
42
|
+
function buildVariantImages(painting, baseUrl, available) {
|
|
43
|
+
const lower = painting.toLowerCase();
|
|
44
|
+
const has = (suffix) => {
|
|
45
|
+
const key = suffix === "" ? lower : `${lower}${suffix}`;
|
|
46
|
+
return available ? available.has(key) : true;
|
|
47
|
+
};
|
|
48
|
+
const url = (suffix) => `${baseUrl}/${painting}${suffix}.webp`;
|
|
49
|
+
const images = {};
|
|
50
|
+
if (has(""))
|
|
51
|
+
images.default = url("");
|
|
52
|
+
if (has(""))
|
|
53
|
+
images.censored = url(""); // alias for default
|
|
54
|
+
if (has("_rw"))
|
|
55
|
+
images.censored_nobg = url("_rw");
|
|
56
|
+
if (has("_n"))
|
|
57
|
+
images.uncensored = url("_n");
|
|
58
|
+
if (has("_n_rw"))
|
|
59
|
+
images.uncensored_nobg = url("_n_rw");
|
|
60
|
+
if (has("_bj"))
|
|
61
|
+
images.background = url("_bj");
|
|
62
|
+
return Object.keys(images).length > 0 ? images : undefined;
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Main
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
function normalizeSkins(inputs) {
|
|
68
|
+
const { groupType, skinTemplate, shopTemplate, thumbnailBaseUrl, availablePaintings } = inputs;
|
|
69
|
+
const base = thumbnailBaseUrl ?? DEFAULT_BASE_URL;
|
|
70
|
+
const groupTypeNum = Number(groupType);
|
|
71
|
+
// Filter skin rows belonging to this ship group, then sort by skin ID ascending
|
|
72
|
+
const skinEntries = Object.entries(skinTemplate)
|
|
73
|
+
.filter(([, row]) => row !== undefined && row.ship_group === groupTypeNum)
|
|
74
|
+
.sort(([a], [b]) => {
|
|
75
|
+
const diff = Number(a) - Number(b);
|
|
76
|
+
return diff;
|
|
77
|
+
});
|
|
78
|
+
if (skinEntries.length === 0) {
|
|
79
|
+
return { skins: [] };
|
|
80
|
+
}
|
|
81
|
+
const skins = [];
|
|
82
|
+
for (const [skinId, row] of skinEntries) {
|
|
83
|
+
if (row === undefined)
|
|
84
|
+
continue;
|
|
85
|
+
// name: row.name if non-empty, else row.desc if non-empty, else "(unnamed)"
|
|
86
|
+
const name = row.name.trim().length > 0
|
|
87
|
+
? row.name.trim()
|
|
88
|
+
: (row.desc?.trim().length ?? 0) > 0
|
|
89
|
+
? (row.desc?.trim() ?? "(unnamed)")
|
|
90
|
+
: "(unnamed)";
|
|
91
|
+
// image URL
|
|
92
|
+
const image = `${base}/${row.painting}.webp`;
|
|
93
|
+
// shop info
|
|
94
|
+
const shopId = row.shop_id;
|
|
95
|
+
let cost;
|
|
96
|
+
let isAlways = false;
|
|
97
|
+
let hasValidShop = false;
|
|
98
|
+
if (shopId !== undefined && shopId !== 0) {
|
|
99
|
+
const shopEntry = shopTemplate[String(shopId)];
|
|
100
|
+
if (shopEntry !== undefined) {
|
|
101
|
+
const isShopGenre = shopEntry.genre === "skin_shop" || shopEntry.effect_args !== undefined;
|
|
102
|
+
const resourceNum = shopEntry.resource_num;
|
|
103
|
+
if (isShopGenre && resourceNum !== undefined && resourceNum > 0) {
|
|
104
|
+
cost = resourceNum;
|
|
105
|
+
}
|
|
106
|
+
isAlways = isAlwaysAvailable(shopEntry.time);
|
|
107
|
+
hasValidShop = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// obtainedFrom heuristic
|
|
111
|
+
let obtainedFrom;
|
|
112
|
+
if (row.skin_type === -1) {
|
|
113
|
+
obtainedFrom = "Default";
|
|
114
|
+
}
|
|
115
|
+
else if (hasValidShop && isAlways) {
|
|
116
|
+
obtainedFrom = "Skin Shop";
|
|
117
|
+
}
|
|
118
|
+
else if (shopId !== undefined && shopId !== 0) {
|
|
119
|
+
obtainedFrom = "Limited (Event)";
|
|
120
|
+
}
|
|
121
|
+
else if (row.skin_type === 7 ||
|
|
122
|
+
name.toLowerCase().includes("pledge")) {
|
|
123
|
+
obtainedFrom = "Wedding";
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
obtainedFrom = "Special";
|
|
127
|
+
}
|
|
128
|
+
// live2dModel
|
|
129
|
+
const live2dModel = hasLive2d(row.l2d_animations) ? true : undefined;
|
|
130
|
+
const info = {
|
|
131
|
+
...(cost !== undefined ? { cost } : {}),
|
|
132
|
+
obtainedFrom,
|
|
133
|
+
...(live2dModel !== undefined ? { live2dModel } : {}),
|
|
134
|
+
enClient: "Yes",
|
|
135
|
+
};
|
|
136
|
+
// Build variant images object
|
|
137
|
+
const images = buildVariantImages(row.painting, base, availablePaintings);
|
|
138
|
+
skins.push({ name, image, images, info });
|
|
139
|
+
}
|
|
140
|
+
return { skins };
|
|
141
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeSlots = normalizeSlots;
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Main
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function normalizeSlots(inputs) {
|
|
8
|
+
const { lb0RowId, lb3RowId, template, statistics, lookups } = inputs;
|
|
9
|
+
const tmplLb0 = template[lb0RowId];
|
|
10
|
+
const tmplLb3 = template[lb3RowId];
|
|
11
|
+
// If either template row is missing, return empty — orchestrator decides what to do.
|
|
12
|
+
if (tmplLb0 === undefined || tmplLb3 === undefined) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const statsLb0 = statistics[lb0RowId];
|
|
16
|
+
const statsLb3 = statistics[lb3RowId];
|
|
17
|
+
const proficiencyLb0 = statsLb0?.equipment_proficiency ?? [];
|
|
18
|
+
const proficiencyLb3 = statsLb3?.equipment_proficiency ?? [];
|
|
19
|
+
// Equipment slot arrays: equip_1, equip_2, equip_3 (ignore 4th augment slot)
|
|
20
|
+
const equipSlots = [
|
|
21
|
+
tmplLb0.equip_1,
|
|
22
|
+
tmplLb0.equip_2,
|
|
23
|
+
tmplLb0.equip_3,
|
|
24
|
+
];
|
|
25
|
+
const slots = [];
|
|
26
|
+
for (let i = 0; i < 3; i++) {
|
|
27
|
+
const equipArr = equipSlots[i];
|
|
28
|
+
const equipTypeId = equipArr?.[0];
|
|
29
|
+
const type = equipTypeId !== undefined ? lookups.equipTypeName(equipTypeId) : "Unknown";
|
|
30
|
+
const minEfficiency = proficiencyLb0[i] ?? 0;
|
|
31
|
+
const maxEfficiency = proficiencyLb3[i] ?? 0;
|
|
32
|
+
slots.push({ type, minEfficiency, maxEfficiency });
|
|
33
|
+
}
|
|
34
|
+
return slots;
|
|
35
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeStats = normalizeStats;
|
|
4
|
+
const enums_js_1 = require("../translate/enums.js");
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Internal helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/**
|
|
9
|
+
* Build a strengthen bonus array (12 elements) from the `durability` field.
|
|
10
|
+
*
|
|
11
|
+
* Strengthen durability mapping (0-indexed):
|
|
12
|
+
* [0] → firepower (attrs index 1)
|
|
13
|
+
* [1] → torpedo (attrs index 2)
|
|
14
|
+
* [2] → (unused / always 0)
|
|
15
|
+
* [3] → aviation (attrs index 4)
|
|
16
|
+
* [4] → reload (attrs index 5)
|
|
17
|
+
*/
|
|
18
|
+
function buildStrengthenBonus(durability) {
|
|
19
|
+
const bonus = new Array(12).fill(0);
|
|
20
|
+
bonus[1] = durability[0] ?? 0; // firepower
|
|
21
|
+
bonus[2] = durability[1] ?? 0; // torpedo
|
|
22
|
+
bonus[4] = durability[3] ?? 0; // aviation
|
|
23
|
+
bonus[5] = durability[4] ?? 0; // reload
|
|
24
|
+
return bonus;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Compute a single stat value at the given level.
|
|
28
|
+
* Formula: base + floor(growth * (level - 1) / 1000) + floor(growthExtra * max(level - 100, 0) / 1000) + strengthenBonus
|
|
29
|
+
*/
|
|
30
|
+
function computeStat(base, growth, growthExtra, level, strengthenBonus) {
|
|
31
|
+
const fromGrowth = Math.floor((growth * (level - 1)) / 1000);
|
|
32
|
+
const fromExtra = level > 100 ? Math.floor((growthExtra * (level - 100)) / 1000) : 0;
|
|
33
|
+
return base + fromGrowth + fromExtra + strengthenBonus;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build a StatBlock for a given level from the statistics arrays.
|
|
37
|
+
*/
|
|
38
|
+
function buildStatBlock(attrs, attrsGrowth, attrsGrowthExtra, level, strengthenBonus) {
|
|
39
|
+
const partial = {};
|
|
40
|
+
for (let i = 0; i < 12; i++) {
|
|
41
|
+
const field = enums_js_1.STAT_INDEX_TO_FIELD[i];
|
|
42
|
+
if (field === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
const stat = computeStat(attrs[i] ?? 0, attrsGrowth[i] ?? 0, attrsGrowthExtra[i] ?? 0, level, strengthenBonus[i] ?? 0);
|
|
45
|
+
partial[field] = stat;
|
|
46
|
+
}
|
|
47
|
+
// Ensure all required StatBlock fields are present (default 0)
|
|
48
|
+
const block = {
|
|
49
|
+
health: partial.health ?? 0,
|
|
50
|
+
firepower: partial.firepower ?? 0,
|
|
51
|
+
torpedo: partial.torpedo ?? 0,
|
|
52
|
+
evasion: partial.evasion ?? 0,
|
|
53
|
+
antiwar: partial.antiwar ?? 0,
|
|
54
|
+
aviation: partial.aviation ?? 0,
|
|
55
|
+
reload: partial.reload ?? 0,
|
|
56
|
+
speed: partial.speed ?? 0,
|
|
57
|
+
luck: partial.luck ?? 0,
|
|
58
|
+
accuracy: partial.accuracy ?? 0,
|
|
59
|
+
};
|
|
60
|
+
return block;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Retrofit raw stat name → StatBlock field mapping.
|
|
64
|
+
*/
|
|
65
|
+
const RETROFIT_RAW_NAME_MAP = {
|
|
66
|
+
durability: "health",
|
|
67
|
+
cannon: "firepower",
|
|
68
|
+
torpedo: "torpedo",
|
|
69
|
+
antiaircraft: "antiwar",
|
|
70
|
+
air: "aviation",
|
|
71
|
+
reload: "reload",
|
|
72
|
+
hit: "accuracy",
|
|
73
|
+
dodge: "evasion",
|
|
74
|
+
speed: "speed",
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Compute retrofit stat deltas by walking the transform_list.
|
|
78
|
+
* Returns a partial StatBlock delta (only fields with non-zero deltas).
|
|
79
|
+
*/
|
|
80
|
+
function computeRetrofitDeltas(groupType, trans, transformDataTemplate) {
|
|
81
|
+
const transRow = trans[groupType];
|
|
82
|
+
if (transRow === undefined)
|
|
83
|
+
return {};
|
|
84
|
+
const deltas = {};
|
|
85
|
+
const seenTransformIds = new Set();
|
|
86
|
+
for (const outerList of transRow.transform_list) {
|
|
87
|
+
for (const pair of outerList) {
|
|
88
|
+
const transformId = pair[1];
|
|
89
|
+
if (transformId === undefined || seenTransformIds.has(transformId))
|
|
90
|
+
continue;
|
|
91
|
+
seenTransformIds.add(transformId);
|
|
92
|
+
const tRow = transformDataTemplate[String(transformId)];
|
|
93
|
+
if (tRow === undefined)
|
|
94
|
+
continue;
|
|
95
|
+
for (const effectEntry of tRow.effect) {
|
|
96
|
+
for (const [rawStatName, delta] of Object.entries(effectEntry)) {
|
|
97
|
+
const field = RETROFIT_RAW_NAME_MAP[rawStatName];
|
|
98
|
+
if (field === undefined)
|
|
99
|
+
continue;
|
|
100
|
+
const current = deltas[field] ?? 0;
|
|
101
|
+
deltas[field] = current + delta;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return deltas;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Apply retrofit deltas to a StatBlock, returning a new StatBlock.
|
|
110
|
+
*/
|
|
111
|
+
function applyRetrofitDeltas(base, deltas) {
|
|
112
|
+
return {
|
|
113
|
+
health: base.health + (deltas.health ?? 0),
|
|
114
|
+
firepower: base.firepower + (deltas.firepower ?? 0),
|
|
115
|
+
torpedo: base.torpedo + (deltas.torpedo ?? 0),
|
|
116
|
+
evasion: base.evasion + (deltas.evasion ?? 0),
|
|
117
|
+
antiwar: base.antiwar + (deltas.antiwar ?? 0),
|
|
118
|
+
aviation: base.aviation + (deltas.aviation ?? 0),
|
|
119
|
+
reload: base.reload + (deltas.reload ?? 0),
|
|
120
|
+
speed: base.speed + (deltas.speed ?? 0),
|
|
121
|
+
luck: base.luck + (deltas.luck ?? 0),
|
|
122
|
+
accuracy: base.accuracy + (deltas.accuracy ?? 0),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Main
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
function normalizeStats(inputs) {
|
|
129
|
+
const { lb3RowId, en, groupType, strengthenId } = inputs;
|
|
130
|
+
const { statistics, strengthen, trans, transformDataTemplate } = en;
|
|
131
|
+
// ------------------------------------------------------------------
|
|
132
|
+
// Get the LB3 statistics row
|
|
133
|
+
// ------------------------------------------------------------------
|
|
134
|
+
const statsRow = statistics[lb3RowId];
|
|
135
|
+
if (statsRow === undefined) {
|
|
136
|
+
throw new Error(`normalizeStats: missing statistics row "${lb3RowId}" for group_type "${groupType}"`);
|
|
137
|
+
}
|
|
138
|
+
const attrs = statsRow.attrs;
|
|
139
|
+
const attrsGrowth = statsRow.attrs_growth;
|
|
140
|
+
const attrsGrowthExtra = statsRow.attrs_growth_extra ?? new Array(12).fill(0);
|
|
141
|
+
// ------------------------------------------------------------------
|
|
142
|
+
// Strengthen bonus
|
|
143
|
+
// ------------------------------------------------------------------
|
|
144
|
+
const strengthenRow = strengthen[strengthenId];
|
|
145
|
+
const durability = strengthenRow?.durability ?? [];
|
|
146
|
+
const strengthenBonus = buildStrengthenBonus(durability);
|
|
147
|
+
// ------------------------------------------------------------------
|
|
148
|
+
// Compute stat blocks at level 100 and 120
|
|
149
|
+
// ------------------------------------------------------------------
|
|
150
|
+
const level100 = buildStatBlock(attrs, attrsGrowth, attrsGrowthExtra, 100, strengthenBonus);
|
|
151
|
+
const level120 = buildStatBlock(attrs, attrsGrowth, attrsGrowthExtra, 120, strengthenBonus);
|
|
152
|
+
// ------------------------------------------------------------------
|
|
153
|
+
// Retrofit deltas
|
|
154
|
+
// ------------------------------------------------------------------
|
|
155
|
+
const hasRetrofit = groupType in trans;
|
|
156
|
+
let level100Retrofit;
|
|
157
|
+
let level120Retrofit;
|
|
158
|
+
if (hasRetrofit) {
|
|
159
|
+
const deltas = computeRetrofitDeltas(groupType, trans, transformDataTemplate);
|
|
160
|
+
level100Retrofit = applyRetrofitDeltas(level100, deltas);
|
|
161
|
+
level120Retrofit = applyRetrofitDeltas(level120, deltas);
|
|
162
|
+
}
|
|
163
|
+
// ------------------------------------------------------------------
|
|
164
|
+
// Enhance value
|
|
165
|
+
// ------------------------------------------------------------------
|
|
166
|
+
const enhanceValue = {
|
|
167
|
+
firepower: durability[0] ?? 0,
|
|
168
|
+
torpedo: durability[1] ?? 0,
|
|
169
|
+
aviation: durability[3] ?? 0,
|
|
170
|
+
reload: durability[4] ?? 0,
|
|
171
|
+
};
|
|
172
|
+
// ------------------------------------------------------------------
|
|
173
|
+
// Assemble output
|
|
174
|
+
// ------------------------------------------------------------------
|
|
175
|
+
const stats = {
|
|
176
|
+
level100,
|
|
177
|
+
level120,
|
|
178
|
+
...(level100Retrofit !== undefined ? { level100Retrofit } : {}),
|
|
179
|
+
...(level120Retrofit !== undefined ? { level120Retrofit } : {}),
|
|
180
|
+
};
|
|
181
|
+
return { stats, enhanceValue };
|
|
182
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./writeShips.js"), exports);
|
|
18
|
+
__exportStar(require("./writeShipList.js"), exports);
|
|
19
|
+
__exportStar(require("./writeIdMap.js"), exports);
|
|
20
|
+
__exportStar(require("./writeVersion.js"), exports);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.writeIdMap = writeIdMap;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// writeIdMap
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Write a name/alias → canonical id map to disk.
|
|
14
|
+
*
|
|
15
|
+
* Shape: Record<string, string>
|
|
16
|
+
*
|
|
17
|
+
* For each ship: emits names.en → id, names.cn → id, names.jp → id, names.code → id
|
|
18
|
+
* For each groupRow: emits padded code → group_type string (legacy AzurAPI lookup)
|
|
19
|
+
*
|
|
20
|
+
* Last-writer-wins for duplicate names.
|
|
21
|
+
*/
|
|
22
|
+
function writeIdMap(ships, groupRows, outputPath = "data/id-map.json") {
|
|
23
|
+
const map = {};
|
|
24
|
+
// Collect all EN names first so we don't let names.code overwrite a real ship name
|
|
25
|
+
const enNames = new Set();
|
|
26
|
+
for (const ship of ships) {
|
|
27
|
+
if (ship.names.en !== undefined)
|
|
28
|
+
enNames.add(ship.names.en);
|
|
29
|
+
}
|
|
30
|
+
// Per-ship name entries (first-writer-wins for code names to avoid collisions)
|
|
31
|
+
for (const ship of ships) {
|
|
32
|
+
const { id, names } = ship;
|
|
33
|
+
if (names.en !== undefined)
|
|
34
|
+
map[names.en] = id;
|
|
35
|
+
if (names.cn !== undefined && !(names.cn in map))
|
|
36
|
+
map[names.cn] = id;
|
|
37
|
+
if (names.jp !== undefined && !(names.jp in map))
|
|
38
|
+
map[names.jp] = id;
|
|
39
|
+
if (names.code !== undefined && !(names.code in map) && !enNames.has(names.code)) {
|
|
40
|
+
map[names.code] = id;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Legacy 3-digit code → group_type mapping from groupRows
|
|
44
|
+
for (const row of groupRows) {
|
|
45
|
+
const paddedCode = String(row.code).padStart(3, "0");
|
|
46
|
+
map[paddedCode] = String(row.group_type);
|
|
47
|
+
}
|
|
48
|
+
const json = JSON.stringify(map, null, 2);
|
|
49
|
+
const dir = path_1.default.dirname(path_1.default.resolve(outputPath));
|
|
50
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
51
|
+
fs_1.default.writeFileSync(outputPath, json, "utf-8");
|
|
52
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.writeShipList = writeShipList;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// writeShipList
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Write a minimal ship list to disk.
|
|
14
|
+
* Shape: Array<{ id: string; name: string; hullType: string; rarity: string }>
|
|
15
|
+
*
|
|
16
|
+
* `name` is resolved in priority order: names.en → names.code → id
|
|
17
|
+
*/
|
|
18
|
+
function writeShipList(ships, outputPath = "data/ship-list.json") {
|
|
19
|
+
const list = ships.map((ship) => ({
|
|
20
|
+
id: ship.id,
|
|
21
|
+
name: ship.names.en ?? ship.names.code ?? ship.id,
|
|
22
|
+
hullType: ship.hullType,
|
|
23
|
+
rarity: ship.rarity,
|
|
24
|
+
}));
|
|
25
|
+
// Sort by id numerically for deterministic output
|
|
26
|
+
list.sort((a, b) => Number(a.id) - Number(b.id));
|
|
27
|
+
const json = JSON.stringify(list, null, 2);
|
|
28
|
+
const dir = path_1.default.dirname(path_1.default.resolve(outputPath));
|
|
29
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
30
|
+
fs_1.default.writeFileSync(outputPath, json, "utf-8");
|
|
31
|
+
}
|