Validate camp visit bond references
This commit is contained in:
@@ -13,19 +13,22 @@ const server = await createServer({
|
||||
|
||||
try {
|
||||
const { battleScenarios, defaultBattleScenario } = await server.ssrLoadModule('/src/game/data/battles.ts');
|
||||
const scenarioData = await server.ssrLoadModule('/src/game/data/scenario.ts');
|
||||
const { isCampaignStep } = await server.ssrLoadModule('/src/game/state/campaignState.ts');
|
||||
const itemRewardArrays = collectItemRewardArrays(source);
|
||||
itemRewardArrays.forEach(({ body, index, offset }) => validateItemRewards(body, index, offset));
|
||||
const campBattleIdEntries = collectCampBattleIdEntries(source, defaultBattleScenario.id);
|
||||
const campBattleIdKeys = new Set(campBattleIdEntries.map((entry) => entry.key));
|
||||
validateCampBattleIdEntries(campBattleIdEntries, battleScenarios);
|
||||
const knownBondsById = collectKnownBondsById(battleScenarios);
|
||||
const knownBondsById = collectKnownBondsById(battleScenarios, scenarioData);
|
||||
const dialogueEvents = collectCampEvents(source, 'campDialogues');
|
||||
const visitEvents = collectCampEvents(source, 'campVisits');
|
||||
const campaignStepReferences =
|
||||
validateCampEventCollection(dialogueEvents, 'campDialogues', campBattleIdKeys, isCampaignStep) +
|
||||
validateCampEventCollection(visitEvents, 'campVisits', campBattleIdKeys, isCampaignStep);
|
||||
const dialogueBondReferences = validateCampDialogueBondReferences(dialogueEvents, knownBondsById);
|
||||
const campBondReferences =
|
||||
validateCampBondReferences(dialogueEvents, 'campDialogues', knownBondsById, { matchUnitIds: true }) +
|
||||
validateCampBondReferences(visitEvents, 'campVisits', knownBondsById);
|
||||
validateNumericProperties('gold', { min: 1, max: 20000 });
|
||||
validateNumericProperties('bondExp', { min: 0, max: 200 });
|
||||
validateNumericProperties('rewardExp', { min: 1, max: 200 });
|
||||
@@ -35,7 +38,7 @@ try {
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Verified ${dialogueEvents.length} camp dialogues, ${visitEvents.length} camp visits, ${campBattleIdEntries.length} camp battle ids, ${campaignStepReferences} campaign-step references, ${dialogueBondReferences} camp dialogue bonds, ${itemRewardArrays.length} camp item reward lists, and camp reward numeric fields.`
|
||||
`Verified ${dialogueEvents.length} camp dialogues, ${visitEvents.length} camp visits, ${campBattleIdEntries.length} camp battle ids, ${campaignStepReferences} campaign-step references, ${campBondReferences} camp bond references, ${itemRewardArrays.length} camp item reward lists, and camp reward numeric fields.`
|
||||
);
|
||||
} finally {
|
||||
await server.close();
|
||||
@@ -129,18 +132,41 @@ function validateCampBattleIdEntries(entries, battleScenarios) {
|
||||
});
|
||||
}
|
||||
|
||||
function collectKnownBondsById(battleScenarios) {
|
||||
function collectKnownBondsById(battleScenarios, scenarioData) {
|
||||
const bondsById = new Map();
|
||||
Object.values(battleScenarios).forEach((scenario) => {
|
||||
(scenario.bonds ?? []).forEach((bond) => {
|
||||
const addBonds = (bonds) => {
|
||||
(bonds ?? []).forEach((bond) => {
|
||||
if (!bondsById.has(bond.id)) {
|
||||
bondsById.set(bond.id, bond);
|
||||
}
|
||||
});
|
||||
};
|
||||
Object.values(battleScenarios).forEach((scenario) => {
|
||||
addBonds(scenario.bonds);
|
||||
});
|
||||
Object.values(scenarioData).forEach((value) => {
|
||||
if (isBattleBondArray(value)) {
|
||||
addBonds(value);
|
||||
}
|
||||
});
|
||||
return bondsById;
|
||||
}
|
||||
|
||||
function isBattleBondArray(value) {
|
||||
return Array.isArray(value) && value.length > 0 && value.every(isBattleBondEntry);
|
||||
}
|
||||
|
||||
function isBattleBondEntry(value) {
|
||||
return (
|
||||
value &&
|
||||
typeof value.id === 'string' &&
|
||||
Array.isArray(value.unitIds) &&
|
||||
typeof value.title === 'string' &&
|
||||
Number.isFinite(value.level) &&
|
||||
Number.isFinite(value.exp)
|
||||
);
|
||||
}
|
||||
|
||||
function collectCampEvents(text, arrayName) {
|
||||
const { body, offset } = extractConstArray(text, arrayName);
|
||||
return collectTopLevelObjects(body).map((event) => ({
|
||||
@@ -218,10 +244,10 @@ function validateAvailableDuringSteps(event, context, isCampaignStep) {
|
||||
return steps.length;
|
||||
}
|
||||
|
||||
function validateCampDialogueBondReferences(events, knownBondsById) {
|
||||
function validateCampBondReferences(events, collectionName, knownBondsById, options = {}) {
|
||||
let bondReferenceCount = 0;
|
||||
events.forEach((event, index) => {
|
||||
const context = `campDialogues[${index}]`;
|
||||
const context = `${collectionName}[${index}]`;
|
||||
const bondIdEntries = collectStringProperties(event.body, 'bondId');
|
||||
if (bondIdEntries.length === 0) {
|
||||
return;
|
||||
@@ -231,8 +257,8 @@ function validateCampDialogueBondReferences(events, knownBondsById) {
|
||||
errors.push(`${sourcePath}:${lineNumber(event.offset)} ${context} has multiple bondId properties`);
|
||||
}
|
||||
|
||||
const unitIds = collectStringArrayProperty(event.body, 'unitIds', event.offset);
|
||||
if (unitIds.length === 0) {
|
||||
const unitIds = options.matchUnitIds ? collectStringArrayProperty(event.body, 'unitIds', event.offset) : [];
|
||||
if (options.matchUnitIds && unitIds.length === 0) {
|
||||
errors.push(`${sourcePath}:${lineNumber(event.offset)} ${context} has bondId but no unitIds`);
|
||||
}
|
||||
|
||||
@@ -242,7 +268,7 @@ function validateCampDialogueBondReferences(events, knownBondsById) {
|
||||
errors.push(`${sourcePath}:${lineNumber(event.offset + entry.offset)} ${context} references unknown bondId "${entry.value}"`);
|
||||
return;
|
||||
}
|
||||
if (!sameStringSet(unitIds.map((unit) => unit.value), bond.unitIds ?? [])) {
|
||||
if (options.matchUnitIds && !sameStringSet(unitIds.map((unit) => unit.value), bond.unitIds ?? [])) {
|
||||
errors.push(
|
||||
`${sourcePath}:${lineNumber(event.offset + entry.offset)} ${context} bondId "${entry.value}" units [${(
|
||||
bond.unitIds ?? []
|
||||
|
||||
Reference in New Issue
Block a user