127 lines
4.3 KiB
JavaScript
127 lines
4.3 KiB
JavaScript
// Rôle : charge et normalise les données publiques des jeux.
|
|
export const INITIAL_MHWILDS_STATE = {
|
|
loaded: false,
|
|
loading: false,
|
|
error: "",
|
|
translations: {},
|
|
monsters: [],
|
|
endemic: [],
|
|
lists: [],
|
|
filterOptions: { monsters: [], endemic: [] },
|
|
filterOptionKeys: { monsters: "", endemic: "" }
|
|
};
|
|
|
|
export const INITIAL_DIABLO4_STATE = {
|
|
loaded: false,
|
|
loading: false,
|
|
error: "",
|
|
affixes: [],
|
|
filterOptions: { affixes: [] },
|
|
categoryMap: {},
|
|
filterOptionKeys: { affixes: "" }
|
|
};
|
|
|
|
export async function loadMhwildsData() {
|
|
const [monstersResponse, endemicResponse, listIndexResponse, translationsResponse] = await Promise.all([
|
|
fetch("/data/mhwilds/monsters.json"),
|
|
fetch("/data/mhwilds/endemic_life.json"),
|
|
fetch("/data/mhwilds/lists/index.json"),
|
|
fetch("/data/mhwilds/i18n/fr.json")
|
|
]);
|
|
|
|
if (!monstersResponse.ok || !endemicResponse.ok || !listIndexResponse.ok || !translationsResponse.ok) {
|
|
throw new Error("Impossible de charger les données Monster Hunter Wilds.");
|
|
}
|
|
|
|
const [monstersJson, endemicJson, listIndexJson, translations] = await Promise.all([
|
|
monstersResponse.json(),
|
|
endemicResponse.json(),
|
|
listIndexResponse.json(),
|
|
translationsResponse.json()
|
|
]);
|
|
const lists = await loadGameLists("mhwilds", listIndexJson);
|
|
const monsterFilterKey = Object.keys(monstersJson).find((key) => key !== "monsters") || "";
|
|
const endemicFilterKey = Object.keys(endemicJson).find((key) => key !== "endemicLife" && key !== "aquaticLife") || "";
|
|
|
|
return {
|
|
loaded: true,
|
|
loading: false,
|
|
error: "",
|
|
translations,
|
|
monsters: monstersJson.monsters || [],
|
|
endemic: [...(endemicJson.endemicLife || []), ...(endemicJson.aquaticLife || [])],
|
|
lists,
|
|
filterOptions: {
|
|
monsters: monstersJson[monsterFilterKey] || [],
|
|
endemic: endemicJson[endemicFilterKey] || []
|
|
},
|
|
filterOptionKeys: {
|
|
monsters: monsterFilterKey,
|
|
endemic: endemicFilterKey
|
|
}
|
|
};
|
|
}
|
|
|
|
async function loadGameLists(gameId, indexPayload) {
|
|
const entries = Array.isArray(indexPayload?.lists) ? indexPayload.lists : [];
|
|
const results = await Promise.all(entries.map(async (entry) => {
|
|
const response = await fetch(`/data/${gameId}/lists/${entry.file}`);
|
|
if (!response.ok) throw new Error(`Impossible de charger la liste ${entry.file}.`);
|
|
const payload = await response.json();
|
|
return normalizeGameListFile(entry, payload);
|
|
}));
|
|
return results;
|
|
}
|
|
|
|
function normalizeGameListFile(entry, payload) {
|
|
const id = String(entry?.id || entry?.file || "").replace(/\.json$/i, "");
|
|
const categories = Object.entries(payload || {}).filter(([, items]) => Array.isArray(items)).map(([categoryId, items]) => ({
|
|
id: categoryId,
|
|
title: formatListTitle(categoryId),
|
|
items: Array.isArray(items) ? items.map(normalizeGameListItem).filter((item) => item.name) : []
|
|
})).filter((category) => category.items.length);
|
|
|
|
return {
|
|
id,
|
|
title: payload?.titre || entry?.title || formatListTitle(id),
|
|
file: entry?.file || `${id}.json`,
|
|
categories,
|
|
itemCount: categories.reduce((count, category) => count + category.items.length, 0)
|
|
};
|
|
}
|
|
|
|
function normalizeGameListItem(item) {
|
|
const hasQuantity = item?.quantite !== undefined || item?.quantity !== undefined;
|
|
const quantity = Number.parseInt(item?.quantite ?? item?.quantity ?? 1, 10);
|
|
return {
|
|
name: String(item?.nom || item?.name || item?.label || "").trim(),
|
|
description: String(item?.description || item?.quete || item?.quest || item?.source || "").trim(),
|
|
quantity: Number.isFinite(quantity) ? quantity : 1,
|
|
hasQuantity
|
|
};
|
|
}
|
|
|
|
function formatListTitle(value) {
|
|
return String(value || "")
|
|
.replace(/_/g, " ")
|
|
.replace(/\b\p{L}/gu, (letter) => letter.toUpperCase());
|
|
}
|
|
|
|
export async function loadDiablo4Data() {
|
|
const response = await fetch("/data/diablo4/affixes_types.json");
|
|
if (!response.ok) throw new Error("Impossible de charger les données Diablo IV.");
|
|
|
|
const payload = await response.json();
|
|
const filterKey = Object.keys(payload).find((key) => key !== "affixes") || "";
|
|
const categories = payload[filterKey] || [];
|
|
|
|
return {
|
|
loaded: true,
|
|
loading: false,
|
|
error: "",
|
|
affixes: payload.affixes || [],
|
|
filterOptions: { affixes: categories },
|
|
categoryMap: Object.fromEntries(categories.map((category) => [category.id, category])),
|
|
filterOptionKeys: { affixes: filterKey }
|
|
};
|
|
}
|