LEGENDARY NIGHT! P22-P25 complete - 4 new systems (2,300 LOC) - Smart Zombies, Tools, Blueprints, Ana Clues!

This commit is contained in:
2025-12-23 21:28:55 +01:00
parent 4d1428b523
commit 8939c51edb
5 changed files with 1954 additions and 68 deletions

View File

@@ -1,6 +1,12 @@
/**
* BLUEPRINT SYSTEM
* 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) {
@@ -16,17 +22,94 @@ class BlueprintSystem {
this.unlockedRecipes.add('pickaxe');
this.unlockedRecipes.add('hoe');
this.unlockedRecipes.add('sword');
this.unlockedRecipes.add('furnace');
this.unlockedRecipes.add('mint');
this.unlockedRecipes.add('grave');
// 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_scooter_part': 'scooter_engine', // Example special part
'blueprint_grave': 'gravestone'
'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}`);
}
/**
@@ -39,16 +122,24 @@ class BlueprintSystem {
}
this.unlockedRecipes.add(recipeId);
console.log(`📜 UNLOCKED RECIPE: ${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 RECIPE: ${recipeId.toUpperCase()}!`,
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;
}
@@ -60,6 +151,21 @@ class BlueprintSystem {
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
*/
@@ -70,33 +176,292 @@ class BlueprintSystem {
const success = this.unlockRecipe(recipeId);
if (success) {
// Consume item
this.scene.inventorySystem.removeItem(itemId, 1);
if (this.scene.inventorySystem) {
this.scene.inventorySystem.removeItem(itemId, 1);
}
return true;
}
return false;
}
/**
* Try to get a blueprint drop from mining/killing
* @param {string} source 'mining', 'combat', 'chest'
* 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
*/
tryDropBlueprint(x, y, source) {
let chance = 0.05; // 5% base chance
if (source === 'boss') chance = 1.0;
if (source === 'chest') chance = 0.3;
tryDiscover(method, x, y, questId = null) {
const discoveryData = this.discoveryMethods[method];
if (!discoveryData) {
console.log(`❌ Unknown discovery method: ${method}`);
return false;
}
if (Math.random() < chance) {
// Select random locked blueprint
const allBlueprints = Object.keys(this.blueprints);
const dropItem = allBlueprints[Math.floor(Math.random() * allBlueprints.length)];
// Roll for discovery
if (Math.random() > discoveryData.chance) {
return false; // No discovery
}
// Check if user already has it unlocked? Maybe drop anyway for trading?
// For now, simple drop.
// Select blueprint from method's pool
let availableBlueprints = discoveryData.blueprints;
if (this.scene.interactionSystem) {
this.scene.interactionSystem.spawnLoot(x, y, dropItem, 1);
console.log(`📜 Dropped Blueprint: ${dropItem}`);
// 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';
}
}