add item text replacements

This commit is contained in:
gymnast86
2026-05-28 20:04:20 -07:00
parent 485374abba
commit 351afd6686
7 changed files with 1991 additions and 36 deletions
@@ -1272,7 +1272,7 @@ RandomizerContext WriteSeedData(randomizer::logic::world::World* world) {
auto language = randomizer::Text::ENGLISH;
std::string text;
if (world->GetTextDatabase().contains(name)) {
text = world->GetDynamicTextStr(name);
text = world->GetText(name);
} else {
text = randomizer::getTextStr(name);
}
File diff suppressed because it is too large Load Diff
@@ -243,10 +243,118 @@
Group: 0
Message Id: 2041
- Name: Slingshot Shop Text
Group: 1
Message Id: 7009
- Name: Slingshot Shop Too Expensive Text
Group: 1
Message Id: 7014
- Name: Slingshot Shop Purchase Confirmation Text
Group: 1
Message Id: 7015
- Name: Slingshot Shop After Purchase Text
Group: 1
Message Id: 7016
- Name: Links House Sign
Group: 1
Message Id: 9005
- Name: Barnes Special Offer Text
Group: 2
Message Id: 5155
- Name: Kakariko Malo Mart Wooden Shield Purchase Confirmation Text
Group: 2
Message Id: 5809
- Name: Kakariko Malo Mart Wooden Shield Too Expensive Text
Group: 2
Message Id: 5810
- Name: Kakariko Malo Mart Hylian Shield Purchase Confirmation Text
Group: 2
Message Id: 5813
- Name: Kakariko Malo Mart Hylian Shield Too Expensive Text
Group: 2
Message Id: 5814
- Name: Kakariko Malo Mart Hylian Shield After Purchase Text
Group: 2
Message Id: 5818
- Name: Kakariko Malo Mart Hawkeye Purchase Confirmation Text
Group: 2
Message Id: 5820
- Name: Kakariko Malo Mart Hawkeye Too Expensive Text
Group: 2
Message Id: 5821
- Name: Kakariko Malo Mart Hawkeye After Purchase Text
Group: 2
Message Id: 5822
- Name: Kakariko Malo Mart Red Potion Too Expensive Text
Group: 2
Message Id: 5824
- Name: Kakariko Malo Mart Red Potion Purchase Confirmation Text
Group: 2
Message Id: 5825
- Name: Kakariko Malo Mart Red Potion Text
Group: 2
Message Id: 5990
- Name: Kakariko Malo Mart Hawkeye Coming Soon Text
Group: 2
Message Id: 5991
- Name: Kakariko Malo Mart Hawkeye Text
Group: 2
Message Id: 5992
- Name: Kakariko Malo Mart Sold Out Text
Group: 2
Message Id: 5996
- Name: Kakariko Malo Mart Wooden Shield Text
Group: 2
Message Id: 5998
- Name: Kakariko Malo Mart Hylian Shield Text
Group: 2
Message Id: 5999
- Name: Chudleys Shop Magic Armor Text
Group: 4
Message Id: 5413
- Name: Castle Town Malo Mart Magic Armor After Purchase Text
Group: 4
Message Id: 5433
- Name: Castle Town Malo Mart Magic Armor Text
Group: 4
Message Id: 5440
- Name: Castle Town Malo Mart Magic Armor Sold Out Text
Group: 4
Message Id: 5451
- Name: Charlo Donation Ask Text
Group: 4
Message Id: 6402
- Name: Charlo Donation Choice Text
Group: 4
Message Id: 6403
- Name: Fishing Hole Sign Text
Group: 7
Message Id: 9502
+49 -4
View File
@@ -20,16 +20,61 @@ namespace randomizer::logic::hints {
};
for (const auto& world : worlds) {
auto& requiredDungeonText = world->AddDynamicTextStr("Links House Sign");
for (const auto& [name, dungeon] : world->GetDungeonTable()) {
auto& requiredDungeonText = world->AddNewText("Links House Sign");
for (const auto& [dungeonName, dungeon] : world->GetDungeonTable()) {
if (dungeon->IsRequired()) {
requiredDungeonText += dungeonColors.at(name) + name + "\n";
requiredDungeonText += dungeonColors.at(dungeonName) + getTextObject(dungeonName) + "\n";
}
}
}
}
static void doItemTextReplacement(const std::unique_ptr<world::World>& world,
const std::string& locationName,
const std::list<std::string>& textNames,
Text::Color color) {
auto itemName = world->GetLocation(locationName)->GetCurrentItem()->GetName();
auto itemStandardName = addColor(getTextObject(itemName), color, 1, true);
auto itemPrettyName = addColor(getTextObject(itemName, Text::PRETTY), color);
for (const auto& textName : textNames) {
auto& text = world->AddNewText(textName);
text = getTextObject(textName + " Template");
text.Replace("<Item Standard Name>", itemStandardName);
text.Replace("<Item Pretty Name>", itemPrettyName);
}
}
static void GenerateItemTextReplacements(world::WorldPool& worlds) {
for (const auto& world : worlds) {
doItemTextReplacement(world, "Fishing Hole Bottle", {"Fishing Hole Sign Text"}, Text::GREEN);
doItemTextReplacement(world, "Charlo Donation Blessing", {"Charlo Donation Ask Text"}, Text::GREEN);
doItemTextReplacement(world, "Sera Shop Slingshot", {"Slingshot Shop Text",
"Slingshot Shop Too Expensive Text", "Slingshot Shop Purchase Confirmation Text",
"Slingshot Shop After Purchase Text"}, Text::ORANGE);
doItemTextReplacement(world, "Barnes Bomb Bag", {"Barnes Special Offer Text"}, Text::ORANGE);
doItemTextReplacement(world, "Kakariko Village Malo Mart Wooden Shield", {"Kakariko Malo Mart Wooden Shield Purchase Confirmation Text",
"Kakariko Malo Mart Wooden Shield Too Expensive Text", "Kakariko Malo Mart Wooden Shield Text"}, Text::ORANGE);
doItemTextReplacement(world, "Kakariko Village Malo Mart Hylian Shield", {"Kakariko Malo Mart Hylian Shield Purchase Confirmation Text",
"Kakariko Malo Mart Hylian Shield Too Expensive Text", "Kakariko Malo Mart Hylian Shield After Purchase Text",
"Kakariko Malo Mart Hylian Shield Text"}, Text::ORANGE);
doItemTextReplacement(world, "Kakariko Village Malo Mart Red Potion", {"Kakariko Malo Mart Red Potion Too Expensive Text",
"Kakariko Malo Mart Red Potion Purchase Confirmation Text", "Kakariko Malo Mart Red Potion Text"}, Text::ORANGE);
doItemTextReplacement(world, "Kakariko Village Malo Mart Hawkeye", {"Kakariko Malo Mart Hawkeye Purchase Confirmation Text",
"Kakariko Malo Mart Hawkeye Too Expensive Text", "Kakariko Malo Mart Hawkeye After Purchase Text",
"Kakariko Malo Mart Hawkeye Coming Soon Text", "Kakariko Malo Mart Hawkeye Text"}, Text::ORANGE);
doItemTextReplacement(world, "Castle Town Malo Mart Magic Armor", {"Chudleys Shop Magic Armor Text",
"Castle Town Malo Mart Magic Armor After Purchase Text", "Castle Town Malo Mart Magic Armor Text",
"Castle Town Malo Mart Magic Armor Sold Out Text"}, Text::ORANGE);
}
}
void GenerateAllHints(world::WorldPool& worlds) {
GenerateRequiredDungeonsHint(worlds);
GenerateItemTextReplacements(worlds);
}
}
}
@@ -151,12 +151,12 @@ namespace randomizer::logic::world
seedgen::settings::Setting& Setting(const std::string& settingName);
TextDatabase& GetTextDatabase() { return this->_textDatabase; }
const std::string& GetDynamicTextStr(const std::string& name) {
const std::string& GetText(const std::string& name) {
return this->_textDatabase.at(name).at(Text::Type::STANDARD).mText.at(Text::Language::ENGLISH);
}
// Make a new custom text entry for this world specifically
std::string& AddDynamicTextStr(const std::string& name, Text::Type type = Text::STANDARD, Text::Language language = Text::ENGLISH) {
return this->_textDatabase[name][type].mText[language];
// Make a new custom text entry for this world specifically and return a reference to it
Text& AddNewText(const std::string& name, Text::Type type = Text::STANDARD) {
return this->_textDatabase[name][type];
}
private:
+108 -19
View File
@@ -1,11 +1,9 @@
#include "text.hpp"
#include <unordered_map>
#include <filesystem>
#include <fstream>
#include "yaml.hpp"
#include <unordered_map>
namespace randomizer {
// std::array<std::string, 3> supported_languages = {"English", "Spanish", "French"};
@@ -156,6 +154,63 @@ namespace randomizer {
// return randomizer::utility::str::erge(lines, u'\n');
// }
Text::Text(const std::string& str) {
for (auto& text : mText) {
text = str;
}
}
void Text::Replace(const std::string& oldStr, const Text& replacementText, int count/* = 1*/) {
for (size_t i = 0; i < mText.size(); ++i) {
auto& curString = mText[i];
for (int i = 0; i < count; ++i) {
if (auto startPos = curString.find(oldStr); startPos != std::string::npos) {
curString.replace(startPos, oldStr.length(), replacementText.mText[i]);
}
}
}
}
void Text::Replace(const std::string& oldStr, const std::string& replacementText, int count/* = 1*/) {
for (size_t i = 0; i < mText.size(); ++i) {
auto& curString = mText[i];
for (int i = 0; i < count; ++i) {
if (auto startPos = curString.find(oldStr); startPos != std::string::npos) {
curString.replace(startPos, oldStr.length(), replacementText);
}
}
}
}
Text& Text::operator+=(const Text& rhs) {
for (size_t i = 0; i < mText.size(); ++i) {
mText[i] += rhs.mText[i];
}
return *this;
}
Text& Text::operator+=(const std::string& rhs) {
for (auto& text : mText) {
text += rhs;
}
return *this;
}
Text operator+(Text lhs, const Text& rhs) {
lhs += rhs;
return lhs;
}
Text operator+(Text lhs, const std::string& rhs) {
for (auto& text : lhs.mText) {
text += rhs;
}
return lhs;
}
Text operator+(const std::string& lhs, const Text& rhs) {
return Text(lhs) + rhs;
}
Text::Type string_to_type(const std::string& str) {
std::unordered_map<std::string, Text::Type> strToType = {
@@ -267,25 +322,59 @@ namespace randomizer {
return tb.at(name).at(type).mText.at(language);
}
Text addColor(const Text& t, Text::Color color, int count /* = 1*/, bool forceAround /* = false*/) {
const static std::unordered_map<Text::Color, std::string> colorStrings = {
{Text::WHITE, "<white>"},
{Text::RED, "<red>"},
{Text::GREEN, "<green>"},
{Text::LIGHT_BLUE, "<light blue>"},
{Text::YELLOW, "<yellow>"},
{Text::PURPLE, "<purple>"},
{Text::ORANGE, "<orange>"},
{Text::DARK_GREEN, "<dark green>"},
{Text::BLUE, "<blue>"},
{Text::SILVER, "<silver>"},
};
if (color == Text::Color::RAW) {
return t;
}
if (!colorStrings.contains(color)) {
throw std::runtime_error("Color enum value \"" + std::to_string(color) + "\" is not recognized.");
}
Text text = t;
if (forceAround) {
text = colorStrings.at(color) + text + colorStrings.at(Text::WHITE);
}
text.Replace("{", colorStrings.at(color), count);
text.Replace("}", colorStrings.at(Text::WHITE), count);
return text;
}
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 },
{"<choice 1>", "\x1A\x06\x00\x00\x09\x01"s},
{"<choice 2>", "\x1A\x06\x00\x00\x09\x02"s},
{"<choice 3>", "\x1A\x06\x00\x00\x09\x03"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},
{"<fast>", "\x1A\x05\x00\x00\x01"s},
{"<slow>", "\x1A\x05\x00\x00\x02"s},
{"<begin choice>", "\x1A\x05\x00\x00\x20"s},
{"<choice 1>", "\x1A\x06\x00\x00\x09\x01"s},
{"<choice 2>", "\x1A\x06\x00\x00\x09\x02"s},
{"<choice 3>", "\x1A\x06\x00\x00\x09\x03"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},
{"<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},
{"<male>", "\x1A\x05\x06\x00\x02"s},
{"<female>", "\x1A\x05\x06\x00\x03"s},
};
for (const auto& [code, replacement] : messageCodes) {
+26 -5
View File
@@ -23,15 +23,16 @@ namespace randomizer {
enum Color
{
RAW = 0,
NONE,
WHITE,
RED,
GREEN,
BLUE,
LIGHT_BLUE,
YELLOW,
CYAN,
MAGENTA,
GRAY,
PURPLE,
ORANGE,
DARK_GREEN,
BLUE,
SILVER,
};
enum Gender
@@ -49,9 +50,26 @@ namespace randomizer {
PLURALITY_MAX,
};
Text() = default;
explicit Text(const std::string& str);
std::array<std::string, LANGUAGE_MAX> mText{};
std::array<Gender, LANGUAGE_MAX> mGender{};
std::array<Plurality, LANGUAGE_MAX> mPlurality{};
/**
*
* @param oldStr the string to replace
* @param replacementText the Text object to replace the old string
* @param count the number of occurences to replace
*/
void Replace(const std::string& oldStr, const Text& replacementText, int count = 1);
void Replace(const std::string& oldStr, const std::string& replacementText, int count = 1);
Text& operator+=(const Text& rhs);
Text& operator+=(const std::string& rhs);
friend Text operator+(Text lhs, Text& rhs);
friend Text operator+(Text lhs, const std::string& rhs);
friend Text operator+(const std::string& lhs, const Text& rhs);
};
inline constexpr std::array supported_languages = {
@@ -71,8 +89,11 @@ namespace randomizer {
const TextDatabase& getTextDatabase();
const Text& getTextObject(const std::string& name, Text::Type type = Text::STANDARD);
const std::string& getTextStr(const std::string& name, Text::Type type = Text::STANDARD, Text::Language language = Text::ENGLISH);
Text addColor(const Text& text, Text::Color color, int count = 1, bool forceAround = false);
// Replaces the message codes in the string with the ingame hex equivalents
void applyMessageCodes(std::string&);
}; // namespace Text