Improve IK-style artifact scanner pipeline
This commit is contained in:
@@ -44,6 +44,9 @@ const artifactPieces = artifacts
|
||||
|
||||
const slotByPiece = Object.fromEntries(artifactPieces.map((piece) => [piece.name, piece.slot]));
|
||||
const setByPiece = Object.fromEntries(artifactPieces.map((piece) => [piece.name, piece.setName]));
|
||||
const setToPieces = Object.fromEntries(
|
||||
artifacts.map((set) => [set.name, artifactPieces.filter((piece) => piece.setName === set.name).map((piece) => piece.name)]),
|
||||
);
|
||||
|
||||
const mainStats = [
|
||||
'Elemental Mastery',
|
||||
@@ -198,6 +201,23 @@ const data = {
|
||||
'Qiqi ': 'Qiqi',
|
||||
},
|
||||
},
|
||||
lookup: {
|
||||
normalizedKeys: {
|
||||
sets: normalizedMap(artifacts.map((set) => set.name)),
|
||||
pieces: normalizedMap(artifactPieces.map((piece) => piece.name)),
|
||||
slots: normalizedMap(['Flower of Life', 'Plume of Death', 'Sands of Eon', 'Goblet of Eonothem', 'Circlet of Logos']),
|
||||
stats: normalizedMap([...mainStats, ...substats]),
|
||||
characters: normalizedMap(characters.map((character) => character.name)),
|
||||
},
|
||||
goodKeys: {
|
||||
sets: Object.fromEntries(artifacts.map((set) => [set.name, goodKey(set.name)])),
|
||||
pieces: Object.fromEntries(artifactPieces.map((piece) => [piece.name, goodKey(piece.name)])),
|
||||
stats: Object.fromEntries([...mainStats, ...substats].map((stat) => [stat, goodStatKey(stat)])),
|
||||
characters: Object.fromEntries(characters.map((character) => [character.name, goodKey(character.name)])),
|
||||
},
|
||||
setToPieces,
|
||||
validation: validateLookupPackage({ artifacts, artifactPieces, characters, mainStats, substats, setToPieces }),
|
||||
},
|
||||
uiProfiles: {
|
||||
artifactDetailEn: {
|
||||
language: 'English',
|
||||
@@ -231,3 +251,89 @@ function slotFromRelicType(relicType) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeLookupKey(value) {
|
||||
return String(value)
|
||||
.toLowerCase()
|
||||
.normalize('NFKD')
|
||||
.replace(/['’]/g, '')
|
||||
.replace(/[^a-z0-9]+/g, '');
|
||||
}
|
||||
|
||||
function normalizedMap(values) {
|
||||
return Object.fromEntries(values.filter(Boolean).map((value) => [normalizeLookupKey(value), value]));
|
||||
}
|
||||
|
||||
function goodKey(value) {
|
||||
return String(value)
|
||||
.replace(/['’]/g, '')
|
||||
.replace(/[^A-Za-z0-9]+(.)/g, (_match, next) => String(next).toUpperCase())
|
||||
.replace(/^[a-z]/, (first) => first.toUpperCase())
|
||||
.replace(/[^A-Za-z0-9]/g, '');
|
||||
}
|
||||
|
||||
function goodStatKey(stat) {
|
||||
switch (stat) {
|
||||
case 'HP':
|
||||
return 'hp';
|
||||
case 'HP%':
|
||||
return 'hp_';
|
||||
case 'ATK':
|
||||
return 'atk';
|
||||
case 'ATK%':
|
||||
return 'atk_';
|
||||
case 'DEF':
|
||||
return 'def';
|
||||
case 'DEF%':
|
||||
return 'def_';
|
||||
case 'Elemental Mastery':
|
||||
return 'eleMas';
|
||||
case 'Energy Recharge':
|
||||
return 'enerRech_';
|
||||
case 'CRIT Rate':
|
||||
return 'critRate_';
|
||||
case 'CRIT DMG':
|
||||
return 'critDMG_';
|
||||
case 'Healing Bonus':
|
||||
return 'heal_';
|
||||
case 'Physical DMG Bonus':
|
||||
return 'physical_dmg_';
|
||||
default:
|
||||
return stat.toLowerCase().replace(' dmg bonus', '_dmg_').replace(/\s+/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
function validateLookupPackage({ artifacts, artifactPieces, characters, mainStats, substats, setToPieces }) {
|
||||
const errors = [];
|
||||
const warnings = [];
|
||||
const setNames = new Set(artifacts.map((set) => set.name));
|
||||
const slotNames = new Set(['Flower of Life', 'Plume of Death', 'Sands of Eon', 'Goblet of Eonothem', 'Circlet of Logos']);
|
||||
const goodSetKeys = new Set();
|
||||
|
||||
for (const set of artifacts) {
|
||||
const key = goodKey(set.name);
|
||||
if (goodSetKeys.has(key)) errors.push(`Duplicate GOOD set key: ${key}`);
|
||||
goodSetKeys.add(key);
|
||||
if ((setToPieces[set.name] ?? []).length === 0) warnings.push(`Set has no pieces: ${set.name}`);
|
||||
}
|
||||
|
||||
for (const piece of artifactPieces) {
|
||||
if (!setNames.has(piece.setName)) errors.push(`Piece ${piece.name} references missing set ${piece.setName}`);
|
||||
if (!slotNames.has(piece.slot)) errors.push(`Piece ${piece.name} references missing slot ${piece.slot}`);
|
||||
}
|
||||
|
||||
if (!characters.length) warnings.push('No characters generated.');
|
||||
if (!mainStats.length || !substats.length) errors.push('Stats were not generated.');
|
||||
|
||||
return {
|
||||
valid: errors.length === 0,
|
||||
errors,
|
||||
warnings,
|
||||
summary: {
|
||||
artifactSets: artifacts.length,
|
||||
artifactPieces: artifactPieces.length,
|
||||
characters: characters.length,
|
||||
stats: mainStats.length + substats.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user