This commit is contained in:
165
src/resource/xml/dialogue.cpp
Normal file
165
src/resource/xml/dialogue.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#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 { return this->at(math::random_max(this->size())); }
|
||||
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()); }
|
||||
}
|
||||
Reference in New Issue
Block a user