Validate campaign save steps

This commit is contained in:
2026-07-05 09:13:10 +09:00
parent 70933a7f51
commit d513aec22c
2 changed files with 33 additions and 1 deletions

View File

@@ -388,6 +388,18 @@ const campaignBattleSteps: Record<string, { victory: CampaignStep; retry: Campai
'sixty-sixth-battle-wuzhang-final': { victory: 'sixty-sixth-camp', retry: 'sixty-sixth-battle' }
};
const campaignStepIds = new Set<CampaignStep>([
'new',
'prologue',
'first-victory-story',
'ending-complete',
'hanzhong-king-camp',
'shu-han-foundation-camp',
'baidi-entrustment-camp',
'northern-campaign-prep-camp',
...Object.values(campaignBattleSteps).flatMap(({ victory, retry }) => [victory, retry])
]);
export type CampaignSaveSlotSummary = {
slot: number;
exists: boolean;
@@ -787,6 +799,7 @@ function normalizeCampaignState(state: Partial<CampaignState>): CampaignState {
};
normalized.version = 1;
normalized.updatedAt = typeof normalized.updatedAt === 'string' && normalized.updatedAt ? normalized.updatedAt : new Date().toISOString();
normalized.step = normalizeCampaignStep(normalized.step);
normalized.activeSaveSlot = normalizeSlot(normalized.activeSaveSlot);
normalized.gold = normalizeNonNegativeInteger(normalized.gold);
normalized.roster = arrayOrEmpty<UnitData>(normalized.roster).map(cloneUnit);
@@ -861,6 +874,10 @@ function normalizeReserveTrainingFocusId(focusId?: string): CampaignReserveTrain
: defaultCampaignReserveTrainingFocusId;
}
function normalizeCampaignStep(step: unknown): CampaignStep {
return typeof step === 'string' && campaignStepIds.has(step as CampaignStep) ? step as CampaignStep : 'new';
}
function reserveTrainingFocusDefinition(focusId?: string) {
const normalizedId = normalizeReserveTrainingFocusId(focusId);
return campaignReserveTrainingFocusDefinitions.find((focus) => focus.id === normalizedId) ?? campaignReserveTrainingFocusDefinitions[0];