fix(sasch40): bald Markus portrait & scene, authentic Schankraum taproom, and cleaned up Hinterland navigation
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 581 KiB After Width: | Height: | Size: 653 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 690 KiB After Width: | Height: | Size: 356 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 798 KiB After Width: | Height: | Size: 206 KiB |
@@ -8,6 +8,15 @@ if (!fs.existsSync(SCREENSHOTS_DIR)) {
|
||||
fs.mkdirSync(SCREENSHOTS_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
async function takeScreenshot(page, filename) {
|
||||
try {
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, filename), timeout: 20000 });
|
||||
} catch (err) {
|
||||
console.warn("⚠️ Warning: Screenshot " + filename + " timed out or failed:", err.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function runPlaytest() {
|
||||
console.log('🚀 Starting Comprehensive Chrome Playtest for Saschas Kronkorken Kreuzzug...');
|
||||
|
||||
@@ -18,11 +27,11 @@ async function runPlaytest() {
|
||||
const browser = await puppeteer.launch({
|
||||
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
||||
headless: 'new',
|
||||
protocolTimeout: 60000,
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-gpu',
|
||||
'--window-size=412,869'
|
||||
]
|
||||
});
|
||||
@@ -64,7 +73,7 @@ async function runPlaytest() {
|
||||
|
||||
// 1. INTRO / PREQUEL SCREEN
|
||||
console.log('📸 01: Capturing Intro Screen...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '01_intro_screen.png') });
|
||||
await takeScreenshot(page, '01_intro_screen.png');
|
||||
|
||||
// Click Start Button
|
||||
console.log('🖱️ Clicking Start Button...');
|
||||
@@ -73,7 +82,7 @@ async function runPlaytest() {
|
||||
|
||||
// 2. PROLOGUE SCREEN (Balcony Scene)
|
||||
console.log('📸 02a: Capturing Prologue Screen (NAT opening)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '02a_prologue_nat.png') });
|
||||
await takeScreenshot(page, '02a_prologue_nat.png');
|
||||
|
||||
// Click first choice -> Flo Maier arrives
|
||||
const natChoice = await page.$('.choice-btn');
|
||||
@@ -81,7 +90,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
|
||||
console.log('📸 02b: Capturing Flo Maier Feierdeifl arrives...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '02b_prologue_flo_feierdeifl.png') });
|
||||
await takeScreenshot(page, '02b_prologue_flo_feierdeifl.png');
|
||||
|
||||
// Test Game Over branch: "Ja freilich, zünd ois o, Flo!"
|
||||
const fireChoice = await page.$('.choice-btn:nth-child(1)');
|
||||
@@ -89,25 +98,33 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
|
||||
console.log('📸 02c: Capturing Flo Maier Game Over (fiery castle)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '02c_prologue_flo_game_over.png') });
|
||||
await takeScreenshot(page, '02c_prologue_flo_game_over.png');
|
||||
|
||||
// Reset via Löschzug
|
||||
const resetFireBtn = await page.$('.game-over-btn');
|
||||
if (resetFireBtn) await resetFireBtn.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
if (resetFireBtn) {
|
||||
await resetFireBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}
|
||||
|
||||
// Skip NAT to Flo again
|
||||
await page.waitForSelector('.choice-btn', { timeout: 4000 }).catch(() => null);
|
||||
const natChoice2 = await page.$('.choice-btn');
|
||||
if (natChoice2) await natChoice2.click();
|
||||
await new Promise(r => setTimeout(r, 600));
|
||||
if (natChoice2) {
|
||||
await natChoice2.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
}
|
||||
|
||||
// Decline Flo Maier -> Viktor arrives
|
||||
await page.waitForSelector('.choice-btn:nth-child(2)', { timeout: 4000 }).catch(() => null);
|
||||
const declineFloBtn = await page.$('.choice-btn:nth-child(2)');
|
||||
if (declineFloBtn) await declineFloBtn.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
if (declineFloBtn) {
|
||||
await declineFloBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}
|
||||
|
||||
console.log('📸 02d: Capturing Viktor Partyvampir arrives...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '02d_prologue_viktor_vampire.png') });
|
||||
await takeScreenshot(page, '02d_prologue_viktor_vampire.png');
|
||||
|
||||
// Test Game Over branch: "Ja geil, mach mi unsterblich!"
|
||||
const biteChoice = await page.$('.choice-btn:nth-child(1)');
|
||||
@@ -115,26 +132,37 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
|
||||
console.log('📸 02e: Capturing Viktor Game Over (glitter dust in sun)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '02e_prologue_viktor_game_over.png') });
|
||||
await takeScreenshot(page, '02e_prologue_viktor_game_over.png');
|
||||
|
||||
// Reset via Knoblauch
|
||||
const resetVampBtn = await page.$('.game-over-btn');
|
||||
if (resetVampBtn) await resetVampBtn.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
if (resetVampBtn) {
|
||||
await resetVampBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}
|
||||
|
||||
// Advance to Mop safely: NAT -> Flo (decline) -> Viktor (decline) -> Mop
|
||||
await page.waitForSelector('.choice-btn', { timeout: 4000 }).catch(() => null);
|
||||
const natC = await page.$('.choice-btn');
|
||||
if (natC) await natC.click();
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
if (natC) {
|
||||
await natC.click();
|
||||
await new Promise(r => setTimeout(r, 600));
|
||||
}
|
||||
await page.waitForSelector('.choice-btn:nth-child(2)', { timeout: 4000 }).catch(() => null);
|
||||
const floC = await page.$('.choice-btn:nth-child(2)');
|
||||
if (floC) await floC.click();
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
if (floC) {
|
||||
await floC.click();
|
||||
await new Promise(r => setTimeout(r, 600));
|
||||
}
|
||||
await page.waitForSelector('.choice-btn:nth-child(2)', { timeout: 4000 }).catch(() => null);
|
||||
const vikC = await page.$('.choice-btn:nth-child(2)');
|
||||
if (vikC) await vikC.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
if (vikC) {
|
||||
await vikC.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
}
|
||||
|
||||
console.log('📸 02f: Capturing Mop Dialogue (Sister Rescue Quest)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '02f_prologue_mop.png') });
|
||||
await takeScreenshot(page, '02f_prologue_mop.png');
|
||||
|
||||
// Advance to Akt II (Doodle Jump Schwesternrettung)
|
||||
const startAkt2Btn = await page.$('.choice-btn');
|
||||
@@ -143,7 +171,7 @@ async function runPlaytest() {
|
||||
|
||||
// 3. AKT II: DOODLE JUMP SCHWESTERNRETTUNG
|
||||
console.log('📸 03a: Capturing Akt II Doodle Jump Start Modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '03a_doodle_jump_intro_modal.png') });
|
||||
await takeScreenshot(page, '03a_doodle_jump_intro_modal.png');
|
||||
|
||||
// Click Start Act Button on modal
|
||||
const startDoodleBtn = await page.$('.start-act-btn');
|
||||
@@ -154,7 +182,7 @@ async function runPlaytest() {
|
||||
|
||||
// Capture Gameplay (Bouncing up platforms)
|
||||
console.log('📸 03b: Capturing Doodle Jump Gameplay...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '03b_doodle_jump_gameplay.png') });
|
||||
await takeScreenshot(page, '03b_doodle_jump_gameplay.png');
|
||||
|
||||
// Trigger Sister 1 Rescue (Saskia)
|
||||
await page.evaluate(() => {
|
||||
@@ -180,7 +208,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
console.log('📸 05: Capturing Tavern Schankraum (seamless oak floor)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '05_tavern_schankraum.png') });
|
||||
await takeScreenshot(page, '05_tavern_schankraum.png');
|
||||
|
||||
// Test Double-Click / Double-Tap on Trapdoor to unlock Party Bunker
|
||||
console.log('🚪 Testing double-click / double-tap on oak floor trapdoor...');
|
||||
@@ -193,7 +221,7 @@ async function runPlaytest() {
|
||||
await trapdoor.click();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
console.log('📸 12b: Capturing Secret VIP Party Bunker...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '12b_tavern_party_bunker_vip.png') });
|
||||
await takeScreenshot(page, '12b_tavern_party_bunker_vip.png');
|
||||
|
||||
// Click Pü in Party Bunker
|
||||
const pueBtn = await page.$('.hotspot-pue');
|
||||
@@ -201,7 +229,7 @@ async function runPlaytest() {
|
||||
await pueBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 13: Capturing Pü Dialog...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '13_tavern_pue_dialog.png') });
|
||||
await takeScreenshot(page, '13_tavern_pue_dialog.png');
|
||||
const actionBtn = await page.$('.dialog-actions .action-btn');
|
||||
if (actionBtn) await actionBtn.click();
|
||||
await new Promise(r => setTimeout(r, 400));
|
||||
@@ -213,7 +241,7 @@ async function runPlaytest() {
|
||||
await backToSchankraum.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
console.log('📸 12: Capturing Schankraum with revealed Luke zum Party Bunker...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '12_tavern_party_bunker_trapdoor.png') });
|
||||
await takeScreenshot(page, '12_tavern_party_bunker_trapdoor.png');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +252,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
|
||||
console.log('📸 05b: Capturing Nebenraum (Atelier & Mirror)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '05b_tavern_nebenraum.png') });
|
||||
await takeScreenshot(page, '05b_tavern_nebenraum.png');
|
||||
|
||||
// Test Zuluman Mirror in Nebenraum
|
||||
const mirrorBtn = await page.$('.hotspot-mirror-nebenraum');
|
||||
@@ -232,7 +260,7 @@ async function runPlaytest() {
|
||||
await mirrorBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 14: Capturing Zuluman Mirror...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '14_tavern_zuluman_mirror.png') });
|
||||
await takeScreenshot(page, '14_tavern_zuluman_mirror.png');
|
||||
const closeBtn = await page.$('.mirror-box .action-btn');
|
||||
if (closeBtn) await closeBtn.click();
|
||||
await new Promise(r => setTimeout(r, 400));
|
||||
@@ -245,14 +273,14 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
|
||||
console.log('📸 08: Capturing Marktplatz...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '08_tavern_marktplatz.png') });
|
||||
await takeScreenshot(page, '08_tavern_marktplatz.png');
|
||||
|
||||
const natBtn = await page.$('.hotspot-nat');
|
||||
if (natBtn) {
|
||||
await natBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 09b: Capturing NAT Dialog...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '09b_tavern_nat_dialog.png') });
|
||||
await takeScreenshot(page, '09b_tavern_nat_dialog.png');
|
||||
|
||||
// Click "🐗 Zum Wildschwein-Duell!" -> opens INTRO MODAL
|
||||
const startBoarIntroBtn = await page.$('.dialog-actions .action-btn');
|
||||
@@ -260,7 +288,7 @@ async function runPlaytest() {
|
||||
await startBoarIntroBtn.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
console.log('📸 09c: Capturing Wildschwein Duel INTRO modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '09c_tavern_boar_duel_intro.png') });
|
||||
await takeScreenshot(page, '09c_tavern_boar_duel_intro.png');
|
||||
|
||||
// Start Duel from Intro
|
||||
const startBoarDuelBtn = await page.$('.start-duel-action-btn');
|
||||
@@ -274,7 +302,7 @@ async function runPlaytest() {
|
||||
await keilerBtn.click();
|
||||
await new Promise(r => setTimeout(r, 600));
|
||||
console.log('📸 09d: Capturing Boar Duel Round Clash (verifying unhighlighted buttons)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '09d_tavern_boar_duel_round.png') });
|
||||
await takeScreenshot(page, '09d_tavern_boar_duel_round.png');
|
||||
}
|
||||
|
||||
// Close modal via ✕
|
||||
@@ -294,7 +322,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
console.log('📸 10: Capturing Hinterland (Mane & Hansi departing toward Münchanien)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '10_tavern_hinterland.png') });
|
||||
await takeScreenshot(page, '10_tavern_hinterland.png');
|
||||
|
||||
// Click Hansi to hear about departure and evening concert
|
||||
const hansiBtn = await page.$('.hotspot-hansi');
|
||||
@@ -302,25 +330,12 @@ async function runPlaytest() {
|
||||
await hansiBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 11: Capturing Hansi Departure Dialog...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11_tavern_hansi_dialog.png') });
|
||||
await takeScreenshot(page, '11_tavern_hansi_dialog.png');
|
||||
const actionBtn = await page.$('.dialog-actions .action-btn');
|
||||
if (actionBtn) await actionBtn.click();
|
||||
await new Promise(r => setTimeout(r, 400));
|
||||
}
|
||||
|
||||
// Test Münchanien Signpost Hint Dialog
|
||||
console.log('🪧 Testing Münchanien Signpost Hint...');
|
||||
const signBtn = await page.$('.hotspot-sign-munchanien');
|
||||
if (signBtn) {
|
||||
await signBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 11b: Capturing Münchanien Signpost Hint Modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11b_tavern_munchanien_hint.png') });
|
||||
const hintCloseBtn = await page.$('.intro-modal-box .action-btn');
|
||||
if (hintCloseBtn) await hintCloseBtn.click();
|
||||
await new Promise(r => setTimeout(r, 400));
|
||||
}
|
||||
|
||||
// Test Hinter den Bergen (Taiwan Valley & Papa Markus)
|
||||
console.log('🏮 Navigating to Hinter den Bergen...');
|
||||
const hdbDoor = await page.$('.hotspot-door-hinter-den-bergen');
|
||||
@@ -333,7 +348,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
console.log('📸 11c: Capturing Hinter den Bergen Scene (Taiwan Alpine Skyline & Papa Markus)...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11c_tavern_hinter_den_bergen.png') });
|
||||
await takeScreenshot(page, '11c_tavern_hinter_den_bergen.png');
|
||||
|
||||
// Click Markus for Liar's Dice
|
||||
const markusBtn = await page.$('.hotspot-markus');
|
||||
@@ -341,7 +356,7 @@ async function runPlaytest() {
|
||||
await markusBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 11d: Capturing Papa Markus Dialog...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11d_tavern_markus_dialog.png') });
|
||||
await takeScreenshot(page, '11d_tavern_markus_dialog.png');
|
||||
|
||||
// Click "🎲 Auf geht's Papa, Liar's Dice spielen!" -> opens intro modal
|
||||
const startDiceIntroBtn = await page.$('.dialog-actions .action-btn');
|
||||
@@ -349,7 +364,7 @@ async function runPlaytest() {
|
||||
await startDiceIntroBtn.click();
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
console.log('📸 11e: Capturing Liar\'s Dice INTRO Modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11e_tavern_liars_dice_intro.png') });
|
||||
await takeScreenshot(page, '11e_tavern_liars_dice_intro.png');
|
||||
|
||||
// Start Liar's Dice Match
|
||||
const startMatchBtn = await page.$('.start-duel-action-btn');
|
||||
@@ -357,7 +372,7 @@ async function runPlaytest() {
|
||||
await startMatchBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1200));
|
||||
console.log('📸 11f: Capturing Liar\'s Dice Initial Round View...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11f_tavern_liars_dice_gameplay.png') });
|
||||
await takeScreenshot(page, '11f_tavern_liars_dice_gameplay.png');
|
||||
|
||||
// Submit player bid
|
||||
const bidBtn = await page.$('.bid-action-btn');
|
||||
@@ -365,7 +380,7 @@ async function runPlaytest() {
|
||||
await bidBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1500)); // wait for Markus response
|
||||
console.log('📸 11g: Capturing Liar\'s Dice Markus Counter-Bid...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11g_tavern_liars_dice_markus_turn.png') });
|
||||
await takeScreenshot(page, '11g_tavern_liars_dice_markus_turn.png');
|
||||
}
|
||||
|
||||
// Call bluff
|
||||
@@ -374,7 +389,7 @@ async function runPlaytest() {
|
||||
await bluffBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1200)); // wait for shot animation
|
||||
console.log('📸 11h: Capturing Liar\'s Dice Bluff Resolution & Gaoliang Shot...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '11h_tavern_liars_dice_bluff_call.png') });
|
||||
await takeScreenshot(page, '11h_tavern_liars_dice_bluff_call.png');
|
||||
}
|
||||
|
||||
// Close modal
|
||||
@@ -401,14 +416,14 @@ async function runPlaytest() {
|
||||
await duelBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 15a: Capturing Gstanzl Duel INTRO modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '15a_tavern_gstanzl_intro.png') });
|
||||
await takeScreenshot(page, '15a_tavern_gstanzl_intro.png');
|
||||
|
||||
const startGstanzlBtn = await page.$('.start-duel-action-btn');
|
||||
if (startGstanzlBtn) {
|
||||
await startGstanzlBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 15b: Capturing Gstanzl Duel Round...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '15b_tavern_gstanzl_duel.png') });
|
||||
await takeScreenshot(page, '15b_tavern_gstanzl_duel.png');
|
||||
|
||||
// Close via ✕
|
||||
const closeDuelBtn = await page.$('.duel-box .duel-close-btn');
|
||||
@@ -430,7 +445,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
console.log('📸 16: Capturing Lute Hero Start Screen Modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '16_lute_hero_start_modal.png') });
|
||||
await takeScreenshot(page, '16_lute_hero_start_modal.png');
|
||||
|
||||
// Start Concert
|
||||
const startConcertBtn = await page.$('.start-act-btn');
|
||||
@@ -452,7 +467,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 300));
|
||||
|
||||
console.log('📸 17: Capturing Castle Stage Rock Concert Gameplay...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '17_lute_hero_gameplay.png') });
|
||||
await takeScreenshot(page, '17_lute_hero_gameplay.png');
|
||||
|
||||
// 6. AKT V: FINALE & CERTIFICATE
|
||||
console.log('👑 Advancing to Finale Certificate (Act V)...');
|
||||
@@ -470,7 +485,7 @@ async function runPlaytest() {
|
||||
await new Promise(r => setTimeout(r, 1500));
|
||||
|
||||
console.log('📸 18: Capturing Certificate Screen...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '18_certificate_screen.png') });
|
||||
await takeScreenshot(page, '18_certificate_screen.png');
|
||||
|
||||
// Test Settings Modal (Gear icon ⚙️)
|
||||
console.log('⚙️ Testing Settings Modal (Pause, Mute, Reset)...');
|
||||
@@ -479,7 +494,7 @@ async function runPlaytest() {
|
||||
await settingsBtn.click();
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
console.log('📸 19: Capturing Settings & Pause Modal...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '19_settings_pause_modal.png') });
|
||||
await takeScreenshot(page, '19_settings_pause_modal.png');
|
||||
|
||||
// Click Resume
|
||||
const resumeBtn = await page.$('.resume-btn');
|
||||
@@ -496,7 +511,7 @@ async function runPlaytest() {
|
||||
await restartBtn.click();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
console.log('📸 20: Capturing post-restart Intro screen...');
|
||||
await page.screenshot({ path: path.join(SCREENSHOTS_DIR, '20_post_restart_intro.png') });
|
||||
await takeScreenshot(page, '20_post_restart_intro.png');
|
||||
}
|
||||
|
||||
// Verify all images loaded properly
|
||||
|
||||
@@ -325,12 +325,6 @@ function openCharacterDialog(charId: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Münchanien Hint Modal
|
||||
const munchanienHintActive = ref(false)
|
||||
function openMunchanienHint() {
|
||||
sound.playDialogueBlip()
|
||||
munchanienHintActive.value = true
|
||||
}
|
||||
|
||||
// Liar's Dice (Chui Niu / 吹牛) State & Logic
|
||||
const liarsDiceIntroOpen = ref(false)
|
||||
@@ -710,13 +704,7 @@ function proceedToExpress() {
|
||||
<!-- Hansi walking towards Münchanien -->
|
||||
<button class="hotspot hotspot-hansi" @click="openCharacterDialog('hansi')">
|
||||
<img :src="CHARACTERS.hansi.portrait" class="hotspot-thumb" alt="Hansi" />
|
||||
<span class="hotspot-badge">Hansi (Richtung Münchanien) 🧔</span>
|
||||
</button>
|
||||
|
||||
<!-- Signpost to Münchanien -->
|
||||
<button class="hotspot hotspot-sign-munchanien" @click="openMunchanienHint">
|
||||
<span class="sign-icon">🪧</span>
|
||||
<span class="hotspot-badge">Wegweiser: Münchanien 🏰</span>
|
||||
<span class="hotspot-badge">Hansi (Münchanien) 🧔</span>
|
||||
</button>
|
||||
|
||||
<!-- Trail to Hinter den Bergen (Taiwan & Papa Markus) -->
|
||||
@@ -1046,24 +1034,6 @@ function proceedToExpress() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Münchanien Hint Modal -->
|
||||
<div v-if="munchanienHintActive" class="dialog-overlay" @click="munchanienHintActive = false">
|
||||
<div class="dialog-box intro-modal-box" @click.stop>
|
||||
<div class="intro-modal-header">
|
||||
<span class="intro-tag">WEGWEISER NACH MÜNCHANIE</span>
|
||||
<button class="duel-close-btn" @click="munchanienHintActive = false" aria-label="Schließen">✕</button>
|
||||
</div>
|
||||
<h2 class="intro-modal-title">🏰 WEGWEISER: NACH MÜNCHANIE</h2>
|
||||
<p class="intro-modal-story">
|
||||
Auf dem geschnitzten Wegweiser steht mit Kreide geschrieben:<br><br>
|
||||
<em>„Hansi ist schon vorausgegangen, um die mächtige Sound-Anlage für das Abschiedskonzert in der Residenzstadt Münchanie aufzubauen! Bereite dich gut vor, sammle Kronkorken und Helles in allen Räumen und besuche alle Freunde, bevor du nach Akt IV aufbrichst!“</em>
|
||||
</p>
|
||||
<button class="action-btn" @click="munchanienHintActive = false">
|
||||
Verstanden! Weiter erkunden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liar's Dice Intro Modal -->
|
||||
<div v-if="liarsDiceIntroOpen" class="dialog-overlay" @click="liarsDiceIntroOpen = false">
|
||||
<div class="dialog-box intro-modal-box" @click.stop>
|
||||
@@ -1300,8 +1270,8 @@ function proceedToExpress() {
|
||||
/* Trapdoor to Party Bunker Easter Egg */
|
||||
.trapdoor-hotspot {
|
||||
position: absolute;
|
||||
top: 84%;
|
||||
left: 35%;
|
||||
top: 76%;
|
||||
left: 32%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: rgba(212, 175, 55, 0.25);
|
||||
border: 2px dashed #ffd700;
|
||||
@@ -1343,11 +1313,11 @@ function proceedToExpress() {
|
||||
}
|
||||
|
||||
/* 1. Schankraum Hotspots */
|
||||
.hotspot-verena { top: 21%; left: 28%; }
|
||||
.hotspot-door-nebenraum { top: 45%; left: 34%; }
|
||||
.hotspot-armend { top: 58%; left: 74%; }
|
||||
.hotspot-lutz { top: 56%; left: 52%; }
|
||||
.hotspot-door-marktplatz { top: 48%; left: 86%; }
|
||||
.hotspot-verena { top: 44%; left: 10%; }
|
||||
.hotspot-door-nebenraum { top: 36%; left: 54%; }
|
||||
.hotspot-armend { top: 58%; left: 22%; }
|
||||
.hotspot-lutz { top: 48%; left: 38%; }
|
||||
.hotspot-door-marktplatz { top: 90%; left: 18%; }
|
||||
|
||||
/* 2. Nebenraum Hotspots */
|
||||
.hotspot-mirror-nebenraum { top: 36%; left: 24%; }
|
||||
@@ -1417,7 +1387,7 @@ function proceedToExpress() {
|
||||
.hotspot-door-hinterland { top: 34%; left: 76%; }
|
||||
|
||||
/* 4. Hinterland Hotspots */
|
||||
.hotspot-mane { top: 52%; left: 82%; }
|
||||
.hotspot-mane { top: 56%; left: 82%; }
|
||||
.hiking-anim {
|
||||
animation: hikeBob 1.2s infinite ease-in-out;
|
||||
}
|
||||
@@ -1432,14 +1402,13 @@ function proceedToExpress() {
|
||||
transform: rotate(20deg);
|
||||
}
|
||||
|
||||
.hotspot-hansi { top: 44%; left: 63%; }
|
||||
.hotspot-sign-munchanien { top: 53%; left: 24%; }
|
||||
.hotspot-door-hinter-den-bergen { top: 42%; left: 24%; }
|
||||
.hotspot-door-back-marktplatz { top: 74%; left: 16%; }
|
||||
.hotspot-hansi { top: 48%; left: 66%; }
|
||||
.hotspot-door-hinter-den-bergen { top: 38%; left: 20%; }
|
||||
.hotspot-door-back-marktplatz { top: 80%; left: 16%; }
|
||||
|
||||
/* 5. Hinter den Bergen Hotspots */
|
||||
.hotspot-markus { top: 56%; left: 50%; }
|
||||
.hotspot-door-back-hinterland { top: 74%; left: 20%; }
|
||||
.hotspot-markus { top: 68%; left: 50%; }
|
||||
.hotspot-door-back-hinterland { top: 88%; left: 16%; }
|
||||
|
||||
/* 6. Hinterzimmer Hotspots & Strobe */
|
||||
.strobe-overlay {
|
||||
|
||||
Reference in New Issue
Block a user