feat: refine exploration presentation and audio flow

This commit is contained in:
2026-07-28 05:00:24 +09:00
parent 1773bffbf2
commit 495f98372c
20 changed files with 2295 additions and 354 deletions

View File

@@ -533,6 +533,13 @@ function verifyExplorationLayout(city, expectedCityStayId) {
assert.equal(city.progress.marketOptional, true);
assert.equal(city.progress.exitUnlocked, true);
assert.equal(city.actors.length, 3);
const companion = city.actors.find((actor) => actor.kind === 'dialogue');
assert(companion, `${expectedCityStayId} must expose its companion actor.`);
assert.equal(
city.objective?.dialogueUnitNames,
`유비 · ${companion.name}`,
`${expectedCityStayId} objective card must use authored Korean character names instead of roster or unit IDs.`
);
assert.deepEqual(
[...city.actors.map((actor) => actor.kind)].sort(),
['dialogue', 'information', 'market']
@@ -824,10 +831,18 @@ async function verifyCompanionResonance(page, cityCase, screenshotPath) {
await page.waitForFunction(() => (
window.__HEROS_DEBUG__?.cityStay?.()?.dialogue?.active === true
));
const initialDialogueState = await readCity(page);
verifyActiveDialoguePortrait(
await readCity(page),
initialDialogueState,
`${cityCase.cityStayId} companion dialogue`
);
const initialCompanionFacing = initialDialogueState.actors.find(
(actor) => actor.kind === 'dialogue'
)?.animationKey;
assert(
initialCompanionFacing,
`${cityCase.cityStayId} companion must expose its facing animation during dialogue.`
);
await advanceDialogueUntilChoice(page);
const choiceState = await readCity(page);
verifyChoiceLayout(choiceState);
@@ -849,6 +864,21 @@ async function verifyCompanionResonance(page, cityCase, screenshotPath) {
});
const afterChoice = await readCity(page);
assert.equal(
afterChoice.dialogue.active,
true,
'Selecting a resonance response must open its acknowledgement dialogue.'
);
assert.equal(
afterChoice.dialogue.lineIndex,
0,
'The pointer event that selects a response must not also skip the first acknowledgement line.'
);
assert.equal(
afterChoice.actors.find((actor) => actor.kind === 'dialogue')?.animationKey,
initialCompanionFacing,
'The companion must turn back toward the player for the acknowledgement dialogue.'
);
assert.equal(
afterChoice.campaign.completedCampDialogues.filter((id) => id === cityCase.dialogueId).length,
1,