Validate battle save campaign step

This commit is contained in:
2026-07-05 14:05:03 +09:00
parent 4d2a311891
commit 15df3532fb
3 changed files with 11 additions and 2 deletions

View File

@@ -44,6 +44,7 @@ try {
['invalid turnNumber', { turnNumber: 0 }], ['invalid turnNumber', { turnNumber: 0 }],
['invalid activeFaction', { activeFaction: 'neutral' }], ['invalid activeFaction', { activeFaction: 'neutral' }],
['invalid rosterTab', { rosterTab: 'neutral' }], ['invalid rosterTab', { rosterTab: 'neutral' }],
['invalid campaign step', { campaignStep: 'lost-progress' }],
['invalid actedUnitIds', { actedUnitIds: 'liu-bei' }], ['invalid actedUnitIds', { actedUnitIds: 'liu-bei' }],
['unknown acted unit id', { actedUnitIds: ['ghost-unit'] }], ['unknown acted unit id', { actedUnitIds: ['ghost-unit'] }],
['duplicate acted unit id', { actedUnitIds: ['liu-bei', 'liu-bei'] }], ['duplicate acted unit id', { actedUnitIds: ['liu-bei', 'liu-bei'] }],

View File

@@ -1,5 +1,5 @@
import type { BattleBond, UnitData } from '../data/scenario'; import type { BattleBond, UnitData } from '../data/scenario';
import type { CampaignStep } from './campaignState'; import { isCampaignStep, type CampaignStep } from './campaignState';
import type { UnitDirection } from '../data/unitAssets'; import type { UnitDirection } from '../data/unitAssets';
import { equipmentExpToNext, equipmentSlots, type EquipmentSlot } from '../data/battleItems'; import { equipmentExpToNext, equipmentSlots, type EquipmentSlot } from '../data/battleItems';
@@ -142,6 +142,10 @@ export function isValidBattleSaveState(state: unknown, options: BattleSaveValida
return false; return false;
} }
if (state.campaignStep !== undefined && !isCampaignStep(state.campaignStep)) {
return false;
}
const attackIntents = state.attackIntents; const attackIntents = state.attackIntents;
const units = state.units; const units = state.units;

View File

@@ -1237,8 +1237,12 @@ function normalizeReserveTrainingFocusId(focusId?: string): CampaignReserveTrain
: defaultCampaignReserveTrainingFocusId; : defaultCampaignReserveTrainingFocusId;
} }
export function isCampaignStep(value: unknown): value is CampaignStep {
return typeof value === 'string' && campaignStepIds.has(value as CampaignStep);
}
function normalizeCampaignStep(step: unknown): CampaignStep { function normalizeCampaignStep(step: unknown): CampaignStep {
return typeof step === 'string' && campaignStepIds.has(step as CampaignStep) ? step as CampaignStep : 'new'; return isCampaignStep(step) ? step : 'new';
} }
function normalizeFirstBattleReport(report: unknown): FirstBattleReport | undefined { function normalizeFirstBattleReport(report: unknown): FirstBattleReport | undefined {