const questsManager = require("../../game/QuestsManager"); const DatapackLoader = require("../../game/DatapackLoader"); const { PlayerQuest } = require("../../models"); module.exports = (io, socket) => { const playerId = socket.user?.id; socket.on("quest:get_list", async () => { if (!playerId) return; try { const autoQuests = DatapackLoader.getAutoStartQuests(); const existingQuests = await PlayerQuest.findAll({ where: { playerId }, attributes: ["questId"], raw: true, }); const existingIds = existingQuests.map((q) => q.questId); const missingQuests = autoQuests.filter( (aq) => !existingIds.includes(aq.id), ); if (missingQuests.length > 0) { const toCreate = missingQuests.map((aq) => ({ playerId, questId: aq.id, status: "active", progress: aq.objectives.map((obj) => ({ ...obj, currentAmount: 0 })), })); await PlayerQuest.bulkCreate(toCreate, { ignoreDuplicates: true }); } const all = await PlayerQuest.findAll({ where: { playerId }, order: [["updatedAt", "DESC"]], }); socket.emit( "quest:list_data", all.map((q) => ({ id: q.questId, status: q.status, objectives: q.progress, rewards: DatapackLoader.getQuest(q.questId)?.rewards, })), ); } catch (err) { console.error("Quest sync error:", err); } }); socket.on("quest:claim_reward", async ({ questId }) => { try { const result = await questsManager.claimRewards(playerId, questId); socket.emit("player:credits_update", { totalCredits: result.newTotalCredits, }); socket.emit("quest:reward_claimed", { questId, rewards: result.rewards, }); const all = await PlayerQuest.findAll({ where: { playerId }, order: [["updatedAt", "DESC"]], }); socket.emit( "quest:list_data", all.map((q) => ({ id: q.questId, status: q.status, objectives: q.progress, rewards: DatapackLoader.getQuest(q.questId)?.rewards, })), ); } catch (err) { const msg = err.message === "QUEST_NOT_READY_OR_CLAIMED" ? "Reward already claimed or objective not met." : "Failed to claim reward."; socket.emit("error", { message: msg }); } }); };