class GameDataManager { constructor() { this.items = new Map(); this.recipes = new Map(); this.skills = new Map(); this.dungeons = new Map(); this.hostiles = new Map(); this.rooms = new Map(); this.quests = new Map(); this.translations = {}; this.manifest = {}; this.currentLang = localStorage.getItem("selected_lang") || "en_US"; this.isLoaded = false; } initialize(data) { if (Array.isArray(data.items)) { data.items.forEach((item) => this.items.set(item.id, item)); } if (Array.isArray(data.recipes)) { data.recipes.forEach((recipe) => this.recipes.set(recipe.id, recipe)); } if (Array.isArray(data.dungeons)) { data.dungeons.forEach((d) => this.dungeons.set(d.id, d)); } if (Array.isArray(data.enemies)) { data.enemies.forEach((e) => this.hostiles.set(e.id, e)); } if (Array.isArray(data.skills)) { data.skills.forEach((s) => this.skills.set(s.id, s)); } if (Array.isArray(data.rooms)) { data.rooms.forEach((r) => this.rooms.set(r.id, r)); } if (Array.isArray(data.quests)) { data.quests.forEach((q) => this.quests.set(q.id, q)); } console.log(this.quests); if (data.languages) { this.translations = data.languages; } if (data.manifest) { this.manifest = data.manifest; } this.isLoaded = true; } t(key) { if (!key) return ""; const langData = this.translations[this.currentLang]; if (!langData) return key; if (langData[key]) return langData[key]; if (key.includes(".")) { const value = key .split(".") .reduce((obj, i) => (obj ? obj[i] : null), langData); if (value) return value; } return key; } getStatName(statPath) { const fullKey = `stats.category.original.${statPath}`; return this.t(fullKey); } _getCategoriesFromManifest(section) { if (!this.manifest[section] || !this.manifest[section].categories) return []; return Object.entries(this.manifest[section].categories).map( ([id, config]) => ({ id, displayName: this.t(config.displayName), rawConfig: config, }), ); } getRecipeCategories() { return this._getCategoriesFromManifest("recipes"); } getShopCategories() { return this._getCategoriesFromManifest("shop"); } getSkillCategories() { return this._getCategoriesFromManifest("skills"); } getRecipesByCategory(category) { return Array.from(this.recipes.values()) .filter((recipe) => recipe.type === category) .map((recipe) => this.getRecipe(recipe.id)) .filter(Boolean); } _cleanId(id) { if (!id || typeof id !== "string") return id; let clean = id.includes(":") ? id.split(":")[1] : id; if (clean.includes("/")) { const parts = clean.split("/"); clean = parts[parts.length - 1]; } return clean; } getHostile(id) { const hostile = this.hostiles.get(id); if (!hostile) { return { id: id, displayName: `Unknown Entity (${id})`, level: 1, stats: { hp: 100 }, }; } return { ...hostile, displayName: this.t(hostile.displayName), }; } getEnemy(id) { return this.getHostile(id); } getItem(id) { const item = this.items.get(id); if (!item) { return { id: id, displayName: id.replace(/_/g, " "), texture: null, description: "Data not found", meta: { rarity: "common" }, }; } return { ...item, displayName: this.t(item.displayName), description: this.t(item.description), }; } getRecipe(recipeId) { const recipe = this.recipes.get(recipeId); if (!recipe) return null; const outputData = Object.entries(recipe.output || {})[0]; const targetItemId = outputData ? outputData[0] : recipe.id; const resultItem = this.getItem(targetItemId); return { ...recipe, displayName: resultItem.displayName, texture: resultItem.texture, description: resultItem.description, ingredients: (recipe.inputs || []).map((inputObj) => { const [itemId, quantity] = Object.entries(inputObj)[0]; const itemInfo = this.getItem(itemId); return { itemId, quantity, ...itemInfo, }; }), }; } getDungeon(id) { const dungeon = this.dungeons.get(id); if (!dungeon) return null; return { ...dungeon, displayName: this.t(dungeon.displayName), description: this.t(dungeon.description), }; } getRoom(id) { const room = this.rooms.get(id); if (!room) return null; return { ...room, displayName: this.t(room.displayName), description: this.t(room.description), }; } getQuest(id) { const quest = this.quests.get(id); if (!quest) return null; return { ...quest, displayName: this.t(quest.displayName), description: this.t(quest.description), objectives: (quest.objectives || []).map((obj) => ({ ...obj, description: obj.description ? this.t(obj.description) : "", })), }; } getAllQuests() { return Array.from(this.quests.values()).map((q) => this.getQuest(q.id)); } setLanguage(langCode) { if (this.translations[langCode]) { this.currentLang = langCode; } } } const instance = new GameDataManager(); export default instance;