Move all C# scripts from flat structure to organized folders: - Core/ for game logic (Game, GameState, GameSettings) - UI/Menus/ and UI/Dialogs/ for user interface - Systems/ for reusable systems (Save, Localization) - Data/ for data models and configuration - Added framework for future: Gameplay/, Story/, Modding/ Update all .tscn scene files to reference new script paths. Fix timing issue in AdvancedSaveDialog focus handling.
255 lines
9.3 KiB
C#
255 lines
9.3 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
|
|
namespace TheGame
|
|
{
|
|
public class LocalizationManager
|
|
{
|
|
private static LocalizationManager _instance;
|
|
private Dictionary<string, string> _currentTranslations;
|
|
private Dictionary<string, string> _fallbackTranslations;
|
|
private string _currentLanguage = "eng";
|
|
private readonly string _languagesPath;
|
|
|
|
public static LocalizationManager Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
_instance = new LocalizationManager();
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
private LocalizationManager()
|
|
{
|
|
// För development: använd fil-systemet
|
|
// För export: använd Godot's resource system
|
|
_languagesPath = "res://resources/languages";
|
|
|
|
// Skapa engelska som fallback om den inte finns
|
|
CreateDefaultEnglishFile();
|
|
|
|
// Ladda engelska som fallback
|
|
_fallbackTranslations = LoadLanguageFile("eng");
|
|
|
|
// Ladda nuvarande språk
|
|
_currentTranslations = _fallbackTranslations;
|
|
}
|
|
|
|
private void CreateDefaultEnglishFile()
|
|
{
|
|
// Kontrollera om engelsk fil finns i resources
|
|
if (!Godot.FileAccess.FileExists("res://resources/languages/eng.json"))
|
|
{
|
|
var defaultTranslations = new Dictionary<string, string>
|
|
{
|
|
// Main Menu
|
|
{"main_menu_title", "THE GAME"},
|
|
{"main_menu_start", "Start Game"},
|
|
{"main_menu_load", "Load Game"},
|
|
{"main_menu_settings", "Settings"},
|
|
{"main_menu_exit", "Exit"},
|
|
|
|
// Pause Menu
|
|
{"pause_menu_title", "PAUSED"},
|
|
{"pause_menu_resume", "Resume"},
|
|
{"pause_menu_save", "Save Game"},
|
|
{"pause_menu_settings", "Settings"},
|
|
{"pause_menu_main_menu", "Exit to Main Menu"},
|
|
{"pause_menu_desktop", "Exit to Desktop"},
|
|
|
|
// Load Game Menu
|
|
{"load_game_title", "LOAD GAME"},
|
|
{"load_game_back", "Back to Main Menu"},
|
|
{"load_game_no_saves", "No saved games found"},
|
|
{"load_game_playtime", "Playtime"},
|
|
{"load_game_saved", "Saved"},
|
|
|
|
// Save Dialog
|
|
{"save_dialog_title", "Save Game"},
|
|
{"save_dialog_enter_name", "Enter save name:"},
|
|
{"save_dialog_placeholder", "My Save Game"},
|
|
|
|
// Settings Menu
|
|
{"settings_title", "SETTINGS"},
|
|
{"settings_general", "General"},
|
|
{"settings_video", "Video"},
|
|
{"settings_audio", "Audio"},
|
|
{"settings_apply", "Apply"},
|
|
{"settings_cancel", "Cancel"},
|
|
{"settings_back", "Back"},
|
|
|
|
// General Settings
|
|
{"settings_language", "Language"},
|
|
|
|
// Video Settings
|
|
{"settings_fullscreen", "Fullscreen"},
|
|
|
|
// Audio Settings
|
|
{"settings_master_volume", "Master Volume"},
|
|
{"settings_background_volume", "Background Volume"},
|
|
{"settings_effects_volume", "Effects Volume"},
|
|
{"settings_radio_volume", "Radio Volume"},
|
|
|
|
// Game
|
|
{"game_content", "GAME CONTENT HERE\\nPress ESC or click pause button to pause"},
|
|
|
|
// Common
|
|
{"ok", "OK"},
|
|
{"cancel", "Cancel"},
|
|
{"yes", "Yes"},
|
|
{"no", "No"}
|
|
};
|
|
|
|
try
|
|
{
|
|
string jsonString = JsonSerializer.Serialize(defaultTranslations, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true
|
|
});
|
|
|
|
// Försök spara endast i development mode
|
|
if (OS.IsDebugBuild())
|
|
{
|
|
var file = Godot.FileAccess.Open("res://resources/languages/eng.json", Godot.FileAccess.ModeFlags.Write);
|
|
if (file != null)
|
|
{
|
|
file.StoreString(jsonString);
|
|
file.Close();
|
|
GD.Print("Created default English language file in resources");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
GD.PrintErr($"Failed to create English language file: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<string> GetAvailableLanguages()
|
|
{
|
|
var languages = new List<string>();
|
|
|
|
try
|
|
{
|
|
// Använd DirAccess för att läsa från resources
|
|
var dir = DirAccess.Open("res://resources/languages");
|
|
if (dir != null)
|
|
{
|
|
dir.ListDirBegin();
|
|
string fileName = dir.GetNext();
|
|
|
|
while (fileName != "")
|
|
{
|
|
if (!dir.CurrentIsDir() && fileName.EndsWith(".json"))
|
|
{
|
|
string languageCode = fileName.GetBaseName();
|
|
languages.Add(languageCode);
|
|
}
|
|
fileName = dir.GetNext();
|
|
}
|
|
dir.ListDirEnd();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
GD.PrintErr($"Failed to get available languages: {ex.Message}");
|
|
}
|
|
|
|
// Se till att engelska alltid finns
|
|
if (!languages.Contains("eng"))
|
|
{
|
|
languages.Add("eng");
|
|
}
|
|
|
|
GD.Print($"Available languages: {string.Join(", ", languages)}");
|
|
return languages;
|
|
}
|
|
|
|
private Dictionary<string, string> LoadLanguageFile(string languageCode)
|
|
{
|
|
var translations = new Dictionary<string, string>();
|
|
string filePath = $"res://resources/languages/{languageCode}.json";
|
|
|
|
try
|
|
{
|
|
if (Godot.FileAccess.FileExists(filePath))
|
|
{
|
|
var file = Godot.FileAccess.Open(filePath, Godot.FileAccess.ModeFlags.Read);
|
|
if (file != null)
|
|
{
|
|
string jsonString = file.GetAsText();
|
|
file.Close();
|
|
|
|
var loadedTranslations = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonString);
|
|
if (loadedTranslations != null)
|
|
{
|
|
translations = loadedTranslations;
|
|
GD.Print($"Loaded {translations.Count} translations for language: {languageCode}");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GD.Print($"Language file not found: {filePath}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
GD.PrintErr($"Failed to load language file {filePath}: {ex.Message}");
|
|
}
|
|
|
|
return translations;
|
|
}
|
|
|
|
public void SetLanguage(string languageCode)
|
|
{
|
|
if (_currentLanguage == languageCode)
|
|
return;
|
|
|
|
_currentLanguage = languageCode;
|
|
_currentTranslations = LoadLanguageFile(languageCode);
|
|
|
|
GD.Print($"Language changed to: {languageCode}");
|
|
|
|
// Skicka signal för att uppdatera alla UI-element
|
|
GetTree().CallGroup("localized_ui", "UpdateLocalization");
|
|
}
|
|
|
|
public string GetText(string key)
|
|
{
|
|
// Försök hämta från nuvarande språk
|
|
if (_currentTranslations != null && _currentTranslations.ContainsKey(key))
|
|
{
|
|
return _currentTranslations[key];
|
|
}
|
|
|
|
// Fallback till engelska
|
|
if (_fallbackTranslations != null && _fallbackTranslations.ContainsKey(key))
|
|
{
|
|
return _fallbackTranslations[key];
|
|
}
|
|
|
|
// Om inte ens engelska finns, returnera nyckeln
|
|
GD.PrintErr($"Missing translation for key: {key}");
|
|
return key;
|
|
}
|
|
|
|
public string GetCurrentLanguage()
|
|
{
|
|
return _currentLanguage;
|
|
}
|
|
|
|
private SceneTree GetTree()
|
|
{
|
|
return Engine.GetMainLoop() as SceneTree;
|
|
}
|
|
}
|
|
} |