Files
snivy/src/resource/xml/dialogue.cpp
shweet 3817f1cc39
Some checks failed
Build / Build Game (push) Has been cancelled
again
2026-02-28 22:19:24 -05:00

171 lines
6.0 KiB
C++

#include "dialogue.hpp"
#include "util.hpp"
#include "../../log.hpp"
#include "../../util/math.hpp"
using namespace tinyxml2;
using namespace game::util;
namespace game::resource::xml
{
void Dialogue::query_entry_id(XMLElement* element, const char* name, int& id)
{
std::string entryID{};
query_string_attribute(element, name, &entryID);
if (entryIDMap.contains(entryID))
id = entryIDMap.at(entryID);
else if (entryID.empty())
entryID = -1;
else
{
logger.warning("Dialogue entries does not contain: " + entryID);
id = -1;
}
}
void Dialogue::query_pool_id(XMLElement* element, const char* name, int& id)
{
std::string poolID{};
query_string_attribute(element, name, &poolID);
if (poolMap.contains(poolID))
id = poolMap.at(poolID);
else if (poolID.empty())
poolID = -1;
else
{
logger.warning("Dialogue pools does not contain: " + poolID);
id = -1;
}
}
Dialogue::Dialogue(const physfs::Path& path)
{
XMLDocument document;
if (document_load(path, document) != XML_SUCCESS) return;
if (auto root = document.RootElement())
{
if (auto element = root->FirstChildElement("Entries"))
{
int id{};
for (auto child = element->FirstChildElement("Entry"); child; child = child->NextSiblingElement("Entry"))
{
std::string stringID{};
query_string_attribute(child, "ID", &stringID);
entryIDMap.emplace(stringID, id);
entryIDMapReverse.emplace(id, stringID);
id++;
}
id = 0;
for (auto child = element->FirstChildElement("Entry"); child; child = child->NextSiblingElement("Entry"))
{
Entry entry{};
entry.name = entryIDMapReverse.at(id);
query_string_attribute(child, "Text", &entry.text);
query_string_attribute(child, "Animation", &entry.animation);
if (child->FindAttribute("Next"))
{
std::string nextID{};
query_string_attribute(child, "Next", &nextID);
if (!entryIDMap.contains(nextID))
logger.warning(std::format("Dialogue: next ID does not point to a valid Entry! ({})", nextID));
else
entry.nextID = entryIDMap.at(nextID);
}
for (auto choiceChild = child->FirstChildElement("Choice"); choiceChild;
choiceChild = choiceChild->NextSiblingElement("Choice"))
{
Choice choice{};
query_entry_id(choiceChild, "Next", choice.nextID);
query_string_attribute(choiceChild, "Text", &choice.text);
entry.choices.emplace_back(std::move(choice));
}
entries.emplace_back(std::move(entry));
id++;
}
}
if (auto element = root->FirstChildElement("Pools"))
{
int id{};
for (auto child = element->FirstChildElement("Pool"); child; child = child->NextSiblingElement("Pool"))
{
Pool pool{};
std::string stringID{};
query_string_attribute(child, "ID", &stringID);
poolMap[stringID] = id;
pools.emplace_back(pool);
id++;
}
id = 0;
for (auto child = element->FirstChildElement("Pool"); child; child = child->NextSiblingElement("Pool"))
{
auto& pool = pools.at(id);
for (auto entryChild = child->FirstChildElement("PoolEntry"); entryChild;
entryChild = entryChild->NextSiblingElement("PoolEntry"))
{
int entryID{};
query_entry_id(entryChild, "ID", entryID);
pool.emplace_back(entryID);
}
id++;
}
logger.info(std::format("Initialized dialogue: {}", path.c_str()));
isValid = true;
}
if (auto element = root->FirstChildElement("Start"))
{
query_entry_id(element, "ID", start.id);
query_string_attribute(element, "Animation", &start.animation);
}
if (auto element = root->FirstChildElement("End")) query_entry_id(element, "ID", end.id);
if (auto element = root->FirstChildElement("Help")) query_entry_id(element, "ID", help.id);
if (auto element = root->FirstChildElement("Digest")) query_pool_id(element, "PoolID", digest.id);
if (auto element = root->FirstChildElement("Eat")) query_pool_id(element, "PoolID", eat.id);
if (auto element = root->FirstChildElement("EatFull")) query_pool_id(element, "PoolID", eatFull.id);
if (auto element = root->FirstChildElement("Feed")) query_pool_id(element, "PoolID", feed.id);
if (auto element = root->FirstChildElement("FeedFull")) query_pool_id(element, "PoolID", feedFull.id);
if (auto element = root->FirstChildElement("FoodTaken")) query_pool_id(element, "PoolID", foodTaken.id);
if (auto element = root->FirstChildElement("FoodTakenFull")) query_pool_id(element, "PoolID", foodTakenFull.id);
if (auto element = root->FirstChildElement("Full")) query_pool_id(element, "PoolID", full.id);
if (auto element = root->FirstChildElement("LowCapacity")) query_pool_id(element, "PoolID", lowCapacity.id);
if (auto element = root->FirstChildElement("Random")) query_pool_id(element, "PoolID", random.id);
if (auto element = root->FirstChildElement("Throw")) query_pool_id(element, "PoolID", throw_.id);
if (auto element = root->FirstChildElement("StageUp")) query_pool_id(element, "PoolID", stageUp.id);
}
}
int Dialogue::Pool::get() const
{
if (this->empty()) return -1;
auto index = rand() % this->size();
return this->at(index);
}
Dialogue::Entry* Dialogue::get(int id) { return &entries.at(id); }
Dialogue::Entry* Dialogue::get(Dialogue::EntryReference& entry) { return &entries.at(entry.id); }
Dialogue::Entry* Dialogue::get(const std::string& string) { return &entries.at(entryIDMap.at(string)); }
Dialogue::Entry* Dialogue::get(Dialogue::PoolReference& pool) { return &entries.at(pools.at(pool.id).get()); }
Dialogue::Entry* Dialogue::get(Dialogue::Pool& pool) { return &entries.at(pool.get()); }
}