Files
cursebreaker-parser/src/configs/achievements.cpp
cdemeyer-teachx ff1b4a93b3 SQL setup
2025-11-12 12:34:20 +09:00

103 lines
4.1 KiB
C++

#include "configs/achievements.h"
#include "project_parser.h"
#include "helpers.hpp"
#include <iostream>
namespace cursebreaker {
// Static helper functions
static std::string getAttributeValue(tinyxml2::XMLElement* element, const char* attribute, const std::string& defaultValue = "");
static int getAttributeValueInt(tinyxml2::XMLElement* element, const char* attribute, int defaultValue = 0);
static bool getAttributeValueBool(tinyxml2::XMLElement* element, const char* attribute, bool defaultValue = false);
static void parseAchievement(tinyxml2::XMLElement* achievementElement);
static void parseRequirements(tinyxml2::XMLElement* achievementElement, Achievement& achievement);
bool loadAchievementsFromXML(const std::string& filepath) {
tinyxml2::XMLDocument doc;
tinyxml2::XMLError result = doc.LoadFile(filepath.c_str());
if (result != tinyxml2::XML_SUCCESS) {
std::cerr << "Failed to load achievements XML file: " << filepath << std::endl;
return false;
}
tinyxml2::XMLElement* root = doc.FirstChildElement("achievements");
if (!root) {
std::cerr << "Invalid XML structure: missing 'achievements' root element" << std::endl;
return false;
}
g_parsedProject.m_achievements.clear();
// Parse all achievements
for (tinyxml2::XMLElement* achievementElement = root->FirstChildElement("achievement");
achievementElement != nullptr;
achievementElement = achievementElement->NextSiblingElement("achievement")) {
parseAchievement(achievementElement);
}
std::cout << "Loaded " << g_parsedProject.m_achievements.size() << " achievements from XML" << std::endl;
return true;
}
void parseAchievement(tinyxml2::XMLElement* achievementElement) {
Achievement achievement;
// Parse basic attributes
achievement.id = static_cast<uint16_t>(getAttributeValueInt(achievementElement, "id"));
achievement.name = getAttributeValue(achievementElement, "name");
achievement.description = getAttributeValue(achievementElement, "description");
achievement.icon = getAttributeValue(achievementElement, "icon");
// Parse numeric attributes
achievement.points = static_cast<uint16_t>(getAttributeValueInt(achievementElement, "points"));
achievement.category = static_cast<uint16_t>(getAttributeValueInt(achievementElement, "category"));
// Parse child elements
parseRequirements(achievementElement, achievement);
g_parsedProject.m_achievements[achievement.id] = std::move(achievement);
}
void parseRequirements(tinyxml2::XMLElement* achievementElement, Achievement& achievement) {
for (tinyxml2::XMLElement* reqElement = achievementElement->FirstChildElement("requirement");
reqElement != nullptr;
reqElement = reqElement->NextSiblingElement("requirement")) {
AchievementRequirement req;
req.action = stringToActionType(getAttributeValue(reqElement, "action"));
req.targetId = static_cast<uint16_t>(getAttributeValueInt(reqElement, "targetid"));
req.count = static_cast<uint16_t>(getAttributeValueInt(reqElement, "count"));
req.description = getAttributeValue(reqElement, "description");
achievement.requirements.push_back(req);
}
}
const Achievement* getAchievementById(uint16_t id) {
auto it = g_parsedProject.m_achievements.find(id);
return (it != g_parsedProject.m_achievements.end()) ? &it->second : nullptr;
}
const std::unordered_map<uint16_t, Achievement>& getAllAchievements() {
return g_parsedProject.m_achievements;
}
std::string getAttributeValue(tinyxml2::XMLElement* element, const char* attribute, const std::string& defaultValue) {
const char* value = element->Attribute(attribute);
return value ? std::string(value) : defaultValue;
}
int getAttributeValueInt(tinyxml2::XMLElement* element, const char* attribute, int defaultValue) {
int value = defaultValue;
element->QueryIntAttribute(attribute, &value);
return value;
}
bool getAttributeValueBool(tinyxml2::XMLElement* element, const char* attribute, bool defaultValue) {
bool value = defaultValue;
element->QueryBoolAttribute(attribute, &value);
return value;
}
} // namespace cursebreaker