#include "item.hpp" #include #include #include #include #include "../../log.hpp" #include #include "util.hpp" using namespace tinyxml2; using namespace game::util; namespace game::resource::xml { Item::Item(const physfs::Path& path) { XMLDocument document; if (document_load(path, document) != XML_SUCCESS) return; auto archive = path.directory_get(); if (auto root = document.RootElement()) { std::string textureRootPath{}; query_string_attribute(root, "TextureRootPath", &textureRootPath); std::string soundRootPath{}; query_string_attribute(root, "SoundRootPath", &soundRootPath); query_anm2(root, "BaseAnm2", archive, textureRootPath, baseAnm2, Anm2::NO_SPRITESHEETS); if (auto element = root->FirstChildElement("Categories")) { for (auto child = element->FirstChildElement("Category"); child; child = child->NextSiblingElement("Category")) { Category category{}; query_string_attribute(child, "Name", &category.name); query_bool_attribute(child, "IsEdible", &category.isEdible); categoryMap[category.name] = (int)categories.size(); categories.push_back(category); } } if (auto element = root->FirstChildElement("Rarities")) { for (auto child = element->FirstChildElement("Rarity"); child; child = child->NextSiblingElement("Rarity")) { Rarity rarity{}; query_string_attribute(child, "Name", &rarity.name); child->QueryFloatAttribute("Chance", &rarity.chance); query_bool_attribute(child, "IsHidden", &rarity.isHidden); query_sound(child, "Sound", archive, soundRootPath, rarity.sound); rarityMap[rarity.name] = (int)rarities.size(); rarities.emplace_back(std::move(rarity)); } } if (auto element = root->FirstChildElement("Flavors")) { for (auto child = element->FirstChildElement("Flavor"); child; child = child->NextSiblingElement("Flavor")) { Flavor flavor{}; query_string_attribute(child, "Name", &flavor.name); flavorMap[flavor.name] = (int)flavors.size(); flavors.push_back(flavor); } } if (auto element = root->FirstChildElement("Animations")) { if (auto child = element->FirstChildElement("Chew")) query_string_attribute(child, "Animation", &animations.chew); } if (auto element = root->FirstChildElement("Sounds")) { query_sound_entry_collection(element, "Bounce", archive, soundRootPath, sounds.bounce); query_sound_entry_collection(element, "Dispose", archive, soundRootPath, sounds.dispose); query_sound_entry_collection(element, "Return", archive, soundRootPath, sounds.return_); query_sound_entry_collection(element, "Summon", archive, soundRootPath, sounds.summon); } if (auto element = root->FirstChildElement("Items")) { std::string itemTextureRootPath{}; query_string_attribute(element, "TextureRootPath", &itemTextureRootPath); element->QueryIntAttribute("ChewCount", &chewCount); element->QueryIntAttribute("QuantityMax", &quantityMax); for (auto child = element->FirstChildElement("Item"); child; child = child->NextSiblingElement("Item")) { Entry item{}; query_string_attribute(child, "Name", &item.name); query_string_attribute(child, "Description", &item.description); query_float_optional_attribute(child, "Calories", item.calories); query_float_optional_attribute(child, "DigestionBonus", item.digestionBonus); query_float_optional_attribute(child, "EatSpeedBonus", item.eatSpeedBonus); query_float_optional_attribute(child, "Gravity", item.gravity); query_int_optional_attribute(child, "ChewCount", item.chewCount); query_bool_attribute(child, "IsPlayReward", &item.isPlayReward); query_bool_attribute(child, "IsToggleSpritesheet", &item.isToggleSpritesheet); std::string categoryString{}; query_string_attribute(child, "Category", &categoryString); item.categoryID = categoryMap.contains(categoryString) ? categoryMap[categoryString] : -1; std::string rarityString{}; query_string_attribute(child, "Rarity", &rarityString); item.rarityID = rarityMap.contains(rarityString) ? rarityMap[rarityString] : -1; std::string flavorString{}; query_string_attribute(child, "Flavor", &flavorString); if (flavorMap.contains(flavorString)) item.flavorID = flavorMap[flavorString]; Texture texture{}; query_texture(child, "Texture", archive, itemTextureRootPath, texture); Anm2 anm2{baseAnm2}; if (child->FindAttribute("Anm2")) query_anm2(child, "Anm2", archive, textureRootPath, anm2); anm2.spritesheets.at(0).texture = std::move(texture); anm2s.emplace_back(std::move(anm2)); items.emplace_back(std::move(item)); } } } for (int i = 0; i < (int)items.size(); i++) { auto& item = items[i]; pools[item.rarityID].emplace_back(i); if (item.isPlayReward) rewardItemPool.emplace_back(i); } for (int i = 0; i < (int)rarities.size(); i++) { rarityIDsSortedByChance.emplace_back(i); } std::stable_sort(rarityIDsSortedByChance.begin(), rarityIDsSortedByChance.end(), [&](int a, int b) { return rarities[a].chance > rarities[b].chance; }); isValid = true; logger.info(std::format("Initialized item schema: {}", path.c_str())); } bool Item::is_valid() const { return isValid; }; }