PHASE 20 COMPLETE: Achievement System - auto-tracking, fancy popups, 8 achievements (harvest, gold, kills, days, etc)
This commit is contained in:
321
src/systems/AchievementTriggers.js
Normal file
321
src/systems/AchievementTriggers.js
Normal file
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
* ACHIEVEMENT TRIGGERS
|
||||
* Automatically tracks game events and unlocks achievements
|
||||
* Connects gameplay to Steam/local achievements
|
||||
*/
|
||||
|
||||
class AchievementTriggers {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.steamIntegration = scene.steamIntegration || new SteamIntegrationSystem();
|
||||
this.steamIntegration.scene = scene; // Link scene for notifications
|
||||
|
||||
// Progress tracking
|
||||
this.trackers = {
|
||||
harvestCount: 0,
|
||||
goldEarned: 0,
|
||||
zombiesKilled: 0,
|
||||
islandsDiscovered: 0,
|
||||
daysSurvived: 0,
|
||||
greenhouseBuilt: false,
|
||||
zombiesTamed: 0
|
||||
};
|
||||
|
||||
// Load saved progress
|
||||
this.loadProgress();
|
||||
|
||||
// Register event listeners
|
||||
this.registerListeners();
|
||||
|
||||
console.log('🏆 Achievement Triggers initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register event listeners for achievements
|
||||
*/
|
||||
registerListeners() {
|
||||
const scene = this.scene;
|
||||
|
||||
// Listen to game events
|
||||
if (scene.events) {
|
||||
// Harvest event
|
||||
scene.events.on('crop-harvested', (cropType) => {
|
||||
this.onHarvest(cropType);
|
||||
});
|
||||
|
||||
// Gold earned event
|
||||
scene.events.on('gold-earned', (amount) => {
|
||||
this.onGoldEarned(amount);
|
||||
});
|
||||
|
||||
// Enemy killed event
|
||||
scene.events.on('enemy-killed', (enemyType) => {
|
||||
this.onEnemyKilled(enemyType);
|
||||
});
|
||||
|
||||
// Building placed event
|
||||
scene.events.on('building-placed', (buildingType) => {
|
||||
this.onBuildingPlaced(buildingType);
|
||||
});
|
||||
|
||||
// Day changed event
|
||||
scene.events.on('day-changed', (dayNumber) => {
|
||||
this.onDayChanged(dayNumber);
|
||||
});
|
||||
|
||||
// Island discovered event
|
||||
scene.events.on('island-discovered', () => {
|
||||
this.onIslandDiscovered();
|
||||
});
|
||||
|
||||
// Zombie tamed event
|
||||
scene.events.on('zombie-tamed', () => {
|
||||
this.onZombieTamed();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Crop harvested
|
||||
*/
|
||||
onHarvest(cropType) {
|
||||
this.trackers.harvestCount++;
|
||||
console.log(`🌾 Harvest count: ${this.trackers.harvestCount}`);
|
||||
|
||||
// FIRST_HARVEST
|
||||
if (this.trackers.harvestCount === 1) {
|
||||
this.unlockAchievement('FIRST_HARVEST');
|
||||
}
|
||||
|
||||
// MASTER_FARMER
|
||||
if (this.trackers.harvestCount >= 1000) {
|
||||
this.unlockAchievement('MASTER_FARMER');
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Gold earned
|
||||
*/
|
||||
onGoldEarned(amount) {
|
||||
this.trackers.goldEarned += amount;
|
||||
console.log(`💰 Total gold earned: ${this.trackers.goldEarned}`);
|
||||
|
||||
// GOLD_RUSH
|
||||
if (this.trackers.goldEarned >= 1000) {
|
||||
this.unlockAchievement('GOLD_RUSH');
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Enemy killed
|
||||
*/
|
||||
onEnemyKilled(enemyType) {
|
||||
if (enemyType === 'zombie' || enemyType === 'elite_zombie') {
|
||||
this.trackers.zombiesKilled++;
|
||||
console.log(`🧟 Zombies killed: ${this.trackers.zombiesKilled}`);
|
||||
|
||||
// ZOMBIE_SLAYER
|
||||
if (this.trackers.zombiesKilled >= 100) {
|
||||
this.unlockAchievement('ZOMBIE_SLAYER');
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Building placed
|
||||
*/
|
||||
onBuildingPlaced(buildingType) {
|
||||
if (buildingType === 'greenhouse') {
|
||||
this.trackers.greenhouseBuilt = true;
|
||||
this.unlockAchievement('GREENHOUSE');
|
||||
this.saveProgress();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Day changed
|
||||
*/
|
||||
onDayChanged(dayNumber) {
|
||||
this.trackers.daysSurvived = dayNumber;
|
||||
console.log(`📅 Day ${dayNumber}`);
|
||||
|
||||
// DAY_30
|
||||
if (dayNumber >= 30) {
|
||||
this.unlockAchievement('DAY_30');
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Island discovered
|
||||
*/
|
||||
onIslandDiscovered() {
|
||||
this.trackers.islandsDiscovered++;
|
||||
console.log(`🏝️ Islands discovered: ${this.trackers.islandsDiscovered}`);
|
||||
|
||||
// OCEAN_EXPLORER
|
||||
if (this.trackers.islandsDiscovered >= 5) {
|
||||
this.unlockAchievement('OCEAN_EXPLORER');
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event: Zombie tamed
|
||||
*/
|
||||
onZombieTamed() {
|
||||
this.trackers.zombiesTamed++;
|
||||
console.log(`🧟♂️ Zombies tamed: ${this.trackers.zombiesTamed}`);
|
||||
|
||||
// TAMED_ZOMBIE
|
||||
if (this.trackers.zombiesTamed >= 1) {
|
||||
this.unlockAchievement('TAMED_ZOMBIE');
|
||||
}
|
||||
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock achievement through Steam Integration
|
||||
*/
|
||||
unlockAchievement(achievementId) {
|
||||
const unlocked = this.steamIntegration.unlockAchievement(achievementId);
|
||||
|
||||
if (unlocked) {
|
||||
// Show fancy notification
|
||||
this.showAchievementNotification(achievementId);
|
||||
|
||||
// Play sound effect
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show achievement unlock notification
|
||||
*/
|
||||
showAchievementNotification(achievementId) {
|
||||
const achievement = this.steamIntegration.achievementDefs[achievementId];
|
||||
if (!achievement) return;
|
||||
|
||||
// Emit to UI Scene for fancy popup
|
||||
if (this.scene.scene && this.scene.scene.get('UIScene')) {
|
||||
const uiScene = this.scene.scene.get('UIScene');
|
||||
|
||||
// Create achievement popup
|
||||
const popup = uiScene.add.container(uiScene.cameras.main.width / 2, 100);
|
||||
popup.setScrollFactor(0);
|
||||
popup.setDepth(100000);
|
||||
|
||||
// Background
|
||||
const bg = uiScene.add.rectangle(0, 0, 350, 80, 0x1a1a1a, 0.95);
|
||||
bg.setStrokeStyle(3, 0xffd700);
|
||||
|
||||
// Trophy icon
|
||||
const icon = uiScene.add.text(-150, 0, '🏆', {
|
||||
fontSize: '48px'
|
||||
});
|
||||
icon.setOrigin(0.5);
|
||||
|
||||
// Title
|
||||
const title = uiScene.add.text(-50, -15, 'ACHIEVEMENT UNLOCKED!', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '14px',
|
||||
color: '#ffd700',
|
||||
fontStyle: 'bold'
|
||||
});
|
||||
title.setOrigin(0, 0.5);
|
||||
|
||||
// Achievement name
|
||||
const name = uiScene.add.text(-50, 10, achievement.name, {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '18px',
|
||||
color: '#ffffff',
|
||||
fontStyle: 'bold'
|
||||
});
|
||||
name.setOrigin(0, 0.5);
|
||||
|
||||
popup.add([bg, icon, title, name]);
|
||||
|
||||
// Animate in
|
||||
popup.setAlpha(0);
|
||||
popup.y = 50;
|
||||
|
||||
uiScene.tweens.add({
|
||||
targets: popup,
|
||||
alpha: 1,
|
||||
y: 100,
|
||||
duration: 500,
|
||||
ease: 'Back.easeOut'
|
||||
});
|
||||
|
||||
// Animate out after delay
|
||||
uiScene.tweens.add({
|
||||
targets: popup,
|
||||
alpha: 0,
|
||||
y: 50,
|
||||
duration: 500,
|
||||
delay: 4000,
|
||||
onComplete: () => {
|
||||
popup.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save progress to localStorage
|
||||
*/
|
||||
saveProgress() {
|
||||
localStorage.setItem('novafarma_achievement_progress', JSON.stringify(this.trackers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load progress from localStorage
|
||||
*/
|
||||
loadProgress() {
|
||||
const saved = localStorage.getItem('novafarma_achievement_progress');
|
||||
if (saved) {
|
||||
try {
|
||||
const loaded = JSON.parse(saved);
|
||||
this.trackers = { ...this.trackers, ...loaded };
|
||||
console.log('📊 Achievement progress loaded:', this.trackers);
|
||||
} catch (e) {
|
||||
console.error('Failed to load achievement progress:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current progress for UI display
|
||||
*/
|
||||
getProgress() {
|
||||
return {
|
||||
...this.trackers,
|
||||
achievements: {
|
||||
FIRST_HARVEST: this.trackers.harvestCount >= 1,
|
||||
GOLD_RUSH: this.trackers.goldEarned >= 1000,
|
||||
ZOMBIE_SLAYER: this.trackers.zombiesKilled >= 100,
|
||||
MASTER_FARMER: this.trackers.harvestCount >= 1000,
|
||||
DAY_30: this.trackers.daysSurvived >= 30,
|
||||
GREENHOUSE: this.trackers.greenhouseBuilt,
|
||||
TAMED_ZOMBIE: this.trackers.zombiesTamed >= 1,
|
||||
OCEAN_EXPLORER: this.trackers.islandsDiscovered >= 5
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Make globally available
|
||||
window.AchievementTriggers = AchievementTriggers;
|
||||
|
||||
console.log('🏆 AchievementTriggers loaded');
|
||||
Reference in New Issue
Block a user