Files
heros_web/src/game/state/firstPursuitScoutActions.ts

92 lines
2.3 KiB
TypeScript

import {
firstPursuitScoutSourceBattleId,
firstPursuitScoutVisitId
} from '../data/firstPursuitScoutMemory';
import {
firstPursuitScoutVisitDefinition,
getFirstPursuitScoutVisitChoice,
type FirstPursuitScoutVisitChoice
} from '../data/firstPursuitScoutVisit';
import {
applyCampVisitReward,
getCampaignState,
setCampaignState,
type CampaignState
} from './campaignState';
type FirstPursuitScoutActionFailure =
| 'invalid-campaign'
| 'invalid-choice'
| 'already-completed'
| 'save-unavailable';
export type FirstPursuitScoutActionResult =
| {
ok: true;
choice: FirstPursuitScoutVisitChoice;
campaign: CampaignState;
}
| {
ok: false;
reason: FirstPursuitScoutActionFailure;
};
export function completeFirstPursuitScoutVisit(
choiceId: string
): FirstPursuitScoutActionResult {
let campaign: CampaignState;
try {
campaign = getCampaignState();
} catch {
return { ok: false, reason: 'save-unavailable' };
}
const settlement = campaign.battleHistory[firstPursuitScoutSourceBattleId];
const report = campaign.firstBattleReport;
if (
campaign.step !== 'first-camp' ||
campaign.latestBattleId !== firstPursuitScoutSourceBattleId ||
settlement?.outcome !== 'victory' ||
report?.battleId !== firstPursuitScoutSourceBattleId ||
report.outcome !== 'victory'
) {
return { ok: false, reason: 'invalid-campaign' };
}
const choice = getFirstPursuitScoutVisitChoice(choiceId);
if (!choice) {
return { ok: false, reason: 'invalid-choice' };
}
if (campaign.completedCampVisits.includes(firstPursuitScoutVisitId)) {
return { ok: false, reason: 'already-completed' };
}
let updated: CampaignState | undefined;
try {
updated = applyCampVisitReward(
firstPursuitScoutVisitId,
{
bondId: firstPursuitScoutVisitDefinition.bondId,
bondExp: choice.bondExp,
itemRewards: [...choice.itemRewards]
},
choice.id
);
} catch {
try {
setCampaignState(campaign);
} catch {
// setCampaignState restores the in-memory snapshot before persistence.
}
return { ok: false, reason: 'save-unavailable' };
}
if (!updated) {
return { ok: false, reason: 'save-unavailable' };
}
return {
ok: true,
choice,
campaign: updated
};
}