/** * TimeSystem.js * ============= * KRVAVA Ε½ETEV - Complete Day/Night Cycle System (Phase 18) * * Features: * - 25-minute days (4 time periods) * - Dynamic lighting system * - Time-based gameplay mechanics * - Sleep system with collapse * - Morning/Night bonuses * - Werewolf spawns at night * * @author NovaFarma Team * @date 2025-12-23 */ export default class TimeSystem { constructor(scene) { this.scene = scene; // Time configuration this.dayLength = 25 * 60 * 1000; // 25 minutes in ms this.currentTime = 6 * 60; // Start at 6:00 AM (in minutes) this.totalMinutes = 24 * 60; // 1440 minutes in a day // Time periods (in hours) this.timePeriods = { morning: { start: 6, end: 12, name: 'Morning', icon: 'πŸŒ…' }, day: { start: 12, end: 18, name: 'Day', icon: 'β˜€οΈ' }, evening: { start: 18, end: 21, name: 'Evening', icon: 'πŸŒ†' }, night: { start: 21, end: 6, name: 'Night', icon: 'πŸŒ™' } }; // Game state this.dayNumber = 1; this.season = 'spring'; // 'spring', 'summer', 'fall', 'winter' this.isPaused = false; // Sleep system this.playerEnergy = 100; this.lastSleptTime = 0; this.hoursAwake = 0; this.collapseWarningShown = false; // Lighting this.ambientLight = null; this.currentLightColor = 0xFFFFFF; // Gameplay modifiers this.zombieEfficiency = 1.0; this.hostileSpawnRate = 1.0; this.werewolfActive = false; console.log('⏰ TimeSystem initialized'); // Start time progression this.startTime(); } /** * Start time progression */ startTime() { // Time progression (1 real second = 0.576 game minutes) this.timeInterval = setInterval(() => { if (!this.isPaused) { this.updateTime(1000); // Update every second } }, 1000); console.log('⏰ Time started at 6:00 AM, Day 1'); } /** * Update time */ updateTime(deltaMs) { // Calculate game minutes passed const gameMinutesPassed = (deltaMs / this.dayLength) * this.totalMinutes; this.currentTime += gameMinutesPassed; this.hoursAwake += gameMinutesPassed / 60; // Check for new day if (this.currentTime >= this.totalMinutes) { this.newDay(); } // Update systems this.updateLighting(); this.updateGameplayModifiers(); this.checkSleepDeprivation(); } /** * New day */ newDay() { this.currentTime = this.currentTime % this.totalMinutes; this.dayNumber++; console.log(`πŸŒ… Day ${this.dayNumber} begins!`); // Check season change (every 28 days) if (this.dayNumber % 28 === 0) { this.changeSeason(); } this.showNotification({ title: `Day ${this.dayNumber}`, text: `πŸŒ… ${this.getCurrentPeriod().name} - ${this.season}`, icon: 'πŸ“…' }); } /** * Change season */ changeSeason() { const seasons = ['spring', 'summer', 'fall', 'winter']; const currentIndex = seasons.indexOf(this.season); this.season = seasons[(currentIndex + 1) % 4]; console.log(`πŸ‚ Season changed to: ${this.season}`); this.showNotification({ title: 'Season Changed!', text: `πŸ‚ Now: ${this.season.toUpperCase()}`, icon: 'πŸ“…' }); } /** * Get current time period */ getCurrentPeriod() { const hour = Math.floor(this.currentTime / 60); if (hour >= 6 && hour < 12) return this.timePeriods.morning; if (hour >= 12 && hour < 18) return this.timePeriods.day; if (hour >= 18 && hour < 21) return this.timePeriods.evening; return this.timePeriods.night; } /** * Update lighting */ updateLighting() { const period = this.getCurrentPeriod(); let targetColor; switch (period.name) { case 'Morning': targetColor = 0xFFE4B5; // Moccasin (warm morning light) break; case 'Day': targetColor = 0xFFFFFF; // Full white break; case 'Evening': targetColor = 0xFFA500; // Orange (sunset) break; case 'Night': targetColor = 0x191970; // Midnight blue break; } // Smooth transition if (this.currentLightColor !== targetColor) { this.currentLightColor = targetColor; this.applyLighting(targetColor); } } /** * Apply lighting to scene */ applyLighting(color) { // TODO: Apply to actual scene // this.scene.cameras.main.setTint(color); console.log(`πŸ’‘ Lighting changed: ${color.toString(16)}`); } /** * Update gameplay modifiers */ updateGameplayModifiers() { const period = this.getCurrentPeriod(); const hour = Math.floor(this.currentTime / 60); // Morning bonus (6:00 - 12:00) if (period.name === 'Morning') { this.zombieEfficiency = 1.2; // +20% this.hostileSpawnRate = 0.5; // 50% reduction this.werewolfActive = false; } // Day (12:00 - 18:00) else if (period.name === 'Day') { this.zombieEfficiency = 1.0; this.hostileSpawnRate = 1.0; this.werewolfActive = false; } // Evening (18:00 - 21:00) else if (period.name === 'Evening') { this.zombieEfficiency = 0.9; this.hostileSpawnRate = 1.5; this.werewolfActive = false; } // Night (21:00 - 6:00) else { this.zombieEfficiency = 0.7; // -30% this.hostileSpawnRate = 2.0; // 2x spawns! this.werewolfActive = true; // Werewolf spawn chance if (Math.random() < 0.01) { // 1% per update this.spawnWerewolf(); } } } /** * Spawn werewolf */ spawnWerewolf() { console.log('🐺 Werewolf spawned!'); this.showNotification({ title: 'WEREWOLF!', text: '🐺 Dangerous creature appeared!', icon: '⚠️' }); // TODO: Actual werewolf spawn } /** * Check sleep deprivation */ checkSleepDeprivation() { const hour = Math.floor(this.currentTime / 60); // Energy decreases based on hours awake if (this.hoursAwake > 16) { this.playerEnergy = Math.max(0, 100 - ((this.hoursAwake - 16) * 10)); } // Warning at 1:00 AM if still awake if (hour === 1 && !this.collapseWarningShown) { this.collapseWarningShown = true; this.showNotification({ title: 'EXHAUSTED!', text: '😴 You need sleep! Will collapse at 2 AM!', icon: '⚠️' }); } // Force collapse at 2:00 AM if (hour === 2 && this.hoursAwake > 20) { this.forceCollapse(); } } /** * Sleep in bed */ sleep() { console.log('😴 Going to sleep...'); // Calculate sleep duration (sleep until 6 AM) const hour = Math.floor(this.currentTime / 60); let hoursToSleep; if (hour >= 6) { // Sleep until tomorrow's 6 AM hoursToSleep = (30 - hour); // Hours until midnight + 6 } else { // Sleep until today's 6 AM hoursToSleep = 6 - hour; } // Advance time this.currentTime += hoursToSleep * 60; if (this.currentTime >= this.totalMinutes) { this.newDay(); } // Restore energy this.playerEnergy = 100; this.hoursAwake = 0; this.lastSleptTime = this.dayNumber; this.collapseWarningShown = false; // Save game this.saveGame(); console.log(`😴 Slept for ${hoursToSleep} hours. Energy restored!`); this.showNotification({ title: 'Well Rested!', text: `😴 Slept ${hoursToSleep} hours. Day ${this.dayNumber}`, icon: '✨' }); return true; } /** * Force collapse (didn't sleep) */ forceCollapse() { console.log('πŸ’€ Collapsed from exhaustion!'); this.showNotification({ title: 'COLLAPSED!', text: 'πŸ’€ You passed out from exhaustion!', icon: '⚠️' }); // Lose some items/money as penalty // TODO: Apply penalties // Force sleep this.sleep(); } /** * Save game */ saveGame() { try { const saveData = { time: this.currentTime, day: this.dayNumber, season: this.season, energy: this.playerEnergy }; localStorage.setItem('krvava_zetev_time', JSON.stringify(saveData)); console.log('πŸ’Ύ Game saved (sleep)'); } catch (error) { console.error('Failed to save game:', error); } } /** * Load game */ loadGame() { try { const saved = localStorage.getItem('krvava_zetev_time'); if (saved) { const data = JSON.parse(saved); this.currentTime = data.time; this.dayNumber = data.day; this.season = data.season; this.playerEnergy = data.energy; console.log(`πŸ“₯ Game loaded: Day ${this.dayNumber}, ${this.getTimeString()}`); return true; } } catch (error) { console.error('Failed to load game:', error); } return false; } /** * Get time as string */ getTimeString() { const totalMinutes = Math.floor(this.currentTime); const hours = Math.floor(totalMinutes / 60) % 24; const minutes = totalMinutes % 60; const period = hours >= 12 ? 'PM' : 'AM'; const displayHours = hours % 12 || 12; return `${displayHours}:${minutes.toString().padStart(2, '0')} ${period}`; } /** * Get current info */ getTimeInfo() { const period = this.getCurrentPeriod(); return { time: this.getTimeString(), day: this.dayNumber, season: this.season, period: period.name, periodIcon: period.icon, energy: this.playerEnergy, hoursAwake: Math.floor(this.hoursAwake), zombieEfficiency: this.zombieEfficiency, hostileSpawnRate: this.hostileSpawnRate, werewolfActive: this.werewolfActive }; } /** * Pause time */ pauseTime() { this.isPaused = true; console.log('⏸️ Time paused'); } /** * Resume time */ resumeTime() { this.isPaused = false; console.log('▢️ Time resumed'); } /** * Set time (for testing) */ setTime(hour, minute = 0) { this.currentTime = (hour * 60) + minute; console.log(`⏰ Time set to ${this.getTimeString()}`); } /** * Cleanup */ destroy() { if (this.timeInterval) { clearInterval(this.timeInterval); } } /** * 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); } } }