import { autorun } from 'mobx'; import type { GameStore } from '../game/GameStore'; import type { Mounted } from './Topbar'; /** Russian plural agreement for "день" (day) after a count. */ function dayWord(n: number): string { const mod10 = n % 10; const mod100 = n % 100; if (mod10 === 1 && mod100 !== 11) return 'день'; if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) return 'дня'; return 'дней'; } /** Builds the "КРОВАВАЯ ЛУНА!" banner and the death screen, both absolutely positioned over the * game map (siblings of the Pixi canvas — see App.ts) — the DOM-side replacement for the * corresponding pieces of GameMap.tsx. Both stay hidden/empty until the store says otherwise, kept * in sync via a single mobx autorun. */ export function createGameOverlays(store: GameStore, onDeath: () => void): Mounted { const root = document.createElement('div'); root.className = 'game-overlays'; const banner = document.createElement('div'); banner.className = 'blood-moon-banner'; banner.textContent = 'КРОВАВАЯ ЛУНА!'; banner.hidden = true; const gameOver = document.createElement('div'); gameOver.className = 'game-over-overlay'; gameOver.hidden = true; const message = document.createElement('div'); message.className = 'game-over-overlay__message'; const stats = document.createElement('div'); stats.className = 'game-over-overlay__stats'; const distance = document.createElement('div'); const chopped = document.createElement('div'); const caught = document.createElement('div'); const coins = document.createElement('div'); stats.append(distance, chopped, caught, coins); const menuBtn = document.createElement('button'); menuBtn.type = 'button'; menuBtn.className = 'menu-btn'; // The whole map underneath (including this overlay) has a pointerdown handler that captures the // pointer and drives character movement — without stopping it here, that handler fires first on // bubble-up and swallows the tap before it becomes a click (see GameCanvas). menuBtn.addEventListener('pointerdown', (e) => e.stopPropagation()); menuBtn.addEventListener('click', onDeath); menuBtn.textContent = 'В меню'; gameOver.append(message, stats, menuBtn); root.append(banner, gameOver); const dispose = autorun(() => { banner.hidden = !store.bloodMoonBannerVisible; gameOver.hidden = !store.isDead; if (!store.isDead) return; message.textContent = `Вы прожили ${store.day} ${dayWord(store.day)}, но вас поймали кролики`; distance.textContent = `Пройдено: ${Math.round(store.character.distanceTraveled)} px`; chopped.textContent = `Срублено: ${store.treesChoppedCount} деревьев, ${store.bushesChoppedCount} кустов`; caught.textContent = `Поймано кроликов: ${store.rabbitsCaughtCount}`; coins.textContent = `Заработано монет: ${store.totalCoinsEarned.toFixed(1)}`; }); return { el: root, dispose }; }