421 lines
13 KiB
JavaScript
421 lines
13 KiB
JavaScript
/**
|
|
* AlbumCollectionSystem.js
|
|
* ========================
|
|
* KRVAVA ŽETEV - Album Collection System (Phase 41)
|
|
*
|
|
* Features:
|
|
* - Collection album UI (book interface)
|
|
* - Auto-discovery on first encounter
|
|
* - 5 categories (Zombies, Plants, Fish, Mutants, Defects)
|
|
* - Completion rewards
|
|
* - Lore entries
|
|
*
|
|
* @author NovaFarma Team
|
|
* @date 2025-12-23
|
|
*/
|
|
|
|
export default class AlbumCollectionSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
// Album state
|
|
this.discovered = new Set();
|
|
this.totalEntries = 0;
|
|
|
|
// Album UI
|
|
this.albumContainer = null;
|
|
this.isAlbumOpen = false;
|
|
this.currentCategory = 'all';
|
|
|
|
// Categories
|
|
this.categories = {
|
|
zombies: { name: 'Legendary Zombies', icon: '🧟', color: 0x00FF00 },
|
|
plants: { name: 'Giant Flowers', icon: '🌸', color: 0xFF69B4 },
|
|
fish: { name: 'Rare Fish', icon: '🐟', color: 0x00CED1 },
|
|
mutants: { name: 'Mutants', icon: '👹', color: 0xFF0000 },
|
|
defects: { name: 'Defective Zombies', icon: '🤪', color: 0xFFD700 }
|
|
};
|
|
|
|
// Album entries
|
|
this.entries = new Map();
|
|
|
|
console.log('📚 AlbumCollectionSystem initialized');
|
|
|
|
// Register all collectibles
|
|
this.registerEntries();
|
|
|
|
// Create album UI
|
|
this.createAlbumUI();
|
|
}
|
|
|
|
/**
|
|
* Register all album entries
|
|
*/
|
|
registerEntries() {
|
|
// Legendary Zombies
|
|
this.registerEntry('zombie_alpha', {
|
|
category: 'zombies',
|
|
name: 'Alpha Zombie',
|
|
description: 'Leader of zombie packs. Stronger and smarter than normal zombies.',
|
|
rarity: 'legendary',
|
|
icon: '👑',
|
|
lore: 'Some say Alphas retain fragments of their human intelligence...'
|
|
});
|
|
this.registerEntry('zombie_tank', {
|
|
category: 'zombies',
|
|
name: 'Tank Zombie',
|
|
description: 'Massive zombie with incredible durability. Slow but deadly.',
|
|
rarity: 'rare',
|
|
icon: '🛡️',
|
|
lore: 'Created from bodybuilders and soldiers.'
|
|
});
|
|
this.registerEntry('zombie_runner', {
|
|
category: 'zombies',
|
|
name: 'Runner Zombie',
|
|
description: 'Fast and agile. Difficult to catch.',
|
|
rarity: 'uncommon',
|
|
icon: '💨',
|
|
lore: 'Athletes who retained their speed in death.'
|
|
});
|
|
|
|
// Giant Flowers (Mesojedke)
|
|
this.registerEntry('mesojedka_giant', {
|
|
category: 'plants',
|
|
name: 'Giant Carnivorous Flower',
|
|
description: 'Stage 5 mesojedka. Massive defense plant with 50 damage output.',
|
|
rarity: 'legendary',
|
|
icon: '🌸',
|
|
lore: 'Fed with legendary meat, these flowers can defend entire farms.'
|
|
});
|
|
this.registerEntry('mesojedka_adult', {
|
|
category: 'plants',
|
|
name: 'Adult Carnivorous Plant',
|
|
description: 'Stage 4 mesojedka. Reliable defense with good harvest.',
|
|
rarity: 'rare',
|
|
icon: '🌺',
|
|
lore: 'The most common defensive plant on farms.'
|
|
});
|
|
|
|
// Rare Fish
|
|
this.registerEntry('fish_golden', {
|
|
category: 'fish',
|
|
name: 'Golden Carp',
|
|
description: 'Extremely rare fish worth 1000 Zlatniki.',
|
|
rarity: 'legendary',
|
|
icon: '🐠',
|
|
lore: 'Legend says catching one brings good fortune for a year.'
|
|
});
|
|
this.registerEntry('fish_nessie', {
|
|
category: 'fish',
|
|
name: 'Nessie',
|
|
description: 'The legendary Loch Ness monster. Portal unlock requirement.',
|
|
rarity: 'legendary',
|
|
icon: '🦕',
|
|
lore: 'She\'s real! And she guards the Loch Ness portal.'
|
|
});
|
|
this.registerEntry('fish_piranha', {
|
|
category: 'fish',
|
|
name: 'Amazon Piranha',
|
|
description: 'Dangerous carnivorous fish from the Amazon zone.',
|
|
rarity: 'rare',
|
|
icon: '🐡',
|
|
lore: 'Survived the apocalypse and got even more aggressive.'
|
|
});
|
|
|
|
// Mutants
|
|
this.registerEntry('mutant_troll', {
|
|
category: 'mutants',
|
|
name: 'Zmaj-Volk (Dragon-Wolf)',
|
|
description: 'Legendary final boss. Hybrid of dragon and wolf.',
|
|
rarity: 'legendary',
|
|
icon: '🐉',
|
|
lore: 'Created by Black Serpent Initiative as the ultimate weapon.'
|
|
});
|
|
this.registerEntry('mutant_frost_giant', {
|
|
category: 'mutants',
|
|
name: 'Frost Giant',
|
|
description: 'Boss of the Frozen Wasteland. Immune to cold.',
|
|
rarity: 'legendary',
|
|
icon: '❄️',
|
|
lore: 'Once a normal person, transformed by experimental freezing.'
|
|
});
|
|
this.registerEntry('mutant_lava_titan', {
|
|
category: 'mutants',
|
|
name: 'Lava Titan',
|
|
description: 'Boss of the Volcanic Crater. Body made of molten rock.',
|
|
rarity: 'legendary',
|
|
icon: '🌋',
|
|
lore: 'Emerged from the volcano after the outbreak.'
|
|
});
|
|
|
|
// Defective Zombies (Lab Jokes)
|
|
this.registerEntry('defect_disco', {
|
|
category: 'defects',
|
|
name: 'Disco Zombie',
|
|
description: 'Lab defect #42. Can\'t stop dancing. Harmless.',
|
|
rarity: 'rare',
|
|
icon: '🕺',
|
|
lore: 'Lab experiment gone wrong. Or... right? He seems happy!'
|
|
});
|
|
this.registerEntry('defect_sleepy', {
|
|
category: 'defects',
|
|
name: 'Sleepy Zombie',
|
|
description: 'Lab defect #13. Always sleeping. Literally cannot wake up.',
|
|
rarity: 'uncommon',
|
|
icon: '😴',
|
|
lore: 'Researchers still don\'t know how he\'s alive while sleeping.'
|
|
});
|
|
this.registerEntry('defect_friendly', {
|
|
category: 'defects',
|
|
name: 'Friendly Zombie',
|
|
description: 'Lab defect #7. Retained all human personality. Just wants hugs.',
|
|
rarity: 'rare',
|
|
icon: '🤗',
|
|
lore: 'The only zombie that remembers its entire past life.'
|
|
});
|
|
|
|
this.totalEntries = this.entries.size;
|
|
console.log(`✅ Registered ${this.totalEntries} album entries`);
|
|
}
|
|
|
|
/**
|
|
* Register single entry
|
|
*/
|
|
registerEntry(id, data) {
|
|
this.entries.set(id, {
|
|
id: id,
|
|
...data,
|
|
discovered: false,
|
|
discoveredDate: null,
|
|
timesEncountered: 0
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Discover entry (first encounter)
|
|
*/
|
|
discoverEntry(id) {
|
|
const entry = this.entries.get(id);
|
|
if (!entry) {
|
|
console.error(`Entry ${id} not found!`);
|
|
return false;
|
|
}
|
|
|
|
if (entry.discovered) {
|
|
// Already discovered, just increment counter
|
|
entry.timesEncountered++;
|
|
return false;
|
|
}
|
|
|
|
// First discovery!
|
|
entry.discovered = true;
|
|
entry.discoveredDate = new Date();
|
|
entry.timesEncountered = 1;
|
|
this.discovered.add(id);
|
|
|
|
console.log(`📖 NEW DISCOVERY: ${entry.name}!`);
|
|
|
|
// Show discovery notification
|
|
this.showDiscoveryNotification(entry);
|
|
|
|
// Check for category completion
|
|
this.checkCategoryCompletion(entry.category);
|
|
|
|
// Check for album completion
|
|
this.checkAlbumCompletion();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Show discovery notification
|
|
*/
|
|
showDiscoveryNotification(entry) {
|
|
this.showNotification({
|
|
title: 'NEW DISCOVERY!',
|
|
text: `${entry.icon} ${entry.name} added to album!`,
|
|
icon: '📖'
|
|
});
|
|
|
|
// Special effects for legendary discoveries
|
|
if (entry.rarity === 'legendary') {
|
|
this.scene.cameras.main.flash(1000, 255, 215, 0); // Golden flash
|
|
this.scene.cameras.main.shake(500, 0.01);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check category completion
|
|
*/
|
|
checkCategoryCompletion(category) {
|
|
const categoryEntries = Array.from(this.entries.values())
|
|
.filter(e => e.category === category);
|
|
const discovered = categoryEntries.filter(e => e.discovered);
|
|
|
|
if (discovered.length === categoryEntries.length) {
|
|
// Category complete!
|
|
const categoryData = this.categories[category];
|
|
|
|
console.log(`🏆 CATEGORY COMPLETE: ${categoryData.name}!`);
|
|
|
|
this.showNotification({
|
|
title: 'CATEGORY COMPLETE!',
|
|
text: `${categoryData.icon} ${categoryData.name} - 100%!`,
|
|
icon: '🏆'
|
|
});
|
|
|
|
// Grant rewards
|
|
this.grantCategoryReward(category);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Grant category completion reward
|
|
*/
|
|
grantCategoryReward(category) {
|
|
const rewards = {
|
|
zombies: { zlatniki: 1000, item: 'alpha_essence' },
|
|
plants: { zlatniki: 1500, item: 'legendary_seeds' },
|
|
fish: { zlatniki: 2000, item: 'master_fishing_rod' },
|
|
mutants: { zlatniki: 5000, item: 'trophy_collection' },
|
|
defects: { zlatniki: 500, item: 'lab_humor_book' }
|
|
};
|
|
|
|
const reward = rewards[category];
|
|
if (reward) {
|
|
console.log(`🎁 Category reward:`, reward);
|
|
// TODO: Grant actual rewards
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check album completion
|
|
*/
|
|
checkAlbumCompletion() {
|
|
if (this.discovered.size === this.totalEntries) {
|
|
console.log('👑 ALBUM 100% COMPLETE!');
|
|
|
|
this.showNotification({
|
|
title: 'ALBUM COMPLETE!',
|
|
text: '👑 100% Collection! You discovered everything!',
|
|
icon: '🏆'
|
|
});
|
|
|
|
// Grant ultimate reward
|
|
this.grantAlbumCompletionReward();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Grant album completion reward
|
|
*/
|
|
grantAlbumCompletionReward() {
|
|
console.log('🎁 ULTIMATE REWARD: Master Collector Trophy!');
|
|
// TODO: Grant legendary item
|
|
}
|
|
|
|
/**
|
|
* Create album UI
|
|
*/
|
|
createAlbumUI() {
|
|
const width = this.scene.cameras.main.width;
|
|
const height = this.scene.cameras.main.height;
|
|
|
|
this.albumContainer = this.scene.add.container(width / 2, height / 2);
|
|
this.albumContainer.setScrollFactor(0);
|
|
this.albumContainer.setDepth(10000);
|
|
this.albumContainer.setVisible(false);
|
|
|
|
// Book background
|
|
const bg = this.scene.add.rectangle(0, 0, 900, 650, 0x8B4513, 0.95);
|
|
bg.setStrokeStyle(5, 0x654321);
|
|
this.albumContainer.add(bg);
|
|
|
|
// Title
|
|
const title = this.scene.add.text(0, -300, '📚 COLLECTION ALBUM', {
|
|
fontSize: '36px',
|
|
fontFamily: 'Georgia',
|
|
color: '#FFD700',
|
|
fontStyle: 'bold'
|
|
});
|
|
title.setOrigin(0.5);
|
|
this.albumContainer.add(title);
|
|
|
|
// Completion percentage
|
|
this.completionText = this.scene.add.text(0, -250, '0%', {
|
|
fontSize: '24px',
|
|
fontFamily: 'Georgia',
|
|
color: '#00FF00'
|
|
});
|
|
this.completionText.setOrigin(0.5);
|
|
this.albumContainer.add(this.completionText);
|
|
|
|
// Close button
|
|
const closeBtn = this.scene.add.text(430, -300, '❌', { fontSize: '24px' });
|
|
closeBtn.setInteractive();
|
|
closeBtn.on('pointerdown', () => this.closeAlbum());
|
|
this.albumContainer.add(closeBtn);
|
|
|
|
console.log('✅ Album UI created');
|
|
}
|
|
|
|
/**
|
|
* Open album
|
|
*/
|
|
openAlbum() {
|
|
this.isAlbumOpen = true;
|
|
this.albumContainer.setVisible(true);
|
|
this.updateAlbumDisplay();
|
|
}
|
|
|
|
/**
|
|
* Close album
|
|
*/
|
|
closeAlbum() {
|
|
this.isAlbumOpen = false;
|
|
this.albumContainer.setVisible(false);
|
|
}
|
|
|
|
/**
|
|
* Update album display
|
|
*/
|
|
updateAlbumDisplay() {
|
|
const completion = (this.discovered.size / this.totalEntries * 100).toFixed(1);
|
|
this.completionText.setText(`${completion}% (${this.discovered.size}/${this.totalEntries})`);
|
|
|
|
// TODO: Display entries
|
|
}
|
|
|
|
/**
|
|
* Get completion percentage
|
|
*/
|
|
getCompletionPercentage() {
|
|
return (this.discovered.size / this.totalEntries * 100).toFixed(1);
|
|
}
|
|
|
|
/**
|
|
* Get category completion
|
|
*/
|
|
getCategoryCompletion(category) {
|
|
const entries = Array.from(this.entries.values()).filter(e => e.category === category);
|
|
const discovered = entries.filter(e => e.discovered);
|
|
return {
|
|
total: entries.length,
|
|
discovered: discovered.length,
|
|
percentage: (discovered.length / entries.length * 100).toFixed(1)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Helper: Show notification
|
|
*/
|
|
showNotification(notification) {
|
|
console.log(`📢 ${notification.icon} ${notification.title}: ${notification.text}`);
|
|
|
|
const ui = this.scene.scene.get('UIScene');
|
|
if (ui && ui.showNotification) {
|
|
ui.showNotification(notification);
|
|
}
|
|
}
|
|
}
|