feat: carry third-camp preparation into battle
This commit is contained in:
@@ -10,6 +10,12 @@ try {
|
||||
const { isValidBattleSaveState, normalizeBattleSaveSlot, normalizeBattleSaveState, parseBattleSaveState } = await server.ssrLoadModule(
|
||||
'/src/game/state/battleSaveState.ts'
|
||||
);
|
||||
const {
|
||||
getThirdCampPreparationPriority,
|
||||
thirdCampPreparationInformationEnemyUnitId,
|
||||
thirdCampPreparationSelectionRecordId,
|
||||
thirdCampPreparationTargetBattleId
|
||||
} = await server.ssrLoadModule('/src/game/data/thirdCampPreparation.ts');
|
||||
|
||||
const options = {
|
||||
expectedBattleId: 'first-battle-zhuo-commandery',
|
||||
@@ -210,6 +216,196 @@ try {
|
||||
}, options),
|
||||
'Expected direct validation to reject unsafe core resonance totals before normalization.'
|
||||
);
|
||||
const fourthBattleOptions = {
|
||||
...options,
|
||||
expectedBattleId: thirdCampPreparationTargetBattleId
|
||||
};
|
||||
const fourthBattleBaseState = {
|
||||
...validState,
|
||||
battleId: thirdCampPreparationTargetBattleId,
|
||||
campaignStep: 'fourth-battle',
|
||||
enemyUsableUseKeys: []
|
||||
};
|
||||
const thirdPreparationLabels = Object.fromEntries(
|
||||
['information', 'equipment', 'companion'].map((priorityId) => [
|
||||
priorityId,
|
||||
getThirdCampPreparationPriority(priorityId)?.label
|
||||
])
|
||||
);
|
||||
const validThirdPreparationStates = [
|
||||
{
|
||||
selectionRecordId: thirdCampPreparationSelectionRecordId,
|
||||
priorityId: 'information',
|
||||
label: thirdPreparationLabels.information,
|
||||
markedEnemyUnitId: thirdCampPreparationInformationEnemyUnitId,
|
||||
informationConsumed: true,
|
||||
equipmentConsumed: false,
|
||||
companionAttempts: 0,
|
||||
companionSuccesses: 0,
|
||||
usageCount: 1,
|
||||
preventedDamage: 0
|
||||
},
|
||||
{
|
||||
selectionRecordId: thirdCampPreparationSelectionRecordId,
|
||||
priorityId: 'equipment',
|
||||
label: thirdPreparationLabels.equipment,
|
||||
informationConsumed: false,
|
||||
equipmentConsumed: true,
|
||||
companionAttempts: 0,
|
||||
companionSuccesses: 0,
|
||||
usageCount: 1,
|
||||
preventedDamage: 8
|
||||
},
|
||||
{
|
||||
selectionRecordId: thirdCampPreparationSelectionRecordId,
|
||||
priorityId: 'companion',
|
||||
label: thirdPreparationLabels.companion,
|
||||
informationConsumed: false,
|
||||
equipmentConsumed: false,
|
||||
companionAttempts: 3,
|
||||
companionSuccesses: 2,
|
||||
usageCount: 3,
|
||||
preventedDamage: 0
|
||||
}
|
||||
];
|
||||
validThirdPreparationStates.forEach((thirdCampPreparation) => {
|
||||
const state = { ...fourthBattleBaseState, thirdCampPreparation };
|
||||
const parsed = parseBattleSaveState(JSON.stringify(state), fourthBattleOptions);
|
||||
assert(
|
||||
isValidBattleSaveState(state, fourthBattleOptions) &&
|
||||
JSON.stringify(parsed?.thirdCampPreparation) === JSON.stringify(thirdCampPreparation) &&
|
||||
parsed?.thirdCampPreparation !== thirdCampPreparation,
|
||||
`Expected ${thirdCampPreparation.priorityId} preparation progress to round-trip as a deep-cloned save field.`
|
||||
);
|
||||
});
|
||||
|
||||
const normalizedWrongBattlePreparation = parseBattleSaveState(JSON.stringify({
|
||||
...validState,
|
||||
thirdCampPreparation: validThirdPreparationStates[0]
|
||||
}), options);
|
||||
assert(
|
||||
normalizedWrongBattlePreparation &&
|
||||
normalizedWrongBattlePreparation.thirdCampPreparation === undefined &&
|
||||
!isValidBattleSaveState(
|
||||
{ ...validState, thirdCampPreparation: validThirdPreparationStates[0] },
|
||||
options
|
||||
),
|
||||
'Expected preparation progress attached to a different battle to be discarded and rejected by direct validation.'
|
||||
);
|
||||
const normalizedUnknownPreparationPriority = parseBattleSaveState(JSON.stringify({
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: {
|
||||
...validThirdPreparationStates[0],
|
||||
priorityId: 'unknown-priority'
|
||||
}
|
||||
}), fourthBattleOptions);
|
||||
const normalizedWrongPreparationRecord = parseBattleSaveState(JSON.stringify({
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: {
|
||||
...validThirdPreparationStates[0],
|
||||
selectionRecordId: 'forged-preparation-record'
|
||||
}
|
||||
}), fourthBattleOptions);
|
||||
assert(
|
||||
normalizedUnknownPreparationPriority?.thirdCampPreparation === undefined &&
|
||||
normalizedWrongPreparationRecord?.thirdCampPreparation === undefined,
|
||||
'Expected unknown priorities and forged preparation record ids to be removed without rejecting the battle save.'
|
||||
);
|
||||
|
||||
const normalizedInformationPreparation = parseBattleSaveState(JSON.stringify({
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: {
|
||||
...validThirdPreparationStates[0],
|
||||
label: 'forged-label',
|
||||
markedEnemyUnitId: 'forged-vanguard',
|
||||
informationConsumed: false,
|
||||
equipmentConsumed: true,
|
||||
companionAttempts: 7,
|
||||
companionSuccesses: 6,
|
||||
usageCount: 999,
|
||||
preventedDamage: 90
|
||||
}
|
||||
}), fourthBattleOptions)?.thirdCampPreparation;
|
||||
assert(
|
||||
normalizedInformationPreparation?.label === thirdPreparationLabels.information &&
|
||||
normalizedInformationPreparation.markedEnemyUnitId === thirdCampPreparationInformationEnemyUnitId &&
|
||||
normalizedInformationPreparation.informationConsumed === false &&
|
||||
normalizedInformationPreparation.equipmentConsumed === false &&
|
||||
normalizedInformationPreparation.companionAttempts === 0 &&
|
||||
normalizedInformationPreparation.companionSuccesses === 0 &&
|
||||
normalizedInformationPreparation.usageCount === 0 &&
|
||||
normalizedInformationPreparation.preventedDamage === 0,
|
||||
`Expected information preparation to restore the canonical mark and derive its unconsumed state: ${JSON.stringify(normalizedInformationPreparation)}`
|
||||
);
|
||||
|
||||
const normalizedUnusedEquipmentPreparation = parseBattleSaveState(JSON.stringify({
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: {
|
||||
...validThirdPreparationStates[1],
|
||||
markedEnemyUnitId: thirdCampPreparationInformationEnemyUnitId,
|
||||
equipmentConsumed: false,
|
||||
usageCount: 55,
|
||||
preventedDamage: 55
|
||||
}
|
||||
}), fourthBattleOptions)?.thirdCampPreparation;
|
||||
const normalizedConsumedEquipmentPreparation = parseBattleSaveState(JSON.stringify({
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: {
|
||||
...validThirdPreparationStates[1],
|
||||
markedEnemyUnitId: thirdCampPreparationInformationEnemyUnitId,
|
||||
usageCount: 0,
|
||||
preventedDamage: Number.MAX_SAFE_INTEGER
|
||||
}
|
||||
}), fourthBattleOptions)?.thirdCampPreparation;
|
||||
assert(
|
||||
normalizedUnusedEquipmentPreparation?.markedEnemyUnitId === undefined &&
|
||||
normalizedUnusedEquipmentPreparation?.equipmentConsumed === false &&
|
||||
normalizedUnusedEquipmentPreparation?.usageCount === 0 &&
|
||||
normalizedUnusedEquipmentPreparation?.preventedDamage === 0 &&
|
||||
normalizedConsumedEquipmentPreparation?.markedEnemyUnitId === undefined &&
|
||||
normalizedConsumedEquipmentPreparation?.equipmentConsumed === true &&
|
||||
normalizedConsumedEquipmentPreparation?.usageCount === 1 &&
|
||||
normalizedConsumedEquipmentPreparation?.preventedDamage === 999999,
|
||||
'Expected equipment preparation to remove unrelated marks, derive consumption count, and clamp prevented damage.'
|
||||
);
|
||||
|
||||
const normalizedOversizedCompanionPreparation = parseBattleSaveState(JSON.stringify({
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: {
|
||||
...validThirdPreparationStates[2],
|
||||
markedEnemyUnitId: thirdCampPreparationInformationEnemyUnitId,
|
||||
informationConsumed: true,
|
||||
equipmentConsumed: true,
|
||||
companionAttempts: Number.MAX_SAFE_INTEGER,
|
||||
companionSuccesses: Number.MAX_SAFE_INTEGER,
|
||||
usageCount: 1,
|
||||
preventedDamage: 1234
|
||||
}
|
||||
}), fourthBattleOptions)?.thirdCampPreparation;
|
||||
assert(
|
||||
normalizedOversizedCompanionPreparation?.markedEnemyUnitId === undefined &&
|
||||
normalizedOversizedCompanionPreparation?.informationConsumed === false &&
|
||||
normalizedOversizedCompanionPreparation?.equipmentConsumed === false &&
|
||||
normalizedOversizedCompanionPreparation?.companionAttempts === 999999 &&
|
||||
normalizedOversizedCompanionPreparation?.companionSuccesses === 999999 &&
|
||||
normalizedOversizedCompanionPreparation?.usageCount === 999999 &&
|
||||
normalizedOversizedCompanionPreparation?.preventedDamage === 0,
|
||||
`Expected companion preparation counters to clamp and unrelated consumption fields to clear: ${JSON.stringify(normalizedOversizedCompanionPreparation)}`
|
||||
);
|
||||
|
||||
const { thirdCampPreparation: _legacyPreparation, ...legacyFourthBattleState } = {
|
||||
...fourthBattleBaseState,
|
||||
thirdCampPreparation: validThirdPreparationStates[0]
|
||||
};
|
||||
const parsedLegacyFourthBattleState = parseBattleSaveState(
|
||||
JSON.stringify(legacyFourthBattleState),
|
||||
fourthBattleOptions
|
||||
);
|
||||
assert(
|
||||
isValidBattleSaveState(legacyFourthBattleState, fourthBattleOptions) &&
|
||||
parsedLegacyFourthBattleState?.thirdCampPreparation === undefined,
|
||||
'Expected legacy fourth-battle saves without preparation progress to remain valid.'
|
||||
);
|
||||
const validSortieStatsState = {
|
||||
...validState,
|
||||
battleStats: {
|
||||
|
||||
Reference in New Issue
Block a user