Files
Hommie_RPG_Game/js/game/Weather.js
Maxim Dolgolyov fb5f09212b Initial commit: 3D Hommie RPG game
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 01:04:09 +03:00

122 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export class Weather {
constructor(game) {
this.game = game;
this.current = 'clear'; // clear | rain | snow | fog
this.temperature = 15; // °C
this.changeTimer = 0;
this.changeCooldown = 180; // секунд реальных между сменами погоды
this.windStrength = 0;
}
init() {
this.current = 'clear';
this.temperature = 15;
this.changeTimer = 60 + Math.random() * 120;
}
update(dt) {
this.changeTimer -= dt;
if (this.changeTimer <= 0) {
this.changeWeather();
this.changeTimer = this.changeCooldown + Math.random() * 120;
}
// Температура зависит от времени суток, погоды и сезона
const hour = this.game.gameTime / 60;
let baseTemp;
if (hour >= 10 && hour < 16) {
baseTemp = 18;
} else if (hour >= 6 && hour < 10) {
baseTemp = 10;
} else if (hour >= 16 && hour < 21) {
baseTemp = 12;
} else {
baseTemp = 3;
}
// Сезонный модификатор температуры
baseTemp += this.game.seasons.getTemperatureModifier();
if (this.current === 'rain') baseTemp -= 5;
if (this.current === 'snow') baseTemp -= 15;
if (this.current === 'fog') baseTemp -= 2;
this.temperature += (baseTemp - this.temperature) * dt * 0.1;
// Влияние на тепло игрока
this.applyEffects(dt);
// Ветер
this.windStrength = (this.current === 'rain' || this.current === 'snow') ?
0.3 + Math.sin(Date.now() * 0.001) * 0.2 : 0.05;
}
changeWeather() {
// Веса погоды зависят от сезона
const weights = this.game.seasons.getWeatherWeights();
const hour = this.game.gameTime / 60;
// Ночью больше тумана и снега
if (hour < 6 || hour > 21) {
weights.fog += 2;
weights.snow += 1;
}
// Строим массив с весами
const pool = [];
for (const [type, w] of Object.entries(weights)) {
for (let i = 0; i < w; i++) pool.push(type);
}
let newWeather;
do {
newWeather = pool[Math.floor(Math.random() * pool.length)];
} while (newWeather === this.current && pool.length > 1);
this.current = newWeather;
this.game.particles.setWeather(newWeather);
// Визуальные эффекты тумана
if (newWeather === 'fog') {
this.game.scene.fog.near = 10;
this.game.scene.fog.far = 50;
} else {
this.game.scene.fog.near = 80;
this.game.scene.fog.far = 200;
}
const names = { clear: 'Ясно', rain: 'Дождь', snow: 'Снег', fog: 'Туман' };
this.game.notify(`Погода: ${names[newWeather]} (${Math.round(this.temperature)}°C)`);
}
applyEffects(dt) {
const player = this.game.player;
const seasonDrain = this.game.seasons.getWarmthDrain();
if (this.current === 'rain') {
player.stats.warmth = Math.max(0, player.stats.warmth - 0.08 * seasonDrain * dt);
player.stats.mood = Math.max(0, player.stats.mood - 0.03 * dt);
}
if (this.current === 'snow') {
player.stats.warmth = Math.max(0, player.stats.warmth - 0.15 * seasonDrain * dt);
player.stats.mood = Math.max(0, player.stats.mood - 0.05 * dt);
}
// Холодная температура
if (this.temperature < 5) {
player.stats.warmth = Math.max(0, player.stats.warmth - 0.1 * seasonDrain * dt);
}
}
getIcon() {
const icons = { clear: '☀️', rain: '🌧️', snow: '❄️', fog: '🌫️' };
return icons[this.current] || '☀️';
}
reset() {
this.init();
}
}