v2.6.0 : page Tresors du Hall - listing equipement lu depuis la BDD

Nouvel endpoint GET /api/reference/gear (db.gearAll()). treasures.js
recupere les equipements de la base de reference a chaque ouverture
(GEAR_DB) avec repli sur gear.js statique si injoignable (file://).
Les editions admin/sqlite-web sont desormais refletees sur le listing.
Intro de la section mise a jour (bonus phys + mag d'equipement).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
perco
2026-06-13 19:18:28 +02:00
co-authored by Claude Opus 4.8
parent 375bb0a778
commit 84b3dd3606
4 changed files with 57 additions and 10 deletions
+8
View File
@@ -234,6 +234,14 @@ non affilié au jeu original de Mountyhall SARL.
## Versions
- **2.6.0** (2026-06-13) — La page **« Trésors du Hall »** lit désormais les
équipements **en direct dans la base de référence** (BDD SQLite) au lieu des
valeurs figées du code : nouvel endpoint `GET /api/reference/gear`
(`db.gearAll()`), et l'encyclopédie récupère ces données à chaque ouverture
(repli automatique sur `gear.js` si la base est injoignable, ex. ouverture en
`file://`). Toute édition de l'équipement faite via l'admin / sqlite-web est
donc reflétée immédiatement sur le listing. L'intro de la section a aussi été
mise à jour (bonus physiques **et** magiques d'équipement).
- **2.5.1** (2026-06-13) — Correction des niveaux de potions : **le niveau 0
n'existe plus** (minimum 1). PufPuff passe de « 0 à 2 » à **« 1 à 3 »** (le
niveau 0 affichait des formules absurdes : `ATT 0 D3`, `VUE (0+1)`,
+1 -1
View File
@@ -4,7 +4,7 @@
"use strict";
const APP_VERSION = "2.5.1";
const APP_VERSION = "2.6.0";
/* Alpha : maîtrise initiale haute pour les tests. Remettre 15 % / 15 % à la v1.0 officielle. */
const START_COMP_PCT = 90;
+40 -9
View File
@@ -82,18 +82,22 @@ function treasuresRender() {
}
html += "</div>";
const gearCount = Object.values(GEAR).reduce((n, list) => n + list.length, 0);
// Source des équipements : la base de référence (BDD SQLite, éditable) si elle
// a pu être chargée, sinon les valeurs statiques de gear.js (ex. hors-ligne).
const gearSource = GEAR_DB || GEAR;
const gearCount = Object.values(gearSource).reduce((n, list) => n + list.length, 0);
html += `<h2 class="tz-section">⚔️ Équipement (${gearCount})</h2>
<p class="tz-intro">Six emplacements : ${Object.values(GEAR_SLOTS).map(s => s.label).join(", ")}.
Tous les bonus d'équipement sont <b>fixes</b> et <b>physiques</b> : ATT/ESQ/DEG/REG
s'ajoutent aux jets (jamais en dés), Armure physique/VUE/PV aussi, RM/MM en %.
L'armure d'équipement réduit les dégâts physiques mais pas les dégâts magiques.
Les bonus d'équipement sont <b>fixes</b> (jamais en dés) et s'ajoutent toujours aux jets.
La plupart sont <b>physiques</b> ; certains objets portent aussi des bonus <b>magiques</b>
(ATT mag., DEG mag., Armure mag.), et les deux saveurs se cumulent. Les dégâts physiques
sont encaissés par l'armure totale, les dégâts magiques par la seule armure magique.
Une arme <b>à 2 mains</b> est incompatible avec un bouclier. S'équiper coûte <b>2 PA</b>.
Valeurs de base de la Mountypedia (sans templates) ; les objets puissants ne se trouvent
qu'en profondeur.</p>`;
Valeurs lues dans la <b>base de référence</b> (modifiables côté admin) ; les objets
puissants ne se trouvent qu'en profondeur.</p>`;
for (const [slot, info] of Object.entries(GEAR_SLOTS)) {
html += `<h3 class="tz-subsection">${info.emoji} ${info.label}s</h3><div class="tz-grid">`;
for (const def of GEAR[slot]) {
for (const def of (gearSource[slot] || [])) {
const fx = [];
for (const [key, label, unit] of GEAR_MOD_LABELS) {
const v = def.mods[key];
@@ -122,12 +126,39 @@ function treasuresRender() {
let treasuresReturnTo = "create";
function treasuresShow(from) {
// É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() {
try {
const res = await fetch("api/reference/gear");
if (!res.ok) throw new Error("indisponible");
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;
} catch {
GEAR_DB = null; // base injoignable (ex. ouverture en file://) → statique
}
}
async function treasuresShow(from) {
treasuresReturnTo = from;
document.getElementById("screen-" + from).classList.add("hidden");
document.getElementById("screen-treasures").classList.remove("hidden");
treasuresRender();
document.getElementById("screen-treasures").scrollTop = 0;
await loadGearReference();
treasuresRender();
}
if (typeof document !== "undefined") {
+8
View File
@@ -257,6 +257,14 @@ function handleMP(req, res, url) {
function handleAPI(req, res, url) {
if (url.pathname.startsWith("/api/mp/")) return handleMP(req, res, url);
// Valeurs de référence des équipements lues EN DIRECT dans la BDD SQLite :
// l'encyclopédie « Trésors du Hall » reflète ainsi les éditions de la base
// (DB Browser / sqlite-web) sans toucher au code.
if (req.method === "GET" && url.pathname === "/api/reference/gear") {
return sendJSON(res, 200, db.gearAll());
}
const idMatch = url.pathname.match(/^\/api\/levels\/([a-f0-9]{12})$/);
if (req.method === "GET" && url.pathname === "/api/levels") {