docs: vollstaendige README mit HUD-Renderings, Luft-Ring mittig
Lint / Lint Resource (push) Has been cancelled
Lint / Lint Resource (push) Has been cancelled
HUD-Layout symmetrisch: Tiefe links, Luft-Ring mittig, Druck rechts, Lampe zentriert darunter. Umgestellt auf Grid, damit die drei Werte garantiert auf einer Mittelachse sitzen und die Lampen-Leiste ohne Ausgleichs-Margins in einer zweiten Zeile haengt. README: - Drei HUD-Renderings (normal, Warnung, kritisch) als SVG. Keine In-Game-Bilder - hier laeuft kein GTA -, sondern massstabsgetreu aus denselben Werten wie style.css erzeugt, per docs/gen-hud-svg.mjs reproduzierbar - Vollstaendige Config-Referenz fuer client.lua und shared.lua - Item-Tabelle mit Laufzeit, Fuelldruck, Gewicht, dazu die Metadata-Keys und warum kein decay gesetzt werden darf - Installation, Bedienung, Exports, Balancing-Hinweis - Bekannte Unsicherheiten offen benannt Item-Snippet mit klarem Copy-Paste-Header. Bewusst keine fertige items.lua zum Ersetzen: die wuerde die restlichen Items des Servers mitloeschen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env node
|
||||
// Erzeugt die HUD-Renderings für die README aus denselben Werten wie nui/style.css.
|
||||
// Keine In-Game-Screenshots - eine massstabsgetreue Nachbildung des Overlays.
|
||||
//
|
||||
// Nutzung: node docs/gen-hud-svg.mjs [ziel-ordner] (default: docs)
|
||||
|
||||
import { writeFileSync, mkdirSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const OUT = process.argv[2] ?? 'docs';
|
||||
mkdirSync(OUT, { recursive: true });
|
||||
|
||||
const C = {
|
||||
accent: '#38bdf8',
|
||||
warn: '#fbbf24',
|
||||
danger: '#f87171',
|
||||
text: '#e2e8f0',
|
||||
muted: '#94a3b8',
|
||||
panel: '#09121c',
|
||||
border: '#94a3b8'
|
||||
};
|
||||
|
||||
// Geometrie spiegelt das Grid aus style.css:
|
||||
// padding 14/22, Spalten 84 | 92 | 84 mit column-gap 22, row-gap 8, Lampe 23 hoch.
|
||||
const PAD_X = 22, PAD_Y = 14, COL = 84, GAUGE = 92, GAP = 22, ROW_GAP = 8, LAMP_H = 23;
|
||||
const PW = PAD_X * 2 + COL * 2 + GAUGE + GAP * 2;
|
||||
const PH = PAD_Y * 2 + GAUGE + ROW_GAP + LAMP_H;
|
||||
|
||||
const W = 520, H = PH + 70;
|
||||
const PX = (W - PW) / 2, PY = (H - PH) / 2;
|
||||
|
||||
const GX = PX + PAD_X + COL + GAP;
|
||||
const CX = GX + GAUGE / 2, CY = PY + PAD_Y + GAUGE / 2;
|
||||
|
||||
const R = 52 * (GAUGE / 120); // r=52 im viewBox 120, auf 92px skaliert
|
||||
const SW = 8 * (GAUGE / 120);
|
||||
const CIRC = 2 * Math.PI * R;
|
||||
|
||||
const DEPTH_X = PX + PAD_X + COL; // rechtsbündig, zeigt zum Ring
|
||||
const PRESS_X = GX + GAUGE + GAP; // linksbündig, zeigt zum Ring
|
||||
const CAP_Y = PY + PAD_Y + 35;
|
||||
const VAL_Y = PY + PAD_Y + 61;
|
||||
|
||||
const FONT = "'Segoe UI',Roboto,system-ui,sans-serif";
|
||||
const fmt = (s) => `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(Math.floor(s % 60)).padStart(2, '0')}`;
|
||||
|
||||
function readout(x, anchor, label, value, unit, colour) {
|
||||
const unitTspan = `<tspan font-size="13" font-weight="500" fill="${C.muted}" dx="3">${unit}</tspan>`;
|
||||
return `<text x="${x}" y="${CAP_Y}" text-anchor="${anchor}" font-family="${FONT}" font-size="9" font-weight="600" letter-spacing="1.4" fill="${C.muted}">${label}</text>
|
||||
<text x="${x}" y="${VAL_Y}" text-anchor="${anchor}" font-family="${FONT}" font-size="26" font-weight="600" fill="${colour}">${value}${unitTspan}</text>`;
|
||||
}
|
||||
|
||||
function build({ file, title, oxygen, capacity, depth, pressure, level, deep, reserve, lamp }) {
|
||||
const ratio = Math.max(0, Math.min(1, oxygen / capacity));
|
||||
const ring = level === 'danger' ? C.danger : level === 'warn' ? C.warn : C.accent;
|
||||
const lampColour = lamp ? C.accent : C.muted;
|
||||
const lampX = CX - 43;
|
||||
|
||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}" role="img" aria-label="${title}">
|
||||
<defs>
|
||||
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
||||
<stop offset="0%" stop-color="#0d3550"/>
|
||||
<stop offset="100%" stop-color="#071a26"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<rect width="${W}" height="${H}" fill="url(#water)"/>
|
||||
|
||||
<rect x="${PX}" y="${PY}" width="${PW}" height="${PH}" rx="16"
|
||||
fill="${C.panel}" fill-opacity="0.72" stroke="${C.border}" stroke-opacity="0.18"/>
|
||||
|
||||
<g transform="rotate(-90 ${CX} ${CY})">
|
||||
<circle cx="${CX}" cy="${CY}" r="${R.toFixed(2)}" fill="none" stroke="${C.muted}" stroke-opacity="0.16" stroke-width="${SW.toFixed(2)}" stroke-linecap="round"/>
|
||||
<circle cx="${CX}" cy="${CY}" r="${R.toFixed(2)}" fill="none" stroke="${ring}" stroke-width="${SW.toFixed(2)}" stroke-linecap="round"
|
||||
stroke-dasharray="${CIRC.toFixed(2)}" stroke-dashoffset="${(CIRC * (1 - ratio)).toFixed(2)}"/>
|
||||
</g>
|
||||
|
||||
<text x="${CX}" y="${CY - 1}" text-anchor="middle" font-family="${FONT}" font-size="21" font-weight="600" fill="${ring}">${fmt(oxygen)}</text>
|
||||
<text x="${CX}" y="${CY + 15}" text-anchor="middle" font-family="${FONT}" font-size="9" font-weight="600" letter-spacing="1.4" fill="${C.muted}">LUFT</text>
|
||||
|
||||
${readout(DEPTH_X, 'end', 'TIEFE', depth.toFixed(1), 'm', deep ? C.warn : C.text)}
|
||||
${readout(PRESS_X, 'start', 'DRUCK', String(Math.round(pressure)), 'bar', reserve ? C.danger : C.text)}
|
||||
|
||||
<g>
|
||||
<rect x="${lampX}" y="${PY + PAD_Y + GAUGE + ROW_GAP}" width="86" height="${LAMP_H}" rx="8" fill="${lampColour}" fill-opacity="${lamp ? 0.15 : 0.1}"/>
|
||||
<circle cx="${lampX + 14}" cy="${PY + PAD_Y + GAUGE + ROW_GAP + LAMP_H / 2}" r="4" fill="${lampColour}"/>
|
||||
<text x="${lampX + 24}" y="${PY + PAD_Y + GAUGE + ROW_GAP + LAMP_H / 2 + 3.5}" font-family="${FONT}" font-size="10" font-weight="600" letter-spacing="1.2" fill="${lampColour}">LAMPE</text>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
writeFileSync(join(OUT, file), svg);
|
||||
console.log(file);
|
||||
}
|
||||
|
||||
build({
|
||||
file: 'hud-normal.svg', title: 'Tauch-HUD: normaler Zustand',
|
||||
oxygen: 545, capacity: 1200, depth: 12.4, pressure: 136, level: 'ok', lamp: true
|
||||
});
|
||||
|
||||
build({
|
||||
file: 'hud-warnung.svg', title: 'Tauch-HUD: Warnstufe und Reservedruck',
|
||||
oxygen: 92, capacity: 900, depth: 27.5, pressure: 31,
|
||||
level: 'warn', deep: true, reserve: true, lamp: false
|
||||
});
|
||||
|
||||
build({
|
||||
file: 'hud-kritisch.svg', title: 'Tauch-HUD: kritischer Luftstand',
|
||||
oxygen: 8, capacity: 600, depth: 31.7, pressure: 4,
|
||||
level: 'danger', deep: true, reserve: true, lamp: true
|
||||
});
|
||||
Reference in New Issue
Block a user