#include "configs/achievements.h" #include "project_parser.h" #include "helpers.hpp" #include 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(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(getAttributeValueInt(achievementElement, "points")); achievement.category = static_cast(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(getAttributeValueInt(reqElement, "targetid")); req.count = static_cast(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& 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