Validate camp campaign step references
This commit is contained in:
@@ -13,6 +13,7 @@ const server = await createServer({
|
||||
|
||||
try {
|
||||
const { battleScenarios, defaultBattleScenario } = await server.ssrLoadModule('/src/game/data/battles.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);
|
||||
@@ -20,8 +21,9 @@ try {
|
||||
validateCampBattleIdEntries(campBattleIdEntries, battleScenarios);
|
||||
const dialogueEvents = collectCampEvents(source, 'campDialogues');
|
||||
const visitEvents = collectCampEvents(source, 'campVisits');
|
||||
validateCampEventCollection(dialogueEvents, 'campDialogues', campBattleIdKeys);
|
||||
validateCampEventCollection(visitEvents, 'campVisits', campBattleIdKeys);
|
||||
const campaignStepReferences =
|
||||
validateCampEventCollection(dialogueEvents, 'campDialogues', campBattleIdKeys, isCampaignStep) +
|
||||
validateCampEventCollection(visitEvents, 'campVisits', campBattleIdKeys, isCampaignStep);
|
||||
validateNumericProperties('gold', { min: 1, max: 20000 });
|
||||
validateNumericProperties('bondExp', { min: 0, max: 200 });
|
||||
validateNumericProperties('rewardExp', { min: 1, max: 200 });
|
||||
@@ -31,7 +33,7 @@ try {
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Verified ${dialogueEvents.length} camp dialogues, ${visitEvents.length} camp visits, ${campBattleIdEntries.length} camp battle ids, ${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, ${itemRewardArrays.length} camp item reward lists, and camp reward numeric fields.`
|
||||
);
|
||||
} finally {
|
||||
await server.close();
|
||||
@@ -133,8 +135,9 @@ function collectCampEvents(text, arrayName) {
|
||||
}));
|
||||
}
|
||||
|
||||
function validateCampEventCollection(events, collectionName, campBattleIdKeys) {
|
||||
function validateCampEventCollection(events, collectionName, campBattleIdKeys, isCampaignStep) {
|
||||
const seenIds = new Map();
|
||||
let campaignStepReferenceCount = 0;
|
||||
if (events.length === 0) {
|
||||
errors.push(`${sourcePath}: ${collectionName} has no entries`);
|
||||
}
|
||||
@@ -176,7 +179,29 @@ function validateCampEventCollection(events, collectionName, campBattleIdKeys) {
|
||||
errors.push(`${sourcePath}:${lineNumber(event.offset)} ${context} references unknown campBattleIds.${reference[1]}`);
|
||||
}
|
||||
}
|
||||
campaignStepReferenceCount += validateAvailableDuringSteps(event, context, isCampaignStep);
|
||||
});
|
||||
return campaignStepReferenceCount;
|
||||
}
|
||||
|
||||
function validateAvailableDuringSteps(event, context, isCampaignStep) {
|
||||
const availableDuringMatch = /availableDuringSteps:\s*\[([\s\S]*?)\]/.exec(event.body);
|
||||
if (!availableDuringMatch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const body = availableDuringMatch[1];
|
||||
const bodyOffset = event.offset + (availableDuringMatch.index ?? 0) + availableDuringMatch[0].indexOf(body);
|
||||
const steps = collectStringLiterals(body, bodyOffset);
|
||||
if (steps.length === 0) {
|
||||
errors.push(`${sourcePath}:${lineNumber(bodyOffset)} ${context} has an empty availableDuringSteps list`);
|
||||
}
|
||||
steps.forEach((step) => {
|
||||
if (!isCampaignStep(step.value)) {
|
||||
errors.push(`${sourcePath}:${lineNumber(step.offset)} ${context} references unknown campaign step "${step.value}"`);
|
||||
}
|
||||
});
|
||||
return steps.length;
|
||||
}
|
||||
|
||||
function collectStringProperties(text, propertyName) {
|
||||
@@ -187,6 +212,13 @@ function collectStringProperties(text, propertyName) {
|
||||
}));
|
||||
}
|
||||
|
||||
function collectStringLiterals(text, offset = 0) {
|
||||
return [...text.matchAll(/'((?:\\'|[^'])*)'/g)].map((match) => ({
|
||||
value: match[1].replace(/\\'/g, "'"),
|
||||
offset: offset + (match.index ?? 0)
|
||||
}));
|
||||
}
|
||||
|
||||
function parseRewardLabel(reward) {
|
||||
const normalized = String(reward).replace(/\s+/g, ' ').trim();
|
||||
const match = normalized.match(/^(.*?)(?:\s*[+xX]?\s*(\d+))$/);
|
||||
|
||||
Reference in New Issue
Block a user