Validate battle tactical guide data
This commit is contained in:
@@ -20,6 +20,15 @@ try {
|
|||||||
const itemKeys = new Set(Object.keys(itemCatalog));
|
const itemKeys = new Set(Object.keys(itemCatalog));
|
||||||
const itemNames = new Set(Object.values(itemCatalog).map((item) => item.name));
|
const itemNames = new Set(Object.values(itemCatalog).map((item) => item.name));
|
||||||
const formationRoles = new Set(sortieFormationRoles);
|
const formationRoles = new Set(sortieFormationRoles);
|
||||||
|
const tacticalGuideEventKeys = new Set([
|
||||||
|
'leader-wavering',
|
||||||
|
'ally-danger',
|
||||||
|
'village-approach',
|
||||||
|
'village-secured',
|
||||||
|
'vanguard-broken',
|
||||||
|
'cavalry-approach',
|
||||||
|
'enemy-posture'
|
||||||
|
]);
|
||||||
const knownRewardUnitIds = new Set([
|
const knownRewardUnitIds = new Set([
|
||||||
...scenarioEntries.flatMap(([, scenario]) => scenario.units.map((unit) => unit.id)),
|
...scenarioEntries.flatMap(([, scenario]) => scenario.units.map((unit) => unit.id)),
|
||||||
...(campaignRecruitUnits ?? []).map((unit) => unit.id)
|
...(campaignRecruitUnits ?? []).map((unit) => unit.id)
|
||||||
@@ -38,6 +47,7 @@ try {
|
|||||||
validateMap(errors, scenario, terrainKeys, context);
|
validateMap(errors, scenario, terrainKeys, context);
|
||||||
validateUnits(errors, scenario, classKeys, itemKeys, equipmentSlots, context);
|
validateUnits(errors, scenario, classKeys, itemKeys, equipmentSlots, context);
|
||||||
validateObjectives(errors, scenario, context);
|
validateObjectives(errors, scenario, context);
|
||||||
|
validateTacticalGuide(errors, scenario, tacticalGuideEventKeys, context);
|
||||||
validateSortie(errors, scenario, classKeys, formationRoles, terrainRules, context);
|
validateSortie(errors, scenario, classKeys, formationRoles, terrainRules, context);
|
||||||
validateRewards(errors, scenario, scenarioIds, itemNames, knownRewardUnitIds, context);
|
validateRewards(errors, scenario, scenarioIds, itemNames, knownRewardUnitIds, context);
|
||||||
});
|
});
|
||||||
@@ -55,8 +65,9 @@ try {
|
|||||||
(total, [, scenario]) => total + scenario.itemRewards.length + campaignRewardLabelCount(scenario.campaignReward),
|
(total, [, scenario]) => total + scenario.itemRewards.length + campaignRewardLabelCount(scenario.campaignReward),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
const tacticalGuideCount = scenarioEntries.reduce((total, [, scenario]) => total + (scenario.tacticalGuide ? 1 : 0), 0);
|
||||||
console.log(
|
console.log(
|
||||||
`Verified ${scenarioEntries.length} battle scenarios, ${unitCount} unit placements, maps, objectives, sortie data, equipment, and ${rewardCount} reward labels.`
|
`Verified ${scenarioEntries.length} battle scenarios, ${unitCount} unit placements, maps, objectives, sortie data, ${tacticalGuideCount} tactical guides, equipment, and ${rewardCount} reward labels.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -190,6 +201,52 @@ function validateObjectives(errors, scenario, context) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateTacticalGuide(errors, scenario, eventKeys, context) {
|
||||||
|
const guide = scenario.tacticalGuide;
|
||||||
|
if (!guide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNonEmptyString(errors, guide.summary, `${context}: tacticalGuide summary`);
|
||||||
|
assertNonEmptyString(errors, guide.route, `${context}: tacticalGuide route`);
|
||||||
|
assertNonEmptyString(errors, guide.focus, `${context}: tacticalGuide focus`);
|
||||||
|
|
||||||
|
if (!Array.isArray(guide.roles) || guide.roles.length === 0) {
|
||||||
|
errors.push(`${context}: tacticalGuide roles must include at least one role`);
|
||||||
|
} else {
|
||||||
|
guide.roles.forEach((role, index) => {
|
||||||
|
assertNonEmptyString(errors, role, `${context}: tacticalGuide roles[${index}]`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guide.events === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!guide.events || typeof guide.events !== 'object' || Array.isArray(guide.events)) {
|
||||||
|
errors.push(`${context}: tacticalGuide events must be an object`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(guide.events).forEach(([eventKey, event]) => {
|
||||||
|
if (!eventKeys.has(eventKey)) {
|
||||||
|
errors.push(`${context}: tacticalGuide event "${eventKey}" is not supported`);
|
||||||
|
}
|
||||||
|
if (!event || typeof event !== 'object' || Array.isArray(event)) {
|
||||||
|
errors.push(`${context}: tacticalGuide event "${eventKey}" must be an object`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNonEmptyString(errors, event.title, `${context}: tacticalGuide event "${eventKey}" title`);
|
||||||
|
if (!Array.isArray(event.lines) || event.lines.length === 0) {
|
||||||
|
errors.push(`${context}: tacticalGuide event "${eventKey}" must include at least one line`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.lines.forEach((line, index) => {
|
||||||
|
assertNonEmptyString(errors, line, `${context}: tacticalGuide event "${eventKey}" lines[${index}]`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function validateCharacterProgress(errors, unit, context) {
|
function validateCharacterProgress(errors, unit, context) {
|
||||||
if (!Number.isInteger(unit.level) || unit.level < 1) {
|
if (!Number.isInteger(unit.level) || unit.level < 1) {
|
||||||
errors.push(`${context}: invalid level ${unit.level}`);
|
errors.push(`${context}: invalid level ${unit.level}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user