v2.6.1 : encyclopedie - plages potions/parchemins depuis la BDD, cache, fix pufPuff
- /api/reference/(gear|monsters|potions|scrolls) generalise ; treasures.js lit aussi les plages de puissance potions/parchemins (powerLabel garde les libelles speciaux -, X (fixe), set discret). - Cache-Control: no-cache sur html/js/css (revalidation systematique) pour que les MAJ et editions BDD soient prises sans vider le cache ; medias en cache 1j. - POTION_POWER_DEFAULTS.pufPuff 0-2 -> 1-3 (incoherent avec le rollPower solo corrige en 2.5.1) + migration db.init() des bases existantes (UPDATE cible). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+51
-23
@@ -72,13 +72,13 @@ function treasuresRender() {
|
||||
|
||||
html += `<h2 class="tz-section">🧪 Potions (${TREASURE_POTIONS.length})</h2><div class="tz-grid">`;
|
||||
for (const [id, x, duration, fx] of TREASURE_POTIONS) {
|
||||
html += treasureCard(POTION_DEFS[id], x, duration, fx);
|
||||
html += treasureCard(POTION_DEFS[id], powerLabel(x, POTIONS_DB && POTIONS_DB[id]), duration, fx);
|
||||
}
|
||||
html += "</div>";
|
||||
|
||||
html += `<h2 class="tz-section">📜 Parchemins standards (${TREASURE_SCROLLS.length})</h2><div class="tz-grid">`;
|
||||
for (const [id, x, duration, fx] of TREASURE_SCROLLS) {
|
||||
html += treasureCard(SCROLL_DEFS[id], x, duration, fx);
|
||||
html += treasureCard(SCROLL_DEFS[id], powerLabel(x, SCROLLS_DB && SCROLLS_DB[id]), duration, fx);
|
||||
}
|
||||
html += "</div>";
|
||||
|
||||
@@ -126,38 +126,66 @@ function treasuresRender() {
|
||||
|
||||
let treasuresReturnTo = "create";
|
||||
|
||||
// Équipements de la base de référence (BDD), rechargés à chaque ouverture pour
|
||||
// refléter les éditions ; null tant qu'on n'a pas (ou pas pu) charger → repli
|
||||
// sur les valeurs statiques de gear.js.
|
||||
let GEAR_DB = null;
|
||||
async function loadGearReference() {
|
||||
// Données de la base de référence (BDD), rechargées à chaque ouverture pour
|
||||
// refléter les éditions (admin OU sqlite-web) ; null tant qu'on n'a pas (ou pas
|
||||
// pu) charger → repli sur les valeurs statiques du code.
|
||||
let GEAR_DB = null, POTIONS_DB = null, SCROLLS_DB = null;
|
||||
|
||||
async function fetchRef(cat) {
|
||||
try {
|
||||
const res = await fetch("api/reference/gear");
|
||||
if (!res.ok) throw new Error("indisponible");
|
||||
const res = await fetch("api/reference/" + cat);
|
||||
if (!res.ok) return null;
|
||||
const rows = await res.json();
|
||||
if (!Array.isArray(rows) || !rows.length) throw new Error("vide");
|
||||
const bySlot = {};
|
||||
for (const r of rows) {
|
||||
const mods = {};
|
||||
for (const [key] of GEAR_MOD_LABELS) mods[key] = r[key] || 0;
|
||||
const staticDef = (GEAR[r.slot] || []).find(d => d.name === r.name);
|
||||
(bySlot[r.slot] = bySlot[r.slot] || []).push({
|
||||
emoji: r.emoji, name: r.name, tier: r.tier, twoHanded: !!r.twoHanded,
|
||||
note: staticDef && staticDef.note, mods,
|
||||
});
|
||||
}
|
||||
GEAR_DB = bySlot;
|
||||
return Array.isArray(rows) && rows.length ? rows : null;
|
||||
} catch {
|
||||
GEAR_DB = null; // base injoignable (ex. ouverture en file://) → statique
|
||||
return null; // base injoignable (ex. ouverture en file://)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadReference() {
|
||||
const [gear, potions, scrolls] = await Promise.all([
|
||||
fetchRef("gear"), fetchRef("potions"), fetchRef("scrolls"),
|
||||
]);
|
||||
GEAR_DB = gear ? gearBySlotFromRows(gear) : null;
|
||||
POTIONS_DB = potions ? indexPowerById(potions) : null;
|
||||
SCROLLS_DB = scrolls ? indexPowerById(scrolls) : null;
|
||||
}
|
||||
|
||||
function gearBySlotFromRows(rows) {
|
||||
const bySlot = {};
|
||||
for (const r of rows) {
|
||||
const mods = {};
|
||||
for (const [key] of GEAR_MOD_LABELS) mods[key] = r[key] || 0;
|
||||
const staticDef = (GEAR[r.slot] || []).find(d => d.name === r.name);
|
||||
(bySlot[r.slot] = bySlot[r.slot] || []).push({
|
||||
emoji: r.emoji, name: r.name, tier: r.tier, twoHanded: !!r.twoHanded,
|
||||
note: staticDef && staticDef.note, mods,
|
||||
});
|
||||
}
|
||||
return bySlot;
|
||||
}
|
||||
|
||||
function indexPowerById(rows) {
|
||||
const map = {};
|
||||
for (const r of rows) map[r.id] = { min: r.powerMin, max: r.powerMax };
|
||||
return map;
|
||||
}
|
||||
|
||||
// Libellé « Niveau X » : on remplace par la plage BDD (min/max) UNIQUEMENT pour
|
||||
// les plages numériques simples « A à B » ; les libellés spéciaux (« — »,
|
||||
// « 5 (fixe) », « 1, 2, 3, 5 ou 8 »…) sont conservés tels quels car la base ne
|
||||
// stocke qu'un min/max qui ne saurait les représenter.
|
||||
function powerLabel(staticLabel, range) {
|
||||
if (!range || !/^\d+ à \d+$/.test(staticLabel)) return staticLabel;
|
||||
return range.min === range.max ? `${range.min} (fixe)` : `${range.min} à ${range.max}`;
|
||||
}
|
||||
|
||||
async function treasuresShow(from) {
|
||||
treasuresReturnTo = from;
|
||||
document.getElementById("screen-" + from).classList.add("hidden");
|
||||
document.getElementById("screen-treasures").classList.remove("hidden");
|
||||
document.getElementById("screen-treasures").scrollTop = 0;
|
||||
await loadGearReference();
|
||||
await loadReference();
|
||||
treasuresRender();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user