Workers P2: Engine-Requisiten und Branchen-Icons

Möbel und Requisiten aus der Vorlage (Schreibtisch, Monitor mit Schalter an/aus, Aktenschrank, Pflanze, Münze, Pokal, Stempel, Radar, Briefkasten, Tresor, Waage), neu Ablagekorb, Schild und die acht 7x7-Branchen-Icons mit drawIcon.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-18 01:58:15 +00:00
1 parent d44b28368d
commit 514469d93c
2 files changed
+337

No files matched your search

+255
View File
@@ -0,0 +1,255 @@
// Möbel, Requisiten und Branchen-Icons des Hustler-Hochhauses.
// Portiert aus entwuerfe/sprites.js (Möbel und Requisiten, ohne drawConveyor und drawZone). Neu: drawTray, drawSign,
// drawIcon samt ICONS und der Schalter `on` an drawMonitor.
// Alle Maße in logischen Einheiten; gezeichnet wird über px() aus sprites.js, es gibt keinen eigenen Zustand.
// Kein React, kein Appwrite, kein window/document.
import { px, label, PAL, TEAM, HAT } from './sprites.js'
// ---------- Möbel ----------
export function drawDesk(ctx, x, y, w, accent) {
px(ctx, x, y, w, 1, PAL.wood2)
px(ctx, x, y + 1, w, 4, PAL.wood)
px(ctx, x, y + 5, w, 1, PAL.wood2)
if (accent) px(ctx, x, y + 5, w, 1, accent)
px(ctx, x + 1, y + 6, 1, 5, PAL.wood2)
px(ctx, x + w - 2, y + 6, 1, 5, PAL.wood2)
px(ctx, x + 1, y + 11, w - 2, 1, PAL.shadow)
}
// on = false: nur Rahmen, Schirm und Fuß, keine Zeilen und kein Blinken
export function drawMonitor(ctx, x, y, t, color, on = true) {
const c = color || '#7fb2ff'
px(ctx, x, y, 10, 7, PAL.o)
px(ctx, x + 1, y + 1, 8, 5, PAL.screen)
if (on) {
const long = Math.floor((t || 0) * 2) % 2 === 0
px(ctx, x + 2, y + 2, 5, 1, c)
px(ctx, x + 2, y + 4, long ? 4 : 2, 1, c)
}
px(ctx, x + 4, y + 7, 2, 2, PAL.o)
px(ctx, x + 2, y + 9, 6, 1, PAL.o)
}
export function drawCabinet(ctx, x, y, drawers) {
const n = drawers || 3
px(ctx, x, y, 12, n * 6 + 1, PAL.metal2)
for (let i = 0; i < n; i++) {
px(ctx, x + 1, y + 1 + i * 6, 10, 5, PAL.metal)
px(ctx, x + 4, y + 3 + i * 6, 4, 1, PAL.metal2)
}
px(ctx, x, y + n * 6 + 1, 12, 1, PAL.shadow)
}
export function drawPlant(ctx, x, y) {
px(ctx, x + 2, y, 2, 2, '#5cbf8a')
px(ctx, x, y + 2, 2, 2, '#5cbf8a')
px(ctx, x + 4, y + 1, 2, 3, '#3a9466')
px(ctx, x + 2, y + 2, 2, 3, '#3a9466')
px(ctx, x + 1, y + 5, 4, 4, '#c9714f')
px(ctx, x + 1, y + 5, 4, 1, '#a85a3c')
}
// Ablagekorb / Eingangskorb, 10 × 4: voll = Papierstapel ragt über den Rand
export function drawTray(ctx, x, y, filled) {
px(ctx, x, y + 1, 10, 1, PAL.metal2) // Rand
px(ctx, x, y + 2, 10, 1, PAL.metal) // Vorderwand
px(ctx, x, y + 3, 10, 1, PAL.metal2) // Boden
if (filled) {
px(ctx, x + 1, y, 8, 1, PAL.g) // Oberkante des Stapels
px(ctx, x + 1, y + 1, 8, 1, PAL.w) // oberstes Blatt in der Öffnung
px(ctx, x + 3, y + 1, 4, 1, PAL.p) // eine Textzeile darauf
}
}
// ---------- Requisiten ----------
export function drawCoin(ctx, x, y, t) {
const f = Math.floor((t || 0) * 6) % 4
const w = [5, 3, 1, 3][f]
const ox = (5 - w) / 2
px(ctx, x + ox, y, w, 5, PAL.gold2)
if (w > 2) px(ctx, x + ox + 1, y + 1, w - 2, 3, PAL.gold)
}
export function drawTrophy(ctx, x, y) {
px(ctx, x, y, 7, 1, PAL.gold2)
px(ctx, x, y + 1, 7, 3, PAL.gold)
px(ctx, x + 1, y + 4, 5, 1, PAL.gold2)
px(ctx, x + 3, y + 5, 1, 2, PAL.gold2)
px(ctx, x + 1, y + 7, 5, 2, PAL.wood2)
px(ctx, x + 1, y + 1, 1, 2, '#fff3c4')
}
export function drawStamp(ctx, x, y, ok) {
const c = ok ? PAL.green : PAL.red
px(ctx, x, y, 7, 1, c)
px(ctx, x, y + 4, 7, 1, c)
px(ctx, x, y, 1, 5, c)
px(ctx, x + 6, y, 1, 5, c)
if (ok) {
// Haken
px(ctx, x + 2, y + 2, 1, 1, c)
px(ctx, x + 3, y + 3, 1, 1, c)
px(ctx, x + 4, y + 1, 1, 2, c)
} else {
// Kreuz
px(ctx, x + 2, y + 1, 1, 1, c)
px(ctx, x + 4, y + 1, 1, 1, c)
px(ctx, x + 3, y + 2, 1, 1, c)
px(ctx, x + 2, y + 3, 1, 1, c)
px(ctx, x + 4, y + 3, 1, 1, c)
}
}
export function drawRadar(ctx, x, y, t) {
px(ctx, x + 2, y, 10, 1, PAL.o)
px(ctx, x, y + 1, 14, 10, PAL.o)
px(ctx, x + 1, y + 2, 12, 8, '#e8f2fc')
px(ctx, x + 6, y + 5, 2, 2, TEAM.radar)
const a = (t || 0) * 2.2
for (let i = 1; i < 6; i++) px(ctx, x + 7 + Math.round(Math.cos(a) * i), y + 6 + Math.round(Math.sin(a) * i * 0.7), 1, 1, TEAM.radar)
const blink = Math.floor((t || 0) * 3) % 3
if (blink === 0) px(ctx, x + 3, y + 3, 1, 1, PAL.red)
if (blink === 1) px(ctx, x + 10, y + 7, 1, 1, PAL.red)
px(ctx, x + 6, y + 11, 2, 3, PAL.o)
px(ctx, x + 3, y + 14, 8, 1, PAL.o)
}
// Briefkasten des Pults; das rote Abzeichen mit „!“ steht nur bei count > 0
export function drawMailbox(ctx, x, y, count) {
px(ctx, x, y + 2, 12, 8, TEAM.freigabe)
px(ctx, x + 1, y, 10, 2, TEAM.freigabe)
px(ctx, x + 2, y + 4, 8, 2, HAT.overseer[1])
px(ctx, x + 5, y + 10, 2, 5, PAL.o)
if (count > 0) {
px(ctx, x + 9, y - 3, 5, 5, PAL.red)
px(ctx, x + 11, y - 2, 1, 3, PAL.w)
}
}
export function drawVault(ctx, x, y, t) {
px(ctx, x, y, 22, 20, PAL.metal2)
px(ctx, x + 1, y + 1, 20, 18, PAL.metal)
px(ctx, x + 7, y + 6, 8, 8, PAL.metal2)
px(ctx, x + 8, y + 7, 6, 6, PAL.metal)
const a = (t || 0) * 0.8
px(ctx, x + 11 + Math.round(Math.cos(a) * 2), y + 10 + Math.round(Math.sin(a) * 2), 1, 1, PAL.o)
px(ctx, x + 18, y + 9, 2, 3, PAL.metal2)
px(ctx, x, y + 20, 22, 1, PAL.shadow)
}
export function drawScale(ctx, x, y, tilt) {
const d = Math.round(tilt || 0)
px(ctx, x + 7, y + 2, 2, 12, PAL.o)
px(ctx, x + 3, y + 14, 10, 2, PAL.o)
px(ctx, x, y + 2 - d, 16, 1, PAL.o)
px(ctx, x - 1, y + 3 - d, 5, 2, TEAM.bewertung)
px(ctx, x + 12, y + 3 + d, 5, 2, TEAM.bewertung)
}
// Weißes Schild mit dunklem Rand, 8 hoch; (x, y) = linke obere Ecke, Text zentriert (z. B. „noch nicht angeschlossen“)
export function drawSign(ctx, x, y, w, text) {
px(ctx, x, y, w, 8, PAL.o)
px(ctx, x + 1, y + 1, w - 2, 6, PAL.w)
label(ctx, text, x + w / 2, y + 2.5, { size: 9, color: PAL.ink, align: 'center' })
}
// ---------- Branchen-Icons (7 × 7) ----------
// '.' leer, 'x' Linie in der Teamfarbe, 'a' Akzent in Gold. Schlüssel = die acht Such-Räume (SEARCH_ROOMS)
const icon = (...rows) => Object.freeze(rows)
export const ICONS = Object.freeze({
netz: icon( // Funkwellen
'.xxxxx.',
'x.....x',
'..xxx..',
'.x...x.',
'.......',
'...a...',
'...a...',
),
kleinanzeigen: icon( // Umschlag mit @-Punkt
'xxxxxxx',
'xx...xx',
'x.x.x.x',
'x..x..x',
'x.....x',
'x..a..x',
'xxxxxxx',
),
portale: icon( // Zeilenliste
'xxxxxxx',
'.......',
'a.xxxx.',
'.......',
'a.xxxx.',
'.......',
'a.xxxx.',
),
foren: icon( // Sprechblase
'.xxxxx.',
'x.....x',
'x.a.a.x',
'x.....x',
'.xxxxx.',
'..xx...',
'.x.....',
),
aerzte: icon( // Kreuz
'..xxx..',
'..xxx..',
'xxxxxxx',
'xxxxxxx',
'xxxxxxx',
'..xxx..',
'..xxx..',
),
handwerk: icon( // Hammer
'.xxxxx.',
'xxxxxxx',
'.xxxxx.',
'...a...',
'...a...',
'...a...',
'...a...',
),
selbst: icon( // Person
'..xxx..',
'.xxxxx.',
'..xxx..',
'.......',
'.xxxxx.',
'xxxxxxx',
'xxxxxxx',
),
laden: icon( // Markise
'.xxxxx.',
'xaxaxax',
'xaxaxax',
'x.x.x.x',
'.......',
'x.....x',
'xxxxxxx',
),
})
// Zeichnet das Icon `name` mit der linken oberen Ecke bei (x, y): 'x' in `color`, 'a' in Gold.
// Gleiche Zeichen einer Zeile werden zu einem Rechteck zusammengefasst; ein unbekannter Name zeichnet nichts.
export function drawIcon(ctx, name, x, y, color) {
const rows = typeof name === 'string' ? ICONS[name] : null
if (!Array.isArray(rows)) return
for (let r = 0; r < rows.length; r++) {
const row = rows[r]
let c = 0
while (c < row.length) {
const ch = row[c]
let end = c + 1
while (end < row.length && row[end] === ch) end++
if (ch === 'x') px(ctx, x + c, y + r, end - c, 1, color)
else if (ch === 'a') px(ctx, x + c, y + r, end - c, 1, PAL.gold)
c = end
}
}
}