62 lines
2.6 KiB
JavaScript
62 lines
2.6 KiB
JavaScript
/**
|
|
* QuestSystem — thin wrapper around ContentLoader for quest definitions.
|
|
*/
|
|
class QuestSystem {
|
|
constructor(contentLoader) {
|
|
this.loader = contentLoader;
|
|
this.playerQuests = new Map();
|
|
}
|
|
|
|
getAllQuests() { return this.loader.getAllQuests(); }
|
|
getQuest(id) { return this.loader.getQuest(id); }
|
|
getQuestsByCategory(cat) { return this.loader.getQuestsByCategory(cat); }
|
|
getQuestCategories() { return this.loader.getQuestCategories(); }
|
|
|
|
initializePlayerData(userId) {
|
|
if (this.playerQuests.has(userId)) return this.playerQuests.get(userId);
|
|
const data = { active: {}, completed: [], failed: [] };
|
|
this.playerQuests.set(userId, data);
|
|
return data;
|
|
}
|
|
|
|
getPlayerData(userId) { return this.initializePlayerData(userId); }
|
|
getPlayerQuests(userId) { return this.initializePlayerData(userId); }
|
|
|
|
startQuest(userId, questId) {
|
|
const quest = this.loader.getQuest(questId);
|
|
if (!quest) return { success: false, error: 'Quest not found' };
|
|
const pd = this.initializePlayerData(userId);
|
|
if (pd.active[questId]) return { success: false, error: 'Already active' };
|
|
const objectives = {};
|
|
for (const obj of (quest.objectives || [])) {
|
|
objectives[obj.id] = { progress: 0, complete: false };
|
|
}
|
|
pd.active[questId] = { startedAt: Date.now(), objectives };
|
|
return { success: true, quest };
|
|
}
|
|
|
|
completeQuest(userId, questId, rewards) {
|
|
const pd = this.initializePlayerData(userId);
|
|
delete pd.active[questId];
|
|
if (!pd.completed.includes(questId)) pd.completed.push(questId);
|
|
return { success: true, questId, rewards };
|
|
}
|
|
|
|
updateObjective(userId, questId, objectiveId, amount = 1) {
|
|
const pd = this.initializePlayerData(userId);
|
|
const state = pd.active[questId];
|
|
if (!state) return null;
|
|
const quest = this.loader.getQuest(questId);
|
|
const objDef = quest?.objectives?.find(o => o.id === objectiveId);
|
|
if (!objDef) return null;
|
|
const obj = state.objectives[objectiveId] || { progress: 0, complete: false };
|
|
obj.progress = Math.min(obj.progress + amount, objDef.target);
|
|
obj.complete = obj.progress >= objDef.target;
|
|
state.objectives[objectiveId] = obj;
|
|
const allDone = quest.objectives.every(o => state.objectives[o.id]?.complete);
|
|
if (allDone) return this.completeQuest(userId, questId, quest.rewards);
|
|
return { questId, objectiveId, progress: obj.progress, completed: false };
|
|
}
|
|
}
|
|
module.exports = QuestSystem;
|