/** * BLUEPRINT SYSTEM (EXPANDED) * Manages unlocking crafting recipes via Blueprint items. * * EXPANSION FEATURES (P24): * - 9 Discovery Methods: Museum, Digging (5%), Beaches, Chests, Boss Drops, NPC Gifts, Quest Rewards, Fishing, Ancient Ruins * - Building Requirements: Cannot build structures without blueprints * - Weapon/Bow Shop Unlocks: Via Wasteland Military Base & Forest Hunter's Lodge quests * - Blueprint UI/Tracker: Collection progress, gallery view */ class BlueprintSystem { constructor(scene) { this.scene = scene; this.unlockedRecipes = new Set(); // Stores IDs of unlocked recipes // Default unlocked recipes (Basic tools & structures) this.unlockedRecipes.add('stick'); this.unlockedRecipes.add('plank'); this.unlockedRecipes.add('chest'); this.unlockedRecipes.add('fence'); this.unlockedRecipes.add('axe'); this.unlockedRecipes.add('pickaxe'); this.unlockedRecipes.add('hoe'); this.unlockedRecipes.add('sword'); // Blueprint Categories this.categories = { basic: ['fence', 'chest', 'campfire', 'torch'], buildings: ['house', 'barn', 'greenhouse', 'workshop', 'silo', 'coop', 'stable'], advanced: ['furnace', 'anvil', 'loom', 'brewery', 'laboratory'], weapons: ['iron_sword', 'steel_sword', 'katana', 'flame_sword', 'plasma_rifle'], bows: ['wooden_bow', 'composite_bow', 'crossbow', 'explosive_bow', 'laser_bow'], vehicles: ['scooter', 'atv', 'tractor', 'helicopter'], special: ['portal_repair', 'time_machine', 'cloning_vat'] }; // Blueprint Definitions (Item ID -> Recipe ID) this.blueprints = { // Basic 'blueprint_campfire': 'campfire', 'blueprint_torch': 'torch', // Buildings (REQUIRED to build!) 'blueprint_house': 'house', 'blueprint_barn': 'barn', 'blueprint_greenhouse': 'greenhouse', 'blueprint_workshop': 'workshop', 'blueprint_silo': 'silo', 'blueprint_chicken_coop': 'coop', 'blueprint_stable': 'stable', // Advanced 'blueprint_furnace': 'furnace', 'blueprint_anvil': 'anvil', 'blueprint_loom': 'loom', 'blueprint_brewery': 'brewery', 'blueprint_laboratory': 'laboratory', // Weapons (Unlocked via Wasteland Military Base quest) 'blueprint_iron_sword': 'iron_sword', 'blueprint_steel_sword': 'steel_sword', 'blueprint_katana': 'katana', 'blueprint_flame_sword': 'flame_sword', 'blueprint_plasma_rifle': 'plasma_rifle', // Bows (Unlocked via Forest Hunter's Lodge quest) 'blueprint_wooden_bow': 'wooden_bow', 'blueprint_composite_bow': 'composite_bow', 'blueprint_crossbow': 'crossbow', 'blueprint_explosive_bow': 'explosive_bow', 'blueprint_laser_bow': 'laser_bow', // Vehicles 'blueprint_scooter': 'scooter_engine', 'blueprint_atv': 'atv', 'blueprint_tractor': 'tractor', 'blueprint_helicopter': 'helicopter', // Special 'blueprint_portal_repair': 'portal_repair', 'blueprint_time_machine': 'time_machine', 'blueprint_cloning_vat': 'cloning_vat' }; // Discovery Methods (9 methods!) this.discoveryMethods = { museum: { chance: 1.0, blueprints: ['blueprint_anvil', 'blueprint_loom', 'blueprint_time_machine'] }, digging: { chance: 0.05, blueprints: ['blueprint_house', 'blueprint_barn', 'blueprint_furnace'] }, beach: { chance: 0.15, blueprints: ['blueprint_workshop', 'blueprint_laboratory'] }, chest: { chance: 0.30, blueprints: Object.keys(this.blueprints) }, boss: { chance: 1.0, blueprints: ['blueprint_plasma_rifle', 'blueprint_laser_bow', 'blueprint_cloning_vat'] }, npc_gift: { chance: 1.0, blueprints: ['blueprint_greenhouse', 'blueprint_brewery', 'blueprint_stable'] }, quest: { chance: 1.0, blueprints: [] }, // Set by specific quests fishing: { chance: 0.08, blueprints: ['blueprint_campfire', 'blueprint_scooter'] }, ruins: { chance: 0.20, blueprints: ['blueprint_katana', 'blueprint_portal_repair', 'blueprint_helicopter'] } }; // Quest-locked blueprints this.questLocks = { 'wasteland_military_base_complete': ['blueprint_iron_sword', 'blueprint_steel_sword', 'blueprint_katana', 'blueprint_flame_sword', 'blueprint_plasma_rifle'], 'forest_hunters_lodge_complete': ['blueprint_wooden_bow', 'blueprint_composite_bow', 'blueprint_crossbow', 'blueprint_explosive_bow', 'blueprint_laser_bow'] }; // Collection tracking this.totalBlueprints = Object.keys(this.blueprints).length; this.discovered = 0; // UI state this.showingGallery = false; console.log('📜 Blueprint System (EXPANDED) initialized!'); console.log(`📊 Total Blueprints: ${this.totalBlueprints}`); } /** * Unlock a recipe */ unlockRecipe(recipeId) { if (this.unlockedRecipes.has(recipeId)) { console.log(`â„šī¸ Recipe ${recipeId} already unlocked.`); return false; } this.unlockedRecipes.add(recipeId); this.discovered++; console.log(`📜 UNLOCKED RECIPE: ${recipeId} (${this.discovered}/${this.totalBlueprints})`); // Notification this.scene.events.emit('show-floating-text', { x: this.scene.player.sprite.x, y: this.scene.player.sprite.y - 100, text: `NEW BLUEPRINT: ${recipeId.toUpperCase()}!`, color: '#00FFFF' }); this.scene.events.emit('notification', { title: 'Blueprint Discovered!', message: `${recipeId.toUpperCase()} unlocked! (${this.discovered}/${this.totalBlueprints})`, icon: '📜' }); if (this.scene.soundManager) this.scene.soundManager.playSuccess(); return true; } /** * Check if unlocked */ isUnlocked(recipeId) { return this.unlockedRecipes.has(recipeId); } /** * Check if can build (buildings require blueprints!) */ canBuild(recipeId) { const buildingCategories = [...this.categories.buildings, ...this.categories.advanced, ...this.categories.special]; // If it's a building, check blueprint if (buildingCategories.includes(recipeId)) { return this.isUnlocked(recipeId); } // Other items can be built without blueprint (but blueprint improves them) return true; } /** * Use a blueprint item from inventory */ useBlueprint(itemId) { const recipeId = this.blueprints[itemId]; if (!recipeId) return false; const success = this.unlockRecipe(recipeId); if (success) { // Consume item if (this.scene.inventorySystem) { this.scene.inventorySystem.removeItem(itemId, 1); } return true; } return false; } /** * Try to discover blueprint via specific method * @param {string} method - 'museum', 'digging', 'beach', 'chest', 'boss', 'npc_gift', 'quest', 'fishing', 'ruins' * @param {number} x - X position * @param {number} y - Y position * @param {string} questId - Optional quest ID for quest-specific blueprints */ tryDiscover(method, x, y, questId = null) { const discoveryData = this.discoveryMethods[method]; if (!discoveryData) { console.log(`❌ Unknown discovery method: ${method}`); return false; } // Roll for discovery if (Math.random() > discoveryData.chance) { return false; // No discovery } // Select blueprint from method's pool let availableBlueprints = discoveryData.blueprints; // Filter out already unlocked availableBlueprints = availableBlueprints.filter(bp => { const recipeId = this.blueprints[bp]; return recipeId && !this.isUnlocked(recipeId); }); if (availableBlueprints.length === 0) { console.log('â„šī¸ All blueprints from this method already discovered!'); return false; } const blueprintItem = availableBlueprints[Math.floor(Math.random() * availableBlueprints.length)]; // Spawn blueprint item if (this.scene.interactionSystem) { this.scene.interactionSystem.spawnLoot(x, y, blueprintItem, 1); console.log(`📜 Discovered Blueprint: ${blueprintItem} via ${method}!`); this.scene.events.emit('notification', { title: 'Blueprint Found!', message: `Discovered ${blueprintItem}!`, icon: '📜' }); return true; } return false; } /** * Unlock quest-specific blueprints */ unlockQuestBlueprints(questId) { const blueprints = this.questLocks[questId]; if (!blueprints) { console.log(`â„šī¸ No blueprints locked behind quest: ${questId}`); return []; } const unlocked = []; blueprints.forEach(blueprintItem => { const recipeId = this.blueprints[blueprintItem]; if (recipeId) { this.unlockRecipe(recipeId); unlocked.push(recipeId); } }); if (unlocked.length > 0) { console.log(`🎉 Quest "${questId}" unlocked ${unlocked.length} blueprints!`); this.scene.events.emit('notification', { title: 'Quest Blueprints Unlocked!', message: `${unlocked.length} new blueprints available!`, icon: '🎉' }); } return unlocked; } /** * Get NPC gift blueprint */ getNPCGift(npcName) { const giftBlueprints = this.discoveryMethods.npc_gift.blueprints; const available = giftBlueprints.filter(bp => { const recipeId = this.blueprints[bp]; return recipeId && !this.isUnlocked(recipeId); }); if (available.length === 0) return null; const blueprintItem = available[Math.floor(Math.random() * available.length)]; console.log(`🎁 ${npcName} gifted blueprint: ${blueprintItem}!`); this.scene.events.emit('notification', { title: 'Gift from ' + npcName, message: `Received ${blueprintItem}!`, icon: '🎁' }); return blueprintItem; } /** * Dig for blueprint (5% chance) */ digForBlueprint(x, y) { return this.tryDiscover('digging', x, y); } /** * Beach combing for blueprint (15% chance) */ beachComb(x, y) { return this.tryDiscover('beach', x, y); } /** * Fishing for blueprint (8% chance) */ fishForBlueprint(x, y) { return this.tryDiscover('fishing', x, y); } /** * Explore ancient ruins for blueprint (20% chance) */ exploreRuins(x, y) { return this.tryDiscover('ruins', x, y); } /** * Open chest for blueprint (30% chance) */ openChest(x, y) { return this.tryDiscover('chest', x, y); } /** * Boss drops blueprint (100% chance, rare blueprints) */ bossDrop(x, y) { return this.tryDiscover('boss', x, y); } /** * Museum visit (specific blueprints, 100% chance) */ visitMuseum() { const museumBlueprints = this.discoveryMethods.museum.blueprints; const available = museumBlueprints.filter(bp => { const recipeId = this.blueprints[bp]; return recipeId && !this.isUnlocked(recipeId); }); if (available.length === 0) { console.log('â„šī¸ All museum blueprints already acquired!'); return null; } const blueprintItem = available[0]; // Give first available console.log(`đŸ›ī¸ Museum blueprint acquired: ${blueprintItem}!`); this.scene.events.emit('notification', { title: 'Museum Discovery!', message: `Acquired ${blueprintItem}!`, icon: 'đŸ›ī¸' }); return blueprintItem; } /** * Get collection progress */ getProgress() { return { discovered: this.discovered, total: this.totalBlueprints, percentage: Math.round((this.discovered / this.totalBlueprints) * 100) }; } /** * Get blueprints by category */ getBlueprintsByCategory(category) { if (!this.categories[category]) return []; return this.categories[category].map(recipeId => { return { recipeId: recipeId, unlocked: this.isUnlocked(recipeId) }; }); } /** * Show blueprint gallery UI */ showGallery() { this.showingGallery = true; const progress = this.getProgress(); console.log('📚 BLUEPRINT GALLERY'); console.log(`Progress: ${progress.discovered}/${progress.total} (${progress.percentage}%)`); console.log('─────────────────────────────────'); Object.keys(this.categories).forEach(category => { const blueprints = this.getBlueprintsByCategory(category); const unlocked = blueprints.filter(bp => bp.unlocked).length; console.log(`${category.toUpperCase()}: ${unlocked}/${blueprints.length}`); blueprints.forEach(bp => { const icon = bp.unlocked ? '✅' : '🔒'; console.log(` ${icon} ${bp.recipeId}`); }); }); // Emit UI event for rendering this.scene.events.emit('show-blueprint-gallery', { progress: progress, categories: this.categories, getBlueprintsByCategory: (cat) => this.getBlueprintsByCategory(cat) }); } /** * Hide blueprint gallery UI */ hideGallery() { this.showingGallery = false; this.scene.events.emit('hide-blueprint-gallery'); } /** * Get hint for locked blueprint */ getHint(recipeId) { // Find blueprint item for this recipe const blueprintItem = Object.keys(this.blueprints).find(key => this.blueprints[key] === recipeId); if (!blueprintItem) return 'Unknown'; // Check which discovery method has it for (const [method, data] of Object.entries(this.discoveryMethods)) { if (data.blueprints.includes(blueprintItem)) { const hints = { museum: 'Visit the Museum', digging: 'Try digging (5% chance)', beach: 'Search beaches (15% chance)', chest: 'Open chests (30% chance)', boss: 'Defeat bosses (100% chance)', npc_gift: 'Befriend NPCs', quest: 'Complete quests', fishing: 'Go fishing (8% chance)', ruins: 'Explore ancient ruins (20% chance)' }; return hints[method] || 'Unknown method'; } } // Check quest locks for (const [questId, blueprints] of Object.entries(this.questLocks)) { if (blueprints.includes(blueprintItem)) { return `Complete quest: ${questId}`; } } return 'Discover through exploration'; } }