198 lines
6.2 KiB
JavaScript
198 lines
6.2 KiB
JavaScript
class QuestSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
// Quest Definitions
|
|
this.questDB = {
|
|
'q1_start': {
|
|
id: 'q1_start',
|
|
title: 'Survival Basics',
|
|
description: 'Collect Wood and Stone to build your first defense.',
|
|
objectives: [
|
|
{ type: 'collect', item: 'wood', amount: 5, current: 0, done: false },
|
|
{ type: 'collect', item: 'stone', amount: 3, current: 0, done: false }
|
|
],
|
|
reward: { gold: 10, xp: 50 },
|
|
nextQuest: 'q2_farm',
|
|
giver: 'villager'
|
|
},
|
|
'q2_farm': {
|
|
id: 'q2_farm',
|
|
title: 'The Farmer',
|
|
description: 'Plant some seeds to grow food. You will need it.',
|
|
objectives: [
|
|
{ type: 'action', action: 'plant', amount: 3, current: 0, done: false }
|
|
],
|
|
reward: { gold: 20, item: 'wood', amount: 10 },
|
|
nextQuest: 'q3_defense',
|
|
giver: 'villager'
|
|
},
|
|
'q3_defense': {
|
|
id: 'q3_defense',
|
|
title: 'Fortification',
|
|
description: 'Build a Fence to keep zombies out.',
|
|
objectives: [
|
|
{ type: 'action', action: 'build_fence', amount: 2, current: 0, done: false }
|
|
],
|
|
reward: { gold: 50, item: 'sword', amount: 1 },
|
|
nextQuest: 'q4_slayer',
|
|
giver: 'merchant'
|
|
},
|
|
'q4_slayer': {
|
|
id: 'q4_slayer',
|
|
title: 'Zombie Slayer',
|
|
description: 'Kill 3 Zombies using your new sword.',
|
|
objectives: [
|
|
{ type: 'kill', target: 'zombie', amount: 3, current: 0, done: false }
|
|
],
|
|
reward: { gold: 100, item: 'gold', amount: 50 },
|
|
nextQuest: null,
|
|
giver: 'villager'
|
|
}
|
|
};
|
|
|
|
this.activeQuest = null;
|
|
this.completedQuests = [];
|
|
}
|
|
|
|
getAvailableQuest(npcType) {
|
|
const chain = ['q1_start', 'q2_farm', 'q3_defense', 'q4_slayer'];
|
|
let targetId = null;
|
|
for (const id of chain) {
|
|
if (!this.completedQuests.includes(id)) {
|
|
targetId = id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!targetId) return null;
|
|
if (this.activeQuest && this.activeQuest.id === targetId) return null;
|
|
|
|
const q = this.questDB[targetId];
|
|
if (q.giver === npcType) return q;
|
|
|
|
return null;
|
|
}
|
|
|
|
startQuest(id) {
|
|
if (this.completedQuests.includes(id)) return;
|
|
|
|
const template = this.questDB[id];
|
|
if (!template) return;
|
|
|
|
this.activeQuest = JSON.parse(JSON.stringify(template));
|
|
console.log(`📜 Quest Started: ${this.activeQuest.title}`);
|
|
|
|
this.updateUI();
|
|
|
|
// Notification
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.x,
|
|
y: this.scene.player.y - 50,
|
|
text: "Quest Accepted!",
|
|
color: '#FFFF00'
|
|
});
|
|
}
|
|
|
|
update(delta) {
|
|
if (!this.activeQuest) return;
|
|
|
|
let changed = false;
|
|
let allDone = true;
|
|
|
|
if (this.scene.inventorySystem) {
|
|
const inv = this.scene.inventorySystem;
|
|
|
|
for (const obj of this.activeQuest.objectives) {
|
|
if (obj.done) continue;
|
|
|
|
if (obj.type === 'collect') {
|
|
const count = inv.getItemCount(obj.item);
|
|
if (count !== obj.current) {
|
|
obj.current = count;
|
|
changed = true;
|
|
}
|
|
if (obj.current >= obj.amount) {
|
|
obj.done = true;
|
|
this.scene.events.emit('show-floating-text', { x: this.scene.player.x, y: this.scene.player.y, text: "Objective Complete!" });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const obj of this.activeQuest.objectives) {
|
|
if (!obj.done) allDone = false;
|
|
}
|
|
|
|
if (changed) this.updateUI();
|
|
|
|
if (allDone) {
|
|
this.completeQuest();
|
|
}
|
|
}
|
|
|
|
trackAction(actionType, amount = 1) {
|
|
if (!this.activeQuest) return;
|
|
|
|
let changed = false;
|
|
for (const obj of this.activeQuest.objectives) {
|
|
if (obj.done) continue;
|
|
|
|
if (obj.type === 'action' && obj.action === actionType) {
|
|
obj.current += amount;
|
|
changed = true;
|
|
if (obj.current >= obj.amount) {
|
|
obj.done = true;
|
|
changed = true;
|
|
}
|
|
}
|
|
if (obj.type === 'kill' && obj.target === actionType) {
|
|
obj.current += amount;
|
|
changed = true;
|
|
if (obj.current >= obj.amount) {
|
|
obj.done = true;
|
|
changed = true;
|
|
}
|
|
}
|
|
}
|
|
if (changed) this.updateUI();
|
|
}
|
|
|
|
completeQuest() {
|
|
console.log(`🏆 Quest Complete: ${this.activeQuest.title}`);
|
|
|
|
if (this.activeQuest.reward) {
|
|
const r = this.activeQuest.reward;
|
|
if (r.gold && this.scene.inventorySystem) {
|
|
this.scene.inventorySystem.addGold(r.gold);
|
|
}
|
|
if (r.item && this.scene.inventorySystem) {
|
|
this.scene.inventorySystem.addItem(r.item, r.amount || 1);
|
|
}
|
|
}
|
|
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.x,
|
|
y: this.scene.player.y - 50,
|
|
text: "Quest Complete!",
|
|
color: '#00FF00'
|
|
});
|
|
|
|
this.completedQuests.push(this.activeQuest.id);
|
|
const next = this.activeQuest.nextQuest;
|
|
this.activeQuest = null;
|
|
this.updateUI();
|
|
|
|
if (next) {
|
|
console.log('Next quest available at NPC.');
|
|
}
|
|
}
|
|
|
|
updateUI() {
|
|
const ui = this.scene.scene.get('UIScene');
|
|
if (ui && ui.updateQuestTracker) {
|
|
ui.updateQuestTracker(this.activeQuest);
|
|
}
|
|
}
|
|
}
|