Initial commit: 3D Hommie RPG game

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-02-25 01:04:09 +03:00
commit fb5f09212b
34 changed files with 14550 additions and 0 deletions

121
js/game/Weather.js Normal file
View File

@@ -0,0 +1,121 @@
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();
}
}