103 lines
4.1 KiB
C++
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
|