export class EventSystem { constructor(game) { this.game = game; this.timer = 30 + Math.random() * 60; this.eventCooldown = 0; this.activeEvent = null; } update(dt) { if (this.eventCooldown > 0) { this.eventCooldown -= dt; return; } this.timer -= dt; if (this.timer <= 0) { this.triggerRandom(); this.timer = 40 + Math.random() * 80; } } triggerRandom() { const hour = this.game.gameTime / 60; const isNight = hour < 6 || hour > 21; const player = this.game.player; const events = [ { weight: 10, fn: () => this.eventFoundWallet() }, { weight: 8, fn: () => this.eventStrayDogFood() }, { weight: 7, fn: () => this.eventOldFriend() }, { weight: 6, fn: () => this.eventRainOfCoins() }, { weight: 8, fn: () => this.eventKindStranger() }, { weight: 5, fn: () => this.eventFoodTruck() }, { weight: isNight ? 10 : 3, fn: () => this.eventColdWind() }, { weight: isNight ? 8 : 2, fn: () => this.eventScaryNoise() }, { weight: player.stats.mood < 30 ? 10 : 3, fn: () => this.eventMemory() }, { weight: 4, fn: () => this.eventStreetMusician() }, { weight: player.stats.health < 40 ? 8 : 2, fn: () => this.eventAmbulance() }, { weight: 5, fn: () => this.eventNewspaper() }, { weight: 6, fn: () => this.eventPigeons() }, { weight: isNight ? 2 : 6, fn: () => this.eventSunshine() }, ]; const totalWeight = events.reduce((s, e) => s + e.weight, 0); let roll = Math.random() * totalWeight; for (const event of events) { roll -= event.weight; if (roll <= 0) { event.fn(); this.eventCooldown = 20; return; } } } eventFoundWallet() { const amount = 20 + Math.floor(Math.random() * 80); this.game.ui.showDialog('Находка', `Вы нашли на земле кошелёк! Внутри ${amount}₽. Что делать?`, [ `Забрать деньги (+${amount}₽)`, 'Оставить на месте (может кто-то вернётся)', ], (i) => { if (i === 0) { this.game.player.stats.money += amount; this.game.sound.playCoin(); this.game.notify(`+${amount}₽`, 'good'); this.game.player.stats.mood = Math.max(0, this.game.player.stats.mood - 2); this.game.reputation.change(-5); } else { this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 8); this.game.notify('+8 Настроение. Вы поступили честно.', 'good'); this.game.reputation.change(10); } this.game.ui.hideDialog(); }); } eventStrayDogFood() { if (this.game.dog && this.game.dog.adopted) return; const hasBread = this.game.inventory.getCount('bread') > 0; const choices = hasBread ? ['Покормить хлебом', 'Прогнать'] : ['Погладить', 'Прогнать']; this.game.ui.showDialog('Событие', 'Бездомный пёс подошёл к вам и смотрит голодными глазами...', choices, (i) => { if (i === 0) { if (hasBread) { this.game.inventory.removeItem('bread', 1); this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 12); this.game.notify('Пёс виляет хвостом! +12 Настроение', 'good'); // Приручить если ещё не приручен if (this.game.dog && !this.game.dog.adopted) { this.game.dog.adopt(); this.game.notify('Пёс решил остаться с вами!', 'good'); this.game.questSystem.onEvent('adopt_dog'); } } else { this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 5); this.game.notify('Пёс благодарно лизнул руку.', 'good'); } } else { this.game.notify('Пёс убежал с поджатым хвостом...'); this.game.player.stats.mood = Math.max(0, this.game.player.stats.mood - 3); } this.game.ui.hideDialog(); }); } eventOldFriend() { this.game.ui.showDialog('Событие', 'Вы встретили старого знакомого. Он узнал вас и выглядит смущённым...', [ '"Привет, давно не виделись..."', 'Отвернуться', ], (i) => { if (i === 0) { const roll = Math.random(); if (roll < 0.5) { const amount = 50 + Math.floor(Math.random() * 100); this.game.player.stats.money += amount; this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 10); this.game.sound.playCoin(); this.game.notify(`Он дал вам ${amount}₽ и пожелал удачи.`, 'good'); } else { this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 5); this.game.notify('Он обнял вас и пожелал сил. +5 Настроение', 'good'); } } else { this.game.player.stats.mood = Math.max(0, this.game.player.stats.mood - 5); this.game.notify('Вы отвернулись. Стало грустно.', 'bad'); } this.game.ui.hideDialog(); }); } eventRainOfCoins() { const amount = 5 + Math.floor(Math.random() * 15); this.game.player.stats.money += amount; this.game.sound.playCoin(); this.game.notify(`Кто-то обронил мелочь! +${amount}₽`, 'good'); } eventKindStranger() { this.game.ui.showDialog('Событие', 'К вам подошёл человек в дорогом пальто. "Я из благотворительной организации. Хотите горячий обед?"', [ 'Да, спасибо!', 'Нет, обойдусь', ], (i) => { if (i === 0) { this.game.player.stats.hunger = Math.min(100, this.game.player.stats.hunger + 50); this.game.player.stats.warmth = Math.min(100, this.game.player.stats.warmth + 15); this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 15); this.game.sound.playEat(); this.game.notify('Вы сытно поели! +50 Сытость, +15 Тепло, +15 Настроение', 'good'); } this.game.ui.hideDialog(); }); } eventFoodTruck() { this.game.notify('Фудтрак раздаёт бесплатную еду рядом!'); this.game.inventory.addItem('can', 1); this.game.inventory.addItem('tea', 1); this.game.sound.playPickup(); this.game.notify('Получено: Консервы, Чай', 'good'); } eventColdWind() { this.game.player.stats.warmth = Math.max(0, this.game.player.stats.warmth - 15); this.game.player.stats.mood = Math.max(0, this.game.player.stats.mood - 5); this.game.notify('Порыв ледяного ветра! -15 Тепло', 'bad'); } eventScaryNoise() { this.game.player.stats.mood = Math.max(0, this.game.player.stats.mood - 8); this.game.notify('Странный шум в темноте... -8 Настроение', 'bad'); this.game.sound.playHurt(); } eventMemory() { const memories = [ 'Вы вспомнили детство... тёплый дом, мамин суп...', 'В голове всплыло лицо старого друга... Где он сейчас?', 'Вы нашли в кармане старую фотографию. Сердце защемило.', 'Знакомая мелодия из окна... Вы когда-то танцевали под неё.', ]; const text = memories[Math.floor(Math.random() * memories.length)]; this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 3); this.game.notify(text); } eventStreetMusician() { this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 10); this.game.notify('Уличный музыкант играет красивую мелодию. +10 Настроение', 'good'); } eventAmbulance() { this.game.ui.showDialog('Событие', 'Медработник-волонтёр заметил вас. "Давайте я вас осмотрю?"', [ 'Да, пожалуйста', 'Не нужно', ], (i) => { if (i === 0) { this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 30); this.game.inventory.addItem('bandage', 1); this.game.notify('+30 Здоровье. Получен: Бинт', 'good'); } this.game.ui.hideDialog(); }); } eventNewspaper() { this.game.inventory.addItem('newspaper', 1); this.game.sound.playPickup(); this.game.notify('Ветер принёс газету. Можно почитать.', 'good'); } eventPigeons() { this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 3); this.game.notify('Стая голубей приземлилась рядом. Маленькая радость.'); } eventSunshine() { this.game.player.stats.warmth = Math.min(100, this.game.player.stats.warmth + 8); this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 5); this.game.notify('Тёплый луч солнца согрел лицо. +8 Тепло', 'good'); } reset() { this.timer = 30 + Math.random() * 60; this.eventCooldown = 0; this.activeEvent = null; } }