226 lines
5.4 KiB
JavaScript
226 lines
5.4 KiB
JavaScript
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;
|