Kelsidavis-WoWee/tools/editor/quest_editor.cpp
Kelsi f59d79537a feat(editor): quest editor with objectives, rewards, and quest chains
- New Quest mode (key 6) with full quest creation panel:
  - Title, description, required level
  - Quest giver / turn-in NPC ID linkage
  - Up to 4 objectives: Kill, Collect, Talk, Explore, Escort, Use Object
  - Rewards: XP and gold
  - Quest chain support via nextQuestId linking
- Quest list showing all created quests with level and objective count
- Save quests to JSON (included in Export Zone package)
- Foundation for campaign system: create quest chains across NPCs,
  link objectives to placed creatures, build storylines
2026-05-05 06:10:14 -07:00

68 lines
2.3 KiB
C++

#include "quest_editor.hpp"
#include "core/logger.hpp"
#include <fstream>
#include <filesystem>
namespace wowee {
namespace editor {
void QuestEditor::addQuest(const Quest& q) {
Quest quest = q;
quest.id = nextId_++;
quests_.push_back(quest);
LOG_INFO("Quest added: [", quest.id, "] ", quest.title);
}
void QuestEditor::removeQuest(int index) {
if (index >= 0 && index < static_cast<int>(quests_.size()))
quests_.erase(quests_.begin() + index);
}
Quest* QuestEditor::getQuest(int index) {
if (index < 0 || index >= static_cast<int>(quests_.size())) return nullptr;
return &quests_[index];
}
bool QuestEditor::saveToFile(const std::string& path) const {
auto dir = std::filesystem::path(path).parent_path();
if (!dir.empty()) std::filesystem::create_directories(dir);
std::ofstream f(path);
if (!f) return false;
f << "[\n";
for (size_t i = 0; i < quests_.size(); i++) {
const auto& q = quests_[i];
f << " {\n";
f << " \"id\": " << q.id << ",\n";
f << " \"title\": \"" << q.title << "\",\n";
f << " \"description\": \"" << q.description << "\",\n";
f << " \"completionText\": \"" << q.completionText << "\",\n";
f << " \"requiredLevel\": " << q.requiredLevel << ",\n";
f << " \"questGiverNpcId\": " << q.questGiverNpcId << ",\n";
f << " \"turnInNpcId\": " << q.turnInNpcId << ",\n";
f << " \"nextQuestId\": " << q.nextQuestId << ",\n";
f << " \"reward\": {\"xp\":" << q.reward.xp
<< ",\"gold\":" << q.reward.gold
<< ",\"silver\":" << q.reward.silver
<< ",\"copper\":" << q.reward.copper << "},\n";
f << " \"objectives\": [";
for (size_t j = 0; j < q.objectives.size(); j++) {
const auto& obj = q.objectives[j];
f << "{\"type\":" << static_cast<int>(obj.type)
<< ",\"desc\":\"" << obj.description << "\""
<< ",\"target\":\"" << obj.targetName << "\""
<< ",\"count\":" << obj.targetCount << "}";
if (j + 1 < q.objectives.size()) f << ",";
}
f << "]\n";
f << " }" << (i + 1 < quests_.size() ? "," : "") << "\n";
}
f << "]\n";
LOG_INFO("Quests saved: ", path, " (", quests_.size(), " quests)");
return true;
}
} // namespace editor
} // namespace wowee