// Crafting UI - Visual panel for crafting interface class CraftingUI { constructor(scene) { this.scene = scene; this.craftingSystem = scene.craftingSystem; this.isOpen = false; this.currentCategory = 'all'; this.selectedRecipe = null; // UI elements this.container = null; this.panel = null; this.categoryButtons = []; this.recipeList = []; this.detailsPanel = null; this.createUI(); this.hide(); // Listen for crafting events this.setupEventListeners(); console.log('🎨 CraftingUI initialized'); } createUI() { const width = this.scene.cameras.main.width; const height = this.scene.cameras.main.height; // Main container this.container = this.scene.add.container(0, 0); this.container.setDepth(10000); this.container.setScrollFactor(0); // Semi-transparent background overlay const overlay = this.scene.add.rectangle(0, 0, width, height, 0x000000, 0.7); overlay.setOrigin(0); overlay.setInteractive(); this.container.add(overlay); // Main panel (centered) const panelWidth = 700; const panelHeight = 500; const panelX = width / 2 - panelWidth / 2; const panelY = height / 2 - panelHeight / 2; this.panel = this.scene.add.rectangle(panelX, panelY, panelWidth, panelHeight, 0x2a1810); this.panel.setOrigin(0); this.panel.setStrokeStyle(3, 0x4a3820); this.container.add(this.panel); // Title const title = this.scene.add.text(width / 2, panelY + 20, '🛠️ CRAFTING', { fontSize: '32px', fontFamily: 'Georgia, serif', fill: '#f4e4c1', stroke: '#2d1b00', strokeThickness: 4 }).setOrigin(0.5); this.container.add(title); // Close button const closeBtn = this.scene.add.text(panelX + panelWidth - 40, panelY + 20, '✖', { fontSize: '24px', fill: '#ff6666' }).setOrigin(0.5); closeBtn.setInteractive({ useHandCursor: true }); closeBtn.on('pointerdown', () => this.hide()); closeBtn.on('pointerover', () => closeBtn.setScale(1.2)); closeBtn.on('pointerout', () => closeBtn.setScale(1.0)); this.container.add(closeBtn); // Category buttons (top) this.createCategoryButtons(panelX, panelY + 60, panelWidth); // Recipe list (left side) this.createRecipeListPanel(panelX + 10, panelY + 120, 300, 350); // Details panel (right side) this.createDetailsPanel(panelX + 320, panelY + 120, 370, 350); } createCategoryButtons(x, y, width) { const categories = this.craftingSystem.categories; const buttonWidth = (width - 40) / categories.length; categories.forEach((category, index) => { const btnX = x + 20 + (index * buttonWidth); const btn = this.scene.add.rectangle(btnX, y, buttonWidth - 10, 40, 0x4a3820); btn.setOrigin(0, 0.5); btn.setStrokeStyle(2, 0x6a5840); btn.setInteractive({ useHandCursor: true }); const text = this.scene.add.text(btnX + buttonWidth / 2 - 5, y, `${category.icon} ${category.name}`, { fontSize: '14px', fontFamily: 'Arial', fill: '#d4c4a1' }).setOrigin(0.5); btn.on('pointerdown', () => this.selectCategory(category.id)); btn.on('pointerover', () => { btn.setFillStyle(0x6a5840); text.setScale(1.05); }); btn.on('pointerout', () => { btn.setFillStyle(0x4a3820); text.setScale(1.0); }); this.container.add(btn); this.container.add(text); this.categoryButtons.push({ category: category.id, btn, text }); }); } createRecipeListPanel(x, y, width, height) { // Background const bg = this.scene.add.rectangle(x, y, width, height, 0x1a1410); bg.setOrigin(0); bg.setStrokeStyle(2, 0x4a3820); this.container.add(bg); // Title const title = this.scene.add.text(x + width / 2, y + 10, 'Recipes', { fontSize: '18px', fontFamily: 'Georgia, serif', fill: '#f4e4c1' }).setOrigin(0.5, 0); this.container.add(title); // Store panel bounds for recipe items this.recipePanelBounds = { x, y: y + 40, width, height: height - 40 }; } createDetailsPanel(x, y, width, height) { // Background const bg = this.scene.add.rectangle(x, y, width, height, 0x1a1410); bg.setOrigin(0); bg.setStrokeStyle(2, 0x4a3820); this.container.add(bg); this.detailsPanelBounds = { x, y, width, height }; } selectCategory(categoryId) { this.currentCategory = categoryId; this.refreshRecipeList(); // Update button styles this.categoryButtons.forEach(({ category, btn, text }) => { if (category === categoryId) { btn.setFillStyle(0x6a5840); text.setStyle({ fill: '#ffffff' }); } else { btn.setFillStyle(0x4a3820); text.setStyle({ fill: '#d4c4a1' }); } }); } refreshRecipeList() { // Clear existing recipe items this.recipeList.forEach(item => item.destroy()); this.recipeList = []; // Get recipes for current category const recipes = this.craftingSystem.getUnlockedRecipes(this.currentCategory); const { x, y, width } = this.recipePanelBounds; const itemHeight = 50; recipes.forEach((recipe, index) => { const itemY = y + (index * itemHeight); // Check if can craft const canCraft = this.craftingSystem.canCraft(recipe.id); // Background const bg = this.scene.add.rectangle(x + 5, itemY, width - 10, itemHeight - 5, 0x2a1810); bg.setOrigin(0); bg.setStrokeStyle(1, canCraft.canCraft ? 0x4a9d5f : 0x6a5840); bg.setInteractive({ useHandCursor: true }); // Recipe name const name = this.scene.add.text(x + 15, itemY + itemHeight / 2, recipe.name, { fontSize: '16px', fontFamily: 'Arial', fill: canCraft.canCraft ? '#ffffff' : '#888888' }).setOrigin(0, 0.5); // Hover effect bg.on('pointerover', () => { bg.setFillStyle(0x3a2820); name.setScale(1.05); }); bg.on('pointerout', () => { bg.setFillStyle(0x2a1810); name.setScale(1.0); }); // Click to select bg.on('pointerdown', () => this.selectRecipe(recipe)); this.container.add(bg); this.container.add(name); this.recipeList.push(bg, name); }); } selectRecipe(recipe) { this.selectedRecipe = recipe; this.showRecipeDetails(); } showRecipeDetails() { if (!this.selectedRecipe) return; // Clear existing details if (this.detailsContent) { this.detailsContent.forEach(item => item.destroy()); } this.detailsContent = []; const { x, y, width } = this.detailsPanelBounds; const recipe = this.selectedRecipe; // Recipe name const name = this.scene.add.text(x + width / 2, y + 20, recipe.name, { fontSize: '24px', fontFamily: 'Georgia, serif', fill: '#f4e4c1', stroke: '#2d1b00', strokeThickness: 2 }).setOrigin(0.5, 0); this.detailsContent.push(name); // Description const desc = this.scene.add.text(x + 20, y + 60, recipe.description, { fontSize: '14px', fontFamily: 'Arial', fill: '#d4c4a1', wordWrap: { width: width - 40 } }); this.detailsContent.push(desc); // Ingredients title const ingredTitle = this.scene.add.text(x + 20, y + 120, 'Required Ingredients:', { fontSize: '16px', fontFamily: 'Arial', fill: '#f4e4c1', fontStyle: 'bold' }); this.detailsContent.push(ingredTitle); // Ingredients list const inventory = this.scene.inventorySystem; let ingredY = y + 150; for (const [itemId, required] of Object.entries(recipe.ingredients)) { const has = inventory ? inventory.getItemCount(itemId) : 0; const hasEnough = has >= required; const text = this.scene.add.text(x + 30, ingredY, `• ${itemId}: ${has}/${required}`, { fontSize: '14px', fontFamily: 'Arial', fill: hasEnough ? '#4a9d5f' : '#ff6666' }); this.detailsContent.push(text); ingredY += 25; } // Result const resultText = this.scene.add.text(x + 20, ingredY + 20, `Produces: ${recipe.result.quantity}x ${recipe.result.item}`, { fontSize: '16px', fontFamily: 'Arial', fill: '#4aa3d0', fontStyle: 'bold' }); this.detailsContent.push(resultText); // Craft button const canCraft = this.craftingSystem.canCraft(recipe.id); const btnY = y + 320; const craftBtn = this.scene.add.rectangle(x + width / 2, btnY, 200, 40, canCraft.canCraft ? 0x4a9d5f : 0x666666); craftBtn.setStrokeStyle(2, 0x000000); const btnText = this.scene.add.text(x + width / 2, btnY, canCraft.canCraft ? '🔨 CRAFT' : '❌ Cannot Craft', { fontSize: '18px', fontFamily: 'Arial', fill: '#ffffff', fontStyle: 'bold' }).setOrigin(0.5); if (canCraft.canCraft) { craftBtn.setInteractive({ useHandCursor: true }); craftBtn.on('pointerover', () => { craftBtn.setFillStyle(0x5abd6f); btnText.setScale(1.1); }); craftBtn.on('pointerout', () => { craftBtn.setFillStyle(0x4a9d5f); btnText.setScale(1.0); }); craftBtn.on('pointerdown', () => this.craftSelectedRecipe()); } this.detailsContent.push(craftBtn, btnText); // Add all to container this.detailsContent.forEach(item => this.container.add(item)); } craftSelectedRecipe() { if (!this.selectedRecipe) return; const success = this.craftingSystem.craftItem(this.selectedRecipe.id); if (success) { // Refresh UI this.refreshRecipeList(); this.showRecipeDetails(); console.log(`✅ Crafting started: ${this.selectedRecipe.name}`); } } setupEventListeners() { // Listen for inventory changes to update recipe availability this.scene.events.on('inventory-changed', () => { if (this.isOpen) { this.refreshRecipeList(); if (this.selectedRecipe) { this.showRecipeDetails(); } } }); // Listen for craft completion this.scene.events.on('craft-complete', (data) => { if (this.isOpen) { this.refreshRecipeList(); if (this.selectedRecipe) { this.showRecipeDetails(); } } }); } show() { this.isOpen = true; this.container.setVisible(true); this.selectCategory(this.currentCategory); console.log('🛠️ Crafting UI opened'); } hide() { this.isOpen = false; this.container.setVisible(false); console.log('🛠️ Crafting UI closed'); } toggle() { if (this.isOpen) { this.hide(); } else { this.show(); } } destroy() { if (this.container) { this.container.destroy(); } } }