// Craft UI import { state } from '../core/state.js'; import { BLOCKS } from '../data/blocks.js'; import { ITEMS } from '../data/items.js'; import { TOOLS } from '../data/tools.js'; import { RECIPES } from '../data/recipes.js'; import { addTool } from '../data/tools.js'; import { tex, itemTex } from '../render/textures.js'; import { playSound } from '../audio/sound-engine.js'; import { rebuildHotbar } from './hotbar.js'; import { renderInventory } from './inventory.js'; export function canCraft(r) { const inv = state.inv; for (const res in r.cost) { if ((inv[res] || 0) < r.cost[res]) return false; } return true; } export function renderCraft() { const inv = state.inv; const recipesEl = state.recipesEl; recipesEl.innerHTML = ''; for (const r of RECIPES) { const row = document.createElement('div'); row.className = 'recipe'; const icon = document.createElement('div'); icon.className = 'ricon'; // Иконка результата — canvas sprite > emoji if (tex[r.out]) { icon.style.backgroundImage = `url(${tex[r.out].toDataURL()})`; } else if (itemTex[r.out]) { icon.style.backgroundImage = `url(${itemTex[r.out].toDataURL()})`; } else if (TOOLS[r.out]) { icon.textContent = TOOLS[r.out].icon || '🔧'; icon.style.fontSize = '24px'; icon.style.display = 'flex'; icon.style.alignItems = 'center'; icon.style.justifyContent = 'center'; } else if (ITEMS[r.out]) { icon.textContent = ITEMS[r.out].icon || '📦'; icon.style.fontSize = '24px'; icon.style.display = 'flex'; icon.style.alignItems = 'center'; icon.style.justifyContent = 'center'; } const info = document.createElement('div'); info.className = 'rinfo'; const nm = document.createElement('div'); nm.className = 'rname'; const itemName = BLOCKS[r.out]?.n || TOOLS[r.out]?.n || ITEMS[r.out]?.n || r.out; nm.textContent = `${itemName} x${r.qty}`; const cs = document.createElement('div'); cs.className = 'rcost'; cs.textContent = Object.keys(r.cost).map(x => { const cn = BLOCKS[x]?.n || TOOLS[x]?.n || ITEMS[x]?.n || x; return `${cn}: ${(inv[x] || 0)}/${r.cost[x]}`; }).join(' '); info.appendChild(nm); info.appendChild(cs); const btn = document.createElement('button'); btn.className = 'rcraft'; btn.textContent = 'Создать'; btn.disabled = !canCraft(r); btn.onclick = () => { if (!canCraft(r)) return; playSound('click'); for (const res in r.cost) inv[res] -= r.cost[res]; inv[r.out] = (inv[r.out] || 0) + r.qty; if (TOOLS[r.out]) addTool(r.out); if (!state.recentItems.includes(r.out)) { state.recentItems.unshift(r.out); state.recentItems = state.recentItems.slice(0, 5); } rebuildHotbar(); renderCraft(); renderInventory(); }; row.appendChild(icon); row.appendChild(info); row.appendChild(btn); recipesEl.appendChild(row); } } let craftOpen = false; let inventoryOpen = false; export function toggleCraft() { playSound('click'); craftOpen = !craftOpen; state.craftPanel.style.display = craftOpen ? 'block' : 'none'; if (craftOpen) { renderCraft(); inventoryOpen = false; state.inventoryPanel.style.display = 'none'; } } export function closeCraft() { playSound('click'); craftOpen = false; state.craftPanel.style.display = 'none'; } export function toggleInventory() { playSound('click'); inventoryOpen = true; state.inventoryPanel.style.display = 'block'; renderInventory(); craftOpen = false; state.craftPanel.style.display = 'none'; } export function closeInventory() { playSound('click'); inventoryOpen = false; state.inventoryPanel.style.display = 'none'; }