Validate sortie recruit availability
This commit is contained in:
@@ -21,7 +21,9 @@ try {
|
|||||||
|
|
||||||
validateRecruitTemplates(errors, recruitTemplates, classKeys, itemKeys, itemCatalog, equipmentSlots);
|
validateRecruitTemplates(errors, recruitTemplates, classKeys, itemKeys, itemCatalog, equipmentSlots);
|
||||||
|
|
||||||
Object.entries(battleScenarios).forEach(([battleId, scenario]) => {
|
const scenarioEntries = Object.entries(battleScenarios);
|
||||||
|
|
||||||
|
scenarioEntries.forEach(([battleId, scenario]) => {
|
||||||
const sameBattleAllies = new Set(scenario.units.filter((unit) => unit.faction === 'ally').map((unit) => unit.id));
|
const sameBattleAllies = new Set(scenario.units.filter((unit) => unit.faction === 'ally').map((unit) => unit.id));
|
||||||
const rewardRecruits = scenario.campaignReward?.recruits ?? [];
|
const rewardRecruits = scenario.campaignReward?.recruits ?? [];
|
||||||
|
|
||||||
@@ -40,6 +42,7 @@ try {
|
|||||||
});
|
});
|
||||||
|
|
||||||
validateReachability(errors, recruitTemplates, recruitRewardRefs);
|
validateReachability(errors, recruitTemplates, recruitRewardRefs);
|
||||||
|
validateSortieRecruitAvailability(errors, scenarioEntries);
|
||||||
|
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
console.error(`Campaign recruit data verification failed with ${errors.length} issue(s):`);
|
console.error(`Campaign recruit data verification failed with ${errors.length} issue(s):`);
|
||||||
@@ -165,6 +168,40 @@ function validateReachability(errors, recruitTemplates, recruitRewardRefs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateSortieRecruitAvailability(errors, scenarioEntries) {
|
||||||
|
const firstBattleAllies = scenarioEntries[0]?.[1]?.units
|
||||||
|
?.filter((unit) => unit.faction === 'ally')
|
||||||
|
.map((unit) => unit.id) ?? [];
|
||||||
|
const availableUnitIds = new Set(firstBattleAllies);
|
||||||
|
|
||||||
|
scenarioEntries.forEach(([battleId, scenario]) => {
|
||||||
|
const unavailableRefs = new Set();
|
||||||
|
const sortie = scenario.sortie;
|
||||||
|
|
||||||
|
(sortie?.requiredUnits ?? []).forEach((unitId) => {
|
||||||
|
if (!availableUnitIds.has(unitId)) {
|
||||||
|
unavailableRefs.add(`requiredUnits:${unitId}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(sortie?.recommendedUnits ?? []).forEach((recommendation) => {
|
||||||
|
if (!availableUnitIds.has(recommendation.unitId)) {
|
||||||
|
unavailableRefs.add(`recommendedUnits:${recommendation.unitId}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(sortie?.deploymentSlots ?? []).forEach((slot) => {
|
||||||
|
if (slot.unitId && !availableUnitIds.has(slot.unitId)) {
|
||||||
|
unavailableRefs.add(`deploymentSlots:${slot.unitId}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (unavailableRefs.size > 0) {
|
||||||
|
errors.push(`${battleId}: sortie references unit(s) before recruit availability: ${Array.from(unavailableRefs).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
(scenario.campaignReward?.recruits ?? []).forEach((unitId) => availableUnitIds.add(unitId));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function assertNonEmptyString(errors, value, context) {
|
function assertNonEmptyString(errors, value, context) {
|
||||||
if (typeof value !== 'string' || value.trim().length === 0) {
|
if (typeof value !== 'string' || value.trim().length === 0) {
|
||||||
errors.push(`${context} must be a non-empty string`);
|
errors.push(`${context} must be a non-empty string`);
|
||||||
|
|||||||
Reference in New Issue
Block a user