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

440
js/game/QuestSystem.js Normal file
View File

@@ -0,0 +1,440 @@
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 = [];
}
}