diff --git a/.gitignore b/.gitignore index 99e8b76..321606f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ # Self-contained NUI-Vorschau, gebaut von .tools/nui-preview.mjs nui/_preview.html + +# Kontrollblatt, gebaut von icons/gen-icons.mjs +icons/_check.html diff --git a/README.md b/README.md index 07ce857..af4eac6 100644 --- a/README.md +++ b/README.md @@ -61,23 +61,28 @@ weich ein und aus. und in `ox_inventory/data/items.lua` innerhalb der `return { … }`-Klammer einfügen. Sechs Items, nichts weiter anzupassen. -3. Icons nach `cdn.d4rkst3r.de/items/` legen: `diving_gear.png`, - `diving_fill.png`, `diving_tank_small.png`, `diving_tank_medium.png`, - `diving_tank_large.png`, `diving_tank_xl.png`. +3. Die sechs PNGs aus [`icons/`](icons) nach `cdn.d4rkst3r.de/items/` hochladen. + Sie heißen genau wie die Items, deshalb braucht es kein `client.image`. Es gibt bewusst **keine** fertige `items.lua` zum Ersetzen — die würde die restlichen Items des Servers überschreiben. ## Items -| Item | Label | Laufzeit | Fülldruck | Gewicht | -|---|---|---|---|---| -| `diving_gear` | Tauchausrüstung | — | — | 5000 | -| `diving_fill` | Pressluft-Kartusche | — | — | 1000 | -| `diving_tank_small` | Tauchflasche (5 Min) | 300 s | 300 bar | 4000 | -| `diving_tank_medium` | Tauchflasche (10 Min) | 600 s | 300 bar | 7000 | -| `diving_tank_large` | Tauchflasche (15 Min) | 900 s | 300 bar | 10000 | -| `diving_tank_xl` | Tauchflasche (20 Min) | 1200 s | 300 bar | 13000 | +| Icon | Item | Label | Laufzeit | Fülldruck | Gewicht | +|---|---|---|---|---|---| +| | `diving_gear` | Tauchausrüstung | — | — | 5000 | +| | `diving_fill` | Pressluft-Kartusche | — | — | 1000 | +| | `diving_tank_small` | Tauchflasche (5 Min) | 300 s | 300 bar | 4000 | +| | `diving_tank_medium` | Tauchflasche (10 Min) | 600 s | 300 bar | 7000 | +| | `diving_tank_large` | Tauchflasche (15 Min) | 900 s | 300 bar | 10000 | +| | `diving_tank_xl` | Tauchflasche (20 Min) | 1200 s | 300 bar | 13000 | + +Die Icons liegen als 128×128 PNG mit transparentem Hintergrund in +[`icons/`](icons), die SVG-Quellen in `icons/src/`. Die Laufzeit steht als Zahl +auf dem Farbband — ohne die sind die Einzelflaschen im Inventar nur noch an der +Bandfarbe auseinanderzuhalten. Wer `capacity` ändert, sollte die Zahlen in +`icons/gen-icons.mjs` mitziehen. Dass alle Flaschen mit demselben Fülldruck starten, ist gewollt: in echt macht das Volumen die Laufzeit, nicht der Druck. Die große Flasche hält 300 bar einfach länger. @@ -197,8 +202,22 @@ solcher Punkte enthält also den Pitch. node ../.tools/lint.mjs # Lua-Lint, CfxLua-tauglich node ../.tools/nui-preview.mjs nui # HUD im Browser anschauen node docs/gen-hud-svg.mjs docs # Renderings für diese README neu bauen + +# Item-Icons neu bauen (SVG -> PNG, braucht ImageMagick mit librsvg) +node icons/gen-icons.mjs +for f in icons/src/*.svg; do + magick -background none "$f" -resize 128x128 "icons/$(basename "$f" .svg).png" +done ``` +`gen-icons.mjs` schreibt außerdem `icons/_check.html` — alle Icons auf +Schachbrett, in Slot-Größe und klein, zum Gegenschauen nach Änderungen. + +> librsvg 2.40 wirft beim Rendern der Zahlen ein +> `Invalid UTF-8 string passed to pango_layout_set_text()`. Das ist harmlos und +> passiert bei jedem ``-Element, auch im minimalsten Testfall — die Zahlen +> kommen korrekt raus. + Der Umbau ist in [PLAN.md](PLAN.md) dokumentiert, inklusive der offenen Punkte. ## Bekannte Unsicherheiten diff --git a/icons/diving_fill.png b/icons/diving_fill.png new file mode 100644 index 0000000..d419cdc Binary files /dev/null and b/icons/diving_fill.png differ diff --git a/icons/diving_gear.png b/icons/diving_gear.png new file mode 100644 index 0000000..3bc5d6a Binary files /dev/null and b/icons/diving_gear.png differ diff --git a/icons/diving_tank_large.png b/icons/diving_tank_large.png new file mode 100644 index 0000000..c013931 Binary files /dev/null and b/icons/diving_tank_large.png differ diff --git a/icons/diving_tank_medium.png b/icons/diving_tank_medium.png new file mode 100644 index 0000000..c11ba02 Binary files /dev/null and b/icons/diving_tank_medium.png differ diff --git a/icons/diving_tank_small.png b/icons/diving_tank_small.png new file mode 100644 index 0000000..53af1c5 Binary files /dev/null and b/icons/diving_tank_small.png differ diff --git a/icons/diving_tank_xl.png b/icons/diving_tank_xl.png new file mode 100644 index 0000000..dfe3d2e Binary files /dev/null and b/icons/diving_tank_xl.png differ diff --git a/icons/gen-icons.mjs b/icons/gen-icons.mjs new file mode 100644 index 0000000..45f699e --- /dev/null +++ b/icons/gen-icons.mjs @@ -0,0 +1,175 @@ +#!/usr/bin/env node +// Erzeugt die Item-Icons als SVG. Die PNGs macht danach ImageMagick daraus: +// +// node icons/gen-icons.mjs +// for f in icons/src/*.svg; do magick -background none "$f" -resize 128x128 "icons/$(basename "$f" .svg).png"; done +// +// Nur SVG 1.1 mit Presentation-Attributen, keine CSS-Bloecke und keine Filter - +// gerendert wird mit librsvg 2.40, und das ist alt. +// +// librsvg 2.40 wirft bei jedem -Element ein +// WARNING: Invalid UTF-8 string passed to pango_layout_set_text() +// Das ist harmlos und tritt auch beim minimalsten Testfall auf - die Zahlen auf +// den Flaschen rendern korrekt. Nachgeprueft, nicht ignoriert. +// +// Erzeugt nebenbei icons/_check.html: alle Icons auf Schachbrett, in Slot-Groesse +// und klein, zum Gegenschauen nach Aenderungen. + +import { writeFileSync, mkdirSync } from 'node:fs'; +import { join, dirname } from 'node:path'; + +const OUT = join(process.argv[2] ?? 'icons', 'src'); +mkdirSync(OUT, { recursive: true }); + +const S = 128; // Canvas, quadratisch + +const C = { + steelLight: '#cbd5e1', + steel: '#94a3b8', + steelDark: '#64748b', + valve: '#334155', + valveDark: '#1e293b', + glass: '#38bdf8', + glassDark: '#0284c7', + rubber: '#1e293b', + outline: '#0f172a' +}; + +/** Farbband pro Groesse, damit die Flaschen im Inventar auf einen Blick unterscheidbar sind. */ +const BANDS = { + small: '#4ade80', + medium: '#38bdf8', + large: '#fbbf24', + xl: '#f472b6' +}; + +const defs = ` + + + + + + + + + + + `; + +const svg = (body) => + ` + ${defs} +${body} + +`; + +/** + * Eine Tauchflasche. cx = Mittelachse, w = Breite, top/bottom = Koerper in y. + * minutes = Laufzeit aufs Band gedruckt. Ohne die Zahl sind die Einzelflaschen + * bei kleiner Darstellung nur noch an der Bandfarbe auseinanderzuhalten. + */ +function tank(cx, w, top, bottom, band, minutes) { + const x = cx - w / 2; + const h = bottom - top; + const valveW = w * 0.4; + const bandY = top + h * 0.34; + const bandH = 22; + + const label = minutes + ? `${minutes}` + : ''; + + return ` + + + + + + ${label} + `; +} + +// --- Flaschen: gleiche Breite, wachsende Hoehe. Die Silhouette traegt die Info, +// --- das Farbband hilft zusaetzlich. +const sizes = { + diving_tank_small: { w: 42, top: 48, bottom: 114, band: BANDS.small, minutes: 5 }, + diving_tank_medium: { w: 46, top: 36, bottom: 116, band: BANDS.medium, minutes: 10 }, + diving_tank_large: { w: 50, top: 26, bottom: 118, band: BANDS.large, minutes: 15 } +}; + +for (const [name, cfg] of Object.entries(sizes)) { + writeFileSync(join(OUT, `${name}.svg`), svg(tank(64, cfg.w, cfg.top, cfg.bottom, cfg.band, cfg.minutes))); +} + +// --- XL = Doppelflasche, passend zum Label. Die Zahl steht auf einem Band +// --- ueber beide Flaschen, sonst muesste sie zweimal auftauchen. +writeFileSync(join(OUT, 'diving_tank_xl.svg'), svg( + ` +${tank(46, 38, 38, 118, BANDS.xl)} +${tank(82, 38, 38, 118, BANDS.xl)} + + 20` +)); + +// --- Tauchmaske +writeFileSync(join(OUT, 'diving_gear.svg'), svg( + ` + + + + + + + ` +)); + +// --- Pressluft-Kartusche: liegende, gedrungene Form mit Manometer. Bewusst quer +// --- statt hochkant, damit sie sich auf einen Blick von den Flaschen abhebt. +writeFileSync(join(OUT, 'diving_fill.svg'), svg( + ` + + + + + + + + + ` +)); + +// --- Kontrollblatt +const NAMES = [ + 'diving_gear', 'diving_fill', + 'diving_tank_small', 'diving_tank_medium', 'diving_tank_large', 'diving_tank_xl' +]; + +const slots = (extra = '') => + NAMES.map((n) => `
${n}
`).join(''); + +writeFileSync(join(dirname(OUT), '_check.html'), ` +

Transparenz

+
${slots()}
+

Inventar-Slot 100px

+
${slots()}
+

Klein 56px

+
${slots()}
+`); + +console.log('SVGs in', OUT, '+ _check.html'); diff --git a/icons/src/diving_fill.svg b/icons/src/diving_fill.svg new file mode 100644 index 0000000..65a592c --- /dev/null +++ b/icons/src/diving_fill.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/src/diving_gear.svg b/icons/src/diving_gear.svg new file mode 100644 index 0000000..8bde5c6 --- /dev/null +++ b/icons/src/diving_gear.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/src/diving_tank_large.svg b/icons/src/diving_tank_large.svg new file mode 100644 index 0000000..a5d6b9f --- /dev/null +++ b/icons/src/diving_tank_large.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + 15 + + diff --git a/icons/src/diving_tank_medium.svg b/icons/src/diving_tank_medium.svg new file mode 100644 index 0000000..cc10565 --- /dev/null +++ b/icons/src/diving_tank_medium.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + 10 + + diff --git a/icons/src/diving_tank_small.svg b/icons/src/diving_tank_small.svg new file mode 100644 index 0000000..2c9b09e --- /dev/null +++ b/icons/src/diving_tank_small.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + 5 + + diff --git a/icons/src/diving_tank_xl.svg b/icons/src/diving_tank_xl.svg new file mode 100644 index 0000000..4ce4562 --- /dev/null +++ b/icons/src/diving_tank_xl.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 20 + diff --git a/items_for_ox_inventory.lua b/items_for_ox_inventory.lua index bcabb84..5e58685 100644 --- a/items_for_ox_inventory.lua +++ b/items_for_ox_inventory.lua @@ -8,6 +8,10 @@ -- Bewusst KEINE fertige items.lua zum Ersetzen: die würde die restlichen Items -- des Servers mitlöschen. -- +-- Kein client.image gesetzt: ox_inventory lädt /.png, und die +-- Icons in icons/ heißen genau wie die Items. Einfach nach cdn.d4rkst3r.de/items/ +-- hochladen, fertig. +-- -- WICHTIG: kein `decay = true` auf den Flaschen. Die durability trägt hier den -- Füllstand, und ox_inventory löscht Items mit decay, sobald durability 0 erreicht -- (modules/items/server.lua) - die leere Flasche würde also verschwinden statt @@ -23,8 +27,7 @@ stack = false, close = true, consume = 0, - description = 'Maske und Tauchanzug. Benutzen zum An- und Ausziehen.', - client = { image = 'diving_gear.png' } + description = 'Maske und Tauchanzug. Benutzen zum An- und Ausziehen.' }, ['diving_fill'] = { @@ -33,8 +36,7 @@ stack = true, close = true, consume = 0, - description = 'Füllt eine Tauchflasche wieder auf.', - client = { image = 'diving_fill.png' } + description = 'Füllt eine Tauchflasche wieder auf.' }, ['diving_tank_small'] = { @@ -43,8 +45,7 @@ stack = false, close = true, consume = 0, - description = 'Kleine Tauchflasche, 300 bar. Reicht für etwa 5 Minuten.', - client = { image = 'diving_tank_small.png' } + description = 'Kleine Tauchflasche, 300 bar. Reicht für etwa 5 Minuten.' }, ['diving_tank_medium'] = { @@ -53,8 +54,7 @@ stack = false, close = true, consume = 0, - description = 'Mittlere Tauchflasche, 300 bar. Reicht für etwa 10 Minuten.', - client = { image = 'diving_tank_medium.png' } + description = 'Mittlere Tauchflasche, 300 bar. Reicht für etwa 10 Minuten.' }, ['diving_tank_large'] = { @@ -63,8 +63,7 @@ stack = false, close = true, consume = 0, - description = 'Große Tauchflasche, 300 bar. Reicht für etwa 15 Minuten.', - client = { image = 'diving_tank_large.png' } + description = 'Große Tauchflasche, 300 bar. Reicht für etwa 15 Minuten.' }, ['diving_tank_xl'] = { @@ -73,6 +72,5 @@ stack = false, close = true, consume = 0, - description = 'Doppelflasche, 300 bar. Reicht für etwa 20 Minuten.', - client = { image = 'diving_tank_xl.png' } + description = 'Doppelflasche, 300 bar. Reicht für etwa 20 Minuten.' }, diff --git a/t1.png b/t1.png new file mode 100644 index 0000000..c299927 Binary files /dev/null and b/t1.png differ diff --git a/t1.svg b/t1.svg new file mode 100644 index 0000000..1ca9fe7 --- /dev/null +++ b/t1.svg @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/t2.png b/t2.png new file mode 100644 index 0000000..c299927 Binary files /dev/null and b/t2.png differ diff --git a/t2.svg b/t2.svg new file mode 100644 index 0000000..2c328c5 --- /dev/null +++ b/t2.svg @@ -0,0 +1,2 @@ +5 \ No newline at end of file