Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/LocalizationSystem.js
2026-01-16 02:43:46 +01:00

478 lines
16 KiB
JavaScript

/**
* LOCALIZATION SYSTEM
* Multi-language support with JSON translation files
*/
class LocalizationSystem {
constructor() {
this.currentLang = 'en'; // Default language
this.translations = {};
this.supportedLanguages = ['slo', 'en', 'de', 'it', 'cn'];
// Load from localStorage
const savedLang = localStorage.getItem('novafarma_language');
if (savedLang && this.supportedLanguages.includes(savedLang)) {
this.currentLang = savedLang;
} else {
// AUTO-DETECT OS LANGUAGE (first launch)
this.currentLang = this.detectOSLanguage();
console.log(`🌍 Auto-detected language: ${this.getCurrentLanguageName()}`);
localStorage.setItem('novafarma_language', this.currentLang);
}
this.loadTranslations();
}
/**
* AUTO-DETECT OS LANGUAGE
*/
detectOSLanguage() {
// Get browser/system language
const browserLang = navigator.language || navigator.userLanguage || 'en';
const langCode = browserLang.toLowerCase().split('-')[0]; // e.g. 'en-US' → 'en'
console.log(`🖥️ System language detected: ${browserLang} (${langCode})`);
// Map to supported language
const langMap = {
'sl': 'slo', // Slovenian
'en': 'en', // English
'de': 'de', // German
'it': 'it', // Italian
'zh': 'cn', // Chinese
'cn': 'cn' // Chinese (alternative)
};
const detected = langMap[langCode] || 'en';
console.log(`✅ Mapped to game language: ${detected}`);
return detected;
}
/**
* GET CURRENT LANGUAGE NAME
*/
getCurrentLanguageName() {
return this.getLanguageName(this.currentLang);
}
loadTranslations() {
// Embedded translations (inline for simplicity)
this.translations = {
'slo': {
// UI
'ui.inventory': 'Inventar',
'ui.crafting': 'Izdelovanje',
'ui.health': 'Zdravje',
'ui.hunger': 'Lakota',
'ui.oxygen': 'Kisik',
'ui.day': 'Dan',
'ui.season': 'Letni čas',
'ui.hp': 'ZDR',
'ui.hun': 'LAK',
'ui.h2o': 'H2O',
'ui.xp': 'IZK',
'ui.lv': 'NIV',
// Items
'item.wood': 'Les',
'item.stone': 'Kamen',
'item.seeds': 'Semena',
'item.wheat': 'Pšenica',
'item.corn': 'Koruza',
// Actions
'action.plant': 'Posadi',
'action.harvest': 'Požanji',
'action.craft': 'Izdelaj',
'action.build': 'Zgradi',
// Seasons
'season.spring': 'Pomlad',
'season.summer': 'Poletje',
'season.autumn': 'Jesen',
'season.winter': 'Zima',
// Pause Menu
'pause.title': 'PAVZA',
'pause.resume': '▶ Nadaljuj',
'pause.save': '💾 Shrani igro',
'pause.settings': '⚙️ Nastavitve',
'pause.quit': '🚪 Izhod v meni',
'pause.hint': 'Pritisni ESC za nadaljevanje',
// Messages
'msg.demo_end': 'Demo končan! Hvala za igranje.',
'msg.freezing': '❄️ Zmrzuješ!',
'msg.overheating': '🔥 Pregrevanje!'
},
'en': {
// UI
'ui.inventory': 'Inventory',
'ui.crafting': 'Crafting',
'ui.health': 'Health',
'ui.hunger': 'Hunger',
'ui.oxygen': 'Oxygen',
'ui.day': 'Day',
'ui.season': 'Season',
'ui.hp': 'HP',
'ui.hun': 'HUN',
'ui.h2o': 'H2O',
'ui.xp': 'XP',
'ui.lv': 'LV',
// Items
'item.wood': 'Wood',
'item.stone': 'Stone',
'item.seeds': 'Seeds',
'item.wheat': 'Wheat',
'item.corn': 'Corn',
// Actions
'action.plant': 'Plant',
'action.harvest': 'Harvest',
'action.craft': 'Craft',
'action.build': 'Build',
// Seasons
'season.spring': 'Spring',
'season.summer': 'Summer',
'season.autumn': 'Autumn',
'season.winter': 'Winter',
// Pause Menu
'pause.title': 'PAUSED',
'pause.resume': '▶ Resume',
'pause.save': '💾 Save Game',
'pause.settings': '⚙️ Settings',
'pause.quit': '🚪 Quit to Menu',
'pause.hint': 'Press ESC to resume',
// Messages
'msg.demo_end': 'Demo Ended! Thanks for playing.',
'msg.freezing': '❄️ Freezing!',
'msg.overheating': '🔥 Overheating!'
},
'de': {
// UI
'ui.inventory': 'Inventar',
'ui.crafting': 'Handwerk',
'ui.health': 'Gesundheit',
'ui.hunger': 'Hunger',
'ui.oxygen': 'Sauerstoff',
'ui.day': 'Tag',
'ui.season': 'Jahreszeit',
'ui.hp': 'LP',
'ui.hun': 'HUN',
'ui.h2o': 'H2O',
'ui.xp': 'EP',
'ui.lv': 'ST',
// Items
'item.wood': 'Holz',
'item.stone': 'Stein',
'item.seeds': 'Samen',
'item.wheat': 'Weizen',
'item.corn': 'Mais',
// Actions
'action.plant': 'Pflanzen',
'action.harvest': 'Ernten',
'action.craft': 'Herstellen',
'action.build': 'Bauen',
// Seasons
'season.spring': 'Frühling',
'season.summer': 'Sommer',
'season.autumn': 'Herbst',
'season.winter': 'Winter',
// Pause Menu
'pause.title': 'PAUSIERT',
'pause.resume': '▶ Fortsetzen',
'pause.save': '💾 Spiel speichern',
'pause.settings': '⚙️ Einstellungen',
'pause.quit': '🚪 Zum Menü',
'pause.hint': 'ESC drücken zum Fortsetzen',
// Messages
'msg.demo_end': 'Demo beendet! Danke fürs Spielen.',
'msg.freezing': '❄️ Du erfrierst!',
'msg.overheating': '🔥 Überhitzung!'
},
'it': {
// UI
'ui.inventory': 'Inventario',
'ui.crafting': 'Artigianato',
'ui.health': 'Salute',
'ui.hunger': 'Fame',
'ui.oxygen': 'Ossigeno',
'ui.day': 'Giorno',
'ui.season': 'Stagione',
'ui.hp': 'PS',
'ui.hun': 'FAM',
'ui.h2o': 'H2O',
'ui.xp': 'ESP',
'ui.lv': 'LIV',
// Items
'item.wood': 'Legno',
'item.stone': 'Pietra',
'item.seeds': 'Semi',
'item.wheat': 'Grano',
'item.corn': 'Mais',
// Actions
'action.plant': 'Pianta',
'action.harvest': 'Raccogli',
'action.craft': 'Crea',
'action.build': 'Costruisci',
// Seasons
'season.spring': 'Primavera',
'season.summer': 'Estate',
'season.autumn': 'Autunno',
'season.winter': 'Inverno',
// Pause Menu
'pause.title': 'IN PAUSA',
'pause.resume': '▶ Riprendi',
'pause.save': '💾 Salva gioco',
'pause.settings': '⚙️ Impostazioni',
'pause.quit': '🚪 Esci al menu',
'pause.hint': 'Premi ESC per riprendere',
// Messages
'msg.demo_end': 'Demo terminata! Grazie per aver giocato.',
'msg.freezing': '❄️ Stai congelando!',
'msg.overheating': '🔥 Surriscaldamento!'
},
'cn': {
// UI
'ui.inventory': '库存',
'ui.crafting': '制作',
'ui.health': '健康',
'ui.hunger': '饥饿',
'ui.oxygen': '氧气',
'ui.day': '天数',
'ui.season': '季节',
'ui.hp': '生命',
'ui.hun': '饥饿',
'ui.h2o': '水',
'ui.xp': '经验',
'ui.lv': '等级',
// Items
'item.wood': '木材',
'item.stone': '石头',
'item.seeds': '种子',
'item.wheat': '小麦',
'item.corn': '玉米',
// Actions
'action.plant': '种植',
'action.harvest': '收获',
'action.craft': '制作',
'action.build': '建造',
// Seasons
'season.spring': '春天',
'season.summer': '夏天',
'season.autumn': '秋天',
'season.winter': '冬天',
// Pause Menu
'pause.title': '暂停',
'pause.resume': '▶ 继续',
'pause.save': '💾 保存游戏',
'pause.settings': '⚙️ 设置',
'pause.quit': '🚪 退出到菜单',
'pause.hint': '按ESC继续',
// Messages
'msg.demo_end': '演示结束!感谢游玩。',
'msg.freezing': '❄️ 你在冻僵!',
'msg.overheating': '🔥 过热!'
}
};
}
/**
* Get translated string
* @param {string} key - Translation key (e.g. 'ui.inventory')
* @param {string} fallback - Fallback text if translation missing
*/
t(key, fallback = key) {
const lang = this.translations[this.currentLang];
if (lang && lang[key]) {
return lang[key];
}
// Fallback to English
const enLang = this.translations['en'];
if (enLang && enLang[key]) {
return enLang[key];
}
return fallback;
}
/**
* LOAD INTRO TEXTS FROM JSON
*/
async loadIntroTexts() {
try {
const response = await fetch('assets/localization.json');
const data = await response.json();
// Merge intro texts into translations
for (const lang in data) {
if (!this.translations[lang]) {
this.translations[lang] = {};
}
// Add intro polaroid texts
if (data[lang].intro_polaroids) {
this.translations[lang].intro_polaroids = data[lang].intro_polaroids;
}
// Add menu texts
if (data[lang].menu) {
Object.assign(this.translations[lang], data[lang].menu);
}
// Add title/subtitle
if (data[lang].game_title) {
this.translations[lang].game_title = data[lang].game_title;
}
if (data[lang].subtitle) {
this.translations[lang].subtitle = data[lang].subtitle;
}
}
console.log('✅ Intro texts loaded from JSON');
return true;
} catch (error) {
console.warn('⚠️ Could not load localization.json:', error);
return false;
}
}
/**
* GET INTRO POLAROID TEXT
*/
getIntroText(polaroidKey) {
const lang = this.translations[this.currentLang];
if (lang && lang.intro_polaroids && lang.intro_polaroids[polaroidKey]) {
return lang.intro_polaroids[polaroidKey];
}
// Fallback to English
const enLang = this.translations['en'];
if (enLang && enLang.intro_polaroids && enLang.intro_polaroids[polaroidKey]) {
return enLang.intro_polaroids[polaroidKey];
}
return polaroidKey; // Return key if not found
}
/**
* GET VOICE FILE PATH (switches language folder)
*/
getVoicePath(character, index, format = 'mp3') {
const langSuffix = this.currentLang === 'en' ? 'en' : 'sl';
// Map language codes to voice folders
if (this.currentLang === 'slo') {
// Slovenian voices in /sl/ folder
return `assets/audio/voiceover/sl/${character}_${String(index).padStart(2, '0')}.${format}`;
} else {
// English voices (default for DE, IT, CN too)
return `assets/audio/voiceover/en/${character}_en_${String(index).padStart(2, '0')}.${format}`;
}
}
/**
* CHECK IF VOICE FILE EXISTS FOR CURRENT LANGUAGE
*/
hasVoiceForLanguage(character, index) {
// Slovenian and English have full voiceovers
// Other languages fall back to English
return this.currentLang === 'slo' || this.currentLang === 'en';
}
/**
* Set current language
*/
setLanguage(langCode) {
if (this.supportedLanguages.includes(langCode)) {
this.currentLang = langCode;
localStorage.setItem('novafarma_language', langCode);
console.log(`🌍 Language changed to: ${langCode}`);
return true;
}
return false;
}
getCurrentLanguage() {
return this.currentLang;
}
getSupportedLanguages() {
return this.supportedLanguages.map(code => ({
code,
name: this.getLanguageName(code)
}));
}
getLanguageName(code) {
const names = {
'slo': 'Slovenščina',
'en': 'English',
'de': 'Deutsch',
'it': 'Italiano',
'cn': '中文'
};
return names[code] || code;
}
/**
* INJECT EXTERNAL JSON DATA (loaded via Phaser)
*/
setExternalData(data) {
try {
// Merge intro texts into translations
for (const lang in data) {
if (!this.translations[lang]) {
this.translations[lang] = {};
}
// Add intro polaroid texts
if (data[lang].intro_polaroids) {
this.translations[lang].intro_polaroids = data[lang].intro_polaroids;
}
// Add menu texts
if (data[lang].menu) {
Object.assign(this.translations[lang], data[lang].menu);
}
// Add title/subtitle
if (data[lang].game_title) {
this.translations[lang].game_title = data[lang].game_title;
}
if (data[lang].subtitle) {
this.translations[lang].subtitle = data[lang].subtitle;
}
}
console.log('✅ Localization data injected successfully');
return true;
} catch (error) {
console.warn('⚠️ Could not inject localization data:', error);
return false;
}
}
}
// Global instance
window.LocalizationSystem = LocalizationSystem;