mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-16 12:24:45 -04:00
implement custom item text
This commit is contained in:
@@ -1,178 +1,291 @@
|
||||
// #include "../utility/text.hpp"
|
||||
// #include "../utility/string.hpp"
|
||||
// #include <filetypes/util/msbtMacros.hpp"
|
||||
// #include <command/Log.hpp"
|
||||
#include "text.hpp"
|
||||
|
||||
// #include <unordered_map>
|
||||
#include <unordered_map>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
// namespace Text {
|
||||
#include "yaml.hpp"
|
||||
|
||||
// std::array<std::string, 3> supported_languages = {"English", "Spanish", "French"};
|
||||
namespace randomizer {
|
||||
|
||||
// static std::unordered_map<Text::Color, std::u16string> nameToColor = {
|
||||
// {Text::Color::NONE, TEXT_COLOR_DEFAULT},
|
||||
// {Text::Color::RED, TEXT_COLOR_RED},
|
||||
// {Text::Color::GREEN, TEXT_COLOR_GREEN},
|
||||
// {Text::Color::BLUE, TEXT_COLOR_BLUE},
|
||||
// {Text::Color::YELLOW, TEXT_COLOR_YELLOW},
|
||||
// {Text::Color::CYAN, TEXT_COLOR_CYAN},
|
||||
// {Text::Color::MAGENTA, TEXT_COLOR_MAGENTA},
|
||||
// {Text::Color::GRAY, TEXT_COLOR_GRAY},
|
||||
// {Text::Color::ORANGE, TEXT_COLOR_ORANGE},
|
||||
// };
|
||||
// std::array<std::string, 3> supported_languages = {"English", "Spanish", "French"};
|
||||
//
|
||||
// static std::unordered_map<Text::Color, std::u16string> nameToColor = {
|
||||
// {Text::Color::NONE, TEXT_COLOR_DEFAULT},
|
||||
// {Text::Color::RED, TEXT_COLOR_RED},
|
||||
// {Text::Color::GREEN, TEXT_COLOR_GREEN},
|
||||
// {Text::Color::BLUE, TEXT_COLOR_BLUE},
|
||||
// {Text::Color::YELLOW, TEXT_COLOR_YELLOW},
|
||||
// {Text::Color::CYAN, TEXT_COLOR_CYAN},
|
||||
// {Text::Color::MAGENTA, TEXT_COLOR_MAGENTA},
|
||||
// {Text::Color::GRAY, TEXT_COLOR_GRAY},
|
||||
// {Text::Color::ORANGE, TEXT_COLOR_ORANGE},
|
||||
// };
|
||||
//
|
||||
// std::u16string apply_name_color(std::u16string str, const Color& color)
|
||||
// {
|
||||
// // Return the raw text (bars included)
|
||||
// if (color == Color::RAW)
|
||||
// {
|
||||
// return str;
|
||||
// }
|
||||
// // If there are no '|'s then just return with the color surrounding the whole string
|
||||
// if (str.find('|') == std::string::npos)
|
||||
// {
|
||||
// auto textColor = nameToColor[color];
|
||||
// return textColor + str + TEXT_COLOR_DEFAULT;
|
||||
// }
|
||||
//
|
||||
// // Alternate between the text color and default incase there are multiple
|
||||
// // pairs of bars
|
||||
// auto textColor = nameToColor[color];
|
||||
// bool insertColor = false;
|
||||
// for (size_t pos = 0; pos < str.length(); pos++)
|
||||
// {
|
||||
// if (str[pos] == '|')
|
||||
// {
|
||||
// insertColor = !insertColor;
|
||||
// str.erase(pos, 1);
|
||||
// str.insert(pos, insertColor ? textColor : TEXT_COLOR_DEFAULT);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return str;
|
||||
// }
|
||||
//
|
||||
// std::u16string word_wrap_string(const std::u16string& string, const size_t& max_line_len) {
|
||||
// size_t index_in_str = 0;
|
||||
// std::u16string wordwrapped_str;
|
||||
// std::u16string current_word;
|
||||
// size_t curr_word_len = 0;
|
||||
// size_t len_curr_line = 0;
|
||||
//
|
||||
// while (index_in_str < string.length()) { //length is weird because its utf-16
|
||||
// char16_t character = string[index_in_str];
|
||||
//
|
||||
// if (character == u'\x0E') { //need to parse the commands, only implementing a few necessary ones for now (will break with other commands)
|
||||
// std::u16string substr;
|
||||
// size_t code_len = 0;
|
||||
// if (string[index_in_str + 1] == u'\x00') {
|
||||
// if (string[index_in_str + 2] == u'\x03') { //color command
|
||||
// if (string[index_in_str + 4] == u'\xFFFF') { //text color white, weird length
|
||||
// code_len = 10;
|
||||
// }
|
||||
// else {
|
||||
// code_len = 5;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x01') { //all implemented commands in this group have length 4
|
||||
// code_len = 4;
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x02') { //all implemented commands in this group have length 4
|
||||
// code_len = 4;
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x03') { //all implemented commands in this group have length 4
|
||||
// code_len = 4;
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x04') { //all implemented commands in this group have length 4. Only used for Ho Ho sound
|
||||
// code_len = 4;
|
||||
// }
|
||||
//
|
||||
// substr = string.substr(index_in_str, code_len);
|
||||
// current_word += substr;
|
||||
// index_in_str += code_len;
|
||||
// }
|
||||
// else if (character == u'\n') {
|
||||
// wordwrapped_str += current_word;
|
||||
// wordwrapped_str += character;
|
||||
// len_curr_line = 0;
|
||||
// current_word = u"";
|
||||
// curr_word_len = 0;
|
||||
// index_in_str += 1;
|
||||
// }
|
||||
// else if (character == u' ') {
|
||||
// wordwrapped_str += current_word;
|
||||
// wordwrapped_str += character;
|
||||
// len_curr_line += curr_word_len + 1;
|
||||
// current_word = u"";
|
||||
// curr_word_len = 0;
|
||||
// index_in_str += 1;
|
||||
// }
|
||||
// else {
|
||||
// current_word += character;
|
||||
// curr_word_len += 1;
|
||||
// index_in_str += 1;
|
||||
//
|
||||
// if (len_curr_line + curr_word_len > max_line_len) {
|
||||
// wordwrapped_str += u'\n';
|
||||
// len_curr_line = 0;
|
||||
//
|
||||
// if (curr_word_len > max_line_len) {
|
||||
// wordwrapped_str += current_word + u'\n';
|
||||
// current_word = u"";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// wordwrapped_str += current_word;
|
||||
//
|
||||
// return wordwrapped_str;
|
||||
// }
|
||||
//
|
||||
// std::string pad_str_4_lines(const std::string& string)
|
||||
// {
|
||||
// std::vector<std::string> lines = randomizer::utility::str::Split(string, '\n');
|
||||
//
|
||||
// unsigned int padding_lines_needed = (4 - lines.size() % 4) % 4;
|
||||
// for (unsigned int i = 0; i < padding_lines_needed; i++)
|
||||
// {
|
||||
// lines.push_back("");
|
||||
// }
|
||||
//
|
||||
// return randomizer::utility::str::Merge(lines, '\n');
|
||||
// }
|
||||
//
|
||||
// std::u16string pad_str_4_lines(const std::u16string& string)
|
||||
// {
|
||||
// std::vector<std::u16string> lines = randomizer::utility::str::Split(string, u'\n');
|
||||
//
|
||||
// unsigned int padding_lines_needed = (4 - lines.size() % 4) % 4;
|
||||
// for (unsigned int i = 0; i < padding_lines_needed; i++)
|
||||
// {
|
||||
// lines.push_back(u"");
|
||||
// }
|
||||
//
|
||||
// return randomizer::utility::str::erge(lines, u'\n');
|
||||
// }
|
||||
|
||||
// std::u16string apply_name_color(std::u16string str, const Color& color)
|
||||
// {
|
||||
// // Return the raw text (bars included)
|
||||
// if (color == Color::RAW)
|
||||
// {
|
||||
// return str;
|
||||
// }
|
||||
// // If there are no '|'s then just return with the color surrounding the whole string
|
||||
// if (str.find('|') == std::string::npos)
|
||||
// {
|
||||
// auto textColor = nameToColor[color];
|
||||
// return textColor + str + TEXT_COLOR_DEFAULT;
|
||||
// }
|
||||
|
||||
// // Alternate between the text color and default incase there are multiple
|
||||
// // pairs of bars
|
||||
// auto textColor = nameToColor[color];
|
||||
// bool insertColor = false;
|
||||
// for (size_t pos = 0; pos < str.length(); pos++)
|
||||
// {
|
||||
// if (str[pos] == '|')
|
||||
// {
|
||||
// insertColor = !insertColor;
|
||||
// str.erase(pos, 1);
|
||||
// str.insert(pos, insertColor ? textColor : TEXT_COLOR_DEFAULT);
|
||||
// }
|
||||
// }
|
||||
Text::Type string_to_type(const std::string& str) {
|
||||
std::unordered_map<std::string, Text::Type> strToType = {
|
||||
{"Standard", Text::Type::STANDARD},
|
||||
{"Pretty", Text::Type::PRETTY},
|
||||
{"Cryptic", Text::Type::CRYPTIC},
|
||||
};
|
||||
|
||||
// return str;
|
||||
// }
|
||||
if (strToType.contains(str))
|
||||
{
|
||||
return strToType.at(str);
|
||||
}
|
||||
|
||||
// std::u16string word_wrap_string(const std::u16string& string, const size_t& max_line_len) {
|
||||
// size_t index_in_str = 0;
|
||||
// std::u16string wordwrapped_str;
|
||||
// std::u16string current_word;
|
||||
// size_t curr_word_len = 0;
|
||||
// size_t len_curr_line = 0;
|
||||
throw std::runtime_error("Text type \"" + str + "\" is not recognized.");
|
||||
}
|
||||
|
||||
// while (index_in_str < string.length()) { //length is weird because its utf-16
|
||||
// char16_t character = string[index_in_str];
|
||||
Text::Language string_to_language(const std::string& str) {
|
||||
std::unordered_map<std::string, Text::Language> strToLanguage = {
|
||||
{"english", Text::Language::ENGLISH},
|
||||
};
|
||||
|
||||
// if (character == u'\x0E') { //need to parse the commands, only implementing a few necessary ones for now (will break with other commands)
|
||||
// std::u16string substr;
|
||||
// size_t code_len = 0;
|
||||
// if (string[index_in_str + 1] == u'\x00') {
|
||||
// if (string[index_in_str + 2] == u'\x03') { //color command
|
||||
// if (string[index_in_str + 4] == u'\xFFFF') { //text color white, weird length
|
||||
// code_len = 10;
|
||||
// }
|
||||
// else {
|
||||
// code_len = 5;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x01') { //all implemented commands in this group have length 4
|
||||
// code_len = 4;
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x02') { //all implemented commands in this group have length 4
|
||||
// code_len = 4;
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x03') { //all implemented commands in this group have length 4
|
||||
// code_len = 4;
|
||||
// }
|
||||
// else if (string[index_in_str + 1] == u'\x04') { //all implemented commands in this group have length 4. Only used for Ho Ho sound
|
||||
// code_len = 4;
|
||||
// }
|
||||
if (strToLanguage.contains(str))
|
||||
{
|
||||
return strToLanguage.at(str);
|
||||
}
|
||||
|
||||
// substr = string.substr(index_in_str, code_len);
|
||||
// current_word += substr;
|
||||
// index_in_str += code_len;
|
||||
// }
|
||||
// else if (character == u'\n') {
|
||||
// wordwrapped_str += current_word;
|
||||
// wordwrapped_str += character;
|
||||
// len_curr_line = 0;
|
||||
// current_word = u"";
|
||||
// curr_word_len = 0;
|
||||
// index_in_str += 1;
|
||||
// }
|
||||
// else if (character == u' ') {
|
||||
// wordwrapped_str += current_word;
|
||||
// wordwrapped_str += character;
|
||||
// len_curr_line += curr_word_len + 1;
|
||||
// current_word = u"";
|
||||
// curr_word_len = 0;
|
||||
// index_in_str += 1;
|
||||
// }
|
||||
// else {
|
||||
// current_word += character;
|
||||
// curr_word_len += 1;
|
||||
// index_in_str += 1;
|
||||
throw std::runtime_error("Language \"" + str + "\" is not recognized.");
|
||||
}
|
||||
|
||||
// if (len_curr_line + curr_word_len > max_line_len) {
|
||||
// wordwrapped_str += u'\n';
|
||||
// len_curr_line = 0;
|
||||
Text::Gender string_to_gender(const std::string& str)
|
||||
{
|
||||
std::unordered_map<std::string, Text::Gender> strToGender = {
|
||||
{"Masculine", Text::Gender::MASCULINE},
|
||||
{"Feminine", Text::Gender::FEMININE}
|
||||
};
|
||||
|
||||
// if (curr_word_len > max_line_len) {
|
||||
// wordwrapped_str += current_word + u'\n';
|
||||
// current_word = u"";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// wordwrapped_str += current_word;
|
||||
if (strToGender.contains(str))
|
||||
{
|
||||
return strToGender.at(str);
|
||||
}
|
||||
|
||||
// return wordwrapped_str;
|
||||
// }
|
||||
return Text::Gender::NUETRAL;
|
||||
}
|
||||
|
||||
// std::string pad_str_4_lines(const std::string& string)
|
||||
// {
|
||||
// std::vector<std::string> lines = randomizer::utility::str::Split(string, '\n');
|
||||
Text::Plurality string_to_plurality(const std::string& str)
|
||||
{
|
||||
if (str == "Plural") return Text::Plurality::PLURAL;
|
||||
return Text::Plurality::SINGULAR;
|
||||
}
|
||||
|
||||
// unsigned int padding_lines_needed = (4 - lines.size() % 4) % 4;
|
||||
// for (unsigned int i = 0; i < padding_lines_needed; i++)
|
||||
// {
|
||||
// lines.push_back("");
|
||||
// }
|
||||
static void LoadTextData(TextDatabase& tb) {
|
||||
std::string dataPath = RANDO_DATA_PATH "text/languages";
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dataPath)) {
|
||||
if (entry.is_regular_file() && entry.path().extension() == ".yaml") {
|
||||
auto language = string_to_language(entry.path().stem().string());
|
||||
auto textData = LoadYAML(entry.path());
|
||||
for (const auto& textNode : textData) {
|
||||
const auto& name = textNode.first.as<std::string>();
|
||||
for (const auto& typeNode : textNode.second) {
|
||||
auto type = string_to_type(typeNode.first.as<std::string>());
|
||||
auto typeData = typeNode.second;
|
||||
const auto& text = typeData["Text"].as<std::string>();
|
||||
tb[name][type].mtext[language] = text;
|
||||
if (typeData["Gender"]) {
|
||||
tb[name][type].mGender[language] = string_to_gender(typeData["Gender"].as<std::string>());
|
||||
}
|
||||
if (typeData["Plurality"]) {
|
||||
tb[name][type].mPlurality[language] = string_to_plurality(typeData["Plurality"].as<std::string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return randomizer::utility::str::Merge(lines, '\n');
|
||||
// }
|
||||
const TextDatabase& getTextDatabase() {
|
||||
static TextDatabase tb{};
|
||||
|
||||
// std::u16string pad_str_4_lines(const std::u16string& string)
|
||||
// {
|
||||
// std::vector<std::u16string> lines = randomizer::utility::str::Split(string, u'\n');
|
||||
// If database is empty, load it up
|
||||
if (tb.empty()) {
|
||||
LoadTextData(tb);
|
||||
}
|
||||
|
||||
// unsigned int padding_lines_needed = (4 - lines.size() % 4) % 4;
|
||||
// for (unsigned int i = 0; i < padding_lines_needed; i++)
|
||||
// {
|
||||
// lines.push_back(u"");
|
||||
// }
|
||||
return tb;
|
||||
}
|
||||
|
||||
// return randomizer::utility::str::erge(lines, u'\n');
|
||||
// }
|
||||
const Text& getTextObject(const std::string& name, Text::Type type /*= Text::STANDARD*/)
|
||||
{
|
||||
const auto& tb = getTextDatabase();
|
||||
if (!tb.contains(name)) {
|
||||
throw std::runtime_error("Text name \"" + name + "\" is not recognized.");
|
||||
}
|
||||
return tb.at(name).at(type);
|
||||
}
|
||||
|
||||
// Gender string_to_gender(const std::string& str)
|
||||
// {
|
||||
// std::unordered_map<std::string, Gender> strToGender = {
|
||||
// {"Male", Gender::MALE},
|
||||
// {"Female", Gender::FEMALE}
|
||||
// };
|
||||
const std::string& getTextStr(const std::string& name,
|
||||
Text::Type type /*= Text::STANDARD*/,
|
||||
Text::Language language /*= Text::ENGLISH*/)
|
||||
{
|
||||
const auto& tb = getTextDatabase();
|
||||
if (!tb.contains(name)) {
|
||||
throw std::runtime_error("Text name \"" + name + "\" is not recognized.");
|
||||
}
|
||||
return tb.at(name).at(type).mtext.at(language);
|
||||
}
|
||||
|
||||
// if (strToGender.contains(str))
|
||||
// {
|
||||
// return strToGender.at(str);
|
||||
// }
|
||||
void applyMessageCodes(std::string& str) {
|
||||
using namespace std::string_literals;
|
||||
const static std::unordered_map<std::string, std::string> messageCodes = {
|
||||
{"<fast>", "\x1A\x05\x00\x00\x01"s },
|
||||
{"<slow>", "\x1A\x05\x00\x00\x02"s },
|
||||
{"<white>", "\x1A\x06\xFF\x00\x00\x00"s},
|
||||
{"<red>", "\x1A\x06\xFF\x00\x00\x01"s},
|
||||
{"<green>", "\x1A\x06\xFF\x00\x00\x02"s},
|
||||
{"<light blue>", "\x1A\x06\xFF\x00\x00\x03"s},
|
||||
{"<yellow>", "\x1A\x06\xFF\x00\x00\x04"s},
|
||||
{"<purple>", "\x1A\x06\xFF\x00\x00\x06"s},
|
||||
{"<orange>", "\x1A\x06\xFF\x00\x00\x08"s},
|
||||
// custom colors
|
||||
{"<dark green>", "\x1A\x06\xFF\x00\x00\x09"s},
|
||||
{"<blue>", "\x1A\x06\xFF\x00\x00\x0A"s},
|
||||
{"<silver>", "\x1A\x06\xFF\x00\x00\x0B"s},
|
||||
};
|
||||
|
||||
// return Gender::NONE;
|
||||
// }
|
||||
|
||||
// Plurality string_to_plurality(const std::string& str)
|
||||
// {
|
||||
// if (str == "Plural") return Plurality::PLURAL;
|
||||
// return Plurality::SINGULAR;
|
||||
// }
|
||||
// }; // namespace Text
|
||||
for (const auto& [code, replacement] : messageCodes) {
|
||||
size_t pos = 0;
|
||||
while ((pos = str.find(code, pos)) != std::string::npos) {
|
||||
str.replace(pos, code.length(), replacement);
|
||||
pos += replacement.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // namespace Text
|
||||
|
||||
Reference in New Issue
Block a user