import * as React from "react"; import type { SymbolStyle, SymbolTier } from "@spinza/game-core/client"; /* ------------------------------------------------------------------------ SymbolSvg — the exact same procedural symbol artwork the PixiJS renderer draws on the reels (`components/game/symbol-art.ts`), ported to SVG so lobby posters show the symbols the player will actually meet in-game. Geometry, colours, highlights and glow follow symbol-art.ts 1:1; `size` is the tile edge, the glyph is centred on (x, y). ------------------------------------------------------------------------ */ const INK = "#0b0d14"; const FONT = "var(--font-geist-sans), Geist, Inter, ui-sans-serif, system-ui, sans-serif"; function clamp8(n: number): number { return Math.max(0, Math.min(255, n)); } function parseHex(c: string): [number, number, number] { const h = c.replace("#", ""); const full = h.length === 3 ? h.split("").map((ch) => ch + ch).join("") : h; const n = parseInt(full, 16); return [(n >> 16) & 255, (n >> 8) & 255, n & 255]; } function toHex(r: number, g: number, b: number): string { return `#${((clamp8(r) << 16) | (clamp8(g) << 8) | clamp8(b)).toString(16).padStart(6, "0")}`; } /** Same arithmetic as symbol-art.ts `lighten` (adds 255*amt per channel). */ export function lightenHex(c: string, amt: number): string { const [r, g, b] = parseHex(c); const d = Math.round(255 * amt); return toHex(r + d, g + d, b + d); } /** Same arithmetic as symbol-art.ts `darken`. */ export function darkenHex(c: string, amt: number): string { const [r, g, b] = parseHex(c); const d = Math.round(255 * amt); return toHex(r - d, g - d, b - d); } const f = (n: number) => Math.round(n * 100) / 100; /** Flat [x0,y0,x1,y1,…] list → SVG points string. */ function pts(list: number[]): string { const out: string[] = []; for (let i = 0; i < list.length; i += 2) out.push(`${f(list[i])},${f(list[i + 1])}`); return out.join(" "); } function polygonPts(cx: number, cy: number, r: number, sides: number, rot = -Math.PI / 2): string { const list: number[] = []; for (let i = 0; i < sides; i++) { const a = rot + (i * Math.PI * 2) / sides; list.push(cx + Math.cos(a) * r, cy + Math.sin(a) * r); } return pts(list); } function starPts(cx: number, cy: number, outer: number, inner: number, points = 5): string { const list: number[] = []; for (let i = 0; i < points * 2; i++) { const r = i % 2 === 0 ? outer : inner; const a = -Math.PI / 2 + (i * Math.PI) / points; list.push(cx + Math.cos(a) * r, cy + Math.sin(a) * r); } return pts(list); } function arcPath(cx: number, cy: number, r: number, a0: number, a1: number): string { const x0 = cx + Math.cos(a0) * r; const y0 = cy + Math.sin(a0) * r; const x1 = cx + Math.cos(a1) * r; const y1 = cy + Math.sin(a1) * r; const large = Math.abs(a1 - a0) > Math.PI ? 1 : 0; const sweep = a1 > a0 ? 1 : 0; return `M${f(x0)} ${f(y0)} A${f(r)} ${f(r)} 0 ${large} ${sweep} ${f(x1)} ${f(y1)}`; } export { pts as svgPoints, polygonPts as svgPolygon, starPts as svgStar, arcPath as svgArc }; function Label({ text, fontSize, color, bold = true }: { text: string; fontSize: number; color: string; bold?: boolean }) { return ( {text} ); } /* ------------------------------------------------------------------ glyph */ function Glyph({ style, size }: { style: SymbolStyle; size: number }) { const main = style.color; const accent = style.accent ?? lightenHex(style.color, 0.35); const r = size * 0.36; const sw = (k: number) => f(size * k); switch (style.shape) { case "gem": return ( <> ); case "hex": return ( <> {style.label ?