feat: add first-victory camp exploration

This commit is contained in:
2026-07-27 09:17:09 +09:00
parent 89c755ca42
commit e9fcd27611
17 changed files with 4557 additions and 113 deletions

View File

@@ -13,6 +13,9 @@ const server = await createServer({
try {
const { battleScenarios, defaultBattleScenario } = await server.ssrLoadModule('/src/game/data/battles.ts');
const { firstPursuitScoutVisitDefinition } = await server.ssrLoadModule(
'/src/game/data/firstPursuitScoutVisit.ts'
);
const scenarioData = await server.ssrLoadModule('/src/game/data/scenario.ts');
const { isCampaignStep } = await server.ssrLoadModule('/src/game/state/campaignState.ts');
const itemRewardArrays = collectItemRewardArrays(source);
@@ -22,7 +25,12 @@ try {
validateCampBattleIdEntries(campBattleIdEntries, battleScenarios);
const knownBondsById = collectKnownBondsById(battleScenarios, scenarioData);
const dialogueEvents = collectCampEvents(source, 'campDialogues');
const visitEvents = collectCampEvents(source, 'campVisits');
const visitEvents = collectCampEvents(source, 'campVisits').map((event) =>
materializeCanonicalFirstPursuitVisit(
event,
firstPursuitScoutVisitDefinition
)
);
const campaignStepReferences =
validateCampEventCollection(dialogueEvents, 'campDialogues', campBattleIdKeys, isCampaignStep) +
validateCampEventCollection(visitEvents, 'campVisits', campBattleIdKeys, isCampaignStep);
@@ -324,6 +332,29 @@ function collectCampEvents(text, arrayName) {
}));
}
function materializeCanonicalFirstPursuitVisit(event, definition) {
if (!event.body.includes('...firstPursuitScoutVisitDefinition')) {
return event;
}
const quote = (value) => `'${String(value).replaceAll('\\', '\\\\').replaceAll("'", "\\'")}'`;
const choiceSource = definition.choices
.map(
(choice) =>
`{ id: ${quote(choice.id)}, bondExp: ${choice.bondExp}, ` +
`itemRewards: [${choice.itemRewards.map(quote).join(', ')}] }`
)
.join(', ');
const canonicalSource =
`{ id: ${quote(definition.id)}, ` +
'availableAfterBattleIds: [campBattleIds.first], ' +
`bondId: ${quote(definition.bondId)}, choices: [${choiceSource}], `;
return {
...event,
body: canonicalSource + event.body.slice(1)
};
}
function validateCampEventCollection(events, collectionName, campBattleIdKeys, isCampaignStep) {
const seenIds = new Map();
let campaignStepReferenceCount = 0;