Files
Hommie_RPG_Game/js/game/QuestSystem.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

441 lines
16 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 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 = [];
}
}