399 lines
10 KiB
JavaScript
399 lines
10 KiB
JavaScript
/**
|
|
* GAME MANAGER - AUTO-SAVE SYSTEM
|
|
* "The Silent Protector" - Never lose progress!
|
|
*/
|
|
|
|
class GameManager {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
this.saveKey = 'mrtva_dolina_save'; // Slot_0
|
|
|
|
// Auto-save state
|
|
this.lastAutoSave = Date.now();
|
|
this.autoSaveInterval = 5 * 60 * 1000; // 5 minutes
|
|
this.isSaving = false;
|
|
|
|
// Save indicator
|
|
this.saveIndicator = null;
|
|
|
|
// Initialize
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
console.log('💾 GameManager initialized - Auto-save active');
|
|
|
|
// Start periodic auto-save timer
|
|
this.startPeriodicAutoSave();
|
|
|
|
// Listen for scene transitions
|
|
this.scene.events.on('shutdown', () => this.onSceneTransition());
|
|
|
|
// Listen for progression events
|
|
this.listenForProgressionEvents();
|
|
}
|
|
|
|
/**
|
|
* TRIGGER 1: SCENE TRANSITION SAVE
|
|
*/
|
|
onSceneTransition() {
|
|
console.log('🚪 Scene transition detected - Auto-saving...');
|
|
this.autoSaveGame('Scene Transition');
|
|
}
|
|
|
|
/**
|
|
* TRIGGER 2: PROGRESSION MILESTONE SAVE
|
|
*/
|
|
listenForProgressionEvents() {
|
|
// Listen for aging events
|
|
this.scene.events.on('kai-aged', (data) => {
|
|
console.log(`⏰ Kai aged to ${data.newAge} - Auto-saving...`);
|
|
this.autoSaveGame('Aging Milestone');
|
|
});
|
|
|
|
// Listen for memory found
|
|
this.scene.events.on('memory-found', (data) => {
|
|
console.log(`📸 Memory found (${data.id}) - Auto-saving...`);
|
|
this.autoSaveGame('Memory Found');
|
|
});
|
|
|
|
// Listen for Gronk level up
|
|
if (window.gronkStats) {
|
|
window.addEventListener('gronk-levelup', (e) => {
|
|
console.log(`💨 Gronk level ${e.detail.level} - Auto-saving...`);
|
|
this.autoSaveGame('Gronk Level Up');
|
|
});
|
|
}
|
|
|
|
// Listen for companion unlocks
|
|
window.addEventListener('companion-unlocked', (e) => {
|
|
console.log(`🐕 Companion unlocked (${e.detail.name}) - Auto-saving...`);
|
|
this.autoSaveGame('Companion Unlock');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* TRIGGER 3: PERIODIC AUTO-SAVE (5 Minutes)
|
|
*/
|
|
startPeriodicAutoSave() {
|
|
this.periodicTimer = this.scene.time.addEvent({
|
|
delay: this.autoSaveInterval,
|
|
callback: () => {
|
|
const timeSinceLastSave = Date.now() - this.lastAutoSave;
|
|
if (timeSinceLastSave >= this.autoSaveInterval) {
|
|
console.log('⏱️ 5 minutes elapsed - Auto-saving...');
|
|
this.autoSaveGame('Periodic (5min)');
|
|
}
|
|
},
|
|
loop: true
|
|
});
|
|
}
|
|
|
|
/**
|
|
* AUTO-SAVE GAME (Silent, no interruption)
|
|
*/
|
|
autoSaveGame(reason = 'Manual') {
|
|
if (this.isSaving) {
|
|
console.log('⚠️ Save already in progress, skipping...');
|
|
return;
|
|
}
|
|
|
|
this.isSaving = true;
|
|
|
|
console.log(`💾 AUTO-SAVING (${reason})...`);
|
|
|
|
// Show save indicator
|
|
this.showSaveIndicator();
|
|
|
|
try {
|
|
// Gather save data
|
|
const saveData = this.gatherSaveData();
|
|
|
|
// Save to LocalStorage (Slot_0)
|
|
localStorage.setItem(this.saveKey, JSON.stringify(saveData));
|
|
|
|
// Update timestamp
|
|
this.lastAutoSave = Date.now();
|
|
|
|
console.log('✅ Auto-save complete!');
|
|
console.log(` Reason: ${reason}`);
|
|
console.log(` Size: ${JSON.stringify(saveData).length} bytes`);
|
|
|
|
} catch (error) {
|
|
console.error('❌ Auto-save failed:', error);
|
|
} finally {
|
|
this.isSaving = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GATHER ALL SAVE DATA
|
|
*/
|
|
gatherSaveData() {
|
|
const data = {
|
|
version: '1.0.0',
|
|
lastSaved: new Date().toISOString(),
|
|
playtime: this.getPlaytime(),
|
|
|
|
// Player data
|
|
player: this.getPlayerData(),
|
|
|
|
// Progress
|
|
progress: this.getProgressData(),
|
|
|
|
// Companions
|
|
companions: this.getCompanionData(),
|
|
|
|
// Farm state
|
|
farm: this.getFarmData(),
|
|
|
|
// Economy
|
|
economy: this.getEconomyData(),
|
|
|
|
// Current scene
|
|
currentScene: this.scene.scene.key
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* GET PLAYER DATA
|
|
*/
|
|
getPlayerData() {
|
|
// Get PlayerStats if exists
|
|
let playerStats = null;
|
|
if (this.scene.playerStats) {
|
|
playerStats = this.scene.playerStats.getAgeInfo();
|
|
} else {
|
|
// Load from LocalStorage
|
|
const stored = localStorage.getItem('player_stats');
|
|
if (stored) {
|
|
playerStats = JSON.parse(stored);
|
|
}
|
|
}
|
|
|
|
return {
|
|
position: this.getPlayerPosition(),
|
|
age_level: playerStats?.level || 1,
|
|
current_age: playerStats?.age || 14,
|
|
age_sprite: playerStats?.sprite || 'kai_age14',
|
|
inventory: this.getInventory(),
|
|
health: 100,
|
|
stamina: 100,
|
|
equipped_tools: {}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* GET PROGRESS DATA
|
|
*/
|
|
getProgressData() {
|
|
return {
|
|
memories_found: this.getMemoriesFound(),
|
|
total_memories: 100,
|
|
quests_completed: [],
|
|
npcs_met: [],
|
|
biomes_unlocked: ['grassland']
|
|
};
|
|
}
|
|
|
|
/**
|
|
* GET COMPANION DATA
|
|
*/
|
|
getCompanionData() {
|
|
const companions = {
|
|
gronk: {
|
|
unlocked: false,
|
|
level: 1,
|
|
xp: 0
|
|
},
|
|
susi: {
|
|
unlocked: false,
|
|
position: { x: 0, y: 0 },
|
|
loyalty: 0
|
|
}
|
|
};
|
|
|
|
// Check Gronk stats
|
|
if (window.gronkStats) {
|
|
const gronkData = gronkStats.getStats();
|
|
companions.gronk = {
|
|
unlocked: true,
|
|
level: gronkData.level,
|
|
xp: gronkData.xp
|
|
};
|
|
}
|
|
|
|
// Check Susi unlock
|
|
const susiUnlocked = localStorage.getItem('susi_unlocked');
|
|
if (susiUnlocked === 'true') {
|
|
companions.susi.unlocked = true;
|
|
}
|
|
|
|
return companions;
|
|
}
|
|
|
|
/**
|
|
* GET FARM DATA
|
|
*/
|
|
getFarmData() {
|
|
return {
|
|
crops: [],
|
|
buildings: [],
|
|
animals: [],
|
|
resources: {}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* GET ECONOMY DATA
|
|
*/
|
|
getEconomyData() {
|
|
return {
|
|
money: 0,
|
|
cannabis_seeds: 5, // Starting capital!
|
|
cannabis_harvested: 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* HELPER: Get player position
|
|
*/
|
|
getPlayerPosition() {
|
|
if (this.scene.player) {
|
|
return {
|
|
x: this.scene.player.x,
|
|
y: this.scene.player.y
|
|
};
|
|
}
|
|
return { x: 640, y: 360 }; // Default center
|
|
}
|
|
|
|
/**
|
|
* HELPER: Get inventory
|
|
*/
|
|
getInventory() {
|
|
// TODO: Get from inventory system
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* HELPER: Get memories found
|
|
*/
|
|
getMemoriesFound() {
|
|
const stored = localStorage.getItem('player_stats');
|
|
if (stored) {
|
|
const data = JSON.parse(stored);
|
|
return data.memoriesFound || 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* HELPER: Get playtime
|
|
*/
|
|
getPlaytime() {
|
|
const stored = localStorage.getItem('playtime');
|
|
if (stored) {
|
|
return parseInt(stored) + Math.floor(this.scene.time.now / 1000);
|
|
}
|
|
return Math.floor(this.scene.time.now / 1000);
|
|
}
|
|
|
|
/**
|
|
* SHOW SAVE INDICATOR (Spinning Longboard)
|
|
*/
|
|
showSaveIndicator() {
|
|
if (this.saveIndicator) {
|
|
return; // Already showing
|
|
}
|
|
|
|
const width = this.scene.cameras.main.width;
|
|
const height = this.scene.cameras.main.height;
|
|
|
|
// Create longboard emoji as indicator
|
|
this.saveIndicator = this.scene.add.text(
|
|
width - 80,
|
|
height - 80,
|
|
'🛹',
|
|
{
|
|
fontSize: '32px'
|
|
}
|
|
);
|
|
this.saveIndicator.setScrollFactor(0);
|
|
this.saveIndicator.setDepth(9999);
|
|
this.saveIndicator.setAlpha(0);
|
|
|
|
// Add "Saving..." text
|
|
const savingText = this.scene.add.text(
|
|
width - 140,
|
|
height - 50,
|
|
'Saving...',
|
|
{
|
|
fontSize: '14px',
|
|
fontFamily: 'Georgia, serif',
|
|
color: '#f4e4c1',
|
|
stroke: '#000000',
|
|
strokeThickness: 3
|
|
}
|
|
);
|
|
savingText.setScrollFactor(0);
|
|
savingText.setDepth(9999);
|
|
savingText.setAlpha(0);
|
|
|
|
// Fade in
|
|
this.scene.tweens.add({
|
|
targets: [this.saveIndicator, savingText],
|
|
alpha: 0.8,
|
|
duration: 300
|
|
});
|
|
|
|
// Spin animation
|
|
this.scene.tweens.add({
|
|
targets: this.saveIndicator,
|
|
angle: 360,
|
|
duration: 1000,
|
|
repeat: 1
|
|
});
|
|
|
|
// Fade out after 2 seconds
|
|
this.scene.time.delayedCall(2000, () => {
|
|
this.scene.tweens.add({
|
|
targets: [this.saveIndicator, savingText],
|
|
alpha: 0,
|
|
duration: 500,
|
|
onComplete: () => {
|
|
if (this.saveIndicator) {
|
|
this.saveIndicator.destroy();
|
|
this.saveIndicator = null;
|
|
}
|
|
if (savingText) {
|
|
savingText.destroy();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* MANUAL SAVE (for explicit save points)
|
|
*/
|
|
manualSave() {
|
|
console.log('💾 Manual save requested...');
|
|
this.autoSaveGame('Manual Save');
|
|
}
|
|
|
|
/**
|
|
* CLEANUP
|
|
*/
|
|
destroy() {
|
|
if (this.periodicTimer) {
|
|
this.periodicTimer.remove();
|
|
}
|
|
console.log('💾 GameManager destroyed');
|
|
}
|
|
}
|
|
|
|
export default GameManager;
|