The Mega Snivy Update
Some checks failed
Build / Build Game (push) Has been cancelled

This commit is contained in:
2026-02-28 21:48:00 -05:00
parent 8b2edd1359
commit 17f3348e94
163 changed files with 8725 additions and 13281 deletions

156
src/resource/xml/item.cpp Normal file
View File

@@ -0,0 +1,156 @@
#include "item.hpp"
#include <ranges>
#include <tinyxml2.h>
#include <algorithm>
#include <utility>
#include "../../log.hpp"
#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; };
}