441 lines
16 KiB
JavaScript
441 lines
16 KiB
JavaScript
export class QuestSystem {
|
||
constructor(game) {
|
||
this.game = game;
|
||
this.quests = [];
|
||
this.completedQuests = [];
|
||
}
|
||
|
||
initQuests() {
|
||
this.quests = [];
|
||
this.completedQuests = [];
|
||
|
||
this.addQuest({
|
||
id: 'first_search',
|
||
title: 'Первые поиски',
|
||
description: 'Обыщите мусорку и найдите что-нибудь полезное.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'collect_bottle',
|
||
altEvents: ['find_food', 'find_money'],
|
||
location: { x: -20, z: -10 },
|
||
reward: () => {
|
||
this.game.player.stats.mood += 10;
|
||
this.game.notify('Квест выполнен! +10 Настроение');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'bottle_collector',
|
||
title: 'Собиратель бутылок',
|
||
description: 'Соберите 5 пустых бутылок.',
|
||
target: 5,
|
||
progress: 0,
|
||
event: 'collect_bottle',
|
||
reward: () => {
|
||
this.game.player.stats.money += 30;
|
||
this.game.notify('Квест выполнен! +30 ₽');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'meet_serega',
|
||
title: 'Новые знакомства',
|
||
description: 'Поговорите с Серёгой в укрытии.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'talk_npc',
|
||
eventFilter: 'Серёга',
|
||
location: { x: -35, z: 28 },
|
||
reward: () => {
|
||
this.game.player.stats.mood += 15;
|
||
this.game.notify('Квест выполнен! +15 Настроение. Серёга теперь ваш друг.');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'first_night',
|
||
title: 'Первая ночь',
|
||
description: 'Переживите первую ночь — поспите в укрытии.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'sleep',
|
||
location: { x: -45, z: 40 },
|
||
reward: () => {
|
||
this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 10);
|
||
this.game.notify('Квест выполнен! +10 Здоровье');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'earn_money',
|
||
title: 'Первый заработок',
|
||
description: 'Заработайте 50 ₽ любым способом.',
|
||
target: 50,
|
||
progress: 0,
|
||
event: 'find_money',
|
||
cumulative: true,
|
||
reward: () => {
|
||
this.game.player.stats.mood += 20;
|
||
this.game.notify('Квест выполнен! +20 Настроение. Вы учитесь выживать!');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'talk_granny',
|
||
title: 'Добрая душа',
|
||
description: 'Поговорите с бабушкой Зиной в парке.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'talk_npc',
|
||
eventFilter: 'Бабушка Зина',
|
||
location: { x: -22, z: 22 },
|
||
reward: () => {
|
||
this.game.player.stats.mood += 10;
|
||
this.game.notify('Квест выполнен! Бабушка Зина вас не забудет.');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'survive_3days',
|
||
title: 'Стойкий',
|
||
description: 'Проживите 3 дня.',
|
||
target: 3,
|
||
progress: 0,
|
||
event: 'new_day',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 25;
|
||
this.game.player.stats.health = 100;
|
||
this.game.notify('Квест выполнен! Вы стали крепче. Полное здоровье!');
|
||
}
|
||
});
|
||
|
||
// === Новые квесты ===
|
||
|
||
this.addQuest({
|
||
id: 'adopt_dog',
|
||
title: 'Верный друг',
|
||
description: 'Приручите бездомного пса.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'adopt_dog',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 25;
|
||
this.game.notify('Квест выполнен! Теперь у вас есть верный друг! +25 Настроение', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'first_beg',
|
||
title: 'Просящему дастся',
|
||
description: 'Успешно попросите милостыню 3 раза.',
|
||
target: 3,
|
||
progress: 0,
|
||
event: 'beg',
|
||
reward: () => {
|
||
this.game.player.stats.money += 50;
|
||
this.game.sound.playCoin();
|
||
this.game.notify('Квест выполнен! +50 ₽ бонус', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'visit_church',
|
||
title: 'Утешение',
|
||
description: 'Посетите церковь.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'visit_church',
|
||
location: { x: 28, z: 35 },
|
||
reward: () => {
|
||
this.game.player.stats.mood = Math.min(100, this.game.player.stats.mood + 15);
|
||
this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 10);
|
||
this.game.notify('Квест выполнен! +15 Настроение, +10 Здоровье', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'sobriety',
|
||
title: 'Трезвость',
|
||
description: 'Преодолейте зависимость от алкоголя.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'sobriety',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 30;
|
||
this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 20);
|
||
this.game.notify('Квест выполнен! Вы завязали! +30 Настроение, +20 Здоровье', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'wash_fountain',
|
||
title: 'Чистота — залог здоровья',
|
||
description: 'Помойтесь у фонтанчика.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'wash',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 15;
|
||
this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 10);
|
||
this.game.notify('Квест выполнен! +15 Настроение, +10 Здоровье', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'street_musician',
|
||
title: 'Уличный музыкант',
|
||
description: 'Заработайте бускингом 3 раза.',
|
||
target: 3,
|
||
progress: 0,
|
||
event: 'busking',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 20;
|
||
this.game.player.stats.money += 50;
|
||
this.game.sound.playCoin();
|
||
this.game.notify('Квест выполнен! +20 Настроение, +50₽ бонус', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'first_craft',
|
||
title: 'Мастер на все руки',
|
||
description: 'Создайте любой предмет в крафте.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'craft_item',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 15;
|
||
this.game.inventory.addItem('scrap', 3);
|
||
this.game.notify('Квест выполнен! +15 Настроение, +3 Хлам', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'survive_7days',
|
||
title: 'Закалённый',
|
||
description: 'Проживите 7 дней на улице.',
|
||
target: 7,
|
||
progress: 0,
|
||
event: 'new_day',
|
||
reward: () => {
|
||
this.game.player.stats.health = 100;
|
||
this.game.player.stats.hunger = 100;
|
||
this.game.player.stats.warmth = 100;
|
||
this.game.player.stats.mood = 100;
|
||
this.game.notify('Квест выполнен! Все статы восстановлены до максимума!', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'rich',
|
||
title: 'Первый капитал',
|
||
description: 'Накопите 300 ₽.',
|
||
target: 300,
|
||
progress: 0,
|
||
event: 'find_money',
|
||
cumulative: true,
|
||
reward: () => {
|
||
this.game.player.stats.mood += 30;
|
||
this.game.notify('Квест выполнен! +30 Настроение. Вы на верном пути!', 'good');
|
||
}
|
||
});
|
||
|
||
// === Квесты новых систем ===
|
||
|
||
this.addQuest({
|
||
id: 'first_job',
|
||
title: 'Рабочий человек',
|
||
description: 'Выполните первую подработку.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'complete_job',
|
||
location: { x: 22, z: -10 },
|
||
reward: () => {
|
||
this.game.player.stats.mood += 15;
|
||
this.game.player.stats.money += 30;
|
||
this.game.sound.playCoin();
|
||
this.game.notify('Квест выполнен! +15 Настроение, +30₽ бонус', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'hard_worker',
|
||
title: 'Трудяга',
|
||
description: 'Выполните 5 подработок.',
|
||
target: 5,
|
||
progress: 0,
|
||
event: 'complete_job',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 25;
|
||
this.game.player.stats.money += 100;
|
||
this.game.sound.playCoin();
|
||
this.game.notify('Квест выполнен! +25 Настроение, +100₽! Вас ценят!', 'good');
|
||
this.game.reputation.change(10);
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'survive_winter',
|
||
title: 'Зимовка',
|
||
description: 'Переживите зиму.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'survive_winter',
|
||
reward: () => {
|
||
this.game.player.stats.health = 100;
|
||
this.game.player.stats.warmth = 100;
|
||
this.game.notify('Квест выполнен! Вы пережили зиму! Здоровье и Тепло восстановлены!', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'respected',
|
||
title: 'Уважаемый человек',
|
||
description: 'Достигните репутации "Уважаемый".',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'reputation_level',
|
||
reward: () => {
|
||
this.game.player.stats.mood = 100;
|
||
this.game.player.stats.money += 200;
|
||
this.game.sound.playCoin();
|
||
this.game.notify('Квест выполнен! Вас уважают! +200₽, Настроение MAX', 'good');
|
||
}
|
||
});
|
||
|
||
// === Квесты для новых систем ===
|
||
|
||
this.addQuest({
|
||
id: 'build_shelter',
|
||
title: 'Свой угол',
|
||
description: 'Постройте собственное укрытие.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'build_shelter',
|
||
location: { x: -32, z: 42 },
|
||
reward: () => {
|
||
this.game.player.stats.mood += 30;
|
||
this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 20);
|
||
this.game.notify('Квест выполнен! Теперь у вас есть дом! +30 Настроение, +20 Здоровье', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'full_equipment',
|
||
title: 'Полная экипировка',
|
||
description: 'Экипируйте предметы во все 4 слота.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'full_equipment',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 20;
|
||
this.game.player.stats.warmth = Math.min(100, this.game.player.stats.warmth + 30);
|
||
this.game.notify('Квест выполнен! Вы полностью одеты! +20 Настроение, +30 Тепло', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'visit_hospital',
|
||
title: 'На поправку',
|
||
description: 'Посетите больницу.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'visit_hospital',
|
||
location: { x: -28, z: -60 },
|
||
reward: () => {
|
||
this.game.player.stats.health = Math.min(100, this.game.player.stats.health + 25);
|
||
this.game.notify('Квест выполнен! +25 Здоровье', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'defeat_enemy',
|
||
title: 'Самозащита',
|
||
description: 'Отбейтесь от врага.',
|
||
target: 1,
|
||
progress: 0,
|
||
event: 'defeat_enemy',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 15;
|
||
this.game.reputation.change(5);
|
||
this.game.notify('Квест выполнен! +15 Настроение, +5 Репутация', 'good');
|
||
}
|
||
});
|
||
|
||
this.addQuest({
|
||
id: 'craft_5',
|
||
title: 'Умелые руки',
|
||
description: 'Создайте 5 предметов в крафте.',
|
||
target: 5,
|
||
progress: 0,
|
||
event: 'craft_item',
|
||
reward: () => {
|
||
this.game.player.stats.mood += 20;
|
||
this.game.inventory.addItem('scrap', 5);
|
||
this.game.inventory.addItem('rope', 3);
|
||
this.game.notify('Квест выполнен! +20 Настроение, +5 Хлам, +3 Верёвка', 'good');
|
||
}
|
||
});
|
||
}
|
||
|
||
addQuest(quest) {
|
||
this.quests.push(quest);
|
||
}
|
||
|
||
onEvent(eventName, data) {
|
||
this.quests.forEach(quest => {
|
||
if (quest.completed) return;
|
||
|
||
let matches = quest.event === eventName;
|
||
if (!matches && quest.altEvents) {
|
||
matches = quest.altEvents.includes(eventName);
|
||
}
|
||
|
||
if (matches) {
|
||
if (quest.eventFilter && data !== quest.eventFilter) return;
|
||
|
||
if (quest.cumulative && typeof data === 'number') {
|
||
quest.progress += data;
|
||
} else {
|
||
quest.progress++;
|
||
}
|
||
|
||
if (quest.progress >= quest.target) {
|
||
this.completeQuest(quest);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
completeQuest(quest) {
|
||
quest.completed = true;
|
||
quest.reward();
|
||
this.completedQuests.push(quest.id);
|
||
this.game.sound.playQuestComplete();
|
||
}
|
||
|
||
update(dt) {
|
||
// Проверка дней
|
||
const prevDay = this._lastDay || 1;
|
||
if (this.game.gameDay > prevDay) {
|
||
for (let d = prevDay + 1; d <= this.game.gameDay; d++) {
|
||
this.onEvent('new_day');
|
||
}
|
||
}
|
||
this._lastDay = this.game.gameDay;
|
||
}
|
||
|
||
getActiveQuests() {
|
||
return this.quests.filter(q => !q.completed);
|
||
}
|
||
|
||
getCompletedQuests() {
|
||
return this.quests.filter(q => q.completed);
|
||
}
|
||
|
||
reset() {
|
||
this.quests = [];
|
||
this.completedQuests = [];
|
||
}
|
||
}
|