/** * COOKING & RECIPE SYSTEM * Complete cooking system with recipes, food buffs, spoilage, and skill progression */ class CookingSystem { constructor(scene) { this.scene = scene; this.enabled = true; // Recipes this.recipes = new Map(); this.knownRecipes = new Set(); // Cooking stations this.cookingStations = new Map(); // Active cooking this.activeCooking = []; // Food items this.foodItems = new Map(); // Cooking skill this.cookingLevel = 1; this.cookingXP = 0; // Settings this.settings = { spoilageRate: 0.01, // 1% per minute xpPerRecipe: 10, xpScaling: 1.5 }; this.loadProgress(); this.init(); console.log('✅ Cooking System initialized'); } init() { this.defineRecipes(); this.defineCookingStations(); console.log('🍳 Cooking system ready'); } // ========== RECIPES ========== defineRecipes() { // Basic recipes this.defineRecipe('wheat_bread', { name: 'Wheat Bread', ingredients: { wheat: 3, water: 1 }, cookTime: 30, // seconds cookingStation: 'oven', buffs: { hunger: 50, health: 10 }, buffDuration: 0, // permanent (hunger/health) spoilTime: 300, // 5 minutes xp: 10, requiredLevel: 1 }); this.defineRecipe('vegetable_soup', { name: 'Vegetable Soup', ingredients: { carrot: 2, potato: 2, water: 1 }, cookTime: 45, cookingStation: 'stove', buffs: { hunger: 60, health: 15, stamina: 20 }, buffDuration: 180, // 3 minutes spoilTime: 240, xp: 15, requiredLevel: 2 }); this.defineRecipe('grilled_meat', { name: 'Grilled Meat', ingredients: { raw_meat: 1 }, cookTime: 20, cookingStation: 'grill', buffs: { hunger: 70, health: 20, strength: 15 }, buffDuration: 300, // 5 minutes spoilTime: 180, xp: 20, requiredLevel: 3 }); this.defineRecipe('mutant_stew', { name: 'Mutant Stew', ingredients: { mutant_meat: 2, carrot: 3, potato: 2, water: 1 }, cookTime: 60, cookingStation: 'cauldron', buffs: { hunger: 80, health: 30, strength: 25, speed: 15 }, buffDuration: 600, // 10 minutes spoilTime: 360, xp: 50, requiredLevel: 5 }); this.defineRecipe('golden_apple_pie', { name: 'Golden Apple Pie', ingredients: { golden_apple: 1, wheat: 5, sugar: 3 }, cookTime: 90, cookingStation: 'oven', buffs: { hunger: 100, health: 50, all_stats: 20 }, buffDuration: 900, // 15 minutes spoilTime: 600, xp: 100, requiredLevel: 10 }); } defineRecipe(id, data) { this.recipes.set(id, { id, ...data, discovered: false }); } // ========== COOKING STATIONS ========== defineCookingStations() { this.cookingStations.set('stove', { name: 'Stove', cost: { iron: 10, wood: 5 }, cookingSpeed: 1.0 }); this.cookingStations.set('oven', { name: 'Oven', cost: { iron: 15, stone: 20 }, cookingSpeed: 1.2 }); this.cookingStations.set('grill', { name: 'Grill', cost: { iron: 8, wood: 10 }, cookingSpeed: 0.8 }); this.cookingStations.set('cauldron', { name: 'Cauldron', cost: { iron: 20, magic_crystal: 1 }, cookingSpeed: 1.5 }); } // ========== COOKING ========== canCook(recipeId) { const recipe = this.recipes.get(recipeId); if (!recipe) return false; // Check level if (this.cookingLevel < recipe.requiredLevel) { console.log(`❌ Requires cooking level ${recipe.requiredLevel}`); return false; } // Check ingredients if (!this.scene.inventorySystem) return false; for (const [ingredient, amount] of Object.entries(recipe.ingredients)) { const has = this.scene.inventorySystem.getItemCount(ingredient); if (has < amount) { console.log(`❌ Missing ${ingredient}: ${has}/${amount}`); return false; } } return true; } startCooking(recipeId, stationType) { if (!this.canCook(recipeId)) return false; const recipe = this.recipes.get(recipeId); const station = this.cookingStations.get(stationType); if (!station) { console.log('❌ Invalid cooking station'); return false; } if (recipe.cookingStation !== stationType) { console.log(`❌ Requires ${recipe.cookingStation}`); return false; } // Consume ingredients for (const [ingredient, amount] of Object.entries(recipe.ingredients)) { this.scene.inventorySystem.removeItem(ingredient, amount); } // Start cooking const cookTime = recipe.cookTime / station.cookingSpeed; const cooking = { recipeId, startTime: Date.now(), cookTime: cookTime * 1000, // convert to ms station: stationType }; this.activeCooking.push(cooking); // Discover recipe if (!recipe.discovered) { this.discoverRecipe(recipeId); } console.log(`🍳 Started cooking ${recipe.name} (${cookTime}s)`); return true; } updateCooking(delta) { const now = Date.now(); for (let i = this.activeCooking.length - 1; i >= 0; i--) { const cooking = this.activeCooking[i]; const elapsed = now - cooking.startTime; if (elapsed >= cooking.cookTime) { // Cooking complete! this.completeCooking(cooking); this.activeCooking.splice(i, 1); } } } completeCooking(cooking) { const recipe = this.recipes.get(cooking.recipeId); // Create food item const food = this.createFoodItem(recipe); // Add to inventory if (this.scene.inventorySystem) { this.scene.inventorySystem.addItem(cooking.recipeId, 1); } // Grant XP this.addCookingXP(recipe.xp); // Visual effect if (this.scene.visualEnhancements) { const player = this.scene.player; if (player) { const pos = player.getPosition(); this.scene.visualEnhancements.createSparkleEffect(pos.x, pos.y); } } console.log(`✅ Cooked ${recipe.name}!`); } createFoodItem(recipe) { const food = { id: `food_${Date.now()}`, recipeId: recipe.id, name: recipe.name, buffs: recipe.buffs, buffDuration: recipe.buffDuration, createdTime: Date.now(), spoilTime: recipe.spoilTime * 1000, spoiled: false }; this.foodItems.set(food.id, food); return food; } // ========== EATING ========== eatFood(foodId) { const food = this.foodItems.get(foodId); if (!food) return false; // Check if spoiled if (this.isSpoiled(food)) { console.log('🤢 Food is spoiled!'); // Negative effects if (this.scene.statsSystem) { this.scene.statsSystem.health -= 10; } this.foodItems.delete(foodId); return false; } // Apply buffs this.applyFoodBuffs(food); // Remove food this.foodItems.delete(foodId); console.log(`😋 Ate ${food.name}!`); return true; } applyFoodBuffs(food) { const buffs = food.buffs; // Permanent buffs (hunger, health) if (this.scene.statsSystem) { if (buffs.hunger) { this.scene.statsSystem.hunger = Math.min(100, this.scene.statsSystem.hunger + buffs.hunger); } if (buffs.health) { this.scene.statsSystem.health = Math.min(this.scene.statsSystem.maxHealth, this.scene.statsSystem.health + buffs.health); } } // Temporary buffs if (food.buffDuration > 0) { this.applyTemporaryBuffs(buffs, food.buffDuration); } } applyTemporaryBuffs(buffs, duration) { // Apply buffs for duration const buffData = { buffs, startTime: Date.now(), duration: duration * 1000 }; // Store active buffs (would integrate with player stats) console.log(`✨ Buffs active for ${duration}s:`, buffs); // Schedule buff removal setTimeout(() => { console.log('⏰ Buffs expired'); }, duration * 1000); } // ========== SPOILAGE ========== updateSpoilage(delta) { const now = Date.now(); for (const food of this.foodItems.values()) { const age = now - food.createdTime; if (age > food.spoilTime) { food.spoiled = true; } } } isSpoiled(food) { const age = Date.now() - food.createdTime; return age > food.spoilTime; } // ========== RECIPE DISCOVERY ========== discoverRecipe(recipeId) { const recipe = this.recipes.get(recipeId); if (!recipe) return; recipe.discovered = true; this.knownRecipes.add(recipeId); console.log(`📖 Discovered recipe: ${recipe.name}!`); // Achievement if (this.scene.uiGraphics && this.knownRecipes.size >= 10) { this.scene.uiGraphics.unlockAchievement('master_chef'); } this.saveProgress(); } tryDiscoverRecipe(ingredients) { // Try to match ingredients to unknown recipes for (const [recipeId, recipe] of this.recipes.entries()) { if (recipe.discovered) continue; // Check if ingredients match const matches = this.matchIngredients(ingredients, recipe.ingredients); if (matches) { this.discoverRecipe(recipeId); return recipe; } } return null; } matchIngredients(provided, required) { const providedKeys = Object.keys(provided).sort(); const requiredKeys = Object.keys(required).sort(); if (providedKeys.length !== requiredKeys.length) return false; for (let i = 0; i < providedKeys.length; i++) { if (providedKeys[i] !== requiredKeys[i]) return false; } return true; } // ========== SKILL PROGRESSION ========== addCookingXP(amount) { this.cookingXP += amount; // Level up check const xpNeeded = this.getCookingXPForLevel(this.cookingLevel + 1); if (this.cookingXP >= xpNeeded) { this.levelUpCooking(); } this.saveProgress(); } getCookingXPForLevel(level) { return Math.floor(100 * Math.pow(this.settings.xpScaling, level - 1)); } levelUpCooking() { this.cookingLevel++; this.cookingXP = 0; console.log(`🎉 Cooking level up! Now level ${this.cookingLevel}`); // Visual effect if (this.scene.visualEnhancements) { const player = this.scene.player; if (player) { const pos = player.getPosition(); this.scene.visualEnhancements.createSparkleEffect(pos.x, pos.y); } } this.saveProgress(); } // ========== UPDATE ========== update(delta) { this.updateCooking(delta); this.updateSpoilage(delta); } // ========== PERSISTENCE ========== saveProgress() { const data = { cookingLevel: this.cookingLevel, cookingXP: this.cookingXP, knownRecipes: Array.from(this.knownRecipes) }; localStorage.setItem('novafarma_cooking', JSON.stringify(data)); } loadProgress() { const saved = localStorage.getItem('novafarma_cooking'); if (saved) { try { const data = JSON.parse(saved); this.cookingLevel = data.cookingLevel || 1; this.cookingXP = data.cookingXP || 0; this.knownRecipes = new Set(data.knownRecipes || []); console.log('✅ Cooking progress loaded'); } catch (error) { console.error('Failed to load cooking progress:', error); } } } destroy() { this.saveProgress(); console.log('🍳 Cooking System destroyed'); } }