mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-02-07 10:50:29 -05:00
Streamline hint generation (#3401)
* reimplement 3drando's hashtag color replacement system. Also generates merchant text at seed gen time instead of runtime. By merchants, I mean Bean Salesman, Medigoron, Granny, and Wasteland Bombchu guy. Scrubs and shops are still dynamic at runtime. * Improved auto-formatting and fixed altar text. * Gets hint text for spoiler direct from context. * Removal of now unused code. * Change warp song hint generation/retrieval Generates full warp location text instead of just location names and stores all six in the custom message tables for later retrieval as opposed to dynamically swapping in the location names every time the text is rendered. * Change Frog Ocarina Game Hint generation/retrieval Similar to previous changes, removes the on-the-fly generation aspect of it and just generates the full hint text once during seed generation. * Update soh/soh/Enhancements/randomizer/3drando/text.hpp Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> * Fix submodules appearing as changed files. * Fix WOTH/Foolish colors to match develop-macready. * Fixes backwards colors for area and item in some hints. --------- Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com>
This commit is contained in:
parent
467ee7ad12
commit
a196dd6b7e
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -6,4 +6,4 @@
|
|||||||
url = https://github.com/harbourmasters/ZAPDTR
|
url = https://github.com/harbourmasters/ZAPDTR
|
||||||
[submodule "OTRExporter"]
|
[submodule "OTRExporter"]
|
||||||
path = OTRExporter
|
path = OTRExporter
|
||||||
url = https://github.com/harbourmasters/OTRExporter/
|
url = https://github.com/harbourmasters/OTRExporter
|
||||||
|
@ -17,6 +17,24 @@ static const std::unordered_map<std::string, char> textBoxSpecialCharacters = {
|
|||||||
static const std::unordered_map<std::string, char> colors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN },
|
static const std::unordered_map<std::string, char> colors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN },
|
||||||
{ "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK },
|
{ "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK },
|
||||||
{ "y", QM_YELLOW }, { "B", QM_BLACK } };
|
{ "y", QM_YELLOW }, { "B", QM_BLACK } };
|
||||||
|
static const std::unordered_map<std::string, ItemID> altarIcons = {
|
||||||
|
{ "0", ITEM_KOKIRI_EMERALD },
|
||||||
|
{ "1", ITEM_GORON_RUBY },
|
||||||
|
{ "2", ITEM_ZORA_SAPPHIRE },
|
||||||
|
{ "8", ITEM_MEDALLION_LIGHT },
|
||||||
|
{ "3", ITEM_MEDALLION_FOREST },
|
||||||
|
{ "4", ITEM_MEDALLION_FIRE },
|
||||||
|
{ "5", ITEM_MEDALLION_WATER },
|
||||||
|
{ "6", ITEM_MEDALLION_SPIRIT },
|
||||||
|
{ "7", ITEM_MEDALLION_SHADOW },
|
||||||
|
{ "l", ITEM_ARROW_LIGHT },
|
||||||
|
{ "b", ITEM_KEY_BOSS },
|
||||||
|
{ "o", ITEM_SWORD_MASTER },
|
||||||
|
{ "c", ITEM_OCARINA_FAIRY },
|
||||||
|
{ "i", ITEM_OCARINA_TIME },
|
||||||
|
{ "L", ITEM_BOW_ARROW_LIGHT },
|
||||||
|
{ "k", ITEM_TUNIC_KOKIRI }
|
||||||
|
};
|
||||||
|
|
||||||
CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_,
|
CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_,
|
||||||
TextBoxPosition position_)
|
TextBoxPosition position_)
|
||||||
@ -116,6 +134,7 @@ void CustomMessage::Format(ItemID iid) {
|
|||||||
}
|
}
|
||||||
ReplaceSpecialCharacters();
|
ReplaceSpecialCharacters();
|
||||||
ReplaceColors();
|
ReplaceColors();
|
||||||
|
ReplaceAltarIcons();
|
||||||
*this += MESSAGE_END();
|
*this += MESSAGE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +146,7 @@ void CustomMessage::Format() {
|
|||||||
}
|
}
|
||||||
ReplaceSpecialCharacters();
|
ReplaceSpecialCharacters();
|
||||||
ReplaceColors();
|
ReplaceColors();
|
||||||
|
ReplaceAltarIcons();
|
||||||
*this += MESSAGE_END();
|
*this += MESSAGE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +191,7 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) {
|
|||||||
|
|
||||||
void CustomMessage::ReplaceColors() {
|
void CustomMessage::ReplaceColors() {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
for (std::string* str : { &english, &french, &german }) {
|
||||||
for (auto colorPair : colors) {
|
for (const auto& colorPair : colors) {
|
||||||
std::string textToReplace = "%";
|
std::string textToReplace = "%";
|
||||||
textToReplace += colorPair.first;
|
textToReplace += colorPair.first;
|
||||||
size_t start_pos = 0;
|
size_t start_pos = 0;
|
||||||
@ -183,27 +203,41 @@ void CustomMessage::ReplaceColors() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CustomMessage::MESSAGE_END() const {
|
void CustomMessage::ReplaceAltarIcons() {
|
||||||
|
for (std::string* str : { &english, &french, &german }) {
|
||||||
|
for (const auto& iconPair : altarIcons) {
|
||||||
|
std::string textToReplace = "$";
|
||||||
|
textToReplace += iconPair.first;
|
||||||
|
size_t start_pos = 0;
|
||||||
|
while ((start_pos = str->find(textToReplace, start_pos)) != std::string::npos) {
|
||||||
|
str->replace(start_pos, textToReplace.length(), ITEM_OBTAINED(iconPair.second));
|
||||||
|
start_pos += textToReplace.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CustomMessage::MESSAGE_END() {
|
||||||
return "\x02"s;
|
return "\x02"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CustomMessage::ITEM_OBTAINED(uint8_t x) const {
|
std::string CustomMessage::ITEM_OBTAINED(uint8_t x) {
|
||||||
return "\x13"s + char(x);
|
return "\x13"s + char(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CustomMessage::NEWLINE() const {
|
std::string CustomMessage::NEWLINE() {
|
||||||
return "\x01"s;
|
return "\x01"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CustomMessage::COLOR(uint8_t x) const {
|
std::string CustomMessage::COLOR(uint8_t x) {
|
||||||
return "\x05"s + char(x);
|
return "\x05"s + char(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CustomMessage::WAIT_FOR_INPUT() const {
|
std::string CustomMessage::WAIT_FOR_INPUT() {
|
||||||
return "\x04"s;
|
return "\x04"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CustomMessage::PLAYER_NAME() const {
|
std::string CustomMessage::PLAYER_NAME() {
|
||||||
return "\x0F"s;
|
return "\x0F"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,13 @@ class CustomMessage {
|
|||||||
CustomMessage(std::string english_, std::string german_, std::string french_,
|
CustomMessage(std::string english_, std::string german_, std::string french_,
|
||||||
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||||
|
|
||||||
|
static std::string MESSAGE_END() ;
|
||||||
|
static std::string ITEM_OBTAINED(uint8_t x) ;
|
||||||
|
static std::string NEWLINE() ;
|
||||||
|
static std::string COLOR(uint8_t x) ;
|
||||||
|
static std::string WAIT_FOR_INPUT() ;
|
||||||
|
static std::string PLAYER_NAME() ;
|
||||||
|
|
||||||
const std::string& GetEnglish() const;
|
const std::string& GetEnglish() const;
|
||||||
const std::string& GetFrench() const;
|
const std::string& GetFrench() const;
|
||||||
const std::string& GetGerman() const;
|
const std::string& GetGerman() const;
|
||||||
@ -80,6 +87,11 @@ class CustomMessage {
|
|||||||
*/
|
*/
|
||||||
void ReplaceColors();
|
void ReplaceColors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces `$<char>` variable strings with OoT control codes.
|
||||||
|
*/
|
||||||
|
void ReplaceAltarIcons();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replaces various symbols with the control codes necessary to
|
* @brief Replaces various symbols with the control codes necessary to
|
||||||
* display them in OoT's textboxes. i.e. special characters, colors, newlines,
|
* display them in OoT's textboxes. i.e. special characters, colors, newlines,
|
||||||
@ -97,13 +109,6 @@ class CustomMessage {
|
|||||||
void Format();
|
void Format();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string MESSAGE_END() const;
|
|
||||||
const std::string ITEM_OBTAINED(uint8_t x) const;
|
|
||||||
const std::string NEWLINE() const;
|
|
||||||
const std::string COLOR(uint8_t x) const;
|
|
||||||
const std::string WAIT_FOR_INPUT() const;
|
|
||||||
const std::string PLAYER_NAME() const;
|
|
||||||
|
|
||||||
std::string english = "";
|
std::string english = "";
|
||||||
std::string french = "";
|
std::string french = "";
|
||||||
std::string german = "";
|
std::string german = "";
|
||||||
|
@ -283,7 +283,7 @@ constexpr std::array DungeonColors = {
|
|||||||
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; }
|
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; }
|
||||||
std::string CURRENT_TIME() { return "\x7F\x17"s; }
|
std::string CURRENT_TIME() { return "\x7F\x17"s; }
|
||||||
std::string UNSKIPPABLE() { return "\x7F\x19"s; }
|
std::string UNSKIPPABLE() { return "\x7F\x19"s; }
|
||||||
std::string TWO_WAY_CHOICE() { return "\x7F\x1A\xFF\xFF\xFF\xFF"s; }
|
std::string TWO_WAY_CHOICE() { return "\x1B"s; }
|
||||||
std::string NEWLINE() { return "\x7F\x1C"s; }
|
std::string NEWLINE() { return "\x7F\x1C"s; }
|
||||||
std::string COLOR(uint8_t x) { return "\x7F\x1D"s + char(x); }
|
std::string COLOR(uint8_t x) { return "\x7F\x1D"s + char(x); }
|
||||||
std::string CENTER_TEXT() { return "\x7F\x1E"s; }
|
std::string CENTER_TEXT() { return "\x7F\x1E"s; }
|
||||||
|
@ -31,12 +31,12 @@ void HintTable_Init() {
|
|||||||
hintTable[RHT_PREFIX] =
|
hintTable[RHT_PREFIX] =
|
||||||
HintText::Exclude({ Text{ "They say that ", /*french*/ "Selon moi, ", /*spanish*/ "Según dicen, " } });
|
HintText::Exclude({ Text{ "They say that ", /*french*/ "Selon moi, ", /*spanish*/ "Según dicen, " } });
|
||||||
hintTable[RHT_WAY_OF_THE_HERO] =
|
hintTable[RHT_WAY_OF_THE_HERO] =
|
||||||
HintText::Exclude({ Text{ " is on %cthe way of the hero%w.", /*french*/ " est sur %cla voie du héros%w.",
|
HintText::Exclude({ Text{ " is on #the way of the hero#.", /*french*/ " est sur #la voie du héros#.",
|
||||||
/*spanish*/ " conduce a la senda del héroe." } });
|
/*spanish*/ " conduce a la senda del héroe." } });
|
||||||
hintTable[RHT_PLUNDERING] =
|
hintTable[RHT_PLUNDERING] =
|
||||||
HintText::Exclude({ Text{ "plundering ", /*french*/ "explorer ", /*spanish*/ "inspeccionar " } });
|
HintText::Exclude({ Text{ "plundering ", /*french*/ "explorer ", /*spanish*/ "inspeccionar " } });
|
||||||
hintTable[RHT_FOOLISH] = HintText::Exclude(
|
hintTable[RHT_FOOLISH] = HintText::Exclude(
|
||||||
{ Text{ " is %pa foolish choice%w.", /*french*/ " est %pfutile%w.", /*spanish*/ " no es una sabia decisión." } });
|
{ Text{ " is #a foolish choice#.", /*french*/ " est #futile#.", /*spanish*/ " #no es una sabia decisión#." } });
|
||||||
hintTable[RHT_CAN_BE_FOUND_AT] =
|
hintTable[RHT_CAN_BE_FOUND_AT] =
|
||||||
HintText::Exclude({ Text{ "can be found at", /*french*/ "se trouve dans", /*spanish*/ "aguarda en" } });
|
HintText::Exclude({ Text{ "can be found at", /*french*/ "se trouve dans", /*spanish*/ "aguarda en" } });
|
||||||
hintTable[RHT_HOARDS] = HintText::Exclude({ Text{ "hoards", /*french*/ "recèle", /*spanish*/ "acapara" } });
|
hintTable[RHT_HOARDS] = HintText::Exclude({ Text{ "hoards", /*french*/ "recèle", /*spanish*/ "acapara" } });
|
||||||
@ -2671,66 +2671,73 @@ void HintTable_Init() {
|
|||||||
|
|
||||||
hintTable[RHT_BRIDGE_OPEN_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_OPEN_HINT] = HintText::Bridge({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "The awakened ones have already&created a bridge to the castle&where the evil dwells.",
|
Text{ "The awakened ones have #already created a bridge# to the castle where the evil dwells.",
|
||||||
/*french*/ "Les êtres de sagesse ont&déjà créé un pont vers&le repaire du mal.",
|
/*french*/ "Les êtres de sagesse ont#déjà créé un pont# vers le repaire du mal.",
|
||||||
/*spanish*/ "Los sabios #ya habrán creado un puente#&al castillo, de donde emana el mal." },
|
/*spanish*/ "Los sabios #ya habrán creado un puente#&al castillo, de donde emana el mal.",
|
||||||
|
/*german*/"Die Weisen haben #bereits&eine Brücke zum Portal von&Ganons Schloss gelegt#..." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_VANILLA_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_VANILLA_HINT] = HintText::Bridge({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "The awakened ones require&the Shadow and Spirit Medallions&as well as the Light Arrows.",
|
Text{ "The awakened ones require the #Shadow and Spirit Medallions# as well as the #Light Arrows#.",
|
||||||
/*french*/
|
/*french*/
|
||||||
"Les êtres de sagesse attendront&le héros muni des %rMédaillons de&l'Ombre et l'Esprit%w et des&%yFlèches de Lumière%w.",
|
"Les êtres de sagesse attendront le héros muni des #Médaillons de l'Ombre et l'Esprit# et des #Flèches de Lumière#.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Los sabios aguardarán a que el héroe&obtenga tanto el #Medallón de las&Sombras y el del Espíritu# junto "
|
"Los sabios aguardarán a que el héroe obtenga tanto el #Medallón de las Sombras y el del Espíritu# junto "
|
||||||
"a la #flecha de luz#." },
|
"a la #flecha de luz#.",
|
||||||
|
/*german*/"Die Weisen werden darauf warten, dass der Held das #Amulett des Schattens, Amulett der Geister# und die #Licht-Pfeile# sammelt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_STONES_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_STONES_HINT] = HintText::Bridge({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{
|
Text{
|
||||||
"The awakened ones will&await for the Hero to collect&%d |Spiritual Stone|Spiritual Stones|.",
|
"The awakened ones will await for the Hero to collect #%d |Spiritual Stone|Spiritual Stones|#.",
|
||||||
/*french*/ "Les êtres de sagesse attendront&le héros muni de %r%d |Pierre&Ancestrale|Pierres&Ancestrales|%w.",
|
/*french*/ "Les êtres de sagesse attendront le héros muni de #%d |Pierre Ancestrale|Pierres Ancestrales|#.",
|
||||||
/*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |piedra espiritual|piedras espirituales|#." },
|
/*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |piedra espiritual|piedras espirituales|#.",
|
||||||
|
/*german*/"Die Weisen werden darauf warten, dass der Held #%d |Heiligen Stein|Heilige Steine|# sammelt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_MEDALLIONS_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_MEDALLIONS_HINT] = HintText::Bridge({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "The awakened ones will await&for the Hero to collect&%d |Medallion|Medallions|.",
|
Text{ "The awakened ones will await for the Hero to collect #%d |Medallion|Medallions|#.",
|
||||||
/*french*/ "Les êtres de sagesse attendront&le héros muni de %r#%d |Médaillon|Médaillons|%w.",
|
/*french*/ "Les êtres de sagesse attendront le héros muni de #%d |Médaillon|Médaillons|#.",
|
||||||
/*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |medallón|medallones|#." },
|
/*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |medallón|medallones|#.",
|
||||||
|
/*german*/"Die Weisen werden darauf warten, dass der Held #%d |Amulett|Amulette|# sammelt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_REWARDS_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_REWARDS_HINT] = HintText::Bridge({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "The awakened ones will await&for the Hero to collect&%d |Spiritual Stone or Medallion|Spiritual Stones "
|
Text{ "The awakened ones will await for the Hero to collect #%d |Spiritual Stone or Medallion|Spiritual Stones "
|
||||||
"and Medallions|.",
|
"and Medallions|#.",
|
||||||
/*french*/
|
/*french*/
|
||||||
"Les êtres de sagesse attendront&le héros muni de %r%d |Pierre&Ancestrale ou Médaillon|Pierres&Ancestrales ou Médaillons|%w.",
|
"Les êtres de sagesse attendront le héros muni de #%d |Pierre Ancestrale ou Médaillon|Pierres Ancestrales ou Médaillons|#.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Los sabios aguardarán a que el héroe&obtenga #%d |piedra espiritual o medallón|piedras espirtuales y "
|
"Los sabios aguardarán a que el héroe obtenga #%d |piedra espiritual o medallón|piedras espirtuales y "
|
||||||
"medallones|#." },
|
"medallones|#.",
|
||||||
|
/*german*/"Die Weisen werden darauf warten, dass der Held #%d |Heiligen Stein oder Amulett|Heilige Steine oder Amulette|# sammelt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_DUNGEONS_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_DUNGEONS_HINT] = HintText::Bridge({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "The awakened ones will await&for the Hero to conquer&%d |Dungeon|Dungeons|.",
|
Text{ "The awakened ones will await for the Hero to conquer #%d |Dungeon|Dungeons|#.",
|
||||||
/*french*/ "Les êtres de sagesse attendront&la conquête de %r%d |Donjon|Donjons|%w.",
|
/*french*/ "Les êtres de sagesse attendront la conquête de #%d |Donjon|Donjons|#.",
|
||||||
/*spanish*/ "Los sabios aguardarán a que el héroe& complete #%d |mazmorra|mazmorras|#." },
|
/*spanish*/ "Los sabios aguardarán a que el héroe complete #%d |mazmorra|mazmorras|#.",
|
||||||
|
/*german*/"Die Weisen werden darauf warten, dass der Held #%d |Labyrinth|Labyrinthe|# abschließt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_TOKENS_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_TOKENS_HINT] = HintText::Bridge({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "The awakened ones will await&for the Hero to collect&%d |Gold Skulltula Token|Gold Skulltula Tokens|.",
|
Text{ "The awakened ones will await for the Hero to collect #%d |Gold Skulltula Token|Gold Skulltula Tokens|#.",
|
||||||
/*french*/ "Les êtres de sagesse attendront&le héros muni de %r%d |Symbole|Symboles| &de Skulltula d'or%w.",
|
/*french*/ "Les êtres de sagesse attendront le héros muni de #%d |Symbole|Symboles| de Skulltula d'or#.",
|
||||||
/*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |símbolo|símbolos| de&skulltula dorada#." },
|
/*spanish*/ "Los sabios aguardarán a que el héroe obtenga #%d |símbolo|símbolos| de skulltula dorada#.",
|
||||||
|
/*german*/"Die Weisen werden darauf warten, dass der Held #%d |Skulltula-Symbol|Skulltula-Symbole|# sammelt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_BRIDGE_GREG_HINT] = HintText::Bridge({
|
hintTable[RHT_BRIDGE_GREG_HINT] = HintText::Bridge({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "The awakened ones will await&for the Hero to find %gGreg%w.",
|
Text{ "The awakened ones will await for the Hero to find %gGreg%w.",
|
||||||
/*french*/ "The awakened ones will await&for the Hero to find %gGreg%w.",
|
/*french*/ "The awakened ones will await for the Hero to find %gGreg%w.",
|
||||||
/*spanish*/ "The awakened ones will await&for the Hero to find %gGreg%w." },
|
/*spanish*/ "The awakened ones will await for the Hero to find %gGreg%w." },
|
||||||
});
|
});
|
||||||
|
|
||||||
/*--------------------------
|
/*--------------------------
|
||||||
@ -2739,57 +2746,64 @@ void HintTable_Init() {
|
|||||||
|
|
||||||
hintTable[RHT_GANON_BK_START_WITH_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_START_WITH_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be given %rfrom the start%w.",
|
Text{ "And the #evil one#'s key will be #given from the start#.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&possession %rmême du héros%w.",
|
/*french*/ "Aussi, la #clé du Malin# sera #possession même du héros#.",
|
||||||
/*spanish*/ "Y obtendrás la llave del #señor del mal# desde el #inicio#." },
|
/*spanish*/ "Y obtendrás la llave del #señor del mal# desde el #inicio#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen#, wird #von Anfang an, im Besitz des Helden# sein." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_VANILLA_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_VANILLA_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be kept in a big chest&%rinside its tower%w.",
|
Text{ "And the #evil one#'s key will be kept in a big chest #inside its tower#.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&encoffrée %rdans sa tour%w.",
|
/*french*/ "Aussi, la #clé du Malin# sera encoffrée #dans sa tour#.",
|
||||||
/*spanish*/ "Y la llave del #señor del mal# aguardará en un gran cofre de #su torre#." },
|
/*spanish*/ "Y la llave del #señor del mal# aguardará en un gran cofre de #su torre#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen#, wird in der großen Truhe #im Teufelsturm# zu finden sein." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_OWN_DUNGEON_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_OWN_DUNGEON_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be hidden somewhere %rinside&its castle%w.",
|
Text{ "And the #evil one#'s key will be hidden somewhere #inside its castle#.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&cachée %rdans son vaste château%w.",
|
/*french*/ "Aussi, la #clé du Malin# sera cachée #dans son vaste château#.",
|
||||||
/*spanish*/ "Y la llave del #señor del mal# aguardará en #algún lugar de su castillo#." },
|
/*spanish*/ "Y la llave del #señor del mal# aguardará en #algún lugar de su castillo#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen#, wird irgendwo #in Ganons Schloss# zu finden sein." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_OVERWORLD_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_OVERWORLD_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be hidden %routside of&dungeons%w in Hyrule.",
|
Text{ "And the #evil one#'s key will be hidden #outside of dungeons# in Hyrule.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w se&trouve %rhors des donjons%w d'Hyrule.",
|
/*french*/ "Aussi, la #clé du Malin# se trouve #hors des donjons# d'Hyrule.",
|
||||||
/*spanish*/ "Y la llave del #señor del mal# aguardará #fuera de las mazmorras# de Hyrule." },
|
/*spanish*/ "Y la llave del #señor del mal# aguardará #fuera de las mazmorras# de Hyrule.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen#, wird irgendwo #in Hyrule, außerhalb von Labyrinthen# zu finden sein." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_ANY_DUNGEON_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_ANY_DUNGEON_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be hidden %rinside a&dungeon%w in Hyrule.",
|
Text{ "And the #evil one#'s key will be hidden #inside a dungeon# in Hyrule.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w se&trouve %rdans un donjon%w d'Hyrule.",
|
/*french*/ "Aussi, la #clé du Malin# se trouve #dans un donjon# d'Hyrule.",
|
||||||
/*spanish*/ "Y la llave del #señor del mal# aguardará #en una mazmorra# de Hyrule." },
|
/*spanish*/ "Y la llave del #señor del mal# aguardará #en una mazmorra# de Hyrule.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen#, wird irgendwo #in Hyrule, innerhalb eines Labyrinths# zu finden sein." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_ANYWHERE_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_ANYWHERE_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be hidden somewhere&%rin Hyrule%w.",
|
Text{ "And the #evil one#'s key will be hidden somewhere&#in Hyrule#.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w se&trouve quelque part %rdans Hyrule%w.",
|
/*french*/ "Aussi, la #clé du Malin# se trouve quelque part #dans Hyrule#.",
|
||||||
/*spanish*/ "Y la llave del #señor del mal# aguardará en #cualquier lugar de Hyrule#." },
|
/*spanish*/ "Y la llave del #señor del mal# aguardará en #cualquier lugar de Hyrule#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen#, wird irgendwo #in Hyrule# zu finden sein." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_TRIFORCE_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_TRIFORCE_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "And the %revil one%w's key will&be given to the Hero once&the %rTriforce%w is completed.",
|
Text{ "And the #evil one#'s key will be given to the Hero once the #Triforce## is completed.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w se&révèlera une fois la %rTriforce%w&assemblée.",
|
/*french*/ "Aussi, la #clé du Malin# se&révèlera une fois la #Triforce#&assemblée.",
|
||||||
/*spanish*/ "Y el héroe recibirá la llave del #señor del mal# cuando haya completado la #Trifuerza#." },
|
/*spanish*/ "Y el héroe recibirá la llave del #señor del mal# cuando haya completado la #Trifuerza#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird verliehen, sobald das #Triforce# vervollständigt wurde." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GANON_BK_SKULLTULA_HINT] = HintText::GanonsBossKey({
|
hintTable[RHT_GANON_BK_SKULLTULA_HINT] = HintText::GanonsBossKey({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text { "And the %revil one%w's key will be&provided by the cursed rich man&once %r100 Gold Skulltula Tokens%w&are retrieved.",
|
Text { "And the #evil one#'s key will be provided by the cursed rich man once #100 Gold Skulltula Tokens# are retrieved.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&donnée par l'homme maudit une&fois que %r100 Symboles de&Skulltula d'or%w auront été trouvés.",
|
/*french*/ "Aussi, la #clé du Malin# sera&donnée par l'homme maudit une fois que #100 Symboles de Skulltula d'or# auront été trouvés.",
|
||||||
/*spanish*/ "Y el rico maldito entregará la llave&del #señor de mal# tras obtener&100 símbolos de skulltula dorada#."},
|
/*spanish*/ "Y el rico maldito entregará la llave&del #señor de mal# tras obtener&100 símbolos de skulltula dorada#."},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2800,57 +2814,63 @@ void HintTable_Init() {
|
|||||||
hintTable[RHT_LACS_VANILLA_HINT] = HintText::LACS({
|
hintTable[RHT_LACS_VANILLA_HINT] = HintText::LACS({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{
|
Text{
|
||||||
"And the %revil one%w's key will be&provided by Zelda once the&%rShadow and Spirit Medallions%w&are retrieved.",
|
"And the #evil one#'s key will be provided by Zelda once the #Shadow and Spirit Medallions# are retrieved.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois que &les %rMédaillons de l'Ombre et de&l'Esprit%w seront récupérés.",
|
/*french*/ "Aussi, la #clé du Malin# sera fournie par Zelda une fois que les #Médaillons de l'Ombre et de l'Esprit# seront récupérés.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Y Zelda entregará la llave&del #señor del mal# tras obtener&#el medallón de las sombras y del "
|
"Y Zelda entregará la llave del #señor del mal# tras obtener #el medallón de las sombras y del "
|
||||||
"espíritu#." },
|
"espíritu#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird von Zelda verliehen, sobald #die Amulette des Schattens und der Geister# geborgen wurden." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_LACS_MEDALLIONS_HINT] = HintText::LACS({
|
hintTable[RHT_LACS_MEDALLIONS_HINT] = HintText::LACS({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d&|Medallion%w is|Medallions%w are| retrieved.",
|
Text{ "And the #evil one#'s key will be provided by Zelda once #%d |Medallion# is|Medallions# are| retrieved.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d Médaillon%w aura été&récupéré|que&%r%d Médaillons%w auront été&récupérés|.",
|
/*french*/ "Aussi, la #clé du Malin# sera fournie par Zelda une fois |qu' #%d Médaillon# aura été récupéré|que #%d Médaillons# auront été récupérés|.",
|
||||||
/*spanish*/ "Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |medallón|medallones|#." },
|
/*spanish*/ "Y Zelda entregará la llave&del #señor del mal# tras obtener #%d |medallón|medallones|#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird von Zelda verliehen, sobald #%d |Amulett# geborgen wurde|Amulette# geborgen wurden|." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_LACS_STONES_HINT] = HintText::LACS({
|
hintTable[RHT_LACS_STONES_HINT] = HintText::LACS({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{
|
Text{
|
||||||
"And the %revil one%w's key will be&provided by Zelda once %r%d&|Spiritual Stone%w is|Spiritual Stones%w are| "
|
"And the #evil one#'s key will be provided by Zelda once #%d |Spiritual Stone# is|Spiritual Stones# are| "
|
||||||
"retrieved.",
|
"retrieved.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d Pierre Ancestrale%w aura été&récupérée|que&%r%d Pierres Ancestrales%w auront été&récupérées|.",
|
/*french*/ "Aussi, la #clé du Malin# sera fournie par Zelda une fois |qu' #%d Pierre Ancestrale# aura été&récupérée|que #%d Pierres Ancestrales# auront été récupérées|.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |piedra espiritual|piedras "
|
"Y Zelda entregará la llave del #señor del mal# tras obtener #%d |piedra espiritual|piedras "
|
||||||
"espirituales|#." },
|
"espirituales|#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird von Zelda verliehen, sobald #%d |Heiliger Stein# geborgen wurde|Heilige Steine# geborgen wurden|." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_LACS_REWARDS_HINT] = HintText::LACS({
|
hintTable[RHT_LACS_REWARDS_HINT] = HintText::LACS({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d&|Spiritual Stone or Medallion%w&"
|
Text{ "And the #evil one#'s key will be provided by Zelda once #%d |Spiritual Stone or Medallion# "
|
||||||
"is|Spiritual Stones and Medallions%w&are| retrieved.",
|
"is|Spiritual Stones and Medallions# are| retrieved.",
|
||||||
/*french*/
|
/*french*/
|
||||||
"Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d Pierre Ancestrale ou %d&Médaillon%w sera récupéré|que&%r%d Pierres Ancestrales et&Médaillons%w seront récupérés|.",
|
"Aussi, la #clé du Malin# sera fournie par Zelda une fois |qu' #%d Pierre Ancestrale ou %d Médaillon# sera récupéré|que&#%d Pierres Ancestrales et&Médaillons# seront récupérés|.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |piedra espiritual o medallón|piedras "
|
"Y Zelda entregará la llave del #señor del mal# tras obtener #%d |piedra espiritual o medallón|piedras "
|
||||||
"espirituales o medallones|#." },
|
"espirituales o medallones|#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird von Zelda verliehen, sobald #%d |Heiliger Stein oder Amulett#&geborgen wurde|Heilige Steine oder Amulette#&geborgen wurden|." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_LACS_DUNGEONS_HINT] = HintText::LACS({
|
hintTable[RHT_LACS_DUNGEONS_HINT] = HintText::LACS({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d&|Dungeon%w is|Dungeons%w are| conquered.",
|
Text{ "And the #evil one#'s key will be provided by Zelda once #%d |Dungeon# is|Dungeons# are| conquered.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d donjon %wsera conquis|que&%r%d donjons%w seront conquis|.",
|
/*french*/ "Aussi, la #clé du Malin# sera fournie par Zelda une fois |qu' #%d donjon #sera conquis|que #%d donjons# seront conquis|.",
|
||||||
/*spanish*/ "Y Zelda entregará la llave&del #señor del mal# tras completar&#%d |mazmorra|mazmorras|#." },
|
/*spanish*/ "Y Zelda entregará la llave del #señor del mal# tras completar #%d |mazmorra|mazmorras|#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird von Zelda verliehen, sobald #%d |Labyrinth# abgeschlossen wurde|Labyrinthe# abgeschlossen wurden|." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_LACS_TOKENS_HINT] = HintText::LACS({
|
hintTable[RHT_LACS_TOKENS_HINT] = HintText::LACS({
|
||||||
// obscure text singular plural
|
// obscure text singular plural
|
||||||
Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d |Gold&Skulltula Token%w is|Gold&Skulltula "
|
Text{ "And the #evil one#'s key will be provided by Zelda once #%d |Gold&Skulltula Token# is|Gold Skulltula "
|
||||||
"Tokens%w are| retrieved.",
|
"Tokens# are| retrieved.",
|
||||||
/*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d symbole de Skulltula d'or&%wsera récupuéré|que &%r%d symboles de Skulltula d'or&%wseront recupérés|.",
|
/*french*/ "Aussi, la #clé du Malin# sera fournie par Zelda une fois |qu' #%d symbole de Skulltula d'or #sera récupuéré|que &#%d symboles de Skulltula d'or&#seront recupérés|.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |símbolo|símbolos| de&skulltula "
|
"Y Zelda entregará la llave del #señor del mal# tras obtener #%d |símbolo|símbolos| de skulltula "
|
||||||
"dorada#." },
|
"dorada#.",
|
||||||
|
/*german*/"Und der #Schlüssel des Bösen# wird von Zelda verliehen, sobald #%d |Skulltula-Symbol# gesammelt wurde|Skulltula-Symbole# gesammelt wurden|." },
|
||||||
});
|
});
|
||||||
/*--------------------------
|
/*--------------------------
|
||||||
| TRIAL HINT TEXT |
|
| TRIAL HINT TEXT |
|
||||||
@ -2860,26 +2880,30 @@ void HintTable_Init() {
|
|||||||
// obscure text
|
// obscure text
|
||||||
Text{ "#Ganon's Tower# is protected by a powerful barrier.",
|
Text{ "#Ganon's Tower# is protected by a powerful barrier.",
|
||||||
/*french*/ "#la Tour de Ganon# est protégée par une puissante barrière",
|
/*french*/ "#la Tour de Ganon# est protégée par une puissante barrière",
|
||||||
/*spanish*/ "la #torre de Ganon# está protegida por una poderosa barrera" },
|
/*spanish*/ "la #torre de Ganon# está protegida por una poderosa barrera",
|
||||||
|
/*german*/"der #Teufelsturm# sei von einer mächtigen Barriere geschützt." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_ZERO_TRIALS] = HintText::Exclude({
|
hintTable[RHT_ZERO_TRIALS] = HintText::Exclude({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "Sheik dispelled the barrier around #Ganon's Tower#.",
|
Text{ "Sheik dispelled the barrier around #Ganon's Tower#.",
|
||||||
/*french*/ "Sheik a dissipé la barrière autour de #la Tour de Ganon#",
|
/*french*/ "Sheik a dissipé la barrière autour de #la Tour de Ganon#",
|
||||||
/*spanish*/ "Sheik disipó la barrera alrededor de la #torre de Ganon#." },
|
/*spanish*/ "Sheik disipó la barrera alrededor de la #torre de Ganon#.",
|
||||||
|
/*german*/"Shiek habe die Barriere um den #Teufelsturm# aufgelöst." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_FOUR_TO_FIVE_TRIALS] = HintText::Exclude({
|
hintTable[RHT_FOUR_TO_FIVE_TRIALS] = HintText::Exclude({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ " was dispelled by Sheik.", /*french*/ " a été dissipée par Sheik.",
|
Text{ " was dispelled by Sheik.", /*french*/ " a été dissipée par Sheik.",
|
||||||
/*spanish*/ " se disipó gracias a Sheik." },
|
/*spanish*/ " se disipó gracias a Sheik.",
|
||||||
|
/*german*/" sei von Shiek aufgelöst worden." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_ONE_TO_THREE_TRIALS] = HintText::Exclude({
|
hintTable[RHT_ONE_TO_THREE_TRIALS] = HintText::Exclude({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ " protects Ganons Tower.", /*french*/ " protège la Tour de Ganon.",
|
Text{ " protects Ganons Tower.", /*french*/ " protège la Tour de Ganon.",
|
||||||
/*spanish*/ " protege la torre de Ganon" },
|
/*spanish*/ " protege la torre de Ganon",
|
||||||
|
/*german*/" schütze den Teufelsturm." },
|
||||||
});
|
});
|
||||||
|
|
||||||
/*--------------------------
|
/*--------------------------
|
||||||
@ -2890,14 +2914,16 @@ void HintTable_Init() {
|
|||||||
// obscure text
|
// obscure text
|
||||||
Text{ "3 Spiritual Stones found in Hyrule...",
|
Text{ "3 Spiritual Stones found in Hyrule...",
|
||||||
/*french*/ "Les trois Pierres Ancestrales cachées&dans Hyrule...",
|
/*french*/ "Les trois Pierres Ancestrales cachées&dans Hyrule...",
|
||||||
/*spanish*/ "Tres piedras espirituales halladas por Hyrule..." },
|
/*spanish*/ "Tres piedras espirituales halladas por Hyrule...",
|
||||||
|
/*german*/"Drei Heilige Steine, zu finden in Hyrule..." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN] = HintText::Altar({
|
hintTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN] = HintText::Altar({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "Ye who may become a Hero...&The path to the future is open...",
|
Text{ "Ye who may become a Hero...&The path to the future is open...",
|
||||||
/*french*/ "À celui qui a quête de devenir&héros...&Le futur vous accueille béant...",
|
/*french*/ "À celui qui a quête de devenir&héros...&Le futur vous accueille béant...",
|
||||||
/*spanish*/ "Para aquel que se convierta en el héroe...&La puerta al futuro está a su disposición..." },
|
/*spanish*/ "Para aquel que se convierta en el héroe...&La puerta al futuro está a su disposición...",
|
||||||
|
/*german*/"Jener auf dem Weg des Helden...&Der Pfad zur Zukunft sei geöffnet..." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY] = HintText::Altar({
|
hintTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY] = HintText::Altar({
|
||||||
@ -2905,7 +2931,8 @@ void HintTable_Init() {
|
|||||||
Text{
|
Text{
|
||||||
"Ye who may become a Hero...&Stand with the Ocarina and&play the Song of Time.",
|
"Ye who may become a Hero...&Stand with the Ocarina and&play the Song of Time.",
|
||||||
/*french*/ "À celui qui a quête de devenir&héros...&Portez l'Ocarina et jouez&le chant du temps.",
|
/*french*/ "À celui qui a quête de devenir&héros...&Portez l'Ocarina et jouez&le chant du temps.",
|
||||||
/*spanish*/ "Para aquel que se convierta en el héroe...&Tome la ocarina y&entone la Canción del Tiempo." },
|
/*spanish*/ "Para aquel que se convierta en el héroe...&Tome la ocarina y&entone la Canción del Tiempo.",
|
||||||
|
/*german*/"Jener auf dem Weg des Helden...&Nehme er seine Okarina zur Hand und&spiele hier die Hymne der Zeit." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED] = HintText::Altar({
|
hintTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED] = HintText::Altar({
|
||||||
@ -2915,30 +2942,32 @@ void HintTable_Init() {
|
|||||||
"À celui qui a quête de devenir&héros... Présentez les Pierres&Ancestrales et jouez&le chant du temps.",
|
"À celui qui a quête de devenir&héros... Présentez les Pierres&Ancestrales et jouez&le chant du temps.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Para aquel que se convierta en el héroe...&Tome las piedras espirituales y&entone la Canción del "
|
"Para aquel que se convierta en el héroe...&Tome las piedras espirituales y&entone la Canción del "
|
||||||
"Tiempo." },
|
"Tiempo.",
|
||||||
|
/*german*/"Jener mit den drei Heiligen Steinen&nehme seine Okarina zur Hand und&spiele hier die Hymne der Zeit." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_ADULT_ALTAR_TEXT_START] = HintText::Altar({
|
hintTable[RHT_ADULT_ALTAR_TEXT_START] = HintText::Altar({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "An awakening voice from the Sacred&Realm will call those destined to be&Sages, who dwell in the five "
|
Text{ "An awakening voice from the Sacred Realm will call those destined to be Sages, who dwell in the #five temples#.",
|
||||||
"temples.",
|
|
||||||
/*french*/
|
/*french*/
|
||||||
"Quand le mal aura triomphé, une voix&du Saint Royaume appellera ceux&cachés dans les cinq temples, "
|
"Quand le mal aura triomphé, une voix du Saint Royaume appellera ceux cachés dans les #cinq temples#, "
|
||||||
"destinés^à être Sages.",
|
"destinés^à être Sages.",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Cuando el mal lo impregne todo, desde el Reino Sagrado surgirá una voz que hará despertar a los sabios "
|
"Cuando el mal lo impregne todo, desde el Reino Sagrado surgirá una voz que hará despertar a los sabios "
|
||||||
"que moran en los #cinco templos#." },
|
"que moran en los #cinco templos#.",
|
||||||
|
/*german*/"Beherrscht das Böse die Welt, weilen&jene Weisen, die von der Stimme des Heiligen Reiches erweckt werden, noch&in den #fünf Tempeln#." },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_ADULT_ALTAR_TEXT_END] = HintText::Altar({
|
hintTable[RHT_ADULT_ALTAR_TEXT_END] = HintText::Altar({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{
|
Text{
|
||||||
"$kTogether with the Hero of Time,&the awakened ones will return&the light of peace to the world...",
|
"$kTogether with the Hero of Time, the awakened ones will return the light of peace to the world...",
|
||||||
/*french*/
|
/*french*/
|
||||||
"$kEnsemble avec le Héros du &Temps, ces Sages emprisonneront&le mal et réinstaureront la&lumière de paix "
|
"$kEnsemble avec le Héros du Temps, ces Sages emprisonneront le mal et réinstaureront la lumière de paix "
|
||||||
"dans le monde...",
|
"dans le monde...",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"Con el Héroe del Tiempo, aquellos&que despierten detendrán el mal y&volverán al mundo de luz la paz..." },
|
"Con el Héroe del Tiempo, aquellos&que despierten detendrán el mal y&volverán al mundo de luz la paz...",
|
||||||
|
/*german*/"$kZusammen mit dem Auserwählten wer-den diese ihre Kräfte einsetzen, um der Welt den Frieden wiederzugeben." },
|
||||||
});
|
});
|
||||||
|
|
||||||
/*--------------------------
|
/*--------------------------
|
||||||
@ -3054,7 +3083,7 @@ void HintTable_Init() {
|
|||||||
hintTable[RHT_SARIA_TEXT01] = HintText::OtherHint({
|
hintTable[RHT_SARIA_TEXT01] = HintText::OtherHint({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{
|
Text{
|
||||||
"Did you feel the %gsurge of magic%w recently? A mysterious bird told me it came from %g",
|
"Did you feel the %gsurge of magic%w recently? A mysterious bird told me it came from %g",
|
||||||
/*french*/
|
/*french*/
|
||||||
"As-tu récemment ressenti une vague de %gpuissance magique%w? Un mystérieux hibou m'a dit qu'elle provenait du %g",
|
"As-tu récemment ressenti une vague de %gpuissance magique%w? Un mystérieux hibou m'a dit qu'elle provenait du %g",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
@ -3071,6 +3100,35 @@ void HintTable_Init() {
|
|||||||
"%w.$C"},
|
"%w.$C"},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_WARP_TO] = HintText::OtherHint({
|
||||||
|
Text{
|
||||||
|
"Warp to&#",
|
||||||
|
"Se téléporter vers&#",
|
||||||
|
"",
|
||||||
|
"Zu&#"},
|
||||||
|
});
|
||||||
|
hintTable[RHT_WARP_CHOICE] = HintText::OtherHint({
|
||||||
|
Text{
|
||||||
|
"#?&" + TWO_WAY_CHOICE() + "#OK&No#",
|
||||||
|
"#?&" + TWO_WAY_CHOICE() + "#OK!&Non#",
|
||||||
|
"###",
|
||||||
|
"#?&" + TWO_WAY_CHOICE() + "#OK&No#"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_FROGS_HINT01] = HintText::OtherHint({Text{
|
||||||
|
"Some frogs holding #",
|
||||||
|
"Des grenouilles se trouvant sous l'eau vous fixent attentivement, tenant fermement #",
|
||||||
|
"",
|
||||||
|
"Unter Wasser gibt es Frösche, die #"
|
||||||
|
}});
|
||||||
|
hintTable[RHT_FROGS_HINT02] = HintText::OtherHint({Text{
|
||||||
|
"# are looking at you from underwater...",
|
||||||
|
"#.",
|
||||||
|
"",
|
||||||
|
"# bei sich haben und Dich neugierig beobachten..."
|
||||||
|
}});
|
||||||
|
|
||||||
/*--------------------------
|
/*--------------------------
|
||||||
| GANON LINE TEXT |
|
| GANON LINE TEXT |
|
||||||
---------------------------*/
|
---------------------------*/
|
||||||
@ -3179,67 +3237,100 @@ void HintTable_Init() {
|
|||||||
| MERCHANTS' ITEMS |
|
| MERCHANTS' ITEMS |
|
||||||
---------------------------*/
|
---------------------------*/
|
||||||
|
|
||||||
|
hintTable[RHT_BEAN_SALESMAN_FIRST] = HintText::MerchantsDialogs({
|
||||||
|
Text{
|
||||||
|
"I tried to be a #magic bean#&salesman, but it turns out my&marketing skills weren't worth&"
|
||||||
|
"beans!^Anyway, want to buy #",
|
||||||
|
/*french*/ "J'ai essayé d'être un vendeur&de #haricots magiques#, mais&j'étais mauvais au niveau du&marketing et ça "
|
||||||
|
"me courait sur&le haricot...^Enfin bref, ça te dirait de m'acheter #",
|
||||||
|
/*spanish*/ "",
|
||||||
|
/*german*/ "Möchten Sie #"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hintTable[RHT_BEAN_SALESMAN_SECOND] = HintText::MerchantsDialogs({
|
||||||
|
Text{
|
||||||
|
"# for #60 Rupees#?&" + TWO_WAY_CHOICE() + "#Yes&No#",
|
||||||
|
/*french*/ "# pour #60 Rubis#?&" + TWO_WAY_CHOICE() + "#Oui&Non#",
|
||||||
|
/*spanish*/ "",
|
||||||
|
/*german*/ "# für #60 Rubine#?&" + TWO_WAY_CHOICE() + "#Ja&Nein#"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
hintTable[RHT_MEDIGORON_DIALOG_FIRST] = HintText::MerchantsDialogs({
|
hintTable[RHT_MEDIGORON_DIALOG_FIRST] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "How about buying ",
|
Text{ "How about buying #",
|
||||||
/*french*/ "Veux-tu acheter ",
|
/*french*/ "Veux-tu acheter #",
|
||||||
/*spanish*/ "¿Me compras " },
|
/*spanish*/ "¿Me compras #",
|
||||||
|
/*german*/ "Möchtest du #" },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_MEDIGORON_DIALOG_SECOND] = HintText::MerchantsDialogs({
|
hintTable[RHT_MEDIGORON_DIALOG_SECOND] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ " for #200 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
Text{ "# for #200 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
||||||
/*french*/ " pour #200 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
/*french*/ "# pour #200 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
||||||
/*spanish*/ " por #200 rupias#?&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#" },
|
/*spanish*/ "# por #200 rupias#?&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#",
|
||||||
|
/*german*/ "# für #200 Rubine# kaufen?&" + TWO_WAY_CHOICE() + "#Klar!&Nie im Leben!#" },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CARPET_SALESMAN_DIALOG_FIRST] = HintText::MerchantsDialogs({
|
hintTable[RHT_CARPET_SALESMAN_DIALOG_FIRST] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "Welcome!^I am selling stuff, strange and rare, from&all over the world to everybody. Today's&special "
|
Text{ "Welcome!^I am selling stuff, strange and rare, from all over the world to everybody. Today's special "
|
||||||
"is...^",
|
"is...^#",
|
||||||
/*french*/
|
/*french*/
|
||||||
"Bienvenue!^Je vends des objets rares et merveilleux du&monde entier. En spécial aujourd'hui...^",
|
"Bienvenue!^Je vends des objets rares et merveilleux du&monde entier. En spécial aujourd'hui...^#",
|
||||||
/*spanish*/
|
/*spanish*/
|
||||||
"¡Acércate!^Vendo productos extraños y difíciles de&encontrar... De todo el mundo a todo el&mundo. La "
|
"¡Acércate!^Vendo productos extraños y difíciles de&encontrar... De todo el mundo a todo el&mundo. La "
|
||||||
"oferta de hoy es...^¡" },
|
"oferta de hoy es...^#¡",
|
||||||
|
/* german */
|
||||||
|
"Sei gegrüßt!^Ich verkaufe allerlei Kuriorisäten.&Stets sonderliche und seltene Ware&aus "
|
||||||
|
"aller Welt für jedermann.&Das heutige Angebot bleibt...^#" },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CARPET_SALESMAN_DIALOG_SECOND] = HintText::MerchantsDialogs({
|
hintTable[RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{
|
Text{ "!# Terrifying! I won't tell you what it is until I see the #money#...^How about #200 Rupees#?&&" +
|
||||||
"! Terrifying!&I won't tell you what it is until I see the&money...^How about #200 Rupees#?&&" +
|
TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
||||||
TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
/*french*/
|
||||||
/*french*/
|
"!# Un concentré de puissance! Mais montre tes #rubis# avant que je te dise ce que c'est...^Disons #200 "
|
||||||
"! Un&concentré de puissance! Mais montre tes&rubis avant que je te dise ce que c'est...^Disons #200 "
|
"rubis#?&&" +
|
||||||
"rubis#?&&" +
|
TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
||||||
TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
/*spanish*/
|
||||||
/*spanish*/
|
"!# ¡Terrorífico! No te revelaré su nombre hasta que vea el #dinero#...^#200 rupias#, ¿qué te parece?&&" +
|
||||||
"! ¡Terrorífico!&No te revelaré su nombre hasta que&vea el dinero...^#200 rupias#, ¿qué te parece?&&" +
|
TWO_WAY_CHOICE() + "#Comprar&No comprar#",
|
||||||
TWO_WAY_CHOICE() + "#Comprar&No comprar#" },
|
/*german*/
|
||||||
|
"!# Furchterregend oder? Ich erzähle Euch mehr, wenn ich #Geld# sehe...^Wie wär's mit #200 Rubinen#?&&" +
|
||||||
|
TWO_WAY_CHOICE() + "#Aber sicher!&Ich bin weg!#" },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CARPET_SALESMAN_DIALOG_THIRD] = HintText::MerchantsDialogs({
|
hintTable[RHT_CARPET_SALESMAN_DIALOG_HINTED] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "Thank you very much!^What I'm selling is... #",
|
Text{ "!# It's real, I promise! A lonely man such as myself wouldn't #lie# to you, hmm?^"
|
||||||
/*french*/ "Merci beaucoup!^Cet objet extraordinaire est... #",
|
"How about #200 Rupees#?&&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
||||||
/*spanish*/ "¡Muchas gracias!^Lo que vendo es... #¡" },
|
/*french*/
|
||||||
|
"!# C'est vrai! J'te jure! Un gars comme moi ne te #mentirai# pas tu ne crois pas?^Disons #200 "
|
||||||
|
"rubis#?&&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
||||||
|
/*spanish*/ // TODO: Flesh this out with the flavor text if we ever support spanish translations
|
||||||
|
"#!^###200 rupias#, ¿qué te parece?&&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#",
|
||||||
|
/*german*/
|
||||||
|
"#! Ich kann versichern es ist ein aufrichtiges Angebot!^Ein einsamer Mann wie ich würde dich doch "
|
||||||
|
"nicht #anlügen#, oder?^Wie wär's mit #200 Rubinen#?&&" + TWO_WAY_CHOICE() +
|
||||||
|
"#Aber sicher!&Ich bin weg!#" },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_CARPET_SALESMAN_DIALOG_FOURTH] = HintText::MerchantsDialogs({
|
hintTable[RHT_CARPET_SALESMAN_DIALOG_FINAL] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "!#^The mark that will lead you to the #Spirit&Temple# is the #flag on the " + IF_NOT_MQ() + "left" +
|
Text{ "Finally! Now I can go back to being &an %rarms dealer%w!",
|
||||||
MQ_ELSE() + "right" + MQ_END() + "# outside the shop. Be seeing you!",
|
/*french*/ "Squalala! Je vais enfin pouvoir &%rprendre des vacances%w!",
|
||||||
/*french*/ "!#^La marque qui te mènera au #Temple de l'Esprit# est le #drapeau " + IF_NOT_MQ() +
|
/*spanish*/ "", // TODO: Flesh this out with the flavor text if we ever support spanish translations
|
||||||
"gauche" + MQ_ELSE() + "droite" + MQ_END() + "# en sortant d'ici. À la prochaine!",
|
/*german*/ "Endlich! Schon bald kann ich wieder &%rKrabbelminen-Händler%w sein!" },
|
||||||
/*spanish*/ "!#^La marca que te guiará al #Templo del&Espíritu# es la #bandera que está a la&" +
|
|
||||||
IF_NOT_MQ() + "izquierda" + MQ_ELSE() + "derecha" + MQ_END() + "# al salir de aquí. ¡Nos vemos!" },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_GRANNY_DIALOG] = HintText::MerchantsDialogs({
|
hintTable[RHT_GRANNY_DIALOG] = HintText::MerchantsDialogs({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "! How about #100 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
Text{ "! How about #100 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
|
||||||
/*french*/ "! Que dis-tu de #100 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
/*french*/ "! Que dis-tu de #100 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
|
||||||
/*spanish*/ ". Vendo por #100 rupias#.&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#" },
|
/*spanish*/ ". Vendo por #100 rupias#.&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#",
|
||||||
|
/*german*/ "! Sagen wir #100 Rubine#!&" + TWO_WAY_CHOICE() + "#Gerne!&Auf keinen Fall!#" },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2115,6 +2115,10 @@ void HintTable_Init_Item() {
|
|||||||
//clear text
|
//clear text
|
||||||
Text{"Epona", /*french*/"Epona", /*spanish*/"a Epona"}
|
Text{"Epona", /*french*/"Epona", /*spanish*/"a Epona"}
|
||||||
);
|
);
|
||||||
|
hintTable[RHT_HINT_MYSTERIOUS] = HintText::Item({
|
||||||
|
Text{"something mysterious", /*french*/"un sacré mystère", /*spanish*/"algo misterioso", /*german*/"etwas Unvorhergesehenes"},
|
||||||
|
Text{"an unknown treasure", /*french*/"un trésor inconnu", /*spanish*/"un desconocido tesoro", /*german*/"ein unbekannter Schatz"},
|
||||||
|
});
|
||||||
|
|
||||||
// [RHT_HINT_ERROR] = HintText::Item({
|
// [RHT_HINT_ERROR] = HintText::Item({
|
||||||
// //obscure text
|
// //obscure text
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "hints.hpp"
|
#include "hints.hpp"
|
||||||
|
|
||||||
#include "custom_messages.hpp"
|
|
||||||
#include "item_pool.hpp"
|
#include "item_pool.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
#include "spoiler_log.hpp"
|
#include "spoiler_log.hpp"
|
||||||
@ -14,7 +13,15 @@
|
|||||||
#include "../context.h"
|
#include "../context.h"
|
||||||
#include "pool_functions.hpp"
|
#include "pool_functions.hpp"
|
||||||
|
|
||||||
using namespace CustomMessages;
|
#define QM_WHITE "%w"
|
||||||
|
#define QM_RED "%r"
|
||||||
|
#define QM_GREEN "%g"
|
||||||
|
#define QM_BLUE "%b"
|
||||||
|
#define QM_LBLUE "%c"
|
||||||
|
#define QM_PINK "%p"
|
||||||
|
#define QM_YELLOW "%y"
|
||||||
|
#define QM_BLACK "%B"
|
||||||
|
|
||||||
using namespace Rando;
|
using namespace Rando;
|
||||||
|
|
||||||
const Text& HintText::GetText() const {
|
const Text& HintText::GetText() const {
|
||||||
@ -90,7 +97,7 @@ const std::array<HintSetting, 4> hintSettingTable{{
|
|||||||
.alwaysCopies = 0,
|
.alwaysCopies = 0,
|
||||||
.trialCopies = 0,
|
.trialCopies = 0,
|
||||||
.junkWeight = 1, //RANDOTODO when the hint pool is not implicitly an itemLocations, handle junk like other hint types
|
.junkWeight = 1, //RANDOTODO when the hint pool is not implicitly an itemLocations, handle junk like other hint types
|
||||||
.distTable = {} /*RANDOTODO Instead of loading a function into this,
|
.distTable = {} /*RANDOTODO Instead of loading a function into this,
|
||||||
apply this filter on all possible hintables in advance and then filter by what is acually in the seed at the start of generation.
|
apply this filter on all possible hintables in advance and then filter by what is acually in the seed at the start of generation.
|
||||||
This allows the distTable to hold the current status in hint generation (reducing potential doubled work) and
|
This allows the distTable to hold the current status in hint generation (reducing potential doubled work) and
|
||||||
will make handling custom hint pools easier later*/
|
will make handling custom hint pools easier later*/
|
||||||
@ -109,7 +116,7 @@ const std::array<HintSetting, 4> hintSettingTable{{
|
|||||||
{"Dungeon", HINT_TYPE_ITEM_LOCATION, 3, 0, 1, FilterDungeonLocations},
|
{"Dungeon", HINT_TYPE_ITEM_LOCATION, 3, 0, 1, FilterDungeonLocations},
|
||||||
{"Named Item", HINT_TYPE_ITEM_AREA, 10, 0, 1, FilterGoodItems},
|
{"Named Item", HINT_TYPE_ITEM_AREA, 10, 0, 1, FilterGoodItems},
|
||||||
{"Random" , HINT_TYPE_ITEM_AREA, 12, 0, 1, NoFilter}
|
{"Random" , HINT_TYPE_ITEM_AREA, 12, 0, 1, NoFilter}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Strong hints
|
// Strong hints
|
||||||
{
|
{
|
||||||
@ -144,37 +151,109 @@ const std::array<HintSetting, 4> hintSettingTable{{
|
|||||||
},
|
},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Text AutoFormatHintText(Text unformattedHintText) {
|
static std::map<std::string, int> pixelWidthTable = {
|
||||||
std::array<std::string, LANGUAGE_MAX> strings;
|
{ " ", 6 }, { "!", 6 }, { "\"", 5 }, { "#", 7 }, { "$", 7 }, { "%", 11 }, { "&", 9 }, { "\'", 3 },
|
||||||
for (int i = 0; i < LANGUAGE_MAX; i++) {
|
{ "(", 6 }, { ")", 6 }, { "*", 6 }, { "+", 7 }, { ",", 3 }, { "-", 5 }, { ".", 3 }, { "/", 7 },
|
||||||
std::string textStr = unformattedHintText.GetForLanguage(i);
|
{ "0", 8 }, { "1", 4 }, { "2", 7 }, { "3", 7 }, { "4", 8 }, { "5", 7 }, { "6", 7 }, { "7", 7 },
|
||||||
// RANDOTODO: don't just make manual exceptions
|
{ "8", 7 }, { "9", 7 }, { ":", 5 }, { ";", 5 }, { "<", 7 }, { "=", 9 }, { ">", 7 }, { "?", 9 },
|
||||||
bool needsAutomaticNewlines = true;
|
{ "@", 10 }, { "A", 9 }, { "B", 7 }, { "C", 9 }, { "D", 9 }, { "E", 6 }, { "F", 6 }, { "G", 9 },
|
||||||
if (textStr == "Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!" ||
|
{ "H", 8 }, { "I", 3 }, { "J", 6 }, { "K", 8 }, { "L", 6 }, { "M", 10 }, { "N", 9 }, { "O", 10 },
|
||||||
textStr == "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda" ||
|
{ "P", 7 }, { "Q", 10 }, { "R", 8 }, { "S", 8 }, { "T", 7 }, { "U", 8 }, { "V", 9 }, { "W", 12 },
|
||||||
textStr == "What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats." ||
|
{ "X", 9 }, { "Y", 8 }, { "Z", 8 }, { "[", 6 }, { "\\", 8 }, { "]", 6 }, { "^", 8 }, { "_", 7 },
|
||||||
textStr == "Many tricks are up my sleeve,&to save yourself&you'd better leave!" ||
|
{ "`", 4 }, { "a", 6 }, { "b", 7 }, { "c", 6 }, { "d", 7 }, { "e", 7 }, { "f", 5 }, { "g", 7 },
|
||||||
textStr == "I've learned this spell,&it's really neat,&I'll keep it later&for your treat!" ||
|
{ "h", 6 }, { "i", 3 }, { "j", 5 }, { "k", 6 }, { "l", 3 }, { "m", 9 }, { "n", 7 }, { "o", 7 },
|
||||||
textStr == "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!" ||
|
{ "p", 7 }, { "q", 7 }, { "r", 6 }, { "s", 6 }, { "t", 6 }, { "u", 6 }, { "v", 7 }, { "w", 9 },
|
||||||
textStr == "Gamin, ton destin achève,&sous mon sort tu périras!&Cette partie ne fut pas brève,&et cette mort, tu subiras!" ||
|
{ "x", 6 }, { "y", 7 }, { "z", 6 }, { "{", 6 }, { "¦", 4 }, { "}", 6 }, { "¡", 5 }, { "¢", 7 },
|
||||||
textStr == "Oh! It's @.&I was expecting someone called Sheik.&Do you know what happened to them?" ||
|
{ "£", 8 }, { "¤", 7 }, { "¥", 8 }, { "|", 4 }, { "§", 12 }, { "¨", 12 }, { "©", 10 }, { "ª", 5 },
|
||||||
textStr == "Ah, c'est @.&J'attendais un certain Sheik.&Tu sais ce qui lui est arrivé?" ||
|
{ "«", 8 }, { "¬", 7 }, { "\u00AD", 6 }, { "®", 10 }, { "¯", 8 }, { "°", 12 }, { "±", 12 }, { "²", 5 },
|
||||||
textStr == "They say \"Forgive me, but-^Your script will not be used.&....After all...^The one writing the rest of the script...&will be me.\"") {
|
{ "³", 5 }, { "µ", 6 }, { "¶", 8 }, { "·", 4 }, { "¹", 4 }, { "º", 5 }, { "»", 9 }, { "¼", 9 },
|
||||||
needsAutomaticNewlines = false;
|
{ "½", 9 }, { "¾", 10 }, { "¿", 7 }, { "À", 11 }, { "Á", 9 }, { "Â", 9 }, { "Ã", 9 }, { "Ä", 9 },
|
||||||
}
|
{ "Å", 9 }, { "Æ", 12 }, { "Ç", 9 }, { "È", 6 }, { "É", 6 }, { "Ê", 6 }, { "Ë", 6 }, { "Ì", 5 },
|
||||||
|
{ "Í", 5 }, { "Î", 5 }, { "Ï", 5 }, { "Ð", 10 }, { "Ñ", 9 }, { "Ò", 10 }, { "Ó", 10 }, { "Ô", 10 },
|
||||||
|
{ "Õ", 10 }, { "Ö", 10 }, { "×", 9 }, { "Ø", 10 }, { "Ù", 8 }, { "Ú", 8 }, { "Û", 8 }, { "Ü", 8 },
|
||||||
|
{ "Ý", 10 }, { "Þ", 8 }, { "ß", 7 }, { "à", 6 }, { "á", 6 }, { "â", 6 }, { "ã", 6 }, { "ä", 6 },
|
||||||
|
{ "å", 6 }, { "æ", 11 }, { "ç", 6 }, { "è", 7 }, { "é", 7 }, { "ê", 7 }, { "ë", 7 }, { "ì", 5 },
|
||||||
|
{ "í", 5 }, { "î", 5 }, { "ï", 5 }, { "ð", 7 }, { "ñ", 7 }, { "ò", 7 }, { "ó", 7 }, { "ô", 7 },
|
||||||
|
{ "õ", 7 }, { "ö", 7 }, { "÷", 11 }, { "ø", 9 }, { "ù", 7 }, { "ú", 7 }, { "û", 7 }, { "ü", 7 },
|
||||||
|
{ "ý", 8 }, { "þ", 8 }, { "ÿ", 8 }, { "Œ", 11 }, { "œ", 11 }, { "„", 5 }, { "”", 5 }, { "€", 10 },
|
||||||
|
{ "Ÿ", 10 }, { "~", 8 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t NextLineLength(const std::string* textStr, const size_t lastNewline, bool hasIcon = false) {
|
||||||
|
const size_t maxLinePixelWidth = hasIcon ? 200 : 216;
|
||||||
|
|
||||||
|
|
||||||
|
size_t totalPixelWidth = 0;
|
||||||
|
size_t currentPos = lastNewline;
|
||||||
|
|
||||||
|
// Looping through the string from the lastNewline until the total
|
||||||
|
// width of counted characters exceeds the maximum pixels in a line.
|
||||||
|
size_t nextPosJump = 0;
|
||||||
|
while (totalPixelWidth < maxLinePixelWidth && currentPos < textStr->length()) {
|
||||||
|
// Skip over control codes
|
||||||
|
if (textStr->at(currentPos) == '%') {
|
||||||
|
nextPosJump = 2;
|
||||||
|
} else if (textStr->at(currentPos) == '$') {
|
||||||
|
nextPosJump = 2;
|
||||||
|
} else if (textStr->at(currentPos) == '@') {
|
||||||
|
nextPosJump = 1;
|
||||||
|
// Assume worst case for player name 12 * 8 (widest character * longest name length)
|
||||||
|
totalPixelWidth += 96;
|
||||||
|
} else {
|
||||||
|
// Some characters only one byte while others are two bytes
|
||||||
|
// So check both possibilities when checking for a character
|
||||||
|
if (pixelWidthTable.count(textStr->substr(currentPos, 1))) {
|
||||||
|
totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 1)];
|
||||||
|
nextPosJump = 1;
|
||||||
|
} else if (pixelWidthTable.count(textStr->substr(currentPos, 2))) {
|
||||||
|
totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 2)];
|
||||||
|
nextPosJump = 2;
|
||||||
|
} else {
|
||||||
|
SPDLOG_DEBUG("Table does not contain " + textStr->substr(currentPos, 1) + "/" + textStr->substr(currentPos, 2));
|
||||||
|
SPDLOG_DEBUG("Full string: " + *textStr);
|
||||||
|
nextPosJump = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentPos += nextPosJump;
|
||||||
|
}
|
||||||
|
// return the total number of characters we looped through
|
||||||
|
if (totalPixelWidth > maxLinePixelWidth && textStr->at(currentPos - nextPosJump) != ' ') {
|
||||||
|
return currentPos - lastNewline - nextPosJump;
|
||||||
|
} else {
|
||||||
|
return currentPos - lastNewline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text AutoFormatHintText(const Text& unformattedHintText, const std::vector<std::string>& colors = {}) {
|
||||||
|
std::array<std::string, LANGUAGE_MAX> strings;
|
||||||
|
for (int i = 0; i < LANGUAGE_MAX; i++) {
|
||||||
|
std::string textStr = unformattedHintText.GetForLanguage(i);
|
||||||
|
|
||||||
|
for (const auto& color: colors) {
|
||||||
|
if (const size_t firstHashtag = textStr.find('#'); firstHashtag != std::string::npos) {
|
||||||
|
textStr.replace(firstHashtag, 1, color);
|
||||||
|
if (const size_t secondHashtag = textStr.find('#', firstHashtag + 1); secondHashtag != std::string::npos) {
|
||||||
|
textStr.replace(secondHashtag, 1, QM_WHITE);
|
||||||
|
} else {
|
||||||
|
SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", textStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove any remaining '#' characters.
|
||||||
|
std::erase(textStr, '#');
|
||||||
|
|
||||||
if (needsAutomaticNewlines) {
|
|
||||||
// insert newlines either manually or when encountering a '&'
|
// insert newlines either manually or when encountering a '&'
|
||||||
constexpr size_t lineLength = 34;
|
|
||||||
size_t lastNewline = 0;
|
size_t lastNewline = 0;
|
||||||
|
const bool hasIcon = textStr.find('$', 0) != std::string::npos;
|
||||||
|
size_t lineLength = NextLineLength(&textStr, lastNewline, hasIcon);
|
||||||
while (lastNewline + lineLength < textStr.length()) {
|
while (lastNewline + lineLength < textStr.length()) {
|
||||||
size_t carrot = textStr.find('^', lastNewline);
|
const size_t carrot = textStr.find('^', lastNewline);
|
||||||
size_t ampersand = textStr.find('&', lastNewline);
|
const size_t ampersand = textStr.find('&', lastNewline);
|
||||||
size_t lastSpace = textStr.rfind(' ', lastNewline + lineLength);
|
const size_t lastSpace = textStr.rfind(' ', lastNewline + lineLength);
|
||||||
size_t lastPeriod = textStr.rfind('.', lastNewline + lineLength);
|
const size_t lastPeriod = textStr.rfind('.', lastNewline + lineLength);
|
||||||
// replace '&' first if it's within the newline range
|
// replace '&' first if it's within the newline range
|
||||||
if (ampersand < lastNewline + lineLength) {
|
if (ampersand < lastNewline + lineLength) {
|
||||||
lastNewline = ampersand;
|
lastNewline = ampersand + 1;
|
||||||
// or move the lastNewline cursor to the next line if a '^' is encountered
|
// or move the lastNewline cursor to the next line if a '^' is encountered
|
||||||
} else if (carrot < lastNewline + lineLength) {
|
} else if (carrot < lastNewline + lineLength) {
|
||||||
lastNewline = carrot + 1;
|
lastNewline = carrot + 1;
|
||||||
@ -186,15 +265,12 @@ Text AutoFormatHintText(Text unformattedHintText) {
|
|||||||
textStr.replace(lastSpace, 1, "&");
|
textStr.replace(lastSpace, 1, "&");
|
||||||
lastNewline = lastSpace + 1;
|
lastNewline = lastSpace + 1;
|
||||||
}
|
}
|
||||||
|
lineLength = NextLineLength(&textStr, lastNewline, hasIcon);
|
||||||
}
|
}
|
||||||
|
strings[i] = textStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo add colors (see `AddColorsAndFormat` in `custom_messages.cpp`)
|
return {strings[0], strings[1], ""/*spanish*/, strings[2]};
|
||||||
textStr.erase(std::remove(textStr.begin(), textStr.end(), '#'), textStr.end());
|
|
||||||
strings[i] = textStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Text(strings[0], strings[1], strings[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<DungeonHintInfo, 10> dungeonInfoData;
|
std::array<DungeonHintInfo, 10> dungeonInfoData;
|
||||||
@ -220,67 +296,10 @@ std::string dampeHintLoc;
|
|||||||
std::string gregHintLoc;
|
std::string gregHintLoc;
|
||||||
std::string sariaHintLoc;
|
std::string sariaHintLoc;
|
||||||
|
|
||||||
|
|
||||||
Text& GetChildAltarText() {
|
|
||||||
return childAltarText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetAdultAltarText() {
|
|
||||||
return adultAltarText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetGanonText(Text text){
|
void SetGanonText(Text text){
|
||||||
ganonText = text;
|
ganonText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
Text& GetGanonText() {
|
|
||||||
return ganonText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetGanonHintText() {
|
|
||||||
return ganonHintText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetDampeHintText() {
|
|
||||||
return dampesText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetGregHintText() {
|
|
||||||
return gregText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetSheikHintText() {
|
|
||||||
return sheikText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetSariaHintText() {
|
|
||||||
return sariaText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetWarpMinuetText() {
|
|
||||||
return warpMinuetText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetWarpBoleroText() {
|
|
||||||
return warpBoleroText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetWarpSerenadeText() {
|
|
||||||
return warpSerenadeText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetWarpRequiemText() {
|
|
||||||
return warpRequiemText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetWarpNocturneText() {
|
|
||||||
return warpNocturneText;
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetWarpPreludeText() {
|
|
||||||
return warpPreludeText;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetMasterSwordHintLoc() {
|
std::string GetMasterSwordHintLoc() {
|
||||||
return masterSwordHintLoc;
|
return masterSwordHintLoc;
|
||||||
}
|
}
|
||||||
@ -350,9 +369,9 @@ static void SetAllInRegionAsHinted(RandomizerArea area, std::vector<RandomizerCh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddGossipStoneHint(Text hint,
|
static void AddGossipStoneHint(Text hint,
|
||||||
const RandomizerCheck gossipStone,
|
const RandomizerCheck gossipStone,
|
||||||
const std::vector<uint8_t>& colors,
|
const std::vector<std::string>& colors,
|
||||||
HintType hintType,
|
HintType hintType,
|
||||||
std::string distributionName,
|
std::string distributionName,
|
||||||
const RandomizerCheck hintedLocation) {
|
const RandomizerCheck hintedLocation) {
|
||||||
@ -361,16 +380,16 @@ static void AddGossipStoneHint(Text hint,
|
|||||||
//GetLocation(gossipStone)->SetPlacedItem(gossipStone);
|
//GetLocation(gossipStone)->SetPlacedItem(gossipStone);
|
||||||
|
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
ctx->AddHint((RandomizerHintKey)((gossipStone - RC_COLOSSUS_GOSSIP_STONE) + 1), AutoFormatHintText(hint), hintedLocation, hintType, distributionName, ctx->GetItemLocation(hintedLocation)->GetArea());
|
ctx->AddHint((RandomizerHintKey)((gossipStone - RC_COLOSSUS_GOSSIP_STONE) + 1), AutoFormatHintText(hint, colors), hintedLocation, hintType, distributionName, ctx->GetItemLocation(hintedLocation)->GetArea());
|
||||||
ctx->GetItemLocation(gossipStone)->SetPlacedItem(RG_HINT); //RANDOTODO, better gossip stone to location to hint key system
|
ctx->GetItemLocation(gossipStone)->SetPlacedItem(RG_HINT); //RANDOTODO, better gossip stone to location to hint key system
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddGossipStoneHintCopies(uint8_t copies,
|
static void AddGossipStoneHintCopies(uint8_t copies,
|
||||||
Text hint,
|
Text hint,
|
||||||
std::vector<uint8_t> colours,
|
std::vector<std::string> colours,
|
||||||
HintType type,
|
HintType type,
|
||||||
std::string distributionName,
|
std::string distributionName,
|
||||||
RandomizerCheck location = RC_UNKNOWN_CHECK,
|
RandomizerCheck location = RC_UNKNOWN_CHECK,
|
||||||
RandomizerCheck firstStone = RC_UNKNOWN_CHECK){
|
RandomizerCheck firstStone = RC_UNKNOWN_CHECK){
|
||||||
if (firstStone != RC_UNKNOWN_CHECK && copies > 0){
|
if (firstStone != RC_UNKNOWN_CHECK && copies > 0){
|
||||||
AddGossipStoneHint(hint, firstStone, colours, type, distributionName, location);
|
AddGossipStoneHint(hint, firstStone, colours, type, distributionName, location);
|
||||||
@ -405,32 +424,32 @@ static bool CreateHint(RandomizerCheck hintedLocation, uint8_t copies, HintType
|
|||||||
//make hint text
|
//make hint text
|
||||||
Text finalHint;
|
Text finalHint;
|
||||||
Text prefix = ::Hint(RHT_PREFIX).GetText();
|
Text prefix = ::Hint(RHT_PREFIX).GetText();
|
||||||
std::vector<uint8_t> colours;
|
std::vector<std::string> colours;
|
||||||
if (type == HINT_TYPE_WOTH){
|
if (type == HINT_TYPE_WOTH){
|
||||||
Text areaText = ::Hint(ctx->GetItemLocation(hintedLocation)->GetArea()).GetText();
|
Text areaText = ::Hint(ctx->GetItemLocation(hintedLocation)->GetArea()).GetText();
|
||||||
finalHint = prefix + "%r#" + areaText + "#%w" + ::Hint(RHT_WAY_OF_THE_HERO).GetText();
|
finalHint = prefix + "#" + areaText + "#" + ::Hint(RHT_WAY_OF_THE_HERO).GetText();
|
||||||
colours = {QM_LBLUE};
|
colours = {QM_RED, QM_LBLUE};
|
||||||
}
|
}
|
||||||
else if(type == HINT_TYPE_BARREN){
|
else if(type == HINT_TYPE_BARREN){
|
||||||
Text areaText = ::Hint(ctx->GetItemLocation(hintedLocation)->GetArea()).GetText();
|
Text areaText = ::Hint(ctx->GetItemLocation(hintedLocation)->GetArea()).GetText();
|
||||||
finalHint = prefix + ::Hint(RHT_PLUNDERING).GetText() + "%r#" + areaText + "#%w" + ::Hint(RHT_FOOLISH).GetText();
|
finalHint = prefix + ::Hint(RHT_PLUNDERING).GetText() + "#" + areaText + "#" + ::Hint(RHT_FOOLISH).GetText();
|
||||||
colours = {QM_PINK};
|
colours = {QM_RED, QM_PINK};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Text itemText = ctx->GetItemLocation(hintedLocation)->GetPlacedItem().GetHint().GetText();
|
Text itemText = ctx->GetItemLocation(hintedLocation)->GetPlacedItem().GetHint().GetText();
|
||||||
if (type == HINT_TYPE_ITEM_LOCATION){
|
if (type == HINT_TYPE_ITEM_LOCATION){
|
||||||
Text locationText = Rando::StaticData::GetLocation(hintedLocation)->GetHint()->GetText();
|
Text locationText = Rando::StaticData::GetLocation(hintedLocation)->GetHint()->GetText();
|
||||||
finalHint = prefix + "%r" + locationText + " %g#"+itemText+"#%w.";
|
finalHint = prefix + locationText + " #"+itemText+"#.";
|
||||||
colours = {QM_GREEN, QM_RED};
|
colours = {QM_RED, QM_GREEN};
|
||||||
}
|
}
|
||||||
else if (type == HINT_TYPE_ITEM_AREA){
|
else if (type == HINT_TYPE_ITEM_AREA){
|
||||||
Text areaText = ::Hint(ctx->GetItemLocation(hintedLocation)->GetArea()).GetText();
|
Text areaText = ::Hint(ctx->GetItemLocation(hintedLocation)->GetArea()).GetText();
|
||||||
if (Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()) {
|
if (Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()) {
|
||||||
finalHint = prefix+"%r#"+areaText+"#%w "+::Hint(RHT_HOARDS).GetText()+" %g#"+itemText+"#%w.";
|
finalHint = prefix+"#"+areaText+"# "+::Hint(RHT_HOARDS).GetText()+" #"+itemText+"#.";
|
||||||
colours = {QM_GREEN, QM_RED};
|
|
||||||
} else {
|
|
||||||
finalHint = prefix+"%r#"+itemText+"#%w "+::Hint(RHT_CAN_BE_FOUND_AT).GetText()+" %g#"+areaText+"#%w.";
|
|
||||||
colours = {QM_RED, QM_GREEN};
|
colours = {QM_RED, QM_GREEN};
|
||||||
|
} else {
|
||||||
|
finalHint = prefix+"#"+itemText+"# "+::Hint(RHT_CAN_BE_FOUND_AT).GetText()+" #"+areaText+"#.";
|
||||||
|
colours = {QM_GREEN, QM_RED};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -451,7 +470,7 @@ static bool CreateHint(RandomizerCheck hintedLocation, uint8_t copies, HintType
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static RandomizerCheck CreateRandomHint(std::vector<RandomizerCheck>& possibleHintLocations,
|
static RandomizerCheck CreateRandomHint(std::vector<RandomizerCheck>& possibleHintLocations,
|
||||||
uint8_t copies,
|
uint8_t copies,
|
||||||
HintType type,
|
HintType type,
|
||||||
std::string distributionName) {
|
std::string distributionName) {
|
||||||
@ -488,7 +507,7 @@ static RandomizerCheck CreateRandomHint(std::vector<RandomizerCheck>& possibleHi
|
|||||||
return hintedLocation;
|
return hintedLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<RandomizerCheck> FilterHintability(std::vector<RandomizerCheck>& locations,
|
static std::vector<RandomizerCheck> FilterHintability(std::vector<RandomizerCheck>& locations,
|
||||||
std::function<bool(RandomizerCheck)> extraFilter = NoFilter){
|
std::function<bool(RandomizerCheck)> extraFilter = NoFilter){
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
return FilterFromPool(locations, [extraFilter, ctx](const RandomizerCheck loc) {
|
return FilterFromPool(locations, [extraFilter, ctx](const RandomizerCheck loc) {
|
||||||
@ -595,10 +614,9 @@ void CreateGanonAndSheikText() {
|
|||||||
ganonHintText = ganonHintText + "!";
|
ganonHintText = ganonHintText + "!";
|
||||||
}
|
}
|
||||||
|
|
||||||
//CreateMessageFromTextObject(0x70CC, 0, 2, 3, AddColorsAndFormat(ganonHintText));
|
|
||||||
ctx->AddHint(RH_GANONDORF_HINT, AutoFormatHintText(ganonHintText), lightArrowLocation[0], HINT_TYPE_STATIC, "Static", lightArrowArea);
|
ctx->AddHint(RH_GANONDORF_HINT, AutoFormatHintText(ganonHintText), lightArrowLocation[0], HINT_TYPE_STATIC, "Static", lightArrowArea);
|
||||||
|
|
||||||
if(!ctx->GetOption(RSK_TRIAL_COUNT).Is(0)){
|
if (!ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) {
|
||||||
sheikText = ::Hint(RHT_SHEIK_LIGHT_ARROW_HINT).GetText() + LightArrowAreaText + "%w.";
|
sheikText = ::Hint(RHT_SHEIK_LIGHT_ARROW_HINT).GetText() + LightArrowAreaText + "%w.";
|
||||||
locsToCheck = {RC_GANONDORF_HINT, RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC};
|
locsToCheck = {RC_GANONDORF_HINT, RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC};
|
||||||
|
|
||||||
@ -622,11 +640,13 @@ void CreateGanonAndSheikText() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Find the location which has the given itemKey and create the generic altar text for the reward
|
//Find the location which has the given itemKey and create the generic altar text for the reward
|
||||||
static Text BuildDungeonRewardText(const RandomizerGet itemKey, bool isChild) {
|
static Text BuildDungeonRewardText(const ItemID itemID, const RandomizerGet itemKey) {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
RandomizerCheck altarLoc = RC_ALTAR_HINT_ADULT;
|
RandomizerCheck altarLoc = RC_ALTAR_HINT_ADULT;
|
||||||
if(isChild){altarLoc = RC_ALTAR_HINT_CHILD;}
|
if (itemKey == RG_KOKIRI_EMERALD || itemKey == RG_GORON_RUBY || itemKey == RG_ZORA_SAPPHIRE) {
|
||||||
RandomizerCheck location = FilterFromPool(ctx->allLocations, [itemKey, ctx](const RandomizerCheck loc) {
|
altarLoc = RC_ALTAR_HINT_CHILD;
|
||||||
|
}
|
||||||
|
const RandomizerCheck location = FilterFromPool(ctx->allLocations, [itemKey, ctx](const RandomizerCheck loc) {
|
||||||
return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == itemKey;
|
return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == itemKey;
|
||||||
})[0];
|
})[0];
|
||||||
if (IsReachableWithout({altarLoc}, location, true) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)){ //RANDOTODO check if works properly
|
if (IsReachableWithout({altarLoc}, location, true) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)){ //RANDOTODO check if works properly
|
||||||
@ -636,9 +656,9 @@ static Text BuildDungeonRewardText(const RandomizerGet itemKey, bool isChild) {
|
|||||||
std::string rewardString = "$" + std::to_string(itemKey - RG_KOKIRI_EMERALD);
|
std::string rewardString = "$" + std::to_string(itemKey - RG_KOKIRI_EMERALD);
|
||||||
|
|
||||||
// RANDOTODO implement colors for locations
|
// RANDOTODO implement colors for locations
|
||||||
return Text() + rewardString +
|
return Text() + rewardString + "#" +
|
||||||
::Hint(ctx->GetItemLocation(location)->GetArea()).GetText().Capitalize() +
|
::Hint(ctx->GetItemLocation(location)->GetArea()).GetText().Capitalize() +
|
||||||
"...^";
|
"#...^";
|
||||||
}
|
}
|
||||||
|
|
||||||
static Text BuildDoorOfTimeText() {
|
static Text BuildDoorOfTimeText() {
|
||||||
@ -765,17 +785,17 @@ void CreateAltarText() {
|
|||||||
//Spiritual Stones
|
//Spiritual Stones
|
||||||
// TODO: Starting Inventory Dungeon Rewards
|
// TODO: Starting Inventory Dungeon Rewards
|
||||||
(/*StartingKokiriEmerald.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingKokiriEmerald.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_KOKIRI_EMERALD, true)) +
|
: BuildDungeonRewardText(ITEM_KOKIRI_EMERALD, RG_KOKIRI_EMERALD)) +
|
||||||
(/*StartingGoronRuby.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingGoronRuby.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_GORON_RUBY, true)) +
|
: BuildDungeonRewardText(ITEM_GORON_RUBY, RG_GORON_RUBY)) +
|
||||||
(/*StartingZoraSapphire.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingZoraSapphire.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_ZORA_SAPPHIRE, true)) +
|
: BuildDungeonRewardText(ITEM_ZORA_SAPPHIRE, RG_ZORA_SAPPHIRE)) +
|
||||||
//How to open Door of Time, the event trigger is necessary to read the altar multiple times
|
//How to open Door of Time, the event trigger is necessary to read the altar multiple times
|
||||||
BuildDoorOfTimeText();
|
BuildDoorOfTimeText();
|
||||||
} else {
|
} else {
|
||||||
childAltarText = BuildDoorOfTimeText();
|
childAltarText = BuildDoorOfTimeText();
|
||||||
}
|
}
|
||||||
ctx->AddHint(RH_ALTAR_CHILD, childAltarText, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
ctx->AddHint(RH_ALTAR_CHILD, AutoFormatHintText(childAltarText, { QM_GREEN, QM_RED, QM_BLUE }), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
||||||
|
|
||||||
//CreateMessageFromTextObject(0x7040, 0, 2, 3, AddColorsAndFormat(childAltarText, {QM_GREEN, QM_RED, QM_BLUE}));
|
//CreateMessageFromTextObject(0x7040, 0, 2, 3, AddColorsAndFormat(childAltarText, {QM_GREEN, QM_RED, QM_BLUE}));
|
||||||
|
|
||||||
@ -785,17 +805,17 @@ void CreateAltarText() {
|
|||||||
adultAltarText = adultAltarText +
|
adultAltarText = adultAltarText +
|
||||||
//Medallion Areas
|
//Medallion Areas
|
||||||
(/*StartingLightMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingLightMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_LIGHT_MEDALLION, false)) +
|
: BuildDungeonRewardText(ITEM_MEDALLION_LIGHT, RG_LIGHT_MEDALLION)) +
|
||||||
(/*StartingForestMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingForestMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_FOREST_MEDALLION, false)) +
|
: BuildDungeonRewardText(ITEM_MEDALLION_FOREST, RG_FOREST_MEDALLION)) +
|
||||||
(/*StartingFireMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingFireMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_FIRE_MEDALLION, false)) +
|
: BuildDungeonRewardText(ITEM_MEDALLION_FIRE, RG_FIRE_MEDALLION)) +
|
||||||
(/*StartingWaterMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingWaterMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_WATER_MEDALLION, false)) +
|
: BuildDungeonRewardText(ITEM_MEDALLION_WATER, RG_WATER_MEDALLION)) +
|
||||||
(/*StartingSpiritMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingSpiritMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_SPIRIT_MEDALLION, false)) +
|
: BuildDungeonRewardText(ITEM_MEDALLION_SPIRIT, RG_SPIRIT_MEDALLION)) +
|
||||||
(/*StartingShadowMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
(/*StartingShadowMedallion.Value<uint8_t>()*/false ? Text{ "##", "##", "##" }
|
||||||
: BuildDungeonRewardText(RG_SHADOW_MEDALLION, false));
|
: BuildDungeonRewardText(ITEM_MEDALLION_SHADOW, RG_SHADOW_MEDALLION));
|
||||||
}
|
}
|
||||||
adultAltarText = adultAltarText +
|
adultAltarText = adultAltarText +
|
||||||
//Bridge requirement
|
//Bridge requirement
|
||||||
@ -807,35 +827,61 @@ void CreateAltarText() {
|
|||||||
//End
|
//End
|
||||||
::Hint(RHT_ADULT_ALTAR_TEXT_END).GetText();
|
::Hint(RHT_ADULT_ALTAR_TEXT_END).GetText();
|
||||||
//CreateMessageFromTextObject(0x7088, 0, 2, 3, AddColorsAndFormat(adultAltarText, {QM_RED, QM_YELLOW, QM_GREEN, QM_RED, QM_BLUE, QM_YELLOW, QM_PINK, QM_RED, QM_RED, QM_RED, QM_RED}));
|
//CreateMessageFromTextObject(0x7088, 0, 2, 3, AddColorsAndFormat(adultAltarText, {QM_RED, QM_YELLOW, QM_GREEN, QM_RED, QM_BLUE, QM_YELLOW, QM_PINK, QM_RED, QM_RED, QM_RED, QM_RED}));
|
||||||
ctx->AddHint(RH_ALTAR_ADULT, adultAltarText, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
ctx->AddHint(RH_ALTAR_ADULT, AutoFormatHintText(adultAltarText, { QM_RED, QM_YELLOW, QM_GREEN, QM_RED, QM_BLUE, QM_YELLOW, QM_PINK, QM_RED, QM_RED, QM_RED, QM_RED }), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateMerchantsHints() {
|
void CreateMerchantsHints() {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
Text medigoronItemText = ctx->GetItemLocation(RC_GC_MEDIGORON)->GetPlacedItem().GetHint().GetText();
|
Text beanSalesmanItemText, medigoronItemText, grannyItemText, carpetSalesmanItemText, carpetSalesmanAfterItemText;
|
||||||
Text grannyItemText = ctx->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPlacedItem().GetHint().GetText().Capitalize();
|
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_HINT)) {
|
||||||
Text carpetSalesmanItemText =
|
RandomizerGet beanSalesmanItem = ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPlacedRandomizerGet();
|
||||||
ctx->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetText();
|
beanSalesmanItemText = ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPlacedItem().GetHint().GetText();
|
||||||
Text carpetSalesmanItemClearText =
|
if (beanSalesmanItem == RG_ICE_TRAP) {
|
||||||
ctx->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetClear();
|
beanSalesmanItemText = ctx->overrides[RC_ZR_MAGIC_BEAN_SALESMAN].GetTrickName();
|
||||||
|
}
|
||||||
|
RandomizerGet medigoronItem = ctx->GetItemLocation(RC_GC_MEDIGORON)->GetPlacedRandomizerGet();
|
||||||
|
medigoronItemText = ctx->GetItemLocation(RC_GC_MEDIGORON)->GetPlacedItem().GetHint().GetText();
|
||||||
|
if (medigoronItem == RG_ICE_TRAP) {
|
||||||
|
medigoronItemText = ctx->overrides[RC_GC_MEDIGORON].GetTrickName();
|
||||||
|
}
|
||||||
|
RandomizerGet grannyItem = ctx->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPlacedRandomizerGet();
|
||||||
|
grannyItemText = ctx->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPlacedItem().GetHint().GetText().Capitalize();
|
||||||
|
if (grannyItem == RG_ICE_TRAP) {
|
||||||
|
grannyItemText = ctx->overrides[RC_KAK_GRANNYS_SHOP].GetTrickName();
|
||||||
|
}
|
||||||
|
RandomizerGet carpetSalesmanItem = ctx->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPlacedRandomizerGet();
|
||||||
|
carpetSalesmanItemText =
|
||||||
|
ctx->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetText();
|
||||||
|
if (carpetSalesmanItem == RG_ICE_TRAP) {
|
||||||
|
carpetSalesmanItemText = ctx->overrides[RC_WASTELAND_BOMBCHU_SALESMAN].GetTrickName();
|
||||||
|
}
|
||||||
|
carpetSalesmanAfterItemText = ::Hint(RHT_CARPET_SALESMAN_DIALOG_HINTED).GetText();
|
||||||
|
} else {
|
||||||
|
medigoronItemText = grannyItemText = carpetSalesmanItemText = hintTable[RHT_HINT_MYSTERIOUS].GetTextCopy();
|
||||||
|
carpetSalesmanAfterItemText = ::Hint(RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS).GetText();
|
||||||
|
beanSalesmanItemText = Text{ "mysterious item", "objet mystérieux", "objeto misterioso", "mysteriöser gegenstand" };
|
||||||
|
}
|
||||||
|
|
||||||
Text medigoronText =
|
Text medigoronText =
|
||||||
::Hint(RHT_MEDIGORON_DIALOG_FIRST).GetText() + medigoronItemText + ::Hint(RHT_MEDIGORON_DIALOG_SECOND).GetText();
|
::Hint(RHT_MEDIGORON_DIALOG_FIRST).GetText() + medigoronItemText + ::Hint(RHT_MEDIGORON_DIALOG_SECOND).GetText();
|
||||||
Text grannyText = grannyItemText + ::Hint(RHT_GRANNY_DIALOG).GetText();
|
Text grannyText = Text{"#"} + grannyItemText + "#" + ::Hint(RHT_GRANNY_DIALOG).GetText();
|
||||||
Text carpetSalesmanTextOne = ::Hint(RHT_CARPET_SALESMAN_DIALOG_FIRST).GetText() + carpetSalesmanItemText +
|
Text carpetSalesmanTextOne = ::Hint(RHT_CARPET_SALESMAN_DIALOG_FIRST).GetText() + carpetSalesmanItemText +
|
||||||
::Hint(RHT_CARPET_SALESMAN_DIALOG_SECOND).GetText();
|
carpetSalesmanAfterItemText;
|
||||||
Text carpetSalesmanTextTwo = ::Hint(RHT_CARPET_SALESMAN_DIALOG_THIRD).GetText() + carpetSalesmanItemClearText +
|
Text carpetSalesmanTextTwo = ::Hint(RHT_CARPET_SALESMAN_DIALOG_FINAL).GetText();
|
||||||
::Hint(RHT_CARPET_SALESMAN_DIALOG_FOURTH).GetText();
|
medigoronText = AutoFormatHintText(medigoronText, {QM_GREEN, QM_YELLOW, QM_GREEN });
|
||||||
|
grannyText = AutoFormatHintText(grannyText, { QM_GREEN, QM_YELLOW, QM_GREEN });
|
||||||
// CreateMessageFromTextObject(0x9120, 0, 2, 3, AddColorsAndFormat(medigoronText, { QM_RED, QM_GREEN }));
|
carpetSalesmanTextOne = AutoFormatHintText(carpetSalesmanTextOne, { QM_GREEN, QM_RED, QM_YELLOW, QM_GREEN });
|
||||||
// CreateMessageFromTextObject(0x9121, 0, 2, 3, AddColorsAndFormat(grannyText, { QM_RED, QM_GREEN }));
|
|
||||||
// CreateMessageFromTextObject(0x6077, 0, 2, 3, AddColorsAndFormat(carpetSalesmanTextOne, { QM_RED, QM_GREEN }));
|
if (ctx->GetOption(RSK_SHUFFLE_MAGIC_BEANS)) {
|
||||||
// CreateMessageFromTextObject(0x6078, 0, 2, 3,
|
Text beanSalesmanText = ::Hint(RHT_BEAN_SALESMAN_FIRST).GetText() + beanSalesmanItemText + ::Hint(RHT_BEAN_SALESMAN_SECOND).GetText();
|
||||||
// AddColorsAndFormat(carpetSalesmanTextTwo, { QM_RED, QM_YELLOW, QM_RED }));
|
ctx->AddHint(RH_BEAN_SALESMAN, AutoFormatHintText(beanSalesmanText, { QM_RED, QM_GREEN, QM_YELLOW, QM_GREEN }), RC_ZR_MAGIC_BEAN_SALESMAN, HINT_TYPE_STATIC, "Static", RA_ZORAS_RIVER);
|
||||||
// ctx->AddHint(RH_MEDIGORON, AutoFormatHintText(medigoronText), RC_GC_MEDIGORON, HINT_TYPE_STATIC, GetHintRegion(RR_GORON_CITY)->GetHint().GetText());
|
}
|
||||||
// ctx->AddHint(RH_GRANNYS_SHOP, AutoFormatHintText(grannyText), RC_KAK_GRANNYS_SHOP, HINT_TYPE_STATIC, GetHintRegion(RR_KAKARIKO_VILLAGE)->GetHint().GetText());
|
|
||||||
// ctx->AddHint(RH_WASTELAND_BOMBCHU_SALESMAN, AutoFormatHintText(carpetSalesmanTextOne), RC_WASTELAND_BOMBCHU_SALESMAN, HINT_TYPE_STATIC, GetHintRegion(RR_HAUNTED_WASTELAND)->GetHint().GetText());
|
ctx->AddHint(RH_MEDIGORON, medigoronText, RC_GC_MEDIGORON, HINT_TYPE_STATIC, "Static", RA_GORON_CITY);
|
||||||
|
ctx->AddHint(RH_GRANNYS_SHOP, grannyText, RC_KAK_GRANNYS_SHOP, HINT_TYPE_STATIC, "Static", RA_KAKARIKO_VILLAGE);
|
||||||
|
ctx->AddHint(RH_WASTELAND_BOMBCHU_SALESMAN, carpetSalesmanTextOne, RC_WASTELAND_BOMBCHU_SALESMAN, HINT_TYPE_STATIC, "Static", RA_HAUNTED_WASTELAND);
|
||||||
|
// Technically not a hint but this is probably the best place we have to store it for now.
|
||||||
|
ctx->AddHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST, carpetSalesmanTextTwo, RC_WASTELAND_BOMBCHU_SALESMAN, HINT_TYPE_STATIC, "Static", RA_HAUNTED_WASTELAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
//RANDOTODO add Better Links Pocket and starting item handling once more starting items are added
|
//RANDOTODO add Better Links Pocket and starting item handling once more starting items are added
|
||||||
@ -862,18 +908,8 @@ void CreateSpecialItemHint(uint32_t item, RandomizerHintKey hintKey, std::vector
|
|||||||
|
|
||||||
void CreateWarpSongTexts() {
|
void CreateWarpSongTexts() {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
if (!ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
|
||||||
warpMinuetText = Text();
|
|
||||||
warpBoleroText = Text();
|
|
||||||
warpSerenadeText = Text();
|
|
||||||
warpRequiemText = Text();
|
|
||||||
warpNocturneText = Text();
|
|
||||||
warpPreludeText = Text();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false);
|
auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false);
|
||||||
|
|
||||||
for (auto entrance : warpSongEntrances) {
|
for (auto entrance : warpSongEntrances) {
|
||||||
auto destination = entrance->GetConnectedRegion()->GetArea();
|
auto destination = entrance->GetConnectedRegion()->GetArea();
|
||||||
Text resolvedHint = ::Hint(destination).GetText();
|
Text resolvedHint = ::Hint(destination).GetText();
|
||||||
@ -881,33 +917,31 @@ void CreateWarpSongTexts() {
|
|||||||
if (destination == RA_NONE) {
|
if (destination == RA_NONE) {
|
||||||
resolvedHint = Text{"","",""} + entrance->GetConnectedRegion()->regionName;
|
resolvedHint = Text{"","",""} + entrance->GetConnectedRegion()->regionName;
|
||||||
}
|
}
|
||||||
|
resolvedHint = ::Hint(RHT_WARP_TO).GetText() + resolvedHint + ::Hint(RHT_WARP_CHOICE).GetText();
|
||||||
|
RandomizerHintKey hintKey = RH_NONE;
|
||||||
switch (entrance->GetIndex()) {
|
switch (entrance->GetIndex()) {
|
||||||
case 0x0600: // minuet RANDOTODO make an entrance enum and use it here
|
case 0x0600: // minuet
|
||||||
warpMinuetText = resolvedHint;
|
hintKey = RH_MINUET_WARP_LOC;
|
||||||
ctx->AddHint(RH_MINUET_WARP_LOC, resolvedHint, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
|
||||||
break;
|
break;
|
||||||
case 0x04F6: // bolero
|
case 0x04F6: // bolero
|
||||||
warpBoleroText = resolvedHint;
|
hintKey = RH_BOLERO_WARP_LOC;
|
||||||
ctx->AddHint(RH_BOLERO_WARP_LOC, resolvedHint, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
|
||||||
break;
|
break;
|
||||||
case 0x0604: // serenade
|
case 0x0604: // serenade
|
||||||
warpSerenadeText = resolvedHint;
|
hintKey = RH_SERENADE_WARP_LOC;
|
||||||
ctx->AddHint(RH_SERENADE_WARP_LOC, resolvedHint, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
|
||||||
break;
|
break;
|
||||||
case 0x01F1: // requiem
|
case 0x01F1: // requiem
|
||||||
warpRequiemText = resolvedHint;
|
hintKey = RH_REQUIEM_WARP_LOC;
|
||||||
ctx->AddHint(RH_REQUIEM_WARP_LOC, resolvedHint, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
|
||||||
break;
|
break;
|
||||||
case 0x0568: // nocturne
|
case 0x0568: // nocturne
|
||||||
warpNocturneText = resolvedHint;
|
hintKey = RH_NOCTURNE_WARP_LOC;
|
||||||
ctx->AddHint(RH_NOCTURNE_WARP_LOC, resolvedHint, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
break;
|
||||||
break;
|
|
||||||
case 0x05F4: // prelude
|
case 0x05F4: // prelude
|
||||||
warpPreludeText = resolvedHint;
|
hintKey = RH_PRELUDE_WARP_LOC;
|
||||||
ctx->AddHint(RH_PRELUDE_WARP_LOC, resolvedHint, RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ctx->AddHint(hintKey, AutoFormatHintText(resolvedHint, { QM_RED, QM_GREEN }), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", destination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,6 +1105,19 @@ void CreateStoneHints() {
|
|||||||
GetAccessibleLocations({});
|
GetAccessibleLocations({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateFrogsHint() {
|
||||||
|
const auto ctx = Rando::Context::GetInstance();
|
||||||
|
Rando::ItemLocation* itemLoc = ctx->GetItemLocation(RC_ZR_FROGS_OCARINA_GAME);
|
||||||
|
Text itemText = itemLoc->GetPlacedItem().GetHint().GetText();
|
||||||
|
if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP) {
|
||||||
|
itemText = ctx->overrides[RC_ZR_FROGS_OCARINA_GAME].GetTrickName();
|
||||||
|
}
|
||||||
|
Text hintText = ::Hint(RHT_FROGS_HINT01).GetText() + itemText + ::Hint(RHT_FROGS_HINT02).GetText();
|
||||||
|
RandomizerArea area = itemLoc->GetArea();
|
||||||
|
itemLoc->SetAsHinted();
|
||||||
|
ctx->AddHint(RH_FROGS, AutoFormatHintText(hintText, { QM_GREEN }), RC_ZR_FROGS_OCARINA_GAME, HINT_TYPE_STATIC, "Static", area);
|
||||||
|
}
|
||||||
|
|
||||||
void CreateAllHints(){
|
void CreateAllHints(){
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
CreateGanonAndSheikText();
|
CreateGanonAndSheikText();
|
||||||
@ -1082,6 +1129,9 @@ void CreateAllHints(){
|
|||||||
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_HINT)) {
|
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_HINT)) {
|
||||||
CreateMerchantsHints();
|
CreateMerchantsHints();
|
||||||
}
|
}
|
||||||
|
if (ctx->GetOption(RSK_FROGS_HINT)) {
|
||||||
|
CreateFrogsHint();
|
||||||
|
}
|
||||||
if (ctx->GetOption(RSK_GOSSIP_STONE_HINTS).IsNot(RO_GOSSIP_STONES_NONE)) {
|
if (ctx->GetOption(RSK_GOSSIP_STONE_HINTS).IsNot(RO_GOSSIP_STONES_NONE)) {
|
||||||
printf("\x1b[10;10HCreating Hints...");
|
printf("\x1b[10;10HCreating Hints...");
|
||||||
CreateStoneHints();
|
CreateStoneHints();
|
||||||
|
@ -217,23 +217,7 @@ extern std::array<ConditionalAlwaysHint, 10> conditionalAlwaysHints;
|
|||||||
extern void CreateAllHints();
|
extern void CreateAllHints();
|
||||||
extern void CreateWarpSongTexts();
|
extern void CreateWarpSongTexts();
|
||||||
|
|
||||||
|
|
||||||
Text& GetChildAltarText();
|
|
||||||
Text& GetAdultAltarText();
|
|
||||||
Text& GetGanonText();
|
|
||||||
void SetGanonText(Text text);
|
void SetGanonText(Text text);
|
||||||
Text& GetGanonHintText();
|
|
||||||
Text& GetDampeHintText();
|
|
||||||
Text& GetGregHintText();
|
|
||||||
Text& GetSheikHintText();
|
|
||||||
Text& GetSariaHintText();
|
|
||||||
|
|
||||||
Text& GetWarpMinuetText();
|
|
||||||
Text& GetWarpBoleroText();
|
|
||||||
Text& GetWarpSerenadeText();
|
|
||||||
Text& GetWarpRequiemText();
|
|
||||||
Text& GetWarpNocturneText();
|
|
||||||
Text& GetWarpPreludeText();
|
|
||||||
|
|
||||||
std::string GetMasterSwordHintLoc();
|
std::string GetMasterSwordHintLoc();
|
||||||
std::string GetLightArrowHintLoc();
|
std::string GetLightArrowHintLoc();
|
||||||
|
@ -36,3 +36,7 @@ template <typename T, typename Container>
|
|||||||
bool ElementInContainer(T& element, const Container& container) {
|
bool ElementInContainer(T& element, const Container& container) {
|
||||||
return std::find(container.begin(), container.end(), element) != container.end();
|
return std::find(container.begin(), container.end(), element) != container.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename First, typename... T> bool IsAnyOf(First&& first, T&&... t) {
|
||||||
|
return ((first == t) || ...);
|
||||||
|
}
|
||||||
|
@ -541,56 +541,6 @@ static void WriteShuffledEntrances() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AutoFormatHintTextString(std::string unformattedHintTextString) {
|
|
||||||
std::string textStr = unformattedHintTextString;
|
|
||||||
|
|
||||||
// RANDOTODO: don't just make manual exceptions
|
|
||||||
bool needsAutomaicNewlines = true;
|
|
||||||
if (textStr == "Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!" ||
|
|
||||||
textStr == "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda" ||
|
|
||||||
textStr == "What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats." ||
|
|
||||||
textStr == "Many tricks are up my sleeve,&to save yourself&you'd better leave!" ||
|
|
||||||
textStr == "I've learned this spell,&it's really neat,&I'll keep it later&for your treat!" ||
|
|
||||||
textStr == "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!" ||
|
|
||||||
textStr == "Gamin, ton destin achève,&sous mon sort tu périras!&Cette partie ne fut pas brève,&et cette mort, tu subiras!" ||
|
|
||||||
textStr == "Oh! It's @.&I was expecting someone called Sheik.&Do you know what happened to them?" ||
|
|
||||||
textStr == "Ah, c'est @.&J'attendais un certain Sheik.&Tu sais ce qui lui est arrivé?" ||
|
|
||||||
textStr == "They say \"Forgive me, but-^Your script will not be used.&....After all...^The one writing the rest of the script...&will be me.\"") {
|
|
||||||
needsAutomaicNewlines = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsAutomaicNewlines) {
|
|
||||||
//insert newlines either manually or when encountering a '&'
|
|
||||||
constexpr size_t lineLength = 34;
|
|
||||||
size_t lastNewline = 0;
|
|
||||||
while (lastNewline + lineLength < textStr.length()) {
|
|
||||||
size_t carrot = textStr.find('^', lastNewline);
|
|
||||||
size_t ampersand = textStr.find('&', lastNewline);
|
|
||||||
size_t lastSpace = textStr.rfind(' ', lastNewline + lineLength);
|
|
||||||
size_t lastPeriod = textStr.rfind('.', lastNewline + lineLength);
|
|
||||||
//replace '&' first if it's within the newline range
|
|
||||||
if (ampersand < lastNewline + lineLength) {
|
|
||||||
lastNewline = ampersand + 1;
|
|
||||||
//or move the lastNewline cursor to the next line if a '^' is encountered
|
|
||||||
} else if (carrot < lastNewline + lineLength) {
|
|
||||||
lastNewline = carrot + 1;
|
|
||||||
//some lines need to be split but don't have spaces, look for periods instead
|
|
||||||
} else if (lastSpace == std::string::npos) {
|
|
||||||
textStr.replace(lastPeriod, 1, ".&");
|
|
||||||
lastNewline = lastPeriod + 2;
|
|
||||||
} else {
|
|
||||||
textStr.replace(lastSpace, 1, "&");
|
|
||||||
lastNewline = lastSpace + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo add colors (see `AddColorsAndFormat` in `custom_messages.cpp`)
|
|
||||||
textStr.erase(std::remove(textStr.begin(), textStr.end(), '#'), textStr.end());
|
|
||||||
|
|
||||||
return textStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rando::ItemLocation* GetItemLocation(RandomizerGet item) {
|
Rando::ItemLocation* GetItemLocation(RandomizerGet item) {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
return ctx->GetItemLocation(FilterFromPool(ctx->allLocations, [item, ctx](const RandomizerCheck loc) {
|
return ctx->GetItemLocation(FilterFromPool(ctx->allLocations, [item, ctx](const RandomizerCheck loc) {
|
||||||
@ -601,54 +551,17 @@ Rando::ItemLocation* GetItemLocation(RandomizerGet item) {
|
|||||||
// Writes the hints to the spoiler log, if they are enabled.
|
// Writes the hints to the spoiler log, if they are enabled.
|
||||||
static void WriteHints() {
|
static void WriteHints() {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
std::string unformattedGanonText;
|
int language = ctx->GetOption(RSK_LANGUAGE).GetSelectedOptionIndex();
|
||||||
std::string unformattedGanonHintText;
|
if (ctx->GetOption(RSK_SHUFFLE_WARP_SONGS)) {
|
||||||
std::string unformattedDampesText;
|
jsonData["warpMinuetText"] = ctx->GetHint(RH_MINUET_WARP_LOC)->GetText().GetForLanguage(language);
|
||||||
std::string unformattedGregText;
|
jsonData["warpBoleroText"] = ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetForLanguage(language);
|
||||||
std::string unformattedSheikText;
|
jsonData["warpSerenadeText"] = ctx->GetHint(RH_SERENADE_WARP_LOC)->GetText().GetForLanguage(language);
|
||||||
std::string unformattedSariaText;
|
jsonData["warpRequiemText"] = ctx->GetHint(RH_REQUIEM_WARP_LOC)->GetText().GetForLanguage(language);
|
||||||
|
jsonData["warpNocturneText"] = ctx->GetHint(RH_NOCTURNE_WARP_LOC)->GetText().GetForLanguage(language);
|
||||||
switch (ctx->GetOption(RSK_LANGUAGE).GetSelectedOptionIndex()) {
|
jsonData["warpPreludeText"] = ctx->GetHint(RH_PRELUDE_WARP_LOC)->GetText().GetForLanguage(language);
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
unformattedGanonText = GetGanonText().GetEnglish();
|
|
||||||
unformattedGanonHintText = GetGanonHintText().GetEnglish();
|
|
||||||
unformattedDampesText = GetDampeHintText().GetEnglish();
|
|
||||||
unformattedGregText = GetGregHintText().GetEnglish();
|
|
||||||
unformattedSheikText = GetSheikHintText().GetEnglish();
|
|
||||||
unformattedSariaText = GetSariaHintText().GetEnglish();
|
|
||||||
|
|
||||||
if (ctx->GetOption(RSK_SHUFFLE_WARP_SONGS)){
|
|
||||||
jsonData["warpMinuetText"] = GetWarpMinuetText().GetEnglish();
|
|
||||||
jsonData["warpBoleroText"] = GetWarpBoleroText().GetEnglish();
|
|
||||||
jsonData["warpSerenadeText"] = GetWarpSerenadeText().GetEnglish();
|
|
||||||
jsonData["warpRequiemText"] = GetWarpRequiemText().GetEnglish();
|
|
||||||
jsonData["warpNocturneText"] = GetWarpNocturneText().GetEnglish();
|
|
||||||
jsonData["warpPreludeText"] = GetWarpPreludeText().GetEnglish();
|
|
||||||
}
|
|
||||||
jsonData["childAltar"]["hintText"] = GetChildAltarText().GetEnglish();
|
|
||||||
jsonData["adultAltar"]["hintText"] = GetAdultAltarText().GetEnglish();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
unformattedGanonText = GetGanonText().GetFrench();
|
|
||||||
unformattedGanonHintText = GetGanonHintText().GetFrench();
|
|
||||||
unformattedDampesText = GetDampeHintText().GetFrench();
|
|
||||||
unformattedGregText = GetGregHintText().GetFrench();
|
|
||||||
unformattedSheikText = GetSheikHintText().GetFrench();
|
|
||||||
unformattedSariaText = GetSariaHintText().GetFrench();
|
|
||||||
|
|
||||||
if (ctx->GetOption(RSK_SHUFFLE_WARP_SONGS)){
|
|
||||||
jsonData["warpMinuetText"] = GetWarpMinuetText().GetFrench();
|
|
||||||
jsonData["warpBoleroText"] = GetWarpBoleroText().GetFrench();
|
|
||||||
jsonData["warpSerenadeText"] = GetWarpSerenadeText().GetFrench();
|
|
||||||
jsonData["warpRequiemText"] = GetWarpRequiemText().GetFrench();
|
|
||||||
jsonData["warpNocturneText"] = GetWarpNocturneText().GetFrench();
|
|
||||||
jsonData["warpPreludeText"] = GetWarpPreludeText().GetFrench();
|
|
||||||
}
|
|
||||||
jsonData["childAltar"]["hintText"] = GetChildAltarText().GetFrench();
|
|
||||||
jsonData["adultAltar"]["hintText"] = GetAdultAltarText().GetFrench();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
jsonData["childAltar"]["hintText"] = ctx->GetHint(RH_ALTAR_CHILD)->GetText().GetForLanguage(language);
|
||||||
|
jsonData["adultAltar"]["hintText"] = ctx->GetHint(RH_ALTAR_ADULT)->GetText().GetForLanguage(language);
|
||||||
|
|
||||||
Rando::ItemLocation* emeraldLoc = GetItemLocation(RG_KOKIRI_EMERALD);
|
Rando::ItemLocation* emeraldLoc = GetItemLocation(RG_KOKIRI_EMERALD);
|
||||||
Rando::ItemLocation* rubyLoc = GetItemLocation(RG_GORON_RUBY);
|
Rando::ItemLocation* rubyLoc = GetItemLocation(RG_GORON_RUBY);
|
||||||
@ -682,35 +595,28 @@ static void WriteHints() {
|
|||||||
jsonData["adultAltar"]["rewards"]["lightMedallionLoc"] =
|
jsonData["adultAltar"]["rewards"]["lightMedallionLoc"] =
|
||||||
Rando::StaticData::GetLocation(lightMedallionLoc->GetRandomizerCheck())->GetName();
|
Rando::StaticData::GetLocation(lightMedallionLoc->GetRandomizerCheck())->GetName();
|
||||||
|
|
||||||
std::string ganonText = AutoFormatHintTextString(unformattedGanonText);
|
jsonData["ganonText"] = ctx->GetHint(RH_GANONDORF_NOHINT)->GetText().GetForLanguage(language);
|
||||||
std::string ganonHintText = AutoFormatHintTextString(unformattedGanonHintText);
|
|
||||||
std::string dampesText = AutoFormatHintTextString(unformattedDampesText);
|
|
||||||
std::string gregText = AutoFormatHintTextString(unformattedGregText);
|
|
||||||
std::string sheikText = AutoFormatHintTextString(unformattedSheikText);
|
|
||||||
std::string sariaText = AutoFormatHintTextString(unformattedSariaText);
|
|
||||||
|
|
||||||
jsonData["ganonText"] = ganonText;
|
|
||||||
if (ctx->GetOption(RSK_LIGHT_ARROWS_HINT)){
|
if (ctx->GetOption(RSK_LIGHT_ARROWS_HINT)){
|
||||||
jsonData["ganonHintText"] = ganonHintText;
|
jsonData["ganonHintText"] = ctx->GetHint(RH_GANONDORF_HINT)->GetText().GetForLanguage(language);
|
||||||
jsonData["lightArrowHintLoc"] = GetLightArrowHintLoc();
|
jsonData["lightArrowHintLoc"] = GetLightArrowHintLoc();
|
||||||
jsonData["lightArrowArea"] = ::Hint(ctx->GetHint(RH_GANONDORF_HINT)->GetHintedArea()).GetText().GetEnglish();
|
jsonData["lightArrowArea"] = ::Hint(ctx->GetHint(RH_GANONDORF_HINT)->GetHintedArea()).GetText().GetEnglish();
|
||||||
jsonData["masterSwordHintLoc"] = GetMasterSwordHintLoc();
|
jsonData["masterSwordHintLoc"] = GetMasterSwordHintLoc();
|
||||||
if (!ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) {
|
if (!ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) {
|
||||||
jsonData["sheikText"] = sheikText;
|
jsonData["sheikText"] = ctx->GetHint(RH_SHEIK_LIGHT_ARROWS)->GetText().GetForLanguage(language);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ctx->GetOption(RSK_DAMPES_DIARY_HINT)){
|
if (ctx->GetOption(RSK_DAMPES_DIARY_HINT)){
|
||||||
jsonData["dampeText"] = dampesText;
|
jsonData["dampeText"] = ctx->GetHint(RH_DAMPES_DIARY)->GetText().GetForLanguage(language);
|
||||||
jsonData["dampeHintLoc"] = GetDampeHintLoc();
|
jsonData["dampeHintLoc"] = GetDampeHintLoc();
|
||||||
jsonData["dampeRegion"] = ::Hint(ctx->GetHint(RH_DAMPES_DIARY)->GetHintedArea()).GetText().GetEnglish();
|
jsonData["dampeRegion"] = ::Hint(ctx->GetHint(RH_DAMPES_DIARY)->GetHintedArea()).GetText().GetEnglish();
|
||||||
}
|
}
|
||||||
if (ctx->GetOption(RSK_GREG_HINT)){
|
if (ctx->GetOption(RSK_GREG_HINT)){
|
||||||
jsonData["gregText"] = gregText;
|
jsonData["gregText"] = ctx->GetHint(RH_GREG_RUPEE)->GetText().GetForLanguage(language);
|
||||||
jsonData["gregLoc"] = GetGregHintLoc();
|
jsonData["gregLoc"] = GetGregHintLoc();
|
||||||
jsonData["gregRegion"] = ::Hint(ctx->GetHint(RH_GREG_RUPEE)->GetHintedArea()).GetText().GetEnglish();
|
jsonData["gregRegion"] = ::Hint(ctx->GetHint(RH_GREG_RUPEE)->GetHintedArea()).GetText().GetEnglish();
|
||||||
}
|
}
|
||||||
if (ctx->GetOption(RSK_SARIA_HINT)){
|
if (ctx->GetOption(RSK_SARIA_HINT)){
|
||||||
jsonData["sariaText"] = sariaText;
|
jsonData["sariaText"] = ctx->GetHint(RH_SARIA)->GetText().GetForLanguage(language);
|
||||||
jsonData["sariaHintLoc"] = GetSariaHintLoc();
|
jsonData["sariaHintLoc"] = GetSariaHintLoc();
|
||||||
jsonData["sariaRegion"] = ::Hint(ctx->GetHint(RH_SARIA)->GetHintedArea()).GetText().GetEnglish();
|
jsonData["sariaRegion"] = ::Hint(ctx->GetHint(RH_SARIA)->GetHintedArea()).GetText().GetEnglish();
|
||||||
}
|
}
|
||||||
@ -721,17 +627,7 @@ static void WriteHints() {
|
|||||||
for (const RandomizerCheck key : Rando::StaticData::gossipStoneLocations) { //RANDOTODO should be merged with static hints, iterate over hint keys
|
for (const RandomizerCheck key : Rando::StaticData::gossipStoneLocations) { //RANDOTODO should be merged with static hints, iterate over hint keys
|
||||||
Rando::Hint* hint = ctx->GetHint((RandomizerHintKey)(key - RC_COLOSSUS_GOSSIP_STONE + 1));
|
Rando::Hint* hint = ctx->GetHint((RandomizerHintKey)(key - RC_COLOSSUS_GOSSIP_STONE + 1));
|
||||||
Rando::ItemLocation* hintedLocation = ctx->GetItemLocation(hint->GetHintedLocation());
|
Rando::ItemLocation* hintedLocation = ctx->GetItemLocation(hint->GetHintedLocation());
|
||||||
std::string hintTextString;
|
std::string hintTextString = hint->GetText().GetForLanguage(language);
|
||||||
switch (ctx->GetOption(RSK_LANGUAGE).GetSelectedOptionIndex()) {
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
hintTextString = hint->GetText().GetEnglish();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
hintTextString = hint->GetText().GetFrench();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
HintType hintType = hint->GetHintType();
|
HintType hintType = hint->GetHintType();
|
||||||
|
|
||||||
std::string textStr = hintTextString;
|
std::string textStr = hintTextString;
|
||||||
|
@ -12,8 +12,14 @@ public:
|
|||||||
Text(std::string english_, std::string french_, std::string spanish_)
|
Text(std::string english_, std::string french_, std::string spanish_)
|
||||||
: english(std::move(english_)),
|
: english(std::move(english_)),
|
||||||
french(std::move(french_)),
|
french(std::move(french_)),
|
||||||
spanish(std::move(spanish_)) {}
|
spanish(std::move(spanish_)),
|
||||||
Text(std::string english_) : english(std::move(english_)), french(std::move("")), spanish(std::move("")) {}
|
german(std::move("")) {}
|
||||||
|
Text(std::string english_, std::string french_, std::string spanish_, std::string german_)
|
||||||
|
: english(std::move(english_)),
|
||||||
|
french(std::move(french_)),
|
||||||
|
spanish(std::move(spanish_)),
|
||||||
|
german(std::move(german_)) {}
|
||||||
|
Text(std::string english_) : english(std::move(english_)), french(std::move("")), spanish(std::move("")), german(std::move("")) {}
|
||||||
|
|
||||||
const std::string& GetEnglish() const {
|
const std::string& GetEnglish() const {
|
||||||
return english;
|
return english;
|
||||||
@ -33,6 +39,13 @@ public:
|
|||||||
return english;
|
return english;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& GetGerman() const {
|
||||||
|
if (german.length() > 0) {
|
||||||
|
return german;
|
||||||
|
}
|
||||||
|
return english;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& GetForLanguage(uint8_t language) const {
|
const std::string& GetForLanguage(uint8_t language) const {
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case LANGUAGE_ENG:
|
case LANGUAGE_ENG:
|
||||||
@ -40,17 +53,19 @@ public:
|
|||||||
case LANGUAGE_FRA:
|
case LANGUAGE_FRA:
|
||||||
return french;
|
return french;
|
||||||
case LANGUAGE_GER:
|
case LANGUAGE_GER:
|
||||||
|
return german;
|
||||||
default:
|
default:
|
||||||
return english; // TODO: German
|
return english;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text operator+ (const Text& right) const {
|
Text operator+ (const Text& right) const {
|
||||||
return Text{english + right.GetEnglish(), french + right.GetFrench(), spanish + right.GetSpanish()};
|
return Text{english + right.GetEnglish(), french + right.GetFrench(), spanish + right.GetSpanish(),
|
||||||
|
german + right.GetGerman()};
|
||||||
}
|
}
|
||||||
|
|
||||||
Text operator+ (const std::string& right) const {
|
Text operator+ (const std::string& right) const {
|
||||||
return Text{english + right, french + right, spanish + right};
|
return Text{english + right, french + right, spanish + right, german + right};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Text& right) const {
|
bool operator==(const Text& right) const {
|
||||||
@ -58,7 +73,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const std::string& right) const {
|
bool operator==(const std::string& right) const {
|
||||||
return english == right || french == right || spanish == right;
|
return english == right || french == right || spanish == right || german == right;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Text& right) const {
|
bool operator!=(const Text& right) const {
|
||||||
@ -67,7 +82,7 @@ public:
|
|||||||
|
|
||||||
void Replace(std::string oldStr, std::string newStr) {
|
void Replace(std::string oldStr, std::string newStr) {
|
||||||
|
|
||||||
for (std::string* str : {&english, &french, &spanish}) {
|
for (std::string* str : {&english, &french, &spanish, &german}) {
|
||||||
size_t position = str->find(oldStr);
|
size_t position = str->find(oldStr);
|
||||||
while (position != std::string::npos) {
|
while (position != std::string::npos) {
|
||||||
str->replace(position, oldStr.length(), newStr);
|
str->replace(position, oldStr.length(), newStr);
|
||||||
@ -79,7 +94,7 @@ public:
|
|||||||
// Convert first char to upper case
|
// Convert first char to upper case
|
||||||
Text Capitalize(void) const {
|
Text Capitalize(void) const {
|
||||||
Text cap = *this + "";
|
Text cap = *this + "";
|
||||||
for (std::string* str : {&cap.english, &cap.french, &cap.spanish}) {
|
for (std::string* str : {&cap.english, &cap.french, &cap.spanish, &cap.german}) {
|
||||||
(*str)[0] = std::toupper((*str)[0]);
|
(*str)[0] = std::toupper((*str)[0]);
|
||||||
}
|
}
|
||||||
return cap;
|
return cap;
|
||||||
@ -87,7 +102,7 @@ public:
|
|||||||
|
|
||||||
//find the appropriate bars that separate singular from plural
|
//find the appropriate bars that separate singular from plural
|
||||||
void SetForm(int form) {
|
void SetForm(int form) {
|
||||||
for (std::string* str : {&english, &french, &spanish}) {
|
for (std::string* str : {&english, &french, &spanish, &german}) {
|
||||||
|
|
||||||
size_t firstBar = str->find('|');
|
size_t firstBar = str->find('|');
|
||||||
if (firstBar != std::string::npos) {
|
if (firstBar != std::string::npos) {
|
||||||
@ -114,4 +129,5 @@ public:
|
|||||||
std::string english = "";
|
std::string english = "";
|
||||||
std::string french = "";
|
std::string french = "";
|
||||||
std::string spanish = "";
|
std::string spanish = "";
|
||||||
|
std::string german = "";
|
||||||
};
|
};
|
||||||
|
@ -42,7 +42,7 @@ Context::Context() {
|
|||||||
{ "Item Location", HINT_TYPE_ITEM_LOCATION },
|
{ "Item Location", HINT_TYPE_ITEM_LOCATION },
|
||||||
{ "Junk", HINT_TYPE_JUNK },
|
{ "Junk", HINT_TYPE_JUNK },
|
||||||
};
|
};
|
||||||
|
|
||||||
mSpoilerfileAreaNameToEnum = {
|
mSpoilerfileAreaNameToEnum = {
|
||||||
{"No Hint", RA_NONE},
|
{"No Hint", RA_NONE},
|
||||||
{"Link's Pocket", RA_LINKS_POCKET},
|
{"Link's Pocket", RA_LINKS_POCKET},
|
||||||
@ -423,187 +423,97 @@ void Context::ParseItemLocationsJson(nlohmann::json spoilerFileJson) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AltarIconString(const char iconChar) {
|
|
||||||
std::string iconString;
|
|
||||||
iconString += '\x13';
|
|
||||||
switch (iconChar) {
|
|
||||||
case '0':
|
|
||||||
// Kokiri Emerald
|
|
||||||
iconString += '\x6C';
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
// Goron Ruby
|
|
||||||
iconString += '\x6D';
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
// Zora Sapphire
|
|
||||||
iconString += '\x6E';
|
|
||||||
break;
|
|
||||||
case '3':
|
|
||||||
// Forest Medallion
|
|
||||||
iconString += '\x66';
|
|
||||||
break;
|
|
||||||
case '4':
|
|
||||||
// Fire Medallion
|
|
||||||
iconString += '\x67';
|
|
||||||
break;
|
|
||||||
case '5':
|
|
||||||
// Water Medallion
|
|
||||||
iconString += '\x68';
|
|
||||||
break;
|
|
||||||
case '6':
|
|
||||||
// Spirit Medallion
|
|
||||||
iconString += '\x69';
|
|
||||||
break;
|
|
||||||
case '7':
|
|
||||||
// Shadow Medallion
|
|
||||||
iconString += '\x6A';
|
|
||||||
break;
|
|
||||||
case '8':
|
|
||||||
// Light Medallion
|
|
||||||
iconString += '\x6B';
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
// Open DOT (master sword)
|
|
||||||
iconString += '\x3C';
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
// Closed DOT (fairy ocarina)
|
|
||||||
iconString += '\x07';
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
// Intended DOT (oot)
|
|
||||||
iconString += '\x08';
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
// Light Arrow (for bridge reqs)
|
|
||||||
iconString += '\x12';
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
// Boss Key (ganon boss key location)
|
|
||||||
iconString += '\x74';
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
// Bow with Light Arrow
|
|
||||||
iconString += '\x3A';
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
// Kokiri Tunic
|
|
||||||
iconString += '\x41';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return iconString;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string FormatJsonHintText(const std::string& jsonHint) {
|
|
||||||
std::string formattedHintMessage = jsonHint;
|
|
||||||
|
|
||||||
// add icons to altar text
|
|
||||||
for (const char iconChar : { '0', '1', '2', '3', '4', '5', '6', '7', '8', 'o', 'c', 'i', 'l', 'b', 'L', 'k' }) {
|
|
||||||
std::string textToReplace = "$";
|
|
||||||
textToReplace += iconChar;
|
|
||||||
if (const size_t start_pos = formattedHintMessage.find(textToReplace); start_pos != std::string::npos) {
|
|
||||||
std::string iconString = AltarIconString(iconChar);
|
|
||||||
formattedHintMessage.replace(start_pos, textToReplace.length(), iconString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return formattedHintMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
|
void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
|
||||||
// Child Altar
|
// Child Altar
|
||||||
std::string childAltarJsonText = spoilerFileJson["childAltar"]["hintText"].get<std::string>();
|
std::string childAltarText = spoilerFileJson["childAltar"]["hintText"].get<std::string>();
|
||||||
std::string formattedChildAltarText = FormatJsonHintText(childAltarJsonText);
|
AddHint(RH_ALTAR_CHILD, Text(childAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", RA_NONE);
|
||||||
AddHint(RH_ALTAR_CHILD, Text(formattedChildAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
|
||||||
mEmeraldLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["emeraldLoc"]];
|
mEmeraldLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["emeraldLoc"]];
|
||||||
mRubyLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["rubyLoc"]];
|
mRubyLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["rubyLoc"]];
|
||||||
mSapphireLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["sapphireLoc"]];
|
mSapphireLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["sapphireLoc"]];
|
||||||
|
|
||||||
// Adult Altar
|
// Adult Altar
|
||||||
std::string adultAltarJsonText = spoilerFileJson["adultAltar"]["hintText"].get<std::string>();
|
std::string adultAltarText = spoilerFileJson["adultAltar"]["hintText"].get<std::string>();
|
||||||
std::string formattedAdultAltarText = FormatJsonHintText(adultAltarJsonText);
|
AddHint(RH_ALTAR_ADULT, Text(adultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", RA_NONE);
|
||||||
AddHint(RH_ALTAR_ADULT, Text(formattedAdultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
|
||||||
mForestMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["forestMedallionLoc"].get<std::string>()];
|
mForestMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["forestMedallionLoc"].get<std::string>()];
|
||||||
mFireMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["fireMedallionLoc"].get<std::string>()];
|
mFireMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["fireMedallionLoc"].get<std::string>()];
|
||||||
mWaterMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["waterMedallionLoc"].get<std::string>()];
|
mWaterMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["waterMedallionLoc"].get<std::string>()];
|
||||||
mShadowMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["shadowMedallionLoc"].get<std::string>()];
|
mShadowMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["shadowMedallionLoc"].get<std::string>()];
|
||||||
mSpiritMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["spiritMedallionLoc"].get<std::string>()];
|
mSpiritMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["spiritMedallionLoc"].get<std::string>()];
|
||||||
mLightMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["lightMedallionLoc"].get<std::string>()];
|
mLightMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["lightMedallionLoc"].get<std::string>()];
|
||||||
|
|
||||||
// Ganondorf and Sheik Light Arrow Hints
|
// Ganondorf and Sheik Light Arrow Hints
|
||||||
std::string ganonHintText = FormatJsonHintText(spoilerFileJson["ganonHintText"].get<std::string>());
|
std::string ganonHintText = spoilerFileJson["ganonHintText"].get<std::string>();
|
||||||
RandomizerCheck lightArrowLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["lightArrowHintLoc"].get<std::string>()];
|
RandomizerCheck lightArrowLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["lightArrowHintLoc"].get<std::string>()];
|
||||||
std::string lightArrowRegion = spoilerFileJson["lightArrowArea"].get<std::string>();
|
std::string lightArrowRegion = spoilerFileJson["lightArrowArea"].get<std::string>();
|
||||||
AddHint(RH_GANONDORF_HINT, Text(ganonHintText), lightArrowLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[lightArrowRegion]);
|
AddHint(RH_GANONDORF_HINT, Text(ganonHintText), lightArrowLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[lightArrowRegion]);
|
||||||
if (spoilerFileJson.contains("sheikText")) {
|
if (spoilerFileJson.contains("sheikText")) {
|
||||||
std::string sheikText = FormatJsonHintText(spoilerFileJson["sheikText"].get<std::string>());
|
std::string sheikText = spoilerFileJson["sheikText"].get<std::string>();
|
||||||
AddHint(RH_SHEIK_LIGHT_ARROWS, Text(sheikText), lightArrowLoc, HINT_TYPE_STATIC, lightArrowRegion);
|
AddHint(RH_SHEIK_LIGHT_ARROWS, Text(sheikText), lightArrowLoc, HINT_TYPE_STATIC, lightArrowRegion);
|
||||||
}
|
}
|
||||||
std::string ganonText = FormatJsonHintText(spoilerFileJson["ganonText"].get<std::string>());
|
std::string ganonText = spoilerFileJson["ganonText"].get<std::string>();
|
||||||
AddHint(RH_GANONDORF_NOHINT, Text(ganonText), RC_UNKNOWN_CHECK, HINT_TYPE_JUNK, "Static", RA_GANONS_CASTLE);
|
AddHint(RH_GANONDORF_NOHINT, Text(ganonText), RC_UNKNOWN_CHECK, HINT_TYPE_JUNK, "Static", RA_GANONS_CASTLE);
|
||||||
|
|
||||||
// Dampe Hookshot Hint
|
// Dampe Hookshot Hint
|
||||||
if (spoilerFileJson.contains("dampeText")) {
|
if (spoilerFileJson.contains("dampeText")) {
|
||||||
std::string dampeText = FormatJsonHintText(spoilerFileJson["dampeText"].get<std::string>());
|
std::string dampeText = spoilerFileJson["dampeText"].get<std::string>();
|
||||||
std::string dampeRegion = spoilerFileJson["dampeRegion"].get<std::string>();
|
std::string dampeRegion = spoilerFileJson["dampeRegion"].get<std::string>();
|
||||||
RandomizerCheck dampeHintLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["dampeHintLoc"].get<std::string>()];
|
RandomizerCheck dampeHintLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["dampeHintLoc"].get<std::string>()];
|
||||||
AddHint(RH_DAMPES_DIARY, Text(dampeText), dampeHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[dampeRegion]);
|
AddHint(RH_DAMPES_DIARY, Text(dampeText), dampeHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[dampeRegion]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Greg Hint
|
// Greg Hint
|
||||||
if (spoilerFileJson.contains("gregText")) {
|
if (spoilerFileJson.contains("gregText")) {
|
||||||
std::string gregText = FormatJsonHintText(spoilerFileJson["gregText"].get<std::string>());
|
std::string gregText = spoilerFileJson["gregText"].get<std::string>();
|
||||||
std::string gregRegion = spoilerFileJson["gregRegion"].get<std::string>();
|
std::string gregRegion = spoilerFileJson["gregRegion"].get<std::string>();
|
||||||
RandomizerCheck gregLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["gregLoc"].get<std::string>()];
|
RandomizerCheck gregLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["gregLoc"].get<std::string>()];
|
||||||
AddHint(RH_GREG_RUPEE, Text(gregText), gregLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[gregRegion]);
|
AddHint(RH_GREG_RUPEE, Text(gregText), gregLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[gregRegion]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saria Magic Hint
|
// Saria Magic Hint
|
||||||
if (spoilerFileJson.contains("sariaText")) {
|
if (spoilerFileJson.contains("sariaText")) {
|
||||||
std::string sariaText = FormatJsonHintText(spoilerFileJson["sariaText"].get<std::string>());
|
std::string sariaText = spoilerFileJson["sariaText"].get<std::string>();
|
||||||
std::string sariaRegion = spoilerFileJson["sariaRegion"].get<std::string>();
|
std::string sariaRegion = spoilerFileJson["sariaRegion"].get<std::string>();
|
||||||
RandomizerCheck sariaHintLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["sariaHintLoc"].get<std::string>()];
|
RandomizerCheck sariaHintLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["sariaHintLoc"].get<std::string>()];
|
||||||
AddHint(RH_SARIA, Text(sariaText), sariaHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[sariaRegion]);
|
AddHint(RH_SARIA, Text(sariaText), sariaHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[sariaRegion]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warp Songs
|
// Warp Songs
|
||||||
if (spoilerFileJson.contains("warpMinuetText")) {
|
if (spoilerFileJson.contains("warpMinuetText")) {
|
||||||
std::string warpMinuetText = FormatJsonHintText(spoilerFileJson["warpMinuetText"].get<std::string>()); //RANDOTODO fall back for if location is used
|
std::string warpMinuetText = spoilerFileJson["warpMinuetText"].get<std::string>(); //RANDOTODO fall back for if location is used
|
||||||
AddHint(RH_MINUET_WARP_LOC, Text(warpMinuetText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpMinuetText]);
|
AddHint(RH_MINUET_WARP_LOC, Text(warpMinuetText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpMinuetText]);
|
||||||
}
|
}
|
||||||
if (spoilerFileJson.contains("warpBoleroText")) {
|
if (spoilerFileJson.contains("warpBoleroText")) {
|
||||||
std::string warpBoleroText = FormatJsonHintText(spoilerFileJson["warpBoleroText"].get<std::string>());
|
std::string warpBoleroText = spoilerFileJson["warpBoleroText"].get<std::string>();
|
||||||
AddHint(RH_BOLERO_WARP_LOC, Text(warpBoleroText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpBoleroText]);
|
AddHint(RH_BOLERO_WARP_LOC, Text(warpBoleroText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpBoleroText]);
|
||||||
}
|
}
|
||||||
if (spoilerFileJson.contains("warpSerenadeText")) {
|
if (spoilerFileJson.contains("warpSerenadeText")) {
|
||||||
std::string warpSerenadeText = FormatJsonHintText(spoilerFileJson["warpSerenadeText"].get<std::string>());
|
std::string warpSerenadeText = spoilerFileJson["warpSerenadeText"].get<std::string>();
|
||||||
AddHint(RH_SERENADE_WARP_LOC, Text(warpSerenadeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpSerenadeText]);
|
AddHint(RH_SERENADE_WARP_LOC, Text(warpSerenadeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpSerenadeText]);
|
||||||
}
|
}
|
||||||
if (spoilerFileJson.contains("warpRequiemText")) {
|
if (spoilerFileJson.contains("warpRequiemText")) {
|
||||||
std::string warpRequiemText = FormatJsonHintText(spoilerFileJson["warpRequiemText"].get<std::string>());
|
std::string warpRequiemText = spoilerFileJson["warpRequiemText"].get<std::string>();
|
||||||
AddHint(RH_REQUIEM_WARP_LOC, Text(warpRequiemText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpRequiemText]);
|
AddHint(RH_REQUIEM_WARP_LOC, Text(warpRequiemText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpRequiemText]);
|
||||||
}
|
}
|
||||||
if (spoilerFileJson.contains("warpNocturneText")) {
|
if (spoilerFileJson.contains("warpNocturneText")) {
|
||||||
std::string warpNocturneText = FormatJsonHintText(spoilerFileJson["warpNocturneText"].get<std::string>());
|
std::string warpNocturneText = spoilerFileJson["warpNocturneText"].get<std::string>();
|
||||||
AddHint(RH_NOCTURNE_WARP_LOC, Text(warpNocturneText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpNocturneText]);
|
AddHint(RH_NOCTURNE_WARP_LOC, Text(warpNocturneText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpNocturneText]);
|
||||||
}
|
}
|
||||||
if (spoilerFileJson.contains("warpPreludeText")) {
|
if (spoilerFileJson.contains("warpPreludeText")) {
|
||||||
std::string warpPreludeText = FormatJsonHintText(spoilerFileJson["warpPreludeText"].get<std::string>());
|
std::string warpPreludeText = spoilerFileJson["warpPreludeText"].get<std::string>();
|
||||||
AddHint(RH_PRELUDE_WARP_LOC, Text(warpPreludeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpPreludeText]);
|
AddHint(RH_PRELUDE_WARP_LOC, Text(warpPreludeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpPreludeText]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gossip Stones
|
// Gossip Stones
|
||||||
nlohmann::json hintsJson = spoilerFileJson["hints"];
|
nlohmann::json hintsJson = spoilerFileJson["hints"];
|
||||||
for (auto it = hintsJson.begin(); it != hintsJson.end(); ++it) {
|
for (auto it = hintsJson.begin(); it != hintsJson.end(); ++it) {
|
||||||
RandomizerCheck gossipStoneLoc = mSpoilerfileCheckNameToEnum[it.key()];
|
RandomizerCheck gossipStoneLoc = mSpoilerfileCheckNameToEnum[it.key()];
|
||||||
nlohmann::json hintInfo = it.value();
|
nlohmann::json hintInfo = it.value();
|
||||||
std::string hintText = FormatJsonHintText(hintInfo["hint"].get<std::string>());
|
std::string hintText = hintInfo["hint"].get<std::string>();
|
||||||
HintType hintType = mSpoilerfileHintTypeNameToEnum[hintInfo["type"].get<std::string>()];
|
HintType hintType = mSpoilerfileHintTypeNameToEnum[hintInfo["type"].get<std::string>()];
|
||||||
RandomizerCheck hintedLocation = hintInfo.contains("location") ? mSpoilerfileCheckNameToEnum[hintInfo["location"]] : RC_UNKNOWN_CHECK;
|
RandomizerCheck hintedLocation = hintInfo.contains("location") ? mSpoilerfileCheckNameToEnum[hintInfo["location"]] : RC_UNKNOWN_CHECK;
|
||||||
std::string hintedArea = hintInfo.contains("area") ? hintInfo["area"].get<std::string>() : "";
|
RandomizerArea hintedArea = hintInfo.contains("area") ? mSpoilerfileAreaNameToEnum[hintInfo["area"].get<std::string>()] : RA_NONE;
|
||||||
AddHint(static_cast<RandomizerHintKey>(gossipStoneLoc - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), hintedLocation, hintType, hintedArea);
|
std::string distribution = hintInfo["distribution"].get<std::string>();
|
||||||
|
AddHint(static_cast<RandomizerHintKey>(gossipStoneLoc - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), hintedLocation, hintType, distribution, hintedArea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ void Randomizer::LoadHintMessages() {
|
|||||||
CustomMessage("{{message}}", "{{message}}", "{{message}}"));
|
CustomMessage("{{message}}", "{{message}}", "{{message}}"));
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::hintMessageTableID, TEXT_SARIAS_SONG_FACE_TO_FACE,
|
Randomizer::hintMessageTableID, TEXT_SARIAS_SONG_FACE_TO_FACE,
|
||||||
CustomMessage(ctx->GetHint(RH_SARIA)->GetText().GetEnglish(), ctx->GetHint(RH_SARIA)->GetText().GetEnglish(), ctx->GetHint(RH_SARIA)->GetText().GetFrench(), TEXTBOX_TYPE_BLUE));
|
CustomMessage(ctx->GetHint(RH_SARIA)->GetText().GetEnglish(), ctx->GetHint(RH_SARIA)->GetText().GetGerman(), ctx->GetHint(RH_SARIA)->GetText().GetFrench(), TEXTBOX_TYPE_BLUE));
|
||||||
|
|
||||||
for (int i : Rando::StaticData::gossipStoneLocations) {
|
for (int i : Rando::StaticData::gossipStoneLocations) {
|
||||||
RandomizerHintKey rhk = RandomizerHintKey(i - RC_COLOSSUS_GOSSIP_STONE + 1);
|
RandomizerHintKey rhk = RandomizerHintKey(i - RC_COLOSSUS_GOSSIP_STONE + 1);
|
||||||
@ -329,19 +329,34 @@ void Randomizer::LoadHintMessages() {
|
|||||||
);
|
);
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_FROGS_UNDERWATER,
|
Randomizer::randoMiscHintsTableID, TEXT_FROGS_UNDERWATER,
|
||||||
CustomMessage("Some frogs holding&%g{{item}}%w&are looking at you from underwater...",
|
CustomMessage(ctx->GetHint(RH_FROGS)->GetText().GetEnglish(),
|
||||||
"Unter Wasser gibt es Frösche,&die %g{{item}}%w&bei sich haben und Dich neugierig&beobachten...",
|
ctx->GetHint(RH_FROGS)->GetText().GetGerman(),
|
||||||
"Des grenouilles se trouvant&sous l'eau vous fixent attentivement,&tenant fermement&%g{{item}}%w.", TEXTBOX_TYPE_BLUE)
|
ctx->GetHint(RH_FROGS)->GetText().GetFrench(), TEXTBOX_TYPE_BLUE)
|
||||||
);
|
);
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_MINUET_OF_FOREST,
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_SARIAS_SONG_FACE_TO_FACE,
|
CustomMessage(ctx->GetHint(RH_MINUET_WARP_LOC)->GetText().GetEnglish(),
|
||||||
CustomMessage("{{message}}", "{{message}}", "{{message}}", TEXTBOX_TYPE_BLUE)
|
ctx->GetHint(RH_MINUET_WARP_LOC)->GetText().GetGerman(),
|
||||||
);
|
ctx->GetHint(RH_MINUET_WARP_LOC)->GetText().GetFrench()));
|
||||||
|
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_BOLERO_OF_FIRE,
|
||||||
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_WARP_RANDOM_REPLACED_TEXT,
|
CustomMessage(ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetEnglish(),
|
||||||
CustomMessage("Warp to&{{location}}?\x1B&%gOK&No%w\x02",
|
ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetGerman(),
|
||||||
"Zu {{location}}?\x1B&%gOK&No%w\x02",
|
ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetFrench()));
|
||||||
"Se téléporter vers&{{location}}?\x1B&%gOK!&Non%w\x02"));
|
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_SERENADE_OF_WATER,
|
||||||
|
CustomMessage(ctx->GetHint(RH_SERENADE_WARP_LOC)->GetText().GetEnglish(),
|
||||||
|
ctx->GetHint(RH_SERENADE_WARP_LOC)->GetText().GetGerman(),
|
||||||
|
ctx->GetHint(RH_SERENADE_WARP_LOC)->GetText().GetFrench()));
|
||||||
|
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_REQUIEM_OF_SPIRIT,
|
||||||
|
CustomMessage(ctx->GetHint(RH_REQUIEM_WARP_LOC)->GetText().GetEnglish(),
|
||||||
|
ctx->GetHint(RH_REQUIEM_WARP_LOC)->GetText().GetGerman(),
|
||||||
|
ctx->GetHint(RH_REQUIEM_WARP_LOC)->GetText().GetFrench()));
|
||||||
|
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_NOCTURNE_OF_SHADOW,
|
||||||
|
CustomMessage(ctx->GetHint(RH_NOCTURNE_WARP_LOC)->GetText().GetEnglish(),
|
||||||
|
ctx->GetHint(RH_NOCTURNE_WARP_LOC)->GetText().GetGerman(),
|
||||||
|
ctx->GetHint(RH_NOCTURNE_WARP_LOC)->GetText().GetFrench()));
|
||||||
|
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_PRELUDE_OF_LIGHT,
|
||||||
|
CustomMessage(ctx->GetHint(RH_PRELUDE_WARP_LOC)->GetText().GetEnglish(),
|
||||||
|
ctx->GetHint(RH_PRELUDE_WARP_LOC)->GetText().GetGerman(),
|
||||||
|
ctx->GetHint(RH_PRELUDE_WARP_LOC)->GetText().GetFrench()));
|
||||||
|
|
||||||
// Bow Shooting Gallery reminder
|
// Bow Shooting Gallery reminder
|
||||||
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW,
|
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW,
|
||||||
@ -394,6 +409,7 @@ std::unordered_map<RandomizerGet, EnGirlAShopItem> randomizerGetToEnGirlShopItem
|
|||||||
};
|
};
|
||||||
|
|
||||||
void Randomizer::LoadMerchantMessages() {
|
void Randomizer::LoadMerchantMessages() {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
CustomMessageManager::Instance->ClearMessageTable(Randomizer::merchantMessageTableID);
|
CustomMessageManager::Instance->ClearMessageTable(Randomizer::merchantMessageTableID);
|
||||||
CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::merchantMessageTableID);
|
CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::merchantMessageTableID);
|
||||||
|
|
||||||
@ -408,12 +424,9 @@ void Randomizer::LoadMerchantMessages() {
|
|||||||
"\x12\x38\x82" "J'abandonne! Tu veux bien m'acheter&un %g{{item}}%w?&Ça fera %r{{price}} Rubis%w!\x07\x10\xA3"));
|
"\x12\x38\x82" "J'abandonne! Tu veux bien m'acheter&un %g{{item}}%w?&Ça fera %r{{price}} Rubis%w!\x07\x10\xA3"));
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_10,
|
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_10,
|
||||||
CustomMessage("I tried to be a %rmagic bean%w salesman,&but it turns out my marketing skills&weren't worth "
|
CustomMessage(ctx->GetHint(RH_BEAN_SALESMAN)->GetText().GetEnglish(),
|
||||||
"beans!^Anyway, want to buy my&%gmysterious item%w for 60 Rupees?\x1B&%gYes&No%w",
|
ctx->GetHint(RH_BEAN_SALESMAN)->GetText().GetGerman(),
|
||||||
"Möchten Sie einen geheimnisvollen&Gegenstand für 60 Rubine?\x1B&%gJa&Nein%w",
|
ctx->GetHint(RH_BEAN_SALESMAN)->GetText().GetFrench()));
|
||||||
"J'ai essayé d'être un vendeur de&%rharicots magiques%w, mais j'étais&mauvais au niveau du marketing et&ça "
|
|
||||||
"me courait sur le haricot...^Enfin bref, ça te dirait de m'acheter un&"
|
|
||||||
"%gobjet mystérieux%w pour 60 Rubis?\x1B&%gOui&Non%w"));
|
|
||||||
|
|
||||||
|
|
||||||
//Setup for merchant text boxes
|
//Setup for merchant text boxes
|
||||||
@ -421,51 +434,30 @@ void Randomizer::LoadMerchantMessages() {
|
|||||||
//RANDOTODO: Implement obscure/ambiguous hints
|
//RANDOTODO: Implement obscure/ambiguous hints
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::merchantMessageTableID, TEXT_MEDIGORON,
|
Randomizer::merchantMessageTableID, TEXT_MEDIGORON,
|
||||||
CustomMessage("How about buying %g&{{item}}%w for %y200 rupees%w?\x1B&%gYes&No%w",
|
CustomMessage(ctx->GetHint(RH_MEDIGORON)->GetText().GetEnglish(),
|
||||||
"Wie wäre es mit %g&{{item}}%w für %y200 Rubine?%w\x1B&%gJa!&Nein!%w",
|
ctx->GetHint(RH_MEDIGORON)->GetText().GetGerman(),
|
||||||
"Veux-tu acheter %g&{{item}}%w pour %y200 rubis?%w\x1B&%gOui&Non&w"));
|
ctx->GetHint(RH_MEDIGORON)->GetText().GetFrench()));
|
||||||
|
|
||||||
//Granny Shopy
|
//Granny Shopy
|
||||||
//RANDOTODO: Implement obscure/ambiguous hints
|
//RANDOTODO: Implement obscure/ambiguous hints
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::merchantMessageTableID, TEXT_GRANNYS_SHOP,
|
Randomizer::merchantMessageTableID, TEXT_GRANNYS_SHOP,
|
||||||
CustomMessage("%g{{item}}%w!&How about %y100 rupees%w?\x1B&%gYes&No%w",
|
CustomMessage(ctx->GetHint(RH_GRANNYS_SHOP)->GetText().GetEnglish(),
|
||||||
"%g{{item}}%w!&Wie wäre es mit %y100 Rubine?%w\x1B&%gJa!&Nein!%w",
|
ctx->GetHint(RH_GRANNYS_SHOP)->GetText().GetGerman(),
|
||||||
"%g{{item}}%w!&Que dis-tu de %y100 rubis?%w\x1B&%gOui&Non&w"));
|
ctx->GetHint(RH_GRANNYS_SHOP)->GetText().GetFrench()));
|
||||||
|
|
||||||
//Carpet Salesman
|
//Carpet Salesman
|
||||||
//RANDOTODO: Implement obscure/ambiguous hints
|
//RANDOTODO: Implement obscure/ambiguous hints
|
||||||
std::vector<std::string> cgBoxTwoText;
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
if (Randomizer::GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ON_HINT) {
|
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_1,
|
||||||
cgBoxTwoText = {
|
CustomMessage(ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN)->GetText().GetEnglish(),
|
||||||
"!%w&It's real, I promise!&A lonely man such as myself&wouldn't %rlie%w to you, hmm?^",
|
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN)->GetText().GetGerman(),
|
||||||
"!%w&Ich kann versichern es ist ein&aufrichtiges Angebot!^Ein einsamer Mann wie ich würde dich&doch nicht %ranlügen%w, oder?^",
|
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN)->GetText().GetFrench()));
|
||||||
"!%w&C'est vrai! J'te jure!&Un gars comme moi ne te %rmentirai%w pas&tu ne crois pas?^"
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
};
|
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_2,
|
||||||
} else {
|
CustomMessage(ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST)->GetText().GetEnglish(),
|
||||||
cgBoxTwoText = {
|
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST)->GetText().GetGerman(),
|
||||||
"!%w&I won't tell you what it is until I see&the money...^",
|
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST)->GetText().GetFrench()));
|
||||||
"!%w&Erst kommt das Geld, dann die Ware...^",
|
|
||||||
"!%w&Je ne te dirai pas ce que c'est avant&d'être payé rubis sur l'ongle...^"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_1,
|
|
||||||
CustomMessage("Welcome!^I am selling stuff, strange and rare, &from all over the world to "
|
|
||||||
"everybody.&Today's special is...^%g{{item}}" +
|
|
||||||
cgBoxTwoText[0] + "How about %y200 Rupees?%w\x1B&&%gYes&No%w",
|
|
||||||
"Sei gegrüßt!^Ich verkaufe allerlei Kuriorisäten.&Stets sonderliche und seltene Ware&aus "
|
|
||||||
"aller Welt für jedermann.&Das heutige Angebot bleibt...^%g{{item}}" +
|
|
||||||
cgBoxTwoText[1] + "Wie wäre es mit %y200 Rubinen?%w\x1B&&%gJa!&Nein!%w",
|
|
||||||
"Bienvenue!^Je vends des trucs étranges et rares,&de partout dans le monde et à tout "
|
|
||||||
"le&monde! L'objet du jour est...^%g{{item}}" +
|
|
||||||
cgBoxTwoText[2] + "Alors, marché conclu pour %y200 rubis?%w\x1B&&%gOui&Non%w"));
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_2,
|
|
||||||
CustomMessage("Finally! Now I can go back to being &an %rarms dealer%w!",
|
|
||||||
"Endlich! Schon bald kann ich wieder &%rKrabbelminen-Händler%w sein!",
|
|
||||||
"Squalala! Je vais enfin pouvoir &%rprendre des vacances%w!"));
|
|
||||||
|
|
||||||
// Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are
|
// Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are
|
||||||
// prompted buy/don't buy
|
// prompted buy/don't buy
|
||||||
@ -1145,7 +1137,7 @@ GetItemID Randomizer::GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItem
|
|||||||
return GI_HEART_PIECE_WIN;
|
return GI_HEART_PIECE_WIN;
|
||||||
case RG_TREASURE_GAME_GREEN_RUPEE:
|
case RG_TREASURE_GAME_GREEN_RUPEE:
|
||||||
return GI_RUPEE_GREEN_LOSE;
|
return GI_RUPEE_GREEN_LOSE;
|
||||||
|
|
||||||
//Ocarina Buttons
|
//Ocarina Buttons
|
||||||
case RG_OCARINA_A_BUTTON:
|
case RG_OCARINA_A_BUTTON:
|
||||||
return (GetItemID)RG_OCARINA_A_BUTTON;
|
return (GetItemID)RG_OCARINA_A_BUTTON;
|
||||||
@ -2368,77 +2360,6 @@ void RandomizerSettingsWindow::UpdateElement() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage Randomizer::GetWarpSongMessage(u16 textId, bool mysterious) {
|
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_WARP_RANDOM_REPLACED_TEXT);
|
|
||||||
if (mysterious) {
|
|
||||||
std::array<const char*, LANGUAGE_MAX> locationName ={
|
|
||||||
"a mysterious place",
|
|
||||||
"ein mysteriöser Ort",
|
|
||||||
"un endroit mystérieux",
|
|
||||||
};
|
|
||||||
|
|
||||||
messageEntry.Replace("{{location}}", locationName[0],
|
|
||||||
locationName[1], locationName[2]);
|
|
||||||
return messageEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ctx = Rando::Context::GetInstance();
|
|
||||||
RandomizerHintKey locHintKey = RH_NONE;
|
|
||||||
switch (textId) {
|
|
||||||
case TEXT_WARP_MINUET_OF_FOREST:
|
|
||||||
locHintKey = RH_MINUET_WARP_LOC;
|
|
||||||
break;
|
|
||||||
case TEXT_WARP_BOLERO_OF_FIRE:
|
|
||||||
locHintKey = RH_BOLERO_WARP_LOC;
|
|
||||||
break;
|
|
||||||
case TEXT_WARP_SERENADE_OF_WATER:
|
|
||||||
locHintKey = RH_SERENADE_WARP_LOC;
|
|
||||||
break;
|
|
||||||
case TEXT_WARP_REQUIEM_OF_SPIRIT:
|
|
||||||
locHintKey = RH_REQUIEM_WARP_LOC;
|
|
||||||
break;
|
|
||||||
case TEXT_WARP_NOCTURNE_OF_SHADOW:
|
|
||||||
locHintKey = RH_NOCTURNE_WARP_LOC;
|
|
||||||
break;
|
|
||||||
case TEXT_WARP_PRELUDE_OF_LIGHT:
|
|
||||||
locHintKey = RH_PRELUDE_WARP_LOC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::string locationName = "";
|
|
||||||
switch (gSaveContext.language) {
|
|
||||||
case LANGUAGE_FRA:
|
|
||||||
locationName = ctx->GetHint(locHintKey)->GetText().GetFrench();
|
|
||||||
break;
|
|
||||||
case LANGUAGE_ENG:
|
|
||||||
default:
|
|
||||||
locationName = ctx->GetHint(locHintKey)->GetText().GetEnglish();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
messageEntry.Replace("{{location}}", std::move(locationName));
|
|
||||||
return messageEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomMessage Randomizer::GetFrogsMessage(u16 originalTextId) {
|
|
||||||
auto ctx = Rando::Context::GetInstance();
|
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, originalTextId);
|
|
||||||
RandomizerGet frogsGet = ctx->GetItemLocation(RC_ZR_FROGS_OCARINA_GAME)->GetPlacedRandomizerGet();
|
|
||||||
std::array<std::string, LANGUAGE_MAX> frogItemName;
|
|
||||||
if (frogsGet == RG_ICE_TRAP) {
|
|
||||||
frogsGet = ctx->overrides[RC_ZR_FROGS_OCARINA_GAME].LooksLike();
|
|
||||||
frogItemName = {
|
|
||||||
ctx->overrides[RC_ZR_FROGS_OCARINA_GAME].GetTrickName().english,
|
|
||||||
ctx->overrides[RC_ZR_FROGS_OCARINA_GAME].GetTrickName().french,
|
|
||||||
ctx->overrides[RC_ZR_FROGS_OCARINA_GAME].GetTrickName().english
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
frogItemName = EnumToSpoilerfileGetName[frogsGet];
|
|
||||||
}
|
|
||||||
messageEntry.Replace("{{item}}", std::move(frogItemName[0]), std::move(frogItemName[1]), std::move(frogItemName[2]));
|
|
||||||
return messageEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) {
|
CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, originalTextId);
|
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, originalTextId);
|
||||||
|
@ -58,9 +58,7 @@ class Randomizer {
|
|||||||
GetItemID GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItemID ogItemId);
|
GetItemID GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItemID ogItemId);
|
||||||
ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck);
|
ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck);
|
||||||
ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck);
|
ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck);
|
||||||
CustomMessage GetWarpSongMessage(u16 textId, bool mysterious = false);
|
|
||||||
CustomMessage GetSheikMessage(s16 scene, u16 originalTextId);
|
CustomMessage GetSheikMessage(s16 scene, u16 originalTextId);
|
||||||
CustomMessage GetFrogsMessage(u16 originalTextId);
|
|
||||||
CustomMessage GetSariaMessage(u16 originalTextId);
|
CustomMessage GetSariaMessage(u16 originalTextId);
|
||||||
CustomMessage GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false);
|
CustomMessage GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false);
|
||||||
CustomMessage GetCursedSkullMessage(s16 params);
|
CustomMessage GetCursedSkullMessage(s16 params);
|
||||||
|
@ -1951,9 +1951,11 @@ typedef enum {
|
|||||||
RH_GANONDORF_NOHINT,
|
RH_GANONDORF_NOHINT,
|
||||||
RH_DAMPES_DIARY,
|
RH_DAMPES_DIARY,
|
||||||
RH_GREG_RUPEE,
|
RH_GREG_RUPEE,
|
||||||
|
RH_BEAN_SALESMAN,
|
||||||
RH_MEDIGORON,
|
RH_MEDIGORON,
|
||||||
RH_GRANNYS_SHOP,
|
RH_GRANNYS_SHOP,
|
||||||
RH_WASTELAND_BOMBCHU_SALESMAN,
|
RH_WASTELAND_BOMBCHU_SALESMAN,
|
||||||
|
RH_WASTELAND_BOMBCHU_SALESMAN_POST,
|
||||||
RH_ALTAR_CHILD,
|
RH_ALTAR_CHILD,
|
||||||
RH_ALTAR_ADULT,
|
RH_ALTAR_ADULT,
|
||||||
RH_SARIA,
|
RH_SARIA,
|
||||||
@ -1964,6 +1966,7 @@ typedef enum {
|
|||||||
RH_REQUIEM_WARP_LOC,
|
RH_REQUIEM_WARP_LOC,
|
||||||
RH_NOCTURNE_WARP_LOC,
|
RH_NOCTURNE_WARP_LOC,
|
||||||
RH_PRELUDE_WARP_LOC,
|
RH_PRELUDE_WARP_LOC,
|
||||||
|
RH_FROGS,
|
||||||
RH_MAX,
|
RH_MAX,
|
||||||
} RandomizerHintKey;
|
} RandomizerHintKey;
|
||||||
|
|
||||||
@ -3050,6 +3053,7 @@ typedef enum {
|
|||||||
RHT_BUY_RED_POTION_50,
|
RHT_BUY_RED_POTION_50,
|
||||||
RHT_TRIFORCE,
|
RHT_TRIFORCE,
|
||||||
RHT_HINT,
|
RHT_HINT,
|
||||||
|
RHT_HINT_MYSTERIOUS,
|
||||||
RHT_TYCOON_WALLET,
|
RHT_TYCOON_WALLET,
|
||||||
RHT_HOOKSHOT,
|
RHT_HOOKSHOT,
|
||||||
RHT_LONGSHOT,
|
RHT_LONGSHOT,
|
||||||
@ -3276,6 +3280,10 @@ typedef enum {
|
|||||||
RHT_GREG_HINT02,
|
RHT_GREG_HINT02,
|
||||||
RHT_SARIA_TEXT01,
|
RHT_SARIA_TEXT01,
|
||||||
RHT_SARIA_TEXT02,
|
RHT_SARIA_TEXT02,
|
||||||
|
RHT_WARP_TO,
|
||||||
|
RHT_WARP_CHOICE,
|
||||||
|
RHT_FROGS_HINT01,
|
||||||
|
RHT_FROGS_HINT02,
|
||||||
// Ganon Line
|
// Ganon Line
|
||||||
RHT_GANON_LINE01,
|
RHT_GANON_LINE01,
|
||||||
RHT_GANON_LINE02,
|
RHT_GANON_LINE02,
|
||||||
@ -3289,12 +3297,14 @@ typedef enum {
|
|||||||
RHT_GANON_LINE10,
|
RHT_GANON_LINE10,
|
||||||
RHT_GANON_LINE11,
|
RHT_GANON_LINE11,
|
||||||
// Merchants
|
// Merchants
|
||||||
|
RHT_BEAN_SALESMAN_FIRST,
|
||||||
|
RHT_BEAN_SALESMAN_SECOND,
|
||||||
RHT_MEDIGORON_DIALOG_FIRST,
|
RHT_MEDIGORON_DIALOG_FIRST,
|
||||||
RHT_MEDIGORON_DIALOG_SECOND,
|
RHT_MEDIGORON_DIALOG_SECOND,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_FIRST,
|
RHT_CARPET_SALESMAN_DIALOG_FIRST,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_SECOND,
|
RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_THIRD,
|
RHT_CARPET_SALESMAN_DIALOG_HINTED,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_FOURTH,
|
RHT_CARPET_SALESMAN_DIALOG_FINAL,
|
||||||
RHT_GRANNY_DIALOG,
|
RHT_GRANNY_DIALOG,
|
||||||
RHT_MAX
|
RHT_MAX
|
||||||
} RandomizerHintTextKey;
|
} RandomizerHintTextKey;
|
||||||
|
@ -2585,15 +2585,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
(Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)) ||
|
(Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)) ||
|
||||||
(textId == TEXT_CARPET_SALESMAN_1 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)) ||
|
(textId == TEXT_CARPET_SALESMAN_1 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)) ||
|
||||||
(textId == TEXT_CARPET_SALESMAN_2 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)))) {
|
(textId == TEXT_CARPET_SALESMAN_2 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)))) {
|
||||||
RandomizerInf randoInf;
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId);
|
||||||
if (textId == TEXT_MEDIGORON) {
|
|
||||||
randoInf = RAND_INF_MERCHANTS_MEDIGORON;
|
|
||||||
} else if (textId == TEXT_GRANNYS_SHOP) {
|
|
||||||
randoInf = RAND_INF_MERCHANTS_GRANNYS_SHOP;
|
|
||||||
} else {
|
|
||||||
randoInf = RAND_INF_MERCHANTS_CARPET_SALESMAN;
|
|
||||||
}
|
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, textId, Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_ON_HINT);
|
|
||||||
} else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) &&
|
} else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) &&
|
||||||
(textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)) {
|
(textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
||||||
@ -2611,7 +2603,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, TEXT_CHEST_GAME_PROCEED);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, TEXT_CHEST_GAME_PROCEED);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS) &&
|
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS) &&
|
||||||
(textId >= TEXT_WARP_MINUET_OF_FOREST && textId <= TEXT_WARP_PRELUDE_OF_LIGHT)) {
|
(textId >= TEXT_WARP_MINUET_OF_FOREST && textId <= TEXT_WARP_PRELUDE_OF_LIGHT)) {
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetWarpSongMessage(textId, Randomizer_GetSettingValue(RSK_WARP_SONG_HINTS) == RO_GENERIC_OFF);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, textId);
|
||||||
} else if (textId == TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI || textId == TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN) {
|
} else if (textId == TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI || textId == TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, textId);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, textId);
|
||||||
} else if (textId == TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW) {
|
} else if (textId == TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW) {
|
||||||
@ -2620,7 +2612,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
u16 choice = Random(0, NUM_GORON_MESSAGES);
|
u16 choice = Random(0, NUM_GORON_MESSAGES);
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetGoronMessage(choice);
|
messageEntry = OTRGlobals::Instance->gRandomizer->GetGoronMessage(choice);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_FROGS_HINT) && textId == TEXT_FROGS_UNDERWATER) {
|
} else if (Randomizer_GetSettingValue(RSK_FROGS_HINT) && textId == TEXT_FROGS_UNDERWATER) {
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetFrogsMessage(textId);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, textId);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_SARIA_HINT)) {
|
} else if (Randomizer_GetSettingValue(RSK_SARIA_HINT)) {
|
||||||
if ((gPlayState->sceneNum == SCENE_SACRED_FOREST_MEADOW && textId == TEXT_SARIA_SFM) || (textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER)) {
|
if ((gPlayState->sceneNum == SCENE_SACRED_FOREST_MEADOW && textId == TEXT_SARIA_SFM) || (textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER)) {
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetSariaMessage(textId);
|
messageEntry = OTRGlobals::Instance->gRandomizer->GetSariaMessage(textId);
|
||||||
|
@ -339,7 +339,7 @@ void SaveManager::LoadRandomizerVersion3() {
|
|||||||
"french", randoContext->GetItemOverride(i).GetTrickName().french);
|
"french", randoContext->GetItemOverride(i).GetTrickName().french);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
uint16_t price = 0;
|
uint16_t price = 0;
|
||||||
SaveManager::Instance->LoadData("price", price, (uint16_t)0);
|
SaveManager::Instance->LoadData("price", price, (uint16_t)0);
|
||||||
if (price > 0) {
|
if (price > 0) {
|
||||||
// Technically an item with a custom price (scrub/shopsanity) could have
|
// Technically an item with a custom price (scrub/shopsanity) could have
|
||||||
@ -385,11 +385,11 @@ void SaveManager::LoadRandomizerVersion3() {
|
|||||||
SaveManager::Instance->LoadStruct("", [&]() {
|
SaveManager::Instance->LoadStruct("", [&]() {
|
||||||
RandomizerHintKey rhk = RH_NONE;
|
RandomizerHintKey rhk = RH_NONE;
|
||||||
SaveManager::Instance->LoadData("hintKey", rhk);
|
SaveManager::Instance->LoadData("hintKey", rhk);
|
||||||
std::string english, french;
|
std::string english, french, german;
|
||||||
SaveManager::Instance->LoadStruct("hintText", [&]() {
|
SaveManager::Instance->LoadStruct("hintText", [&]() {
|
||||||
SaveManager::Instance->LoadData("english", english);
|
SaveManager::Instance->LoadData("english", english);
|
||||||
SaveManager::Instance->LoadData("french", french);
|
SaveManager::Instance->LoadData("french", french);
|
||||||
// TODO: German Hint Translations
|
SaveManager::Instance->LoadData("german", german);
|
||||||
});
|
});
|
||||||
RandomizerCheck rc = RC_UNKNOWN_CHECK;
|
RandomizerCheck rc = RC_UNKNOWN_CHECK;
|
||||||
SaveManager::Instance->LoadData("hintedCheck", rc);
|
SaveManager::Instance->LoadData("hintedCheck", rc);
|
||||||
@ -397,7 +397,7 @@ void SaveManager::LoadRandomizerVersion3() {
|
|||||||
SaveManager::Instance->LoadData("hintType", ht);
|
SaveManager::Instance->LoadData("hintType", ht);
|
||||||
RandomizerArea savedArea;
|
RandomizerArea savedArea;
|
||||||
SaveManager::Instance->LoadData("hintedArea", savedArea);
|
SaveManager::Instance->LoadData("hintedArea", savedArea);
|
||||||
randoContext->AddHint(rhk, Text(english, french, english), rc, ht, "Unknown", savedArea);//RANDOTODO, maybe store and load distrabution, but it's a string...
|
randoContext->AddHint(rhk, Text(english, french, /*spanish*/"", german), rc, ht, "Unknown", savedArea);//RANDOTODO, maybe store and load distrabution, but it's a string...
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -479,8 +479,7 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
|
|||||||
SaveManager::Instance->SaveStruct("hintText", [&]() {
|
SaveManager::Instance->SaveStruct("hintText", [&]() {
|
||||||
SaveManager::Instance->SaveData("english", hint->GetText().GetEnglish());
|
SaveManager::Instance->SaveData("english", hint->GetText().GetEnglish());
|
||||||
SaveManager::Instance->SaveData("french", hint->GetText().GetFrench());
|
SaveManager::Instance->SaveData("french", hint->GetText().GetFrench());
|
||||||
SaveManager::Instance->SaveData("german", hint->GetText().GetEnglish());
|
SaveManager::Instance->SaveData("german", hint->GetText().GetGerman());
|
||||||
// TODO: German Translation of hints
|
|
||||||
});
|
});
|
||||||
SaveManager::Instance->SaveData("hintedCheck", hint->GetHintedLocation());
|
SaveManager::Instance->SaveData("hintedCheck", hint->GetHintedLocation());
|
||||||
SaveManager::Instance->SaveData("hintType", hint->GetHintType());
|
SaveManager::Instance->SaveData("hintType", hint->GetHintType());
|
||||||
@ -1113,13 +1112,13 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se
|
|||||||
if (std::filesystem::exists(fileName)) {
|
if (std::filesystem::exists(fileName)) {
|
||||||
std::filesystem::remove(fileName);
|
std::filesystem::remove(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||||
copy_file(tempFile.c_str(), fileName.c_str());
|
copy_file(tempFile.c_str(), fileName.c_str());
|
||||||
#else
|
#else
|
||||||
std::filesystem::copy_file(tempFile, fileName);
|
std::filesystem::copy_file(tempFile, fileName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (std::filesystem::exists(tempFile)) {
|
if (std::filesystem::exists(tempFile)) {
|
||||||
std::filesystem::remove(tempFile);
|
std::filesystem::remove(tempFile);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user