/* global React, Btn, Coin, useGame, fmt, useState, useEffect, useRef, scf, scfIdem */ const EMOJI_BY_VALUE = (v) => v >= 100000 ? "🏎️" : v >= 10000 ? "💎" : v >= 1000 ? "🎁" : v >= 100 ? "🏆" : "⭐"; const DRIVE_UNIT = 500; const GUAR = [ { lv: "第5次", c: "linear-gradient(180deg,#3a7bd5,#2a5bb5)", t: "50% 必得價值1000 / 50% 必得3344" }, { lv: "第10次", c: "linear-gradient(180deg,#4a8fd5,#2f6bb5)", t: "70% 必得5200 / 30% 必得9900" }, { lv: "第15次", c: "linear-gradient(180deg,#7a4dd0,#5a2db5)", t: "10% 必得9900 / 90% 必得18800" }, { lv: "第20次", c: "linear-gradient(180deg,#9a4dd0,#7a2db5)", t: "70% 必得18800 / 30% 必得52000" }, { lv: "第25次", c: "linear-gradient(180deg,#d04d9a,#b52d7a)", t: "90% 必得52000 / 10% 必得100000" }, { lv: "第30次", c: "linear-gradient(180deg,#e2235a,#b01040)", t: "80% 必得100000 / 20% 必得300000(全服)" }, ]; function TreasureScreen({ onBoxOpen, onDrawResult }) { const g = useGame(); const [loading, setLoading] = useState(true); const [board, setBoard] = useState([]); const [chest, setChest] = useState({ roundNo: 1, driveAccCoin: 0, litLevel: 0, levels: [] }); const [refresh, setRefresh] = useState({ count: 0, max: 30, nextCost: 0 }); const [hot, setHot] = useState(-1); const [rolling, setRolling] = useState(false); const [busy, setBusy] = useState(false); const timer = useRef(null); const apply = (d) => { setBoard(d.board || []); if (d.chest) setChest(d.chest); if (d.refresh) setRefresh(d.refresh); }; const load = async () => { setLoading(true); try { apply(await scf("treasure/board")); } catch (e) { g.showToast("✗ " + e.message); } setLoading(false); }; useEffect(() => { load(); return () => { if (timer.current) clearInterval(timer.current); }; }, []); const boxPct = (() => { const acc = Number(chest.driveAccCoin || 0); const levels = [...(chest.levels || [])].sort((a, b) => Number(a.thresholdCoin) - Number(b.thresholdCoin)); const next = levels.find(l => Number(l.thresholdCoin) > acc); if (!next) return 100; return Math.max(0, Math.min(100, Math.round(acc / Number(next.thresholdCoin) * 100))); })(); const drive = async (times) => { if (rolling || busy) return; setRolling(true); setBusy(true); let i = 0; if (timer.current) clearInterval(timer.current); timer.current = setInterval(() => { i++; setHot(i % 16); }, 80); try { const d = await scf("treasure/drive", { times, idemKey: scfIdem() }); await new Promise(r => setTimeout(r, 650)); clearInterval(timer.current); const first = (d.results || [])[0]; let target = (Math.random() * 16) | 0; if (first) { const idx = board.findIndex(b => String(b.valueTier) === String(first.value)); if (idx >= 0) target = idx; } setHot(target); if (d.chest) setChest(d.chest); g.refreshWallet(); if (onDrawResult) onDrawResult(d, times); setTimeout(() => setHot(-1), 1200); } catch (e) { clearInterval(timer.current); setHot(-1); g.showToast("✗ " + e.message); } finally { setRolling(false); setBusy(false); } }; const doRefresh = async () => { if (rolling || busy) return; if (refresh.count >= refresh.max) { g.showToast("已達刷新上限"); return; } setBusy(true); try { apply(await scf("treasure/refresh", { idemKey: scfIdem() })); g.refreshWallet(); g.showToast("禮物盤已刷新!刷新不計入寶箱進度"); } catch (e) { g.showToast("✗ " + e.message); } finally { setBusy(false); } }; if (loading) return React.createElement("div", { style: { padding: "40px 0", textAlign: "center", color: "var(--txt-mute)" } }, "載入中…"); const railLevels = [...(chest.levels || [])].sort((a, b) => b.level - a.level); return React.createElement("div", { className: "fade-in", style: { padding: "10px 14px 8px" } }, React.createElement("div", { className: "panel", style: { padding: 9, display: "flex", gap: 8 } }, React.createElement("div", { className: "grid16", style: { flex: 1 } }, board.map((cell, i) => React.createElement("div", { key: i, className: "gcell" + (i === hot ? " hot" : "") }, React.createElement("div", { className: "gc-ico" }, EMOJI_BY_VALUE(Number(cell.valueTier))), React.createElement("div", { className: "gc-val" }, React.createElement(Coin, { s: 9 }), fmt(Number(cell.valueTier)))))), React.createElement("div", { className: "rail" }, railLevels.map(l => { const st = l.state; return React.createElement("button", { key: l.level, className: "tbox" + (st === "LIT" ? " lit" : (st === "ABANDONED" || st === "OPENED") ? " dead" : ""), onClick: () => st === "LIT" ? onBoxOpen(l.level) : g.showToast(st === "ABANDONED" ? "該寶箱已作廢" : st === "OPENED" ? "本輪已開啟" : "開車累計達標後點亮"), style: { border: "none", cursor: "pointer" } }, React.createElement("div", { style: { fontSize: 18 } }, st === "LIT" ? "🎁" : "🔒"), React.createElement("div", { className: "tb-lv" }, l.level + " 級")); }))), React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "10px 2px 0" } }, React.createElement("span", { style: { fontSize: 11, color: "var(--txt-dim)" } }, "寶箱進度"), React.createElement("div", { className: "prog", style: { flex: 1 } }, React.createElement("i", { style: { width: boxPct + "%" } })), React.createElement("span", { className: "disp", style: { fontSize: 12, color: "var(--gold-100)" } }, boxPct + "%")), React.createElement("div", { className: "actrow", style: { marginTop: 12 } }, React.createElement("button", { className: "actbtn act-refresh", onClick: doRefresh, disabled: busy }, React.createElement("span", null, "🔄 刷新"), React.createElement("span", { className: "ab-cost" }, "(" + refresh.count + "/" + refresh.max + ") ", React.createElement(Coin, { s: 9 }), fmt(Number(refresh.nextCost)))), [1, 10, 50].map(t => React.createElement("button", { key: t, className: "actbtn act-go", onClick: () => drive(t), disabled: rolling }, React.createElement("span", null, "開車 " + t + " 次"), React.createElement("span", { className: "ab-cost" }, React.createElement(Coin, { s: 9 }), fmt(DRIVE_UNIT * t))))), React.createElement("div", { className: "panel panel-red", style: { marginTop: 14, padding: "12px 14px 14px" } }, React.createElement("div", { style: { textAlign: "center", fontSize: 13, fontWeight: 700, color: "var(--gold-100)", marginBottom: 8 } }, "持續刷新至指定次數,下次抽獎必得對應價值禮物"), GUAR.map((r, i) => React.createElement("div", { key: i, className: "guar-row" }, React.createElement("span", { className: "guar-cap", style: { background: r.c } }, r.lv), React.createElement("span", { style: { textWrap: "pretty" } }, r.t)))), React.createElement("div", { style: { fontSize: 11, color: "var(--txt-mute)", lineHeight: 1.7, padding: "10px 4px 0", textWrap: "pretty" } }, "寶箱:5 級,按【開車】累計消費點亮(刷新不計入)。每輪只能開 1 個;不開即作廢。5 級封頂後超額消費結轉下一輪。") ); } Object.assign(window, { TreasureScreen });