mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-01 13:52:19 -05:00
Merge branch 'develop-rando' of garrettjoecox.github.com:HarbourMasters/Shipwright into develop-rando-changes
This commit is contained in:
commit
0aad8d4491
@ -3,7 +3,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <map>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <variables.h>
|
||||||
|
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
|
|
||||||
@ -14,9 +16,10 @@ static const std::unordered_map<std::string, char> textBoxSpecialCharacters = {
|
|||||||
{ "è", 0x95 }, { "é", 0x96 }, { "ê", 0x97 }, { "ë", 0x98 }, { "ï", 0x99 }, { "ô", 0x9A }, { "ö", 0x9B },
|
{ "è", 0x95 }, { "é", 0x96 }, { "ê", 0x97 }, { "ë", 0x98 }, { "ï", 0x99 }, { "ô", 0x9A }, { "ö", 0x9B },
|
||||||
{ "ù", 0x9C }, { "û", 0x9D }, { "ü", 0x9E }
|
{ "ù", 0x9C }, { "û", 0x9D }, { "ü", 0x9E }
|
||||||
};
|
};
|
||||||
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, std::string> percentColors = { { "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 = {
|
static const std::unordered_map<std::string, ItemID> altarIcons = {
|
||||||
{ "0", ITEM_KOKIRI_EMERALD },
|
{ "0", ITEM_KOKIRI_EMERALD },
|
||||||
{ "1", ITEM_GORON_RUBY },
|
{ "1", ITEM_GORON_RUBY },
|
||||||
@ -33,61 +36,190 @@ static const std::unordered_map<std::string, ItemID> altarIcons = {
|
|||||||
{ "c", ITEM_OCARINA_FAIRY },
|
{ "c", ITEM_OCARINA_FAIRY },
|
||||||
{ "i", ITEM_OCARINA_TIME },
|
{ "i", ITEM_OCARINA_TIME },
|
||||||
{ "L", ITEM_BOW_ARROW_LIGHT },
|
{ "L", ITEM_BOW_ARROW_LIGHT },
|
||||||
{ "k", ITEM_TUNIC_KOKIRI }
|
{ "k", ITEM_TUNIC_KOKIRI },
|
||||||
|
{ "m", ITEM_DUNGEON_MAP },
|
||||||
|
{ "C", ITEM_COMPASS },
|
||||||
|
{ "s", ITEM_SKULL_TOKEN },
|
||||||
|
{ "g", ITEM_MASK_GORON }
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, int> pixelWidthTable = {
|
||||||
|
{ " ", 6 }, { "!", 6 }, { "\"", 5 }, { "#", 7 }, { "$", 7 }, { "%", 11 }, { "&", 9 }, { "\'", 3 },
|
||||||
|
{ "(", 6 }, { ")", 6 }, { "*", 6 }, { "+", 7 }, { ",", 3 }, { "-", 5 }, { ".", 3 }, { "/", 7 },
|
||||||
|
{ "0", 8 }, { "1", 4 }, { "2", 7 }, { "3", 7 }, { "4", 8 }, { "5", 7 }, { "6", 7 }, { "7", 7 },
|
||||||
|
{ "8", 7 }, { "9", 7 }, { ":", 5 }, { ";", 5 }, { "<", 7 }, { "=", 9 }, { ">", 7 }, { "?", 9 },
|
||||||
|
{ "@", 10 }, { "A", 9 }, { "B", 7 }, { "C", 9 }, { "D", 9 }, { "E", 6 }, { "F", 6 }, { "G", 9 },
|
||||||
|
{ "H", 8 }, { "I", 3 }, { "J", 6 }, { "K", 8 }, { "L", 6 }, { "M", 10 }, { "N", 9 }, { "O", 10 },
|
||||||
|
{ "P", 7 }, { "Q", 10 }, { "R", 8 }, { "S", 8 }, { "T", 7 }, { "U", 8 }, { "V", 9 }, { "W", 12 },
|
||||||
|
{ "X", 9 }, { "Y", 8 }, { "Z", 8 }, { "[", 6 }, { "\\", 8 }, { "]", 6 }, { "^", 8 }, { "_", 7 },
|
||||||
|
{ "`", 4 }, { "a", 6 }, { "b", 7 }, { "c", 6 }, { "d", 7 }, { "e", 7 }, { "f", 5 }, { "g", 7 },
|
||||||
|
{ "h", 6 }, { "i", 3 }, { "j", 5 }, { "k", 6 }, { "l", 3 }, { "m", 9 }, { "n", 7 }, { "o", 7 },
|
||||||
|
{ "p", 7 }, { "q", 7 }, { "r", 6 }, { "s", 6 }, { "t", 6 }, { "u", 6 }, { "v", 7 }, { "w", 9 },
|
||||||
|
{ "x", 6 }, { "y", 7 }, { "z", 6 }, { "{", 6 }, { "¦", 4 }, { "}", 6 }, { "¡", 5 }, { "¢", 7 },
|
||||||
|
{ "£", 8 }, { "¤", 7 }, { "¥", 8 }, { "|", 4 }, { "§", 12 }, { "¨", 12 }, { "©", 10 }, { "ª", 5 },
|
||||||
|
{ "«", 8 }, { "¬", 7 }, { "\u00AD", 6 }, { "®", 10 }, { "¯", 8 }, { "°", 12 }, { "±", 12 }, { "²", 5 },
|
||||||
|
{ "³", 5 }, { "µ", 6 }, { "¶", 8 }, { "·", 4 }, { "¹", 4 }, { "º", 5 }, { "»", 9 }, { "¼", 9 },
|
||||||
|
{ "½", 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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
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_)
|
||||||
: english(std::move(english_)), german(std::move(german_)), french(std::move(french_)), type(type_),
|
: type(type_), position(position_){
|
||||||
position(position_) {
|
messages[LANGUAGE_ENG] = std::move(english_);
|
||||||
|
messages[LANGUAGE_GER] = std::move(german_);
|
||||||
|
messages[LANGUAGE_FRA] = std::move(french_);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, std::vector<std::string> colors_,
|
||||||
|
std::vector<bool> capital_, TextBoxType type_, TextBoxPosition position_) {
|
||||||
|
messages[LANGUAGE_ENG] = std::move(english_);
|
||||||
|
messages[LANGUAGE_GER] = std::move(german_);
|
||||||
|
messages[LANGUAGE_FRA] = std::move(french_);
|
||||||
|
colors = colors_;
|
||||||
|
capital = capital_;
|
||||||
|
type = type_;
|
||||||
|
position = position_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMessage::CustomMessage(std::string english_, TextBoxType type_, TextBoxPosition position_)
|
||||||
|
: type(type_), position(position_) {
|
||||||
|
messages[LANGUAGE_ENG] = std::move(english_);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMessage::CustomMessage(std::string english_, std::vector<std::string> colors_, std::vector<bool> capital_, TextBoxType type_, TextBoxPosition position_){
|
||||||
|
messages[LANGUAGE_ENG] = std::move(english_);
|
||||||
|
colors = colors_;
|
||||||
|
capital = capital_;
|
||||||
|
type = type_;
|
||||||
|
position = position_;
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage::CustomMessage(Text text, TextBoxType type_,TextBoxPosition position_)
|
CustomMessage::CustomMessage(Text text, TextBoxType type_,TextBoxPosition position_)
|
||||||
: english(text.GetEnglish()), german(text.GetGerman()), french(text.GetFrench()), type(type_),
|
: type(type_), position(position_) {
|
||||||
position(position_) {
|
messages[LANGUAGE_ENG] = text.GetEnglish();
|
||||||
|
messages[LANGUAGE_GER] = text.GetGerman();
|
||||||
|
messages[LANGUAGE_FRA] = text.GetFrench();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& CustomMessage::GetEnglish() const {
|
const std::string CustomMessage::GetEnglish(MessageFormat format) const {
|
||||||
return english;
|
return GetForLanguage(LANGUAGE_ENG, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& CustomMessage::GetFrench() const {
|
const std::string CustomMessage::GetGerman(MessageFormat format) const {
|
||||||
if (french.length() > 0) {
|
return GetForLanguage(LANGUAGE_GER, format);
|
||||||
return french;
|
|
||||||
}
|
|
||||||
return english;
|
|
||||||
}
|
}
|
||||||
const std::string& CustomMessage::GetGerman() const {
|
|
||||||
if (german.length() > 0) {
|
const std::string CustomMessage::GetFrench(MessageFormat format) const {
|
||||||
return german;
|
return GetForLanguage(LANGUAGE_FRA, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const {
|
||||||
|
return GetForLanguage(gSaveContext.language, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const {
|
||||||
|
std::string output = messages[language].length() > 0 ? messages[language] : messages[LANGUAGE_ENG];
|
||||||
|
ProcessMessageFormat(output, format);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> CustomMessage::GetAllMessages(MessageFormat format) const{
|
||||||
|
std::vector<std::string> output = messages;
|
||||||
|
for (auto str : output){
|
||||||
|
ProcessMessageFormat(str, format);
|
||||||
}
|
}
|
||||||
return english;
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::ProcessMessageFormat(std::string& str, MessageFormat format) const {
|
||||||
|
if (format == MF_FORMATTED){
|
||||||
|
FormatString(str);
|
||||||
|
} else if (format == MF_CLEAN){
|
||||||
|
CleanString(str);
|
||||||
|
} else if (format == MF_AUTO_FORMAT){
|
||||||
|
AutoFormatString(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<bool>& CustomMessage::GetCapital() const {
|
||||||
|
return capital;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::SetCapital(std::vector<bool> capital_){
|
||||||
|
capital = capital_;
|
||||||
|
}
|
||||||
|
const std::vector<std::string>& CustomMessage::GetColors() const {
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::SetColors(std::vector<std::string> colors_){
|
||||||
|
colors = colors_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TextBoxType& CustomMessage::GetTextBoxType() const {
|
const TextBoxType& CustomMessage::GetTextBoxType() const {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CustomMessage::SetTextBoxType(TextBoxType boxType){
|
||||||
|
type = boxType;
|
||||||
|
}
|
||||||
|
|
||||||
const TextBoxPosition& CustomMessage::GetTextBoxPosition() const {
|
const TextBoxPosition& CustomMessage::GetTextBoxPosition() const {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage CustomMessage::operator+(const CustomMessage& right) const {
|
CustomMessage CustomMessage::operator+(const CustomMessage& right) const {
|
||||||
return CustomMessage(english + right.GetEnglish(), german + right.GetGerman(), french + right.GetFrench());
|
std::vector<std::string> newColors = colors;
|
||||||
|
std::vector<std::string> rColors = right.GetColors();
|
||||||
|
for (auto color: rColors){
|
||||||
|
newColors.push_back(color);
|
||||||
|
}
|
||||||
|
std::vector<bool> newCapital = capital;
|
||||||
|
newCapital.insert(capital.end(), right.GetCapital().begin(), right.GetCapital().end());
|
||||||
|
return CustomMessage(messages[LANGUAGE_ENG] + right.GetEnglish(MF_RAW),
|
||||||
|
messages[LANGUAGE_GER] + right.GetGerman(MF_RAW),
|
||||||
|
messages[LANGUAGE_FRA] + right.GetFrench(MF_RAW),
|
||||||
|
newColors, newCapital, type, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage CustomMessage::operator+(const std::string& right) const {
|
CustomMessage CustomMessage::operator+(const std::string& right) const {
|
||||||
return CustomMessage(english + right, german + right, french + right);
|
return CustomMessage(messages[LANGUAGE_ENG] + right, messages[LANGUAGE_GER] + right, messages[LANGUAGE_FRA] + right);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::operator+=(const CustomMessage& right) {
|
||||||
|
messages[LANGUAGE_ENG] += right.GetEnglish(MF_RAW);
|
||||||
|
messages[LANGUAGE_GER] += right.GetGerman(MF_RAW);
|
||||||
|
messages[LANGUAGE_FRA] += right.GetFrench(MF_RAW);
|
||||||
|
colors.insert(colors.end(), right.GetColors().begin(), right.GetColors().end());
|
||||||
|
capital.insert(capital.end(), right.GetCapital().begin(), right.GetCapital().end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::operator+=(const std::string& right) {
|
void CustomMessage::operator+=(const std::string& right) {
|
||||||
english += right;
|
messages[LANGUAGE_ENG] += right;
|
||||||
french += right;
|
messages[LANGUAGE_GER] += right;
|
||||||
german += right;
|
messages[LANGUAGE_FRA] += right;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CustomMessage::operator==(const CustomMessage& operand) const {
|
bool CustomMessage::operator==(const CustomMessage& operand) const {
|
||||||
return english == operand.english;
|
return messages[LANGUAGE_ENG] == operand.messages[LANGUAGE_ENG];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomMessage::operator==(const std::string& operand) const {
|
||||||
|
for (auto str: messages){
|
||||||
|
if (str == operand){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CustomMessage::operator!=(const CustomMessage& operand) const {
|
bool CustomMessage::operator!=(const CustomMessage& operand) const {
|
||||||
@ -95,85 +227,211 @@ bool CustomMessage::operator!=(const CustomMessage& operand) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::Replace(std::string&& oldStr, std::string&& newStr) {
|
void CustomMessage::Replace(std::string&& oldStr, std::string&& newStr) {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
for (std::string& str : messages) {
|
||||||
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);
|
||||||
position = str->find(oldStr);
|
position = str.find(oldStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Format();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman,
|
void CustomMessage::Replace(std::string&& oldStr, CustomMessage newMessage) {
|
||||||
std::string&& newFrench) {
|
for (uint8_t language = 0; language < LANGUAGE_MAX; language++) {
|
||||||
size_t position = 0;
|
size_t position = messages[language].find(oldStr);
|
||||||
position = english.find(oldStr);
|
|
||||||
while (position != std::string::npos) {
|
while (position != std::string::npos) {
|
||||||
english.replace(position, oldStr.length(), newEnglish);
|
messages[language].replace(position, oldStr.length(), newMessage.messages[language]);
|
||||||
position = english.find(oldStr);
|
position = messages[language].find(oldStr);
|
||||||
}
|
}
|
||||||
position = french.find(oldStr);
|
|
||||||
while (position != std::string::npos) {
|
|
||||||
french.replace(position, oldStr.length(), newFrench);
|
|
||||||
position = french.find(oldStr);
|
|
||||||
}
|
}
|
||||||
position = german.find(oldStr);
|
|
||||||
while (position != std::string::npos) {
|
|
||||||
german.replace(position, oldStr.length(), newGerman);
|
|
||||||
position = german.find(oldStr);
|
|
||||||
}
|
|
||||||
Format();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::Format(ItemID iid) {
|
void CustomMessage::Format(ItemID iid) {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
for (std::string &str : messages) {
|
||||||
str->insert(0, ITEM_OBTAINED(iid));
|
str.insert(0, ITEM_OBTAINED(iid));
|
||||||
size_t start_pos = 0;
|
size_t start_pos = 0;
|
||||||
std::replace(str->begin(), str->end(), '&', NEWLINE()[0]);
|
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
|
||||||
while ((start_pos = str->find('^', start_pos)) != std::string::npos) {
|
while ((start_pos = str.find('^', start_pos)) != std::string::npos) {
|
||||||
str->replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid));
|
str.replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid));
|
||||||
start_pos += 3;
|
start_pos += 3;
|
||||||
}
|
}
|
||||||
std::replace(str->begin(), str->end(), '@', PLAYER_NAME()[0]);
|
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
|
||||||
|
ReplaceSpecialCharacters(str);
|
||||||
|
ReplaceColors(str);
|
||||||
|
ReplaceAltarIcons(str);
|
||||||
}
|
}
|
||||||
ReplaceSpecialCharacters();
|
|
||||||
ReplaceColors();
|
|
||||||
ReplaceAltarIcons();
|
|
||||||
*this += MESSAGE_END();
|
*this += MESSAGE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::Format() {
|
void CustomMessage::Format() {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
for (std::string& str : messages) {
|
||||||
std::replace(str->begin(), str->end(), '&', NEWLINE()[0]);
|
FormatString(str);
|
||||||
std::replace(str->begin(), str->end(), '^', WAIT_FOR_INPUT()[0]);
|
|
||||||
std::replace(str->begin(), str->end(), '@', PLAYER_NAME()[0]);
|
|
||||||
}
|
}
|
||||||
ReplaceSpecialCharacters();
|
|
||||||
ReplaceColors();
|
|
||||||
ReplaceAltarIcons();
|
|
||||||
*this += MESSAGE_END();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CustomMessage::AutoFormat() {
|
||||||
|
for (std::string& str : messages) {
|
||||||
|
AutoFormatString(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::Clean() {
|
||||||
|
for (std::string& str : messages) {
|
||||||
|
CleanString(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::FormatString(std::string& str) const {
|
||||||
|
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
|
||||||
|
std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]);
|
||||||
|
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
|
||||||
|
ReplaceSpecialCharacters(str);
|
||||||
|
ReplaceColors(str);
|
||||||
|
ReplaceAltarIcons(str);
|
||||||
|
str += MESSAGE_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteControlCode(std::string& str, std::string code){
|
||||||
|
size_t start_pos = 0;
|
||||||
|
while ((start_pos = str.find(code, start_pos)) != std::string::npos) {
|
||||||
|
str.replace(start_pos, code.length(), "");
|
||||||
|
start_pos += code.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::CleanString(std::string& str) const {
|
||||||
|
std::replace(str.begin(), str.end(), '&', "\n"[0]);
|
||||||
|
std::replace(str.begin(), str.end(), '^', " "[0]);
|
||||||
|
for (const auto& colorPair : percentColors) {
|
||||||
|
DeleteControlCode(str, "%" + colorPair.first);
|
||||||
|
}
|
||||||
|
std::erase(str, '#');
|
||||||
|
for (const auto& iconPair : altarIcons) {
|
||||||
|
DeleteControlCode(str, "$" + iconPair.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::AutoFormatString(std::string& str) const {// did I do this right?
|
||||||
|
ReplaceAltarIcons(str);
|
||||||
|
ReplaceColors(str);
|
||||||
|
// insert newlines either manually or when encountering a '&'
|
||||||
|
size_t lastNewline = 0;
|
||||||
|
const bool hasIcon = str.find('$', 0) != std::string::npos;
|
||||||
|
size_t lineLength = NextLineLength(&str, lastNewline, hasIcon);
|
||||||
|
while (lastNewline + lineLength < str.length()) {
|
||||||
|
const size_t carrot = str.find('^', lastNewline);
|
||||||
|
const size_t ampersand = str.find('&', lastNewline);
|
||||||
|
const size_t lastSpace = str.rfind(' ', lastNewline + lineLength);
|
||||||
|
const size_t lastPeriod = str.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) {
|
||||||
|
str.replace(lastPeriod, 1, ".&");
|
||||||
|
lastNewline = lastPeriod + 2;
|
||||||
|
} else {
|
||||||
|
str.replace(lastSpace, 1, "&");
|
||||||
|
lastNewline = lastSpace + 1;
|
||||||
|
}
|
||||||
|
lineLength = NextLineLength(&str, lastNewline, hasIcon);
|
||||||
|
}
|
||||||
|
ReplaceSpecialCharacters(str);
|
||||||
|
ReplaceAltarIcons(str);
|
||||||
|
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
|
||||||
|
std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]);
|
||||||
|
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
|
||||||
|
str += MESSAGE_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::InsertNumber(uint8_t num){
|
||||||
|
for (std::string& str : messages) {
|
||||||
|
size_t firstBar = str.find('|');
|
||||||
|
if (firstBar != std::string::npos) {
|
||||||
|
size_t secondBar = str.find('|', firstBar + 1);
|
||||||
|
if (secondBar != std::string::npos) {
|
||||||
|
size_t thirdBar = str.find('|', secondBar + 1);
|
||||||
|
if (thirdBar != std::string::npos) {
|
||||||
|
if (num == 1) {
|
||||||
|
str.erase(secondBar, thirdBar - secondBar);
|
||||||
|
} else {
|
||||||
|
str.erase(firstBar, secondBar - firstBar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//remove the remaining bar
|
||||||
|
this->Replace("|", "");
|
||||||
|
Replace("[[d]]", std::to_string(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CustomMessage::Capitalize() {
|
void CustomMessage::Capitalize() {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
for (std::string str : messages) {
|
||||||
(*str)[0] = std::toupper((*str)[0]);
|
(str)[0] = std::toupper((str)[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::ReplaceSpecialCharacters() {
|
void CustomMessage::ReplaceSpecialCharacters(std::string& str) const {
|
||||||
// add special characters
|
// add special characters
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
|
||||||
for (auto specialCharacterPair : textBoxSpecialCharacters) {
|
for (auto specialCharacterPair : textBoxSpecialCharacters) {
|
||||||
size_t start_pos = 0;
|
size_t start_pos = 0;
|
||||||
std::string textBoxSpecialCharacterString = ""s;
|
std::string textBoxSpecialCharacterString = ""s;
|
||||||
textBoxSpecialCharacterString += specialCharacterPair.second;
|
textBoxSpecialCharacterString += specialCharacterPair.second;
|
||||||
while ((start_pos = str->find(specialCharacterPair.first, start_pos)) != std::string::npos) {
|
while ((start_pos = str.find(specialCharacterPair.first, start_pos)) != std::string::npos) {
|
||||||
str->replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString);
|
str.replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString);
|
||||||
start_pos += textBoxSpecialCharacterString.length();
|
start_pos += textBoxSpecialCharacterString.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Interface_ReplaceSpecialCharacters(char text[]) {
|
const char* Interface_ReplaceSpecialCharacters(char text[]) {
|
||||||
@ -194,31 +452,49 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) {
|
|||||||
return textChar;
|
return textChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::ReplaceColors() {
|
void CustomMessage::ReplaceColors(std::string& str) const {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
for (const auto& colorPair : percentColors) {
|
||||||
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;
|
||||||
while ((start_pos = str->find(textToReplace, start_pos)) != std::string::npos) {
|
while ((start_pos = str.find(textToReplace, start_pos)) != std::string::npos) {
|
||||||
str->replace(start_pos, textToReplace.length(), COLOR(colorPair.second));
|
str.replace(start_pos, textToReplace.length(), COLOR(colorPair.second));
|
||||||
start_pos += textToReplace.length();
|
start_pos += textToReplace.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto color: colors) {
|
||||||
|
if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) {
|
||||||
|
str.replace(firstHashtag, 1, COLOR(color));
|
||||||
|
if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) {
|
||||||
|
str.replace(secondHashtag, 1, COLOR(QM_WHITE));
|
||||||
|
} else {
|
||||||
|
SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", str);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove any remaining '#' characters.
|
||||||
|
std::erase(str, '#');
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomMessage::ReplaceAltarIcons() {
|
void CustomMessage::ReplaceAltarIcons(std::string& str) const {
|
||||||
for (std::string* str : { &english, &french, &german }) {
|
|
||||||
for (const auto& iconPair : altarIcons) {
|
for (const auto& iconPair : altarIcons) {
|
||||||
std::string textToReplace = "$";
|
std::string textToReplace = "$";
|
||||||
textToReplace += iconPair.first;
|
textToReplace += iconPair.first;
|
||||||
size_t start_pos = 0;
|
size_t start_pos = 0;
|
||||||
while ((start_pos = str->find(textToReplace, start_pos)) != std::string::npos) {
|
while ((start_pos = str.find(textToReplace, start_pos)) != std::string::npos) {
|
||||||
str->replace(start_pos, textToReplace.length(), ITEM_OBTAINED(iconPair.second));
|
str.replace(start_pos, textToReplace.length(), ITEM_OBTAINED(iconPair.second));
|
||||||
start_pos += textToReplace.length();
|
start_pos += textToReplace.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomMessage::InsertNames(std::vector<CustomMessage> toInsert){
|
||||||
|
for(uint8_t a = 0; a < toInsert.size(); a++){
|
||||||
|
CustomMessage temp = toInsert[a];
|
||||||
|
if ((capital.size() > a) && (capital[a] = true)){
|
||||||
|
temp.Capitalize();
|
||||||
|
}
|
||||||
|
Replace("[[" + std::to_string(a+1) + "]]", temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +510,12 @@ std::string CustomMessage::NEWLINE() {
|
|||||||
return "\x01"s;
|
return "\x01"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CustomMessage::COLOR(uint8_t x) {
|
std::string CustomMessage::COLOR(std::string x) {
|
||||||
return "\x05"s + char(x);
|
return "\x05"s + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CustomMessage::POINTS(std::string x) {
|
||||||
|
return "\x1E"s + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CustomMessage::WAIT_FOR_INPUT() {
|
std::string CustomMessage::WAIT_FOR_INPUT() {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "../../../include/z64item.h"
|
#include "../../../include/z64item.h"
|
||||||
#include "../../../include/message_data_textbox_types.h"
|
#include "../../../include/message_data_textbox_types.h"
|
||||||
@ -10,14 +11,23 @@
|
|||||||
|
|
||||||
#undef MESSAGE_END
|
#undef MESSAGE_END
|
||||||
|
|
||||||
#define QM_WHITE 0x00
|
#define QM_WHITE "\x00"s
|
||||||
#define QM_RED 0x41
|
#define QM_RED "\x41"
|
||||||
#define QM_GREEN 0x42
|
#define QM_GREEN "\x42"
|
||||||
#define QM_BLUE 0x43
|
#define QM_BLUE "\x43"
|
||||||
#define QM_LBLUE 0x44
|
#define QM_LBLUE "\x44"
|
||||||
#define QM_PINK 0x45
|
#define QM_PINK "\x45"
|
||||||
#define QM_YELLOW 0x46
|
#define QM_YELLOW "\x46"
|
||||||
#define QM_BLACK 0x47
|
#define QM_BLACK "\x47"
|
||||||
|
|
||||||
|
#define HS_HORSE_ARCHERY "\x00"s //HS_HBA is an enum already
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MF_FORMATTED,
|
||||||
|
MF_CLEAN,
|
||||||
|
MF_RAW,
|
||||||
|
MF_AUTO_FORMAT
|
||||||
|
} MessageFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encapsulates logic surrounding languages, and formatting strings for OoT's textboxes and
|
* @brief Encapsulates logic surrounding languages, and formatting strings for OoT's textboxes and
|
||||||
@ -30,25 +40,41 @@ class CustomMessage {
|
|||||||
CustomMessage() = default;
|
CustomMessage() = default;
|
||||||
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);
|
||||||
|
CustomMessage(std::string english_, std::string german_, std::string french_, std::vector<std::string> colors_, std::vector<bool> capital_ = {},
|
||||||
|
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||||
|
CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||||
|
CustomMessage(std::string english_, std::vector<std::string> colors_, std::vector<bool> capital_ = {}, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||||
CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||||
|
|
||||||
static std::string MESSAGE_END() ;
|
static std::string MESSAGE_END() ;
|
||||||
static std::string ITEM_OBTAINED(uint8_t x) ;
|
static std::string ITEM_OBTAINED(uint8_t x) ;
|
||||||
static std::string NEWLINE() ;
|
static std::string NEWLINE() ;
|
||||||
static std::string COLOR(uint8_t x) ;
|
static std::string COLOR(std::string x) ;
|
||||||
|
static std::string POINTS(std::string x) ;//HIGH_SCORE is also a macro
|
||||||
static std::string WAIT_FOR_INPUT() ;
|
static std::string WAIT_FOR_INPUT() ;
|
||||||
static std::string PLAYER_NAME() ;
|
static std::string PLAYER_NAME() ;
|
||||||
|
|
||||||
const std::string& GetEnglish() const;
|
const std::string GetEnglish(MessageFormat format = MF_FORMATTED) const;
|
||||||
const std::string& GetFrench() const;
|
const std::string GetFrench(MessageFormat format = MF_FORMATTED) const;
|
||||||
const std::string& GetGerman() const;
|
const std::string GetGerman(MessageFormat format = MF_FORMATTED) const;
|
||||||
|
const std::string GetForCurrentLanguage(MessageFormat format = MF_FORMATTED) const;
|
||||||
|
const std::string GetForLanguage(uint8_t language, MessageFormat format = MF_FORMATTED) const;
|
||||||
|
const std::vector<std::string> GetAllMessages(MessageFormat format = MF_FORMATTED) const;
|
||||||
|
void ProcessMessageFormat(std::string& str, MessageFormat format) const;
|
||||||
|
const std::vector<std::string>& GetColors() const;
|
||||||
|
void SetColors(std::vector<std::string> colors_);
|
||||||
|
const std::vector<bool>& GetCapital() const;
|
||||||
|
void SetCapital(std::vector<bool> capital_);
|
||||||
const TextBoxType& GetTextBoxType() const;
|
const TextBoxType& GetTextBoxType() const;
|
||||||
|
void SetTextBoxType(TextBoxType boxType);
|
||||||
const TextBoxPosition& GetTextBoxPosition() const;
|
const TextBoxPosition& GetTextBoxPosition() const;
|
||||||
|
|
||||||
CustomMessage operator+(const CustomMessage& right) const;
|
CustomMessage operator+(const CustomMessage& right) const;
|
||||||
CustomMessage operator+(const std::string& right) const;
|
CustomMessage operator+(const std::string& right) const;
|
||||||
void operator+=(const std::string& right);
|
void operator+=(const std::string& right);
|
||||||
bool operator==(const CustomMessage& right) const;
|
void operator+=(const CustomMessage& right);
|
||||||
|
bool operator==(const CustomMessage& operand) const;
|
||||||
|
bool operator==(const std::string& operand) const;
|
||||||
bool operator!=(const CustomMessage& right) const;
|
bool operator!=(const CustomMessage& right) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,15 +89,13 @@ class CustomMessage {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Finds an instance of oldStr in each language of the CustomMessage,
|
* @brief Finds an instance of oldStr in each language of the CustomMessage,
|
||||||
* and replaces it with the corresponding new string provided for each language.
|
* and replaces it with the corresponding string in the provided CustomMessage.
|
||||||
* Typically used for dynamic variable replacement (i.e. gameplay stats, skulltula count)
|
* Typically used for dynamic variable replacement (i.e. gameplay stats, skulltula count)
|
||||||
*
|
*
|
||||||
* @param oldStr the string to be replaced
|
* @param oldStr the string to be replaced
|
||||||
* @param newEnglish the new string for the English message
|
* @param newMessage the message containing the new strings.
|
||||||
* @param newGerman the new string for the German message
|
|
||||||
* @param newFrench the new string for the French message
|
|
||||||
*/
|
*/
|
||||||
void Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman, std::string&& newFrench);
|
void Replace(std::string&& oldStr, CustomMessage newMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Capitalizes the first letter of the string for each language.
|
* @brief Capitalizes the first letter of the string for each language.
|
||||||
@ -82,17 +106,22 @@ class CustomMessage {
|
|||||||
* @brief Replaces special characters (things like diacritics for non-english langugages)
|
* @brief Replaces special characters (things like diacritics for non-english langugages)
|
||||||
* with the control codes used to display them in OoT's textboxes.
|
* with the control codes used to display them in OoT's textboxes.
|
||||||
*/
|
*/
|
||||||
void ReplaceSpecialCharacters();
|
void ReplaceSpecialCharacters(std::string& str) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replaces our color variable strings with the OoT control codes.
|
* @brief Replaces our color variable strings with the OoT control codes.
|
||||||
*/
|
*/
|
||||||
void ReplaceColors();
|
void ReplaceColors(std::string& str) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replaces `$<char>` variable strings with OoT control codes.
|
* @brief Replaces `$<char>` variable strings with OoT control codes.
|
||||||
*/
|
*/
|
||||||
void ReplaceAltarIcons();
|
void ReplaceAltarIcons(std::string& str) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces [[1]] style variable strings with the provided vector of customMessages
|
||||||
|
*/
|
||||||
|
void InsertNames(std::vector<CustomMessage> toInsert);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replaces various symbols with the control codes necessary to
|
* @brief Replaces various symbols with the control codes necessary to
|
||||||
@ -103,6 +132,15 @@ class CustomMessage {
|
|||||||
*/
|
*/
|
||||||
void Format(ItemID iid);
|
void Format(ItemID iid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces [[d]] in text with the supplied number, and if plural
|
||||||
|
* options exist (2 blocks of text surrounded by |) choose the former if it 1,
|
||||||
|
* and the latter otherwise, deleting the other and the |'s.
|
||||||
|
*
|
||||||
|
* @param num the number to insert.
|
||||||
|
*/
|
||||||
|
void InsertNumber(uint8_t num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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,
|
||||||
@ -110,12 +148,44 @@ class CustomMessage {
|
|||||||
*/
|
*/
|
||||||
void Format();
|
void Format();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief formats the message specifically to fit in OoT's
|
||||||
|
* textboxes, and use it's formatting.
|
||||||
|
*/
|
||||||
|
void AutoFormat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes all OoT formatting from the message,
|
||||||
|
* making it a good form for writing into spoiler logs.
|
||||||
|
*/
|
||||||
|
void Clean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces various symbols with the control codes necessary to
|
||||||
|
* display them in OoT's textboxes for a single string
|
||||||
|
* . i.e. special characters, colors, newlines, wait for input, etc.
|
||||||
|
*/
|
||||||
|
void FormatString(std::string& str) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief formats the string specifically to fit in OoT's
|
||||||
|
* textboxes, and use it's formatting.
|
||||||
|
* RANDOTODO whoever knows exactly what this does check my adaption
|
||||||
|
*/
|
||||||
|
void AutoFormatString(std::string& str) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes symbols used for control codes from the string,
|
||||||
|
* leaving raw text
|
||||||
|
*/
|
||||||
|
void CleanString(std::string& str) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string english = "";
|
std::vector<std::string> messages = {"","",""};
|
||||||
std::string french = "";
|
|
||||||
std::string german = "";
|
|
||||||
TextBoxType type = TEXTBOX_TYPE_BLACK;
|
TextBoxType type = TEXTBOX_TYPE_BLACK;
|
||||||
TextBoxPosition position = TEXTBOX_POS_BOTTOM;
|
TextBoxPosition position = TEXTBOX_POS_BOTTOM;
|
||||||
|
std::vector<std::string> colors = {};
|
||||||
|
std::vector<bool> capital = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unordered_map<uint16_t, CustomMessage> CustomMessageTable;
|
typedef std::unordered_map<uint16_t, CustomMessage> CustomMessageTable;
|
||||||
|
@ -100,6 +100,7 @@ typedef enum {
|
|||||||
TEXT_MALON_LINK_HAS_TIME_BUT_NO_RECORD = 0x2090,
|
TEXT_MALON_LINK_HAS_TIME_BUT_NO_RECORD = 0x2090,
|
||||||
TEXT_MALON_LINK_HAS_RECORD = 0x2091,
|
TEXT_MALON_LINK_HAS_RECORD = 0x2091,
|
||||||
TEXT_MALON_FIRST_BEAT_THIS_RECORD = 0x2092,
|
TEXT_MALON_FIRST_BEAT_THIS_RECORD = 0x2092,
|
||||||
|
TEXT_BIGGORON_I_MAAAADE_THISSSS = 0x3002,
|
||||||
TEXT_MEDIGORON = 0x304C,
|
TEXT_MEDIGORON = 0x304C,
|
||||||
TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME = 0x3052,
|
TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME = 0x3052,
|
||||||
TEXT_BIGGORON_BETTER_AT_SMITHING = 0x3053,
|
TEXT_BIGGORON_BETTER_AT_SMITHING = 0x3053,
|
||||||
|
@ -204,16 +204,7 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan
|
|||||||
const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId);
|
const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId);
|
||||||
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
|
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case LANGUAGE_FRA:
|
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize);
|
||||||
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetFrench(), maxBufferSize);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_GER:
|
|
||||||
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetGerman(), maxBufferSize);
|
|
||||||
break;
|
|
||||||
case LANGUAGE_ENG:
|
|
||||||
default:
|
|
||||||
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetEnglish(), maxBufferSize);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
msgCtx->msgLength = static_cast<int32_t>(font->msgLength);
|
msgCtx->msgLength = static_cast<int32_t>(font->msgLength);
|
||||||
}
|
}
|
||||||
|
@ -1164,9 +1164,7 @@ void RegisterAltTrapTypes() {
|
|||||||
void RegisterRandomizerSheikSpawn() {
|
void RegisterRandomizerSheikSpawn() {
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
|
||||||
if (!gPlayState) return;
|
if (!gPlayState) return;
|
||||||
bool canSheik = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIAL_COUNT) != 0 &&
|
if (!IS_RANDO || !LINK_IS_ADULT || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHEIK_LA_HINT)) return;
|
||||||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LIGHT_ARROWS_HINT));
|
|
||||||
if (!IS_RANDO || !LINK_IS_ADULT || !canSheik) return;
|
|
||||||
switch (gPlayState->sceneNum) {
|
switch (gPlayState->sceneNum) {
|
||||||
case SCENE_TEMPLE_OF_TIME:
|
case SCENE_TEMPLE_OF_TIME:
|
||||||
if (gPlayState->roomCtx.curRoom.num == 1) {
|
if (gPlayState->roomCtx.curRoom.num == 1) {
|
||||||
|
@ -417,7 +417,8 @@ const std::vector<const char*> randomizerCvars = {
|
|||||||
"gRandomizeLacsRewardOptions",
|
"gRandomizeLacsRewardOptions",
|
||||||
"gRandomizeLacsStoneCount",
|
"gRandomizeLacsStoneCount",
|
||||||
"gRandomizeLacsTokenCount",
|
"gRandomizeLacsTokenCount",
|
||||||
"gRandomizeLAHint",
|
"gRandomizeGanondorfHint",
|
||||||
|
"gRandomizeSheikLAHint",
|
||||||
"gRandomizeLinksPocket",
|
"gRandomizeLinksPocket",
|
||||||
"gRandomizeLogicRules",
|
"gRandomizeLogicRules",
|
||||||
"gRandomizeMedallionCount",
|
"gRandomizeMedallionCount",
|
||||||
|
@ -158,7 +158,7 @@ constexpr std::array DungeonColors = {
|
|||||||
CreateMessage(textId, unk_04, textBoxType, textBoxPosition, text.GetEnglish(), text.GetFrench(), text.GetSpanish());
|
CreateMessage(textId, unk_04, textBoxType, textBoxPosition, text.GetEnglish(), text.GetFrench(), text.GetSpanish());
|
||||||
}
|
}
|
||||||
|
|
||||||
Text AddColorsAndFormat(Text text, const std::vector<uint8_t>& colors /*= {}*/) {
|
Text AddColorsAndFormat(Text text, const std::vector<std::string>& colors /*= {}*/) {
|
||||||
|
|
||||||
//for each language
|
//for each language
|
||||||
for (std::string* textStr : {&text.english, &text.french, &text.spanish}) {
|
for (std::string* textStr : {&text.english, &text.french, &text.spanish}) {
|
||||||
@ -280,12 +280,12 @@ constexpr std::array DungeonColors = {
|
|||||||
std::string SET_SPEED(uint8_t x) {
|
std::string SET_SPEED(uint8_t x) {
|
||||||
return "\x7F\x10"s + char(x);
|
return "\x7F\x10"s + char(x);
|
||||||
}
|
}
|
||||||
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; }
|
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } //RANDOTODO just refernce the versions in CustomMessage
|
||||||
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 "\x1B"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(std::string x) { return "\x7F\x1D"s + x; }
|
||||||
std::string CENTER_TEXT() { return "\x7F\x1E"s; }
|
std::string CENTER_TEXT() { return "\x7F\x1E"s; }
|
||||||
std::string IF_NOT_MQ() { return "\x7F\x29"s; }
|
std::string IF_NOT_MQ() { return "\x7F\x29"s; }
|
||||||
std::string MQ_ELSE() { return "\x7F\x2A"s; }
|
std::string MQ_ELSE() { return "\x7F\x2A"s; }
|
||||||
|
@ -7,15 +7,6 @@
|
|||||||
|
|
||||||
#include "text.hpp"
|
#include "text.hpp"
|
||||||
|
|
||||||
#define QM_WHITE 0x00
|
|
||||||
#define QM_RED 0x41
|
|
||||||
#define QM_GREEN 0x42
|
|
||||||
#define QM_BLUE 0x43
|
|
||||||
#define QM_LBLUE 0x44
|
|
||||||
#define QM_PINK 0x45
|
|
||||||
#define QM_YELLOW 0x46
|
|
||||||
#define QM_BLACK 0x47
|
|
||||||
|
|
||||||
namespace CustomMessages {
|
namespace CustomMessages {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// In the true file format, offset is the offset into the QM file.
|
// In the true file format, offset is the offset into the QM file.
|
||||||
@ -73,7 +64,7 @@ typedef struct {
|
|||||||
std::string UNSKIPPABLE();
|
std::string UNSKIPPABLE();
|
||||||
std::string TWO_WAY_CHOICE();
|
std::string TWO_WAY_CHOICE();
|
||||||
std::string NEWLINE();
|
std::string NEWLINE();
|
||||||
std::string COLOR(uint8_t x);
|
std::string COLOR(std::string x);
|
||||||
std::string CENTER_TEXT();
|
std::string CENTER_TEXT();
|
||||||
std::string IF_NOT_MQ();
|
std::string IF_NOT_MQ();
|
||||||
std::string MQ_ELSE();
|
std::string MQ_ELSE();
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "spoiler_log.hpp"
|
#include "spoiler_log.hpp"
|
||||||
#include "starting_inventory.hpp"
|
#include "starting_inventory.hpp"
|
||||||
#include "hints.hpp"
|
#include "hints.hpp"
|
||||||
#include "hint_list.hpp"
|
|
||||||
#include "../entrance.h"
|
#include "../entrance.h"
|
||||||
#include "shops.hpp"
|
#include "shops.hpp"
|
||||||
#include "pool_functions.hpp"
|
#include "pool_functions.hpp"
|
||||||
@ -1157,13 +1156,6 @@ int Fill() {
|
|||||||
ctx->CreateItemOverrides();
|
ctx->CreateItemOverrides();
|
||||||
ctx->GetEntranceShuffler()->CreateEntranceOverrides();
|
ctx->GetEntranceShuffler()->CreateEntranceOverrides();
|
||||||
|
|
||||||
SPDLOG_INFO("Creating Other Hint Texts...");
|
|
||||||
//funny ganon line
|
|
||||||
Text ganonText = RandomElement(GetHintCategory(HintCategory::GanonLine)).GetText();
|
|
||||||
CreateMessageFromTextObject(0x70CB, 0, 2, 3, AddColorsAndFormat(ganonText));
|
|
||||||
SetGanonText(ganonText);
|
|
||||||
SPDLOG_INFO("Creating Other Hint Texts Done");
|
|
||||||
|
|
||||||
CreateAllHints();
|
CreateAllHints();
|
||||||
CreateWarpSongTexts();
|
CreateWarpSongTexts();
|
||||||
return 1;
|
return 1;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hints.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
extern std::array<HintText, RHT_MAX> hintTable;
|
|
||||||
|
|
||||||
void HintTable_Init();
|
|
||||||
const HintText& Hint(const RandomizerHintTextKey hintKey);
|
|
||||||
const HintText& Hint(const RandomizerArea area);
|
|
||||||
std::vector<HintText> GetHintCategory(HintCategory category);
|
|
||||||
|
|
||||||
void HintTable_Init_Item();
|
|
||||||
void HintTable_Init_Exclude_Overworld();
|
|
||||||
void HintTable_Init_Exclude_Dungeon();
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#include "text.hpp"
|
#include "text.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "../randomizerTypes.h"
|
||||||
|
#include "../../custom-message/CustomMessageManager.h"
|
||||||
|
|
||||||
struct HintDistributionSetting {
|
struct HintDistributionSetting {
|
||||||
std::string name;
|
std::string name;
|
||||||
HintType type;
|
HintType type;
|
||||||
@ -16,21 +19,8 @@ struct HintDistributionSetting {
|
|||||||
std::function<bool(RandomizerCheck)> filter;
|
std::function<bool(RandomizerCheck)> filter;
|
||||||
uint8_t dungeonLimit;
|
uint8_t dungeonLimit;
|
||||||
|
|
||||||
HintDistributionSetting(std::string _name,
|
HintDistributionSetting(std::string _name, HintType _type, uint32_t _weight, uint8_t _fixed, uint8_t _copies,
|
||||||
HintType _type,
|
std::function<bool(RandomizerCheck)> _filter, uint8_t _dungeonLimit = 40);
|
||||||
uint32_t _weight,
|
|
||||||
uint8_t _fixed,
|
|
||||||
uint8_t _copies,
|
|
||||||
std::function<bool(RandomizerCheck)> _filter,
|
|
||||||
uint8_t _dungeonLimit = 40){
|
|
||||||
name = _name;
|
|
||||||
type = _type;
|
|
||||||
weight = _weight;
|
|
||||||
fixed = _fixed;
|
|
||||||
copies = _copies;
|
|
||||||
filter = _filter;
|
|
||||||
dungeonLimit = _dungeonLimit;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HintSetting {
|
struct HintSetting {
|
||||||
@ -40,185 +30,45 @@ struct HintSetting {
|
|||||||
std::vector<HintDistributionSetting> distTable;
|
std::vector<HintDistributionSetting> distTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class HintCategory {
|
|
||||||
Item,
|
|
||||||
Always,
|
|
||||||
Sometimes,
|
|
||||||
Exclude,
|
|
||||||
Entrance,
|
|
||||||
Region,
|
|
||||||
Junk,
|
|
||||||
DungeonName,
|
|
||||||
Boss,
|
|
||||||
Bridge,
|
|
||||||
GanonsBossKey,
|
|
||||||
LACS,
|
|
||||||
Altar,
|
|
||||||
Validation,
|
|
||||||
OtherHint,
|
|
||||||
MasterSword,
|
|
||||||
GanonLine,
|
|
||||||
SheikLine,
|
|
||||||
MerchantsDialogs,
|
|
||||||
};
|
|
||||||
|
|
||||||
class HintText {
|
class HintText {
|
||||||
public:
|
public:
|
||||||
HintText() = default;
|
HintText() = default;
|
||||||
HintText(std::vector<Text> obscureText_, std::vector<Text> ambiguousText_, Text clearText_, HintCategory type_)
|
HintText(CustomMessage clearText_, std::vector<CustomMessage> ambiguousText_ = {}, std::vector<CustomMessage> obscureText_ = {});
|
||||||
: obscureText(std::move(obscureText_)),
|
const CustomMessage& GetClear() const;
|
||||||
ambiguousText(std::move(ambiguousText_)),
|
const CustomMessage& GetObscure() const;
|
||||||
clearText(std::move(clearText_)),
|
const CustomMessage& GetObscure(uint8_t selection) const;
|
||||||
type(type_) {
|
const CustomMessage& GetAmbiguous() const;
|
||||||
}
|
const CustomMessage& GetAmbiguous(uint8_t selection) const;
|
||||||
|
uint8_t GetAmbiguousSize() const;
|
||||||
static auto Item(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
uint8_t GetObscureSize() const;
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Item};
|
const CustomMessage& GetHintMessage(uint8_t selection = 0) const;
|
||||||
}
|
const CustomMessage GetMessageCopy() const;
|
||||||
|
bool operator==(const HintText& right) const;
|
||||||
static auto Always(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
bool operator!=(const HintText& right) const;
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Always};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Sometimes(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Sometimes};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Exclude(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Exclude};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Entrance(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Entrance};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Region(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Region};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Junk(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Junk};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto DungeonName(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::DungeonName};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Boss(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Boss};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Bridge(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Bridge};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto GanonsBossKey(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonsBossKey};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto LACS(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LACS};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Altar(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Altar};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Validation(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Validation};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto OtherHint(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::OtherHint};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto MasterSword(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MasterSword};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto GanonLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto SheikLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::SheikLine};
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto MerchantsDialogs(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MerchantsDialogs};
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetObscure() {
|
|
||||||
return RandomElement(obscureText);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Text& GetObscure() const {
|
|
||||||
return RandomElement(obscureText);
|
|
||||||
}
|
|
||||||
|
|
||||||
Text& GetAmbiguous() {
|
|
||||||
if (ambiguousText.size() > 0) {
|
|
||||||
return RandomElement(ambiguousText);
|
|
||||||
}
|
|
||||||
return RandomElement(obscureText);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Text& GetAmbiguous() const {
|
|
||||||
if (ambiguousText.size() > 0) {
|
|
||||||
return RandomElement(ambiguousText);
|
|
||||||
}
|
|
||||||
return RandomElement(obscureText);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Text& GetClear() const {
|
|
||||||
if (clearText.GetEnglish().empty()) {
|
|
||||||
return GetObscure();
|
|
||||||
}
|
|
||||||
return clearText;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Text& GetText() const;
|
|
||||||
|
|
||||||
const Text GetTextCopy() const;
|
|
||||||
|
|
||||||
HintCategory GetType() const {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const HintText& right) const {
|
|
||||||
return obscureText == right.obscureText &&
|
|
||||||
ambiguousText == right.ambiguousText &&
|
|
||||||
clearText == right.clearText;
|
|
||||||
}
|
|
||||||
bool operator!=(const HintText& right) const {
|
|
||||||
return !operator==(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Text> obscureText = {};
|
CustomMessage clearText;
|
||||||
std::vector<Text> ambiguousText = {};
|
std::vector<CustomMessage> ambiguousText = {};
|
||||||
Text clearText;
|
std::vector<CustomMessage> obscureText = {};
|
||||||
HintCategory type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using ConditionalAlwaysHint = std::pair<RandomizerCheck, std::function<bool()>>;
|
struct StaticHintInfo{
|
||||||
|
HintType type;
|
||||||
|
std::vector<RandomizerHintTextKey> hintKeys;
|
||||||
|
RandomizerSettingKey setting;
|
||||||
|
std::variant<bool, uint8_t> condition;
|
||||||
|
std::vector<RandomizerCheck> targetChecks;
|
||||||
|
std::vector<RandomizerGet> targetItems;
|
||||||
|
std::vector<RandomizerCheck> hintChecks;
|
||||||
|
bool yourPocket;
|
||||||
|
int num;
|
||||||
|
|
||||||
typedef enum {
|
StaticHintInfo() = default;
|
||||||
DUNGEON_NEITHER,
|
StaticHintInfo(HintType _type, std::vector<RandomizerHintTextKey> _hintKeys, RandomizerSettingKey _setting, std::variant<bool, uint8_t> _condition,
|
||||||
DUNGEON_BARREN,
|
std::vector<RandomizerCheck> _targetChecks, std::vector<RandomizerGet> _targetItems = {},
|
||||||
DUNGEON_WOTH,
|
std::vector<RandomizerCheck> _hintChecks = {}, bool _yourPocket = false, int _num = 0);
|
||||||
} DungeonHintInfo;
|
};
|
||||||
|
|
||||||
//10 dungeons as GTG and GC are excluded
|
|
||||||
extern std::array<DungeonHintInfo, 10> dungeonInfoData;
|
|
||||||
|
|
||||||
extern std::array<ConditionalAlwaysHint, 12> conditionalAlwaysHints;
|
|
||||||
|
|
||||||
extern void CreateAllHints();
|
extern void CreateAllHints();
|
||||||
extern void CreateWarpSongTexts();
|
extern void CreateWarpSongTexts();
|
||||||
|
void CreateStaticHints();
|
||||||
void SetGanonText(Text text);
|
|
||||||
|
|
||||||
std::string GetMasterSwordHintLoc();
|
|
||||||
std::string GetLightArrowHintLoc();
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "hint_list.hpp"
|
|
||||||
#include "fill.hpp"
|
#include "fill.hpp"
|
||||||
#include "../randomizerTypes.h"
|
#include "../randomizerTypes.h"
|
||||||
#include "../context.h"
|
#include "../context.h"
|
||||||
|
@ -38,10 +38,10 @@ void AreaTable_Init_CastleTown() {
|
|||||||
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
|
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
|
||||||
}, {
|
}, {
|
||||||
//Locations
|
//Locations
|
||||||
LocationAccess(RC_TOT_LEFT_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_TOT_LEFTMOST_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_TOT_LEFT_CENTER_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_TOT_LEFT_CENTER_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_TOT_RIGHT_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_TOT_RIGHTMOST_GOSSIP_STONE, {[]{return true;}}),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_THE_MARKET, {[]{return true;}}),
|
Entrance(RR_THE_MARKET, {[]{return true;}}),
|
||||||
|
@ -32,12 +32,12 @@ void AreaTable_Init_GanonsCastle() {
|
|||||||
Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}),
|
Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}),
|
||||||
Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}),
|
Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}),
|
||||||
Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
|
Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
|
||||||
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(Rando::FOREST_TRIAL)->IsSkipped()) &&
|
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||||
(logic->FireTrialClear || randoCtx->GetTrial(Rando::FIRE_TRIAL)->IsSkipped()) &&
|
(logic->FireTrialClear || randoCtx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||||
(logic->WaterTrialClear || randoCtx->GetTrial(Rando::WATER_TRIAL)->IsSkipped()) &&
|
(logic->WaterTrialClear || randoCtx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||||
(logic->ShadowTrialClear || randoCtx->GetTrial(Rando::SHADOW_TRIAL)->IsSkipped()) &&
|
(logic->ShadowTrialClear || randoCtx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||||
(logic->SpiritTrialClear || randoCtx->GetTrial(Rando::SPIRIT_TRIAL)->IsSkipped()) &&
|
(logic->SpiritTrialClear || randoCtx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
|
||||||
(logic->LightTrialClear || randoCtx->GetTrial(Rando::LIGHT_TRIAL)->IsSkipped());}}),
|
(logic->LightTrialClear || randoCtx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}),
|
||||||
Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
|
Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -134,12 +134,12 @@ void AreaTable_Init_GanonsCastle() {
|
|||||||
Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL, {[]{return true;}}),
|
Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL, {[]{return true;}}),
|
||||||
Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL, {[]{return true;}}),
|
Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL, {[]{return true;}}),
|
||||||
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
|
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
|
||||||
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(Rando::FOREST_TRIAL)->IsSkipped()) &&
|
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||||
(logic->FireTrialClear || randoCtx->GetTrial(Rando::FIRE_TRIAL)->IsSkipped()) &&
|
(logic->FireTrialClear || randoCtx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||||
(logic->WaterTrialClear || randoCtx->GetTrial(Rando::WATER_TRIAL)->IsSkipped()) &&
|
(logic->WaterTrialClear || randoCtx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||||
(logic->ShadowTrialClear || randoCtx->GetTrial(Rando::SHADOW_TRIAL)->IsSkipped()) &&
|
(logic->ShadowTrialClear || randoCtx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||||
(logic->SpiritTrialClear || randoCtx->GetTrial(Rando::SPIRIT_TRIAL)->IsSkipped()) &&
|
(logic->SpiritTrialClear || randoCtx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
|
||||||
(logic->LightTrialClear || randoCtx->GetTrial(Rando::LIGHT_TRIAL)->IsSkipped());}}),
|
(logic->LightTrialClear || randoCtx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}),
|
||||||
Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
|
Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ void AreaTable_Init_HyruleField() {
|
|||||||
//Locations
|
//Locations
|
||||||
LocationAccess(RC_HF_SOUTHEAST_GROTTO_CHEST, {[]{return true;}}),
|
LocationAccess(RC_HF_SOUTHEAST_GROTTO_CHEST, {[]{return true;}}),
|
||||||
LocationAccess(RC_HF_SOUTHEAST_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
LocationAccess(RC_HF_SOUTHEAST_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
||||||
LocationAccess(RC_HF_SOUTHEAST_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
}, {
|
}, {
|
||||||
@ -77,7 +77,7 @@ void AreaTable_Init_HyruleField() {
|
|||||||
//Locations
|
//Locations
|
||||||
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_CHEST, {[]{return true;}}),
|
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_CHEST, {[]{return true;}}),
|
||||||
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
||||||
LocationAccess(RC_HF_NEAR_MARKET_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
}, {
|
}, {
|
||||||
|
@ -281,7 +281,7 @@ void AreaTable_Init_Kakariko() {
|
|||||||
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
|
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
|
||||||
}, {
|
}, {
|
||||||
//Locations
|
//Locations
|
||||||
LocationAccess(RC_GY_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_GRAVEYARD_GOSSIP_STONE, {[]{return true;}}),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),
|
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),
|
||||||
|
@ -98,7 +98,7 @@ void AreaTable_Init_LostWoods() {
|
|||||||
//Locations
|
//Locations
|
||||||
LocationAccess(RC_KF_STORMS_GROTTO_CHEST, {[]{return true;}}),
|
LocationAccess(RC_KF_STORMS_GROTTO_CHEST, {[]{return true;}}),
|
||||||
LocationAccess(RC_KF_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
LocationAccess(RC_KF_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
||||||
LocationAccess(RC_KF_STORMS_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_KF_STORMS_GROTTO_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
}, {
|
}, {
|
||||||
@ -168,7 +168,7 @@ void AreaTable_Init_LostWoods() {
|
|||||||
//Locations
|
//Locations
|
||||||
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, {[]{return true;}}),
|
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, {[]{return true;}}),
|
||||||
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, {[]{return logic->HasBottle;}}),
|
||||||
LocationAccess(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
|
||||||
}, {
|
}, {
|
||||||
|
@ -158,8 +158,8 @@ void AreaTable_Init_ZorasDomain() {
|
|||||||
LocationAccess(RC_ZF_GS_TREE, {[]{return logic->IsChild;}}),
|
LocationAccess(RC_ZF_GS_TREE, {[]{return logic->IsChild;}}),
|
||||||
LocationAccess(RC_ZF_GS_ABOVE_THE_LOG, {[]{return logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS;}}),
|
LocationAccess(RC_ZF_GS_ABOVE_THE_LOG, {[]{return logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS;}}),
|
||||||
LocationAccess(RC_ZF_GS_HIDDEN_CAVE, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBlastOrSmash && logic->HookshotOrBoomerang && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS;}}),
|
LocationAccess(RC_ZF_GS_HIDDEN_CAVE, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBlastOrSmash && logic->HookshotOrBoomerang && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS;}}),
|
||||||
LocationAccess(RC_FAIRY_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_ZF_FAIRY_GOSSIP_STONE, {[]{return true;}}),
|
||||||
LocationAccess(RC_JABU_GOSSIP_STONE, {[]{return true;}}),
|
LocationAccess(RC_ZF_JABU_GOSSIP_STONE, {[]{return true;}}),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}),
|
Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}),
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
#include "hint_list.hpp"
|
|
||||||
#include "../static_data.h"
|
#include "../static_data.h"
|
||||||
#include "../item_location.h"
|
#include "../item_location.h"
|
||||||
#include "location_access.hpp"
|
#include "location_access.hpp"
|
||||||
@ -12,7 +11,6 @@
|
|||||||
|
|
||||||
void RandoMain::GenerateRando(std::set<RandomizerCheck> excludedLocations, std::set<RandomizerTrick> enabledTricks,
|
void RandoMain::GenerateRando(std::set<RandomizerCheck> excludedLocations, std::set<RandomizerTrick> enabledTricks,
|
||||||
std::string seedString) {
|
std::string seedString) {
|
||||||
HintTable_Init();
|
|
||||||
|
|
||||||
// std::string settingsFileName = "./randomizer/latest_settings.json";
|
// std::string settingsFileName = "./randomizer/latest_settings.json";
|
||||||
// CVarSetString("gLoadedPreset", settingsFileName.c_str());
|
// CVarSetString("gLoadedPreset", settingsFileName.c_str());
|
||||||
|
@ -38,7 +38,6 @@ using namespace Rando;
|
|||||||
json jsonData;
|
json jsonData;
|
||||||
std::map<RandomizerHintTextKey, Rando::ItemLocation*> hintedLocations;
|
std::map<RandomizerHintTextKey, Rando::ItemLocation*> hintedLocations;
|
||||||
|
|
||||||
extern std::array<std::string, HINT_TYPE_MAX> hintTypeNames;
|
|
||||||
extern std::array<std::string, 17> hintCategoryNames;
|
extern std::array<std::string, 17> hintCategoryNames;
|
||||||
extern Area* GetHintRegion(uint32_t);
|
extern Area* GetHintRegion(uint32_t);
|
||||||
|
|
||||||
@ -499,16 +498,7 @@ static void WriteRequiredTrials() {
|
|||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
for (const auto& trial : ctx->GetTrials()->GetTrialList()) {
|
for (const auto& trial : ctx->GetTrials()->GetTrialList()) {
|
||||||
if (trial->IsRequired()) {
|
if (trial->IsRequired()) {
|
||||||
std::string trialName;
|
std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN);
|
||||||
switch (gSaveContext.language) {
|
|
||||||
case LANGUAGE_FRA:
|
|
||||||
trialName = trial->GetName().GetFrench();
|
|
||||||
break;
|
|
||||||
case LANGUAGE_ENG:
|
|
||||||
default:
|
|
||||||
trialName = trial->GetName().GetEnglish();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName));
|
jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,117 +543,13 @@ Rando::ItemLocation* GetItemLocation(RandomizerGet item) {
|
|||||||
})[0]);
|
})[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes the hints to the spoiler log, if they are enabled.
|
|
||||||
static void WriteHints() {
|
|
||||||
auto ctx = Rando::Context::GetInstance();
|
|
||||||
|
|
||||||
uint8_t language = ctx->GetOption(RSK_LANGUAGE).GetSelectedOptionIndex();
|
|
||||||
|
|
||||||
if (ctx->GetOption(RSK_SHUFFLE_WARP_SONGS)) {
|
|
||||||
jsonData["warpMinuetText"] = ctx->GetHint(RH_MINUET_WARP_LOC)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["warpBoleroText"] = ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["warpSerenadeText"] = ctx->GetHint(RH_SERENADE_WARP_LOC)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["warpRequiemText"] = ctx->GetHint(RH_REQUIEM_WARP_LOC)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["warpNocturneText"] = ctx->GetHint(RH_NOCTURNE_WARP_LOC)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["warpPreludeText"] = ctx->GetHint(RH_PRELUDE_WARP_LOC)->GetText().GetForLanguage(language);
|
|
||||||
}
|
|
||||||
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* rubyLoc = GetItemLocation(RG_GORON_RUBY);
|
|
||||||
Rando::ItemLocation* sapphireLoc = GetItemLocation(RG_ZORA_SAPPHIRE);
|
|
||||||
std::string emeraldArea;
|
|
||||||
std::string erubyArea;
|
|
||||||
std::string sapphireArea;
|
|
||||||
|
|
||||||
jsonData["childAltar"]["rewards"]["emeraldLoc"] = Rando::StaticData::GetLocation(emeraldLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["childAltar"]["rewards"]["rubyLoc"] = Rando::StaticData::GetLocation(rubyLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["childAltar"]["rewards"]["sapphireLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(sapphireLoc->GetRandomizerCheck())->GetName();
|
|
||||||
|
|
||||||
Rando::ItemLocation* forestMedallionLoc = GetItemLocation(RG_FOREST_MEDALLION);
|
|
||||||
Rando::ItemLocation* fireMedallionLoc = GetItemLocation(RG_FIRE_MEDALLION);
|
|
||||||
Rando::ItemLocation* waterMedallionLoc = GetItemLocation(RG_WATER_MEDALLION);
|
|
||||||
Rando::ItemLocation* shadowMedallionLoc = GetItemLocation(RG_SHADOW_MEDALLION);
|
|
||||||
Rando::ItemLocation* spiritMedallionLoc = GetItemLocation(RG_SPIRIT_MEDALLION);
|
|
||||||
Rando::ItemLocation* lightMedallionLoc = GetItemLocation(RG_LIGHT_MEDALLION);
|
|
||||||
|
|
||||||
jsonData["adultAltar"]["rewards"]["forestMedallionLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(forestMedallionLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["adultAltar"]["rewards"]["fireMedallionLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(fireMedallionLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["adultAltar"]["rewards"]["waterMedallionLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(waterMedallionLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["adultAltar"]["rewards"]["shadowMedallionLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(shadowMedallionLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["adultAltar"]["rewards"]["spiritMedallionLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(spiritMedallionLoc->GetRandomizerCheck())->GetName();
|
|
||||||
jsonData["adultAltar"]["rewards"]["lightMedallionLoc"] =
|
|
||||||
Rando::StaticData::GetLocation(lightMedallionLoc->GetRandomizerCheck())->GetName();
|
|
||||||
|
|
||||||
jsonData["ganonText"] = ctx->GetHint(RH_GANONDORF_NOHINT)->GetText().GetForLanguage(language);
|
|
||||||
if (ctx->GetOption(RSK_LIGHT_ARROWS_HINT)){
|
|
||||||
jsonData["ganonHintText"] = ctx->GetHint(RH_GANONDORF_HINT)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["lightArrowHintLoc"] = GetLightArrowHintLoc();
|
|
||||||
jsonData["lightArrowArea"] = ::Hint(ctx->GetHint(RH_GANONDORF_HINT)->GetHintedArea()).GetText().GetEnglish();
|
|
||||||
jsonData["masterSwordHintLoc"] = GetMasterSwordHintLoc();
|
|
||||||
if (!ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) {
|
|
||||||
jsonData["sheikText"] = ctx->GetHint(RH_SHEIK_LIGHT_ARROWS)->GetText().GetForLanguage(language);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ctx->GetOption(RSK_DAMPES_DIARY_HINT)){
|
|
||||||
jsonData["dampeText"] = ctx->GetHint(RH_DAMPES_DIARY)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["dampeHintLoc"] = Rando::StaticData::GetLocation(ctx->GetHint(RH_DAMPES_DIARY)->GetHintedLocation())->GetName();
|
|
||||||
jsonData["dampeRegion"] = ::Hint(ctx->GetHint(RH_DAMPES_DIARY)->GetHintedArea()).GetText().GetEnglish();
|
|
||||||
}
|
|
||||||
if (ctx->GetOption(RSK_GREG_HINT)){
|
|
||||||
jsonData["gregText"] = ctx->GetHint(RH_GREG_RUPEE)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["gregLoc"] = Rando::StaticData::GetLocation(ctx->GetHint(RH_GREG_RUPEE)->GetHintedLocation())->GetName();
|
|
||||||
jsonData["gregRegion"] = ::Hint(ctx->GetHint(RH_GREG_RUPEE)->GetHintedArea()).GetText().GetEnglish();
|
|
||||||
}
|
|
||||||
if (ctx->GetOption(RSK_SARIA_HINT)){
|
|
||||||
jsonData["sariaText"] = ctx->GetHint(RH_SARIA)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["sariaHintLoc"] = Rando::StaticData::GetLocation(ctx->GetHint(RH_SARIA)->GetHintedLocation())->GetName();
|
|
||||||
jsonData["sariaRegion"] = ::Hint(ctx->GetHint(RH_SARIA)->GetHintedArea()).GetText().GetEnglish();
|
|
||||||
}
|
|
||||||
if (ctx->GetOption(RSK_FISHING_POLE_HINT)) {
|
|
||||||
jsonData["fishingPoleText"] = ctx->GetHint(RH_FISHING_POLE)->GetText().GetForLanguage(language);
|
|
||||||
jsonData["fishingPoleHintLoc"] = Rando::StaticData::GetLocation(ctx->GetHint(RH_FISHING_POLE)->GetHintedLocation())->GetName();
|
|
||||||
jsonData["fishingPoleRegion"] = ::Hint(ctx->GetHint(RH_FISHING_POLE)->GetHintedArea()).GetText().GetEnglish();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->GetOption(RSK_GOSSIP_STONE_HINTS).Is(RO_GOSSIP_STONES_NONE)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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::ItemLocation* hintedLocation = ctx->GetItemLocation(hint->GetHintedLocation());
|
|
||||||
std::string hintTextString = hint->GetText().GetForLanguage(language);
|
|
||||||
HintType hintType = hint->GetHintType();
|
|
||||||
|
|
||||||
std::string textStr = hintTextString;
|
|
||||||
std::string name = Rando::StaticData::GetLocation(key)->GetName();
|
|
||||||
jsonData["hints"][name]["hint"] = textStr;
|
|
||||||
jsonData["hints"][name]["distribution"] = hint->GetDistribution();
|
|
||||||
jsonData["hints"][name]["type"] = hintTypeNames[(int)hintType];
|
|
||||||
if (hintType == HINT_TYPE_ITEM_LOCATION || hintType == HINT_TYPE_ITEM_AREA || hintType == HINT_TYPE_WOTH) {
|
|
||||||
jsonData["hints"][name]["item"] = hintedLocation->GetPlacedItemName().GetEnglish();
|
|
||||||
jsonData["hints"][name]["location"] = Rando::StaticData::GetLocation(hintedLocation->GetRandomizerCheck())->GetName();
|
|
||||||
}
|
|
||||||
if (hintType != HINT_TYPE_TRIAL && hintType != HINT_TYPE_JUNK) {
|
|
||||||
jsonData["hints"][name]["area"] = ::Hint(hint->GetHintedArea()).GetText().Capitalize().GetEnglish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WriteAllLocations() {
|
static void WriteAllLocations() {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
for (const RandomizerCheck key : ctx->allLocations) {
|
for (const RandomizerCheck key : ctx->allLocations) {
|
||||||
Rando::ItemLocation* location = ctx->GetItemLocation(key);
|
Rando::ItemLocation* location = ctx->GetItemLocation(key);
|
||||||
std::string placedItemName;
|
std::string placedItemName;
|
||||||
|
|
||||||
switch (ctx->GetOption(RSK_LANGUAGE).GetSelectedOptionIndex()) {
|
switch (gSaveContext.language) {
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
placedItemName = location->GetPlacedItemName().english;
|
placedItemName = location->GetPlacedItemName().english;
|
||||||
@ -689,12 +575,12 @@ static void WriteAllLocations() {
|
|||||||
jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["price"] =
|
jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["price"] =
|
||||||
location->GetPrice();
|
location->GetPrice();
|
||||||
}
|
}
|
||||||
if (location->IsHintedAt()) {
|
if (location->IsAHintAccessible()) {
|
||||||
hintedLocations.emplace(Rando::StaticData::GetLocation(key)->GetHintKey(), location);
|
hintedLocations.emplace(Rando::StaticData::GetLocation(key)->GetHintKey(), location);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location->GetPlacedRandomizerGet() == RG_ICE_TRAP) {
|
if (location->GetPlacedRandomizerGet() == RG_ICE_TRAP) {
|
||||||
switch (ctx->GetOption(RSK_LANGUAGE).GetSelectedOptionIndex()) {
|
switch (gSaveContext.language) {
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["model"] =
|
jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["model"] =
|
||||||
@ -737,7 +623,7 @@ const char* SpoilerLog_Write() {
|
|||||||
WriteSettings();
|
WriteSettings();
|
||||||
WriteExcludedLocations();
|
WriteExcludedLocations();
|
||||||
WriteStartingInventory();
|
WriteStartingInventory();
|
||||||
WriteEnabledTricks(spoilerLog);
|
WriteEnabledTricks(spoilerLog); //RANDOTODO clean up spoilerLog refernces
|
||||||
//if (Settings::Logic.Is(LOGIC_GLITCHED)) {
|
//if (Settings::Logic.Is(LOGIC_GLITCHED)) {
|
||||||
// WriteEnabledGlitches(spoilerLog);
|
// WriteEnabledGlitches(spoilerLog);
|
||||||
//}
|
//}
|
||||||
@ -748,7 +634,7 @@ const char* SpoilerLog_Write() {
|
|||||||
ctx->playthroughLocations.clear();
|
ctx->playthroughLocations.clear();
|
||||||
ctx->playthroughBeatable = false;
|
ctx->playthroughBeatable = false;
|
||||||
|
|
||||||
WriteHints();
|
ctx->WriteHintJson(jsonData);
|
||||||
WriteShuffledEntrances();
|
WriteShuffledEntrances();
|
||||||
WriteAllLocations();
|
WriteAllLocations();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "z64.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PLURAL 0
|
#define PLURAL 0
|
||||||
#define SINGULAR 1
|
#define SINGULAR 1
|
||||||
@ -54,11 +54,11 @@ public:
|
|||||||
|
|
||||||
const std::string& GetForLanguage(uint8_t language) const {
|
const std::string& GetForLanguage(uint8_t language) const {
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case LANGUAGE_ENG:
|
case 0: //LANGUAGE_ENG: changed to resolve #include loops
|
||||||
return GetEnglish();
|
return GetEnglish();
|
||||||
case LANGUAGE_FRA:
|
case 2: //LANGUAGE_FRA:
|
||||||
return GetFrench();
|
return GetFrench();
|
||||||
case LANGUAGE_GER:
|
case 1: //LANGUAGE_GER:
|
||||||
return GetGerman();
|
return GetGerman();
|
||||||
default:
|
default:
|
||||||
return GetEnglish();
|
return GetEnglish();
|
||||||
@ -97,6 +97,29 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Replace(std::string oldStr, Text newText) {
|
||||||
|
size_t position = english.find(oldStr);
|
||||||
|
while (position != std::string::npos) {
|
||||||
|
english.replace(position, oldStr.length(), newText.GetEnglish());
|
||||||
|
position = english.find(oldStr);
|
||||||
|
}
|
||||||
|
position = french.find(oldStr);
|
||||||
|
while (position != std::string::npos) {
|
||||||
|
french.replace(position, oldStr.length(), newText.GetFrench());
|
||||||
|
position = french.find(oldStr);
|
||||||
|
}
|
||||||
|
position = spanish.find(oldStr);
|
||||||
|
while (position != std::string::npos) {
|
||||||
|
spanish.replace(position, oldStr.length(), newText.GetSpanish());
|
||||||
|
position = spanish.find(oldStr);
|
||||||
|
}
|
||||||
|
position = german.find(oldStr);
|
||||||
|
while (position != std::string::npos) {
|
||||||
|
german.replace(position, oldStr.length(), newText.GetGerman());
|
||||||
|
position = german.find(oldStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 + "";
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
#include "3drando/shops.hpp"
|
#include "3drando/shops.hpp"
|
||||||
#include "dungeon.h"
|
#include "dungeon.h"
|
||||||
#include "logic.h"
|
#include "logic.h"
|
||||||
#include "trial.h"
|
|
||||||
#include "entrance.h"
|
#include "entrance.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "rando_hash.h"
|
#include "rando_hash.h"
|
||||||
#include "fishsanity.h"
|
#include "fishsanity.h"
|
||||||
|
#include "3drando/hints.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
@ -20,56 +20,6 @@ namespace Rando {
|
|||||||
std::weak_ptr<Context> Context::mContext;
|
std::weak_ptr<Context> Context::mContext;
|
||||||
|
|
||||||
Context::Context() {
|
Context::Context() {
|
||||||
mSpoilerfileHintTypeNameToEnum = {
|
|
||||||
{ "Static", HINT_TYPE_STATIC },
|
|
||||||
{ "Trial", HINT_TYPE_TRIAL },
|
|
||||||
{ "WotH", HINT_TYPE_WOTH },
|
|
||||||
{ "Barren", HINT_TYPE_BARREN },
|
|
||||||
{ "Entrance", HINT_TYPE_ENTRANCE },
|
|
||||||
{ "Item Area", HINT_TYPE_ITEM_AREA },
|
|
||||||
{ "Item Location", HINT_TYPE_ITEM_LOCATION },
|
|
||||||
{ "Junk", HINT_TYPE_JUNK },
|
|
||||||
};
|
|
||||||
|
|
||||||
mSpoilerfileAreaNameToEnum = {
|
|
||||||
{"No Hint", RA_NONE},
|
|
||||||
{"Link's Pocket", RA_LINKS_POCKET},
|
|
||||||
{"Kokiri Forest", RA_KOKIRI_FOREST},
|
|
||||||
{"The Lost Woods", RA_THE_LOST_WOODS},
|
|
||||||
{"Sacred Forest Meadow", RA_SACRED_FOREST_MEADOW},
|
|
||||||
{"Hyrule Field", RA_HYRULE_FIELD},
|
|
||||||
{"Lake Hylia", RA_LAKE_HYLIA},
|
|
||||||
{"Gerudo Valley", RA_GERUDO_VALLEY},
|
|
||||||
{"Gerudo Fortress", RA_GERUDO_FORTRESS},
|
|
||||||
{"Haunted Wasteland", RA_HAUNTED_WASTELAND},
|
|
||||||
{"Desert Colossus", RA_DESERT_COLOSSUS},
|
|
||||||
{"The Market", RA_THE_MARKET},
|
|
||||||
{"Temple of Time", RA_TEMPLE_OF_TIME},
|
|
||||||
{"Hyrule Castle", RA_HYRULE_CASTLE},
|
|
||||||
{"Outside Ganon's Castle", RA_OUTSIDE_GANONS_CASTLE},
|
|
||||||
{"Castle Grounds", RA_CASTLE_GROUNDS},
|
|
||||||
{"Kakariko Village", RA_KAKARIKO_VILLAGE},
|
|
||||||
{"the Graveyard", RA_THE_GRAVEYARD},
|
|
||||||
{"Death Mountain Trail", RA_DEATH_MOUNTAIN_TRAIL},
|
|
||||||
{"Goron City", RA_GORON_CITY},
|
|
||||||
{"Death Mountain Crater", RA_DEATH_MOUNTAIN_CRATER},
|
|
||||||
{"Zora's River", RA_ZORAS_RIVER},
|
|
||||||
{"Zora's Domain", RA_ZORAS_DOMAIN},
|
|
||||||
{"Zora's Fountain", RA_ZORAS_FOUNTAIN},
|
|
||||||
{"Lon Lon Ranch", RA_LON_LON_RANCH},
|
|
||||||
{"Deku Tree", RA_DEKU_TREE},
|
|
||||||
{"Dodongo's Cavern", RA_DODONGOS_CAVERN},
|
|
||||||
{"Jabu-Jabu's Belly", RA_JABU_JABUS_BELLY},
|
|
||||||
{"Forest Temple", RA_FOREST_TEMPLE},
|
|
||||||
{"Fire Temple", RA_FIRE_TEMPLE},
|
|
||||||
{"Water Temple", RA_WATER_TEMPLE},
|
|
||||||
{"Spirit Temple", RA_SPIRIT_TEMPLE},
|
|
||||||
{"Shadow Temple", RA_SHADOW_TEMPLE},
|
|
||||||
{"Bottom of the Well", RA_BOTTOM_OF_THE_WELL},
|
|
||||||
{"Ice Cavern", RA_ICE_CAVERN},
|
|
||||||
{"Gerudo training Grounds", RA_GERUDO_TRAINING_GROUND},
|
|
||||||
{"Inside Ganon's Castle", RA_GANONS_CASTLE},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < RC_MAX; i++) {
|
for (int i = 0; i < RC_MAX; i++) {
|
||||||
itemLocationTable[i] = ItemLocation(static_cast<RandomizerCheck>(i));
|
itemLocationTable[i] = ItemLocation(static_cast<RandomizerCheck>(i));
|
||||||
@ -83,11 +33,15 @@ Context::Context() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RandomizerArea Context::GetAreaFromString(std::string str) {
|
RandomizerArea Context::GetAreaFromString(std::string str) {
|
||||||
return mSpoilerfileAreaNameToEnum[str];
|
return (RandomizerArea)StaticData::areaNameToEnum[str];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::InitStaticData() {
|
void Context::InitStaticData() {
|
||||||
StaticData::InitItemTable();
|
StaticData::HintTable_Init();
|
||||||
|
StaticData::trialNameToEnum = StaticData::PopulateTranslationMap(StaticData::trialData);
|
||||||
|
StaticData::hintNameToEnum = StaticData::PopulateTranslationMap(StaticData::hintNames);
|
||||||
|
StaticData::hintTypeNameToEnum = StaticData::PopulateTranslationMap(StaticData::hintTypeNames);
|
||||||
|
StaticData::areaNameToEnum = StaticData::PopulateTranslationMap(StaticData::areaNames);
|
||||||
StaticData::InitLocationTable();
|
StaticData::InitLocationTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,14 +58,12 @@ std::shared_ptr<Context> Context::GetInstance() {
|
|||||||
return mContext.lock();
|
return mContext.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Hint* Context::GetHint(const RandomizerHintKey hintKey) {
|
Hint* Context::GetHint(const RandomizerHint hintKey) {
|
||||||
return &hintTable[hintKey];
|
return &hintTable[hintKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::AddHint(const RandomizerHintKey hintId, const Text& text, const RandomizerCheck hintedLocation, const HintType hintType,
|
void Context::AddHint(const RandomizerHint hintId, const Hint hint) {
|
||||||
std::string distributionName, RandomizerArea hintedArea) {
|
hintTable[hintId] = hint; //RANDOTODO this should probably be an rvalue
|
||||||
hintTable[hintId] = Hint(text, hintedLocation, hintType, distributionName, hintedArea);
|
|
||||||
GetItemLocation(hintedLocation)->AddHintedBy(hintId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemLocation* Context::GetItemLocation(const RandomizerCheck locKey) {
|
ItemLocation* Context::GetItemLocation(const RandomizerCheck locKey) {
|
||||||
@ -222,7 +174,7 @@ std::vector<RandomizerCheck> Context::GetLocations(const std::vector<RandomizerC
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Context::ClearItemLocations() {
|
void Context::ClearItemLocations() {
|
||||||
for (int i = 0; i < itemLocationTable.size(); i++) {
|
for (size_t i = 0; i < itemLocationTable.size(); i++) {
|
||||||
GetItemLocation(static_cast<RandomizerCheck>(i))->ResetVariables();
|
GetItemLocation(static_cast<RandomizerCheck>(i))->ResetVariables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +202,7 @@ void Context::LocationReset() {
|
|||||||
GetItemLocation(il)->RemoveFromPool();
|
GetItemLocation(il)->RemoveFromPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const RandomizerCheck il : StaticData::otherHintLocations) {
|
for (const RandomizerCheck il : StaticData::staticHintLocations) {
|
||||||
GetItemLocation(il)->RemoveFromPool();
|
GetItemLocation(il)->RemoveFromPool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,7 +210,9 @@ void Context::LocationReset() {
|
|||||||
void Context::HintReset() {
|
void Context::HintReset() {
|
||||||
for (const RandomizerCheck il : StaticData::gossipStoneLocations) {
|
for (const RandomizerCheck il : StaticData::gossipStoneLocations) {
|
||||||
GetItemLocation(il)->ResetVariables();
|
GetItemLocation(il)->ResetVariables();
|
||||||
GetHint(static_cast<RandomizerHintKey>(il - RC_COLOSSUS_GOSSIP_STONE + 1))->ResetVariables();
|
}
|
||||||
|
for (Hint& hint : hintTable){
|
||||||
|
hint.ResetVariables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,126 +347,52 @@ void Context::ParseHashIconIndexesJson(nlohmann::json spoilerFileJson) {
|
|||||||
void Context::ParseItemLocationsJson(nlohmann::json spoilerFileJson) {
|
void Context::ParseItemLocationsJson(nlohmann::json spoilerFileJson) {
|
||||||
nlohmann::json locationsJson = spoilerFileJson["locations"];
|
nlohmann::json locationsJson = spoilerFileJson["locations"];
|
||||||
for (auto it = locationsJson.begin(); it != locationsJson.end(); ++it) {
|
for (auto it = locationsJson.begin(); it != locationsJson.end(); ++it) {
|
||||||
RandomizerCheck rc = StaticData::SpoilerfileCheckNameToEnum[it.key()];
|
RandomizerCheck rc = StaticData::locationNameToEnum[it.key()];
|
||||||
if (it->is_structured()) {
|
if (it->is_structured()) {
|
||||||
nlohmann::json itemJson = *it;
|
nlohmann::json itemJson = *it;
|
||||||
for (auto itemit = itemJson.begin(); itemit != itemJson.end(); ++itemit) {
|
for (auto itemit = itemJson.begin(); itemit != itemJson.end(); ++itemit) {
|
||||||
if (itemit.key() == "item") {
|
if (itemit.key() == "item") {
|
||||||
itemLocationTable[rc].SetPlacedItem(StaticData::SpoilerfileItemNameToEnum[itemit.value().get<std::string>()]);
|
itemLocationTable[rc].SetPlacedItem(StaticData::itemNameToEnum[itemit.value().get<std::string>()]);
|
||||||
} else if (itemit.key() == "price") {
|
} else if (itemit.key() == "price") {
|
||||||
itemLocationTable[rc].SetCustomPrice(itemit.value().get<uint16_t>());
|
itemLocationTable[rc].SetCustomPrice(itemit.value().get<uint16_t>());
|
||||||
} else if (itemit.key() == "model") {
|
} else if (itemit.key() == "model") {
|
||||||
overrides[rc] = ItemOverride(rc, StaticData::SpoilerfileItemNameToEnum[itemit.value().get<std::string>()]);
|
overrides[rc] = ItemOverride(rc, StaticData::itemNameToEnum[itemit.value().get<std::string>()]);
|
||||||
} else if (itemit.key() == "trickName") {
|
} else if (itemit.key() == "trickName") {
|
||||||
overrides[rc].SetTrickName(Text(itemit.value().get<std::string>()));
|
overrides[rc].SetTrickName(Text(itemit.value().get<std::string>()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
itemLocationTable[rc].SetPlacedItem(StaticData::SpoilerfileItemNameToEnum[it.value().get<std::string>()]);
|
itemLocationTable[rc].SetPlacedItem(StaticData::itemNameToEnum[it.value().get<std::string>()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::WriteHintJson(nlohmann::ordered_json& spoilerFileJson){
|
||||||
|
for (Hint hint: hintTable){
|
||||||
|
hint.logHint(spoilerFileJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json getValueForMessage(std::unordered_map<std::string, nlohmann::json> map, CustomMessage message){
|
||||||
|
std::vector<std::string> strings = message.GetAllMessages();
|
||||||
|
for (uint8_t language = 0; language < LANGUAGE_MAX; language++){
|
||||||
|
if (map.contains(strings[language])){
|
||||||
|
return strings[language];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
|
void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
|
||||||
// Child Altar
|
for (auto hintData : spoilerFileJson["Gossip Stone Hints"].items()){
|
||||||
std::string childAltarText = spoilerFileJson["childAltar"]["hintText"].get<std::string>();
|
RandomizerHint hint = (RandomizerHint)StaticData::hintNameToEnum[hintData.key()];
|
||||||
AddHint(RH_ALTAR_CHILD, Text(childAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", RA_NONE);
|
AddHint(hint, Hint(hint, hintData.value()));
|
||||||
mEmeraldLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["emeraldLoc"]];
|
|
||||||
mRubyLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["rubyLoc"]];
|
|
||||||
mSapphireLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["sapphireLoc"]];
|
|
||||||
|
|
||||||
// Adult Altar
|
|
||||||
std::string adultAltarText = spoilerFileJson["adultAltar"]["hintText"].get<std::string>();
|
|
||||||
AddHint(RH_ALTAR_ADULT, Text(adultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", RA_NONE);
|
|
||||||
mForestMedallionLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["forestMedallionLoc"].get<std::string>()];
|
|
||||||
mFireMedallionLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["fireMedallionLoc"].get<std::string>()];
|
|
||||||
mWaterMedallionLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["waterMedallionLoc"].get<std::string>()];
|
|
||||||
mShadowMedallionLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["shadowMedallionLoc"].get<std::string>()];
|
|
||||||
mSpiritMedallionLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["spiritMedallionLoc"].get<std::string>()];
|
|
||||||
mLightMedallionLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["lightMedallionLoc"].get<std::string>()];
|
|
||||||
|
|
||||||
// Ganondorf and Sheik Light Arrow Hints
|
|
||||||
std::string ganonHintText = spoilerFileJson["ganonHintText"].get<std::string>();
|
|
||||||
RandomizerCheck lightArrowLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["lightArrowHintLoc"].get<std::string>()];
|
|
||||||
std::string lightArrowRegion = spoilerFileJson["lightArrowArea"].get<std::string>();
|
|
||||||
AddHint(RH_GANONDORF_HINT, Text(ganonHintText), lightArrowLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[lightArrowRegion]);
|
|
||||||
if (spoilerFileJson.contains("sheikText")) {
|
|
||||||
std::string sheikText = spoilerFileJson["sheikText"].get<std::string>();
|
|
||||||
AddHint(RH_SHEIK_LIGHT_ARROWS, Text(sheikText), lightArrowLoc, HINT_TYPE_STATIC, lightArrowRegion);
|
|
||||||
}
|
}
|
||||||
std::string ganonText = spoilerFileJson["ganonText"].get<std::string>();
|
for (auto hintData : spoilerFileJson["Static Hints"].items()){
|
||||||
AddHint(RH_GANONDORF_NOHINT, Text(ganonText), RC_UNKNOWN_CHECK, HINT_TYPE_JUNK, "Static", RA_GANONS_CASTLE);
|
RandomizerHint hint = (RandomizerHint)StaticData::hintNameToEnum[hintData.key()];
|
||||||
|
AddHint(hint, Hint(hint, hintData.value()));
|
||||||
// Dampe Hookshot Hint
|
|
||||||
if (spoilerFileJson.contains("dampeText")) {
|
|
||||||
std::string dampeText = spoilerFileJson["dampeText"].get<std::string>();
|
|
||||||
std::string dampeRegion = spoilerFileJson["dampeRegion"].get<std::string>();
|
|
||||||
RandomizerCheck dampeHintLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["dampeHintLoc"].get<std::string>()];
|
|
||||||
AddHint(RH_DAMPES_DIARY, Text(dampeText), dampeHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[dampeRegion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Greg Hint
|
|
||||||
if (spoilerFileJson.contains("gregText")) {
|
|
||||||
std::string gregText = spoilerFileJson["gregText"].get<std::string>();
|
|
||||||
std::string gregRegion = spoilerFileJson["gregRegion"].get<std::string>();
|
|
||||||
RandomizerCheck gregLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["gregLoc"].get<std::string>()];
|
|
||||||
AddHint(RH_GREG_RUPEE, Text(gregText), gregLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[gregRegion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saria Magic Hint
|
|
||||||
if (spoilerFileJson.contains("sariaText")) {
|
|
||||||
std::string sariaText = spoilerFileJson["sariaText"].get<std::string>();
|
|
||||||
std::string sariaRegion = spoilerFileJson["sariaRegion"].get<std::string>();
|
|
||||||
RandomizerCheck sariaHintLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["sariaHintLoc"].get<std::string>()];
|
|
||||||
AddHint(RH_SARIA, Text(sariaText), sariaHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[sariaRegion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fishing Pole Hint
|
|
||||||
if(spoilerFileJson.contains("fishingPoleText")) {
|
|
||||||
std::string fishingPoleText = spoilerFileJson["fishingPoleText"].get<std::string>();
|
|
||||||
std::string fishingPoleRegion = spoilerFileJson["fishingPoleRegion"].get<std::string>();
|
|
||||||
RandomizerCheck fishingPoleHintLoc = StaticData::SpoilerfileCheckNameToEnum[spoilerFileJson["fishingPoleHintLoc"].get<std::string>()];
|
|
||||||
AddHint(RH_FISHING_POLE, Text(fishingPoleText), fishingPoleHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[fishingPoleRegion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warp Songs
|
|
||||||
if (spoilerFileJson.contains("warpMinuetText")) {
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
if (spoilerFileJson.contains("warpBoleroText")) {
|
|
||||||
std::string warpBoleroText = spoilerFileJson["warpBoleroText"].get<std::string>();
|
|
||||||
AddHint(RH_BOLERO_WARP_LOC, Text(warpBoleroText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpBoleroText]);
|
|
||||||
}
|
|
||||||
if (spoilerFileJson.contains("warpSerenadeText")) {
|
|
||||||
std::string warpSerenadeText = spoilerFileJson["warpSerenadeText"].get<std::string>();
|
|
||||||
AddHint(RH_SERENADE_WARP_LOC, Text(warpSerenadeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpSerenadeText]);
|
|
||||||
}
|
|
||||||
if (spoilerFileJson.contains("warpRequiemText")) {
|
|
||||||
std::string warpRequiemText = spoilerFileJson["warpRequiemText"].get<std::string>();
|
|
||||||
AddHint(RH_REQUIEM_WARP_LOC, Text(warpRequiemText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpRequiemText]);
|
|
||||||
}
|
|
||||||
if (spoilerFileJson.contains("warpNocturneText")) {
|
|
||||||
std::string warpNocturneText = spoilerFileJson["warpNocturneText"].get<std::string>();
|
|
||||||
AddHint(RH_NOCTURNE_WARP_LOC, Text(warpNocturneText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpNocturneText]);
|
|
||||||
}
|
|
||||||
if (spoilerFileJson.contains("warpPreludeText")) {
|
|
||||||
std::string warpPreludeText = spoilerFileJson["warpPreludeText"].get<std::string>();
|
|
||||||
AddHint(RH_PRELUDE_WARP_LOC, Text(warpPreludeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpPreludeText]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gossip Stones
|
|
||||||
nlohmann::json hintsJson = spoilerFileJson["hints"];
|
|
||||||
for (auto it = hintsJson.begin(); it != hintsJson.end(); ++it) {
|
|
||||||
RandomizerCheck gossipStoneLoc = StaticData::SpoilerfileCheckNameToEnum[it.key()];
|
|
||||||
nlohmann::json hintInfo = it.value();
|
|
||||||
std::string hintText = hintInfo["hint"].get<std::string>();
|
|
||||||
HintType hintType = mSpoilerfileHintTypeNameToEnum[hintInfo["type"].get<std::string>()];
|
|
||||||
RandomizerCheck hintedLocation = hintInfo.contains("location") ? StaticData::SpoilerfileCheckNameToEnum[hintInfo["location"]] : RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerArea hintedArea = hintInfo.contains("area") ? mSpoilerfileAreaNameToEnum[hintInfo["area"].get<std::string>()] : RA_NONE;
|
|
||||||
std::string distribution = hintInfo["distribution"].get<std::string>();
|
|
||||||
AddHint(static_cast<RandomizerHintKey>(gossipStoneLoc - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), hintedLocation, hintType, distribution, hintedArea);
|
|
||||||
}
|
}
|
||||||
|
CreateStaticHints();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Settings> Context::GetSettings() {
|
std::shared_ptr<Settings> Context::GetSettings() {
|
||||||
@ -554,6 +434,10 @@ TrialInfo* Context::GetTrial(size_t key) const {
|
|||||||
return mTrials->GetTrial(static_cast<TrialKey>(key));
|
return mTrials->GetTrial(static_cast<TrialKey>(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrialInfo* Context::GetTrial(TrialKey key) const {
|
||||||
|
return mTrials->GetTrial(key);
|
||||||
|
}
|
||||||
|
|
||||||
Sprite* Context::GetSeedTexture(const uint8_t index) {
|
Sprite* Context::GetSeedTexture(const uint8_t index) {
|
||||||
return &gSeedTextures[index];
|
return &gSeedTextures[index];
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "3drando/text.hpp"
|
#include "3drando/text.hpp"
|
||||||
#include "hint.h"
|
#include "hint.h"
|
||||||
#include "fishsanity.h"
|
#include "fishsanity.h"
|
||||||
|
#include "trial.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -36,9 +37,8 @@ class Context {
|
|||||||
static std::shared_ptr<Context> CreateInstance();
|
static std::shared_ptr<Context> CreateInstance();
|
||||||
static std::shared_ptr<Context> GetInstance();
|
static std::shared_ptr<Context> GetInstance();
|
||||||
void InitStaticData();
|
void InitStaticData();
|
||||||
Hint* GetHint(RandomizerHintKey hintKey);
|
Hint* GetHint(RandomizerHint hintKey);
|
||||||
void AddHint(RandomizerHintKey hintId, const Text& text, RandomizerCheck hintedLocation, HintType hintType, std::string distributionName,
|
void AddHint(const RandomizerHint hintId, const Hint hint);
|
||||||
RandomizerArea hintedArea = RA_NONE);
|
|
||||||
ItemLocation* GetItemLocation(RandomizerCheck locKey);
|
ItemLocation* GetItemLocation(RandomizerCheck locKey);
|
||||||
ItemLocation* GetItemLocation(size_t locKey);
|
ItemLocation* GetItemLocation(size_t locKey);
|
||||||
ItemOverride& GetItemOverride(RandomizerCheck locKey);
|
ItemOverride& GetItemOverride(RandomizerCheck locKey);
|
||||||
@ -73,6 +73,7 @@ class Context {
|
|||||||
void ResetLogic();
|
void ResetLogic();
|
||||||
std::shared_ptr<Trials> GetTrials();
|
std::shared_ptr<Trials> GetTrials();
|
||||||
TrialInfo* GetTrial(size_t key) const;
|
TrialInfo* GetTrial(size_t key) const;
|
||||||
|
TrialInfo* GetTrial(TrialKey key) const;
|
||||||
static Sprite* GetSeedTexture(uint8_t index);
|
static Sprite* GetSeedTexture(uint8_t index);
|
||||||
Option& GetOption(RandomizerSettingKey key) const;
|
Option& GetOption(RandomizerSettingKey key) const;
|
||||||
TrickOption& GetTrickOption(RandomizerTrick key) const;
|
TrickOption& GetTrickOption(RandomizerTrick key) const;
|
||||||
@ -80,6 +81,7 @@ class Context {
|
|||||||
void ParseSpoiler(const char* spoilerFileName, bool plandoMode);
|
void ParseSpoiler(const char* spoilerFileName, bool plandoMode);
|
||||||
void ParseHashIconIndexesJson(nlohmann::json spoilerFileJson);
|
void ParseHashIconIndexesJson(nlohmann::json spoilerFileJson);
|
||||||
void ParseItemLocationsJson(nlohmann::json spoilerFileJson);
|
void ParseItemLocationsJson(nlohmann::json spoilerFileJson);
|
||||||
|
void WriteHintJson(nlohmann::ordered_json& spoilerFileJson);
|
||||||
void ParseHintJson(nlohmann::json spoilerFileJson);
|
void ParseHintJson(nlohmann::json spoilerFileJson);
|
||||||
std::map<RandomizerCheck, ItemOverride> overrides = {};
|
std::map<RandomizerCheck, ItemOverride> overrides = {};
|
||||||
std::vector<std::vector<RandomizerCheck>> playthroughLocations = {};
|
std::vector<std::vector<RandomizerCheck>> playthroughLocations = {};
|
||||||
@ -93,18 +95,7 @@ class Context {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static std::weak_ptr<Context> mContext;
|
static std::weak_ptr<Context> mContext;
|
||||||
std::unordered_map<std::string, HintType> mSpoilerfileHintTypeNameToEnum;
|
|
||||||
std::unordered_map<std::string, RandomizerArea> mSpoilerfileAreaNameToEnum;
|
|
||||||
std::array<Hint, RH_MAX> hintTable = {};
|
std::array<Hint, RH_MAX> hintTable = {};
|
||||||
RandomizerCheck mEmeraldLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mRubyLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mSapphireLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mForestMedallionLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mFireMedallionLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mWaterMedallionLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mShadowMedallionLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mSpiritMedallionLoc = RC_UNKNOWN_CHECK;
|
|
||||||
RandomizerCheck mLightMedallionLoc = RC_UNKNOWN_CHECK;
|
|
||||||
std::array<ItemLocation, RC_MAX> itemLocationTable = {};
|
std::array<ItemLocation, RC_MAX> itemLocationTable = {};
|
||||||
std::shared_ptr<Settings> mSettings;
|
std::shared_ptr<Settings> mSettings;
|
||||||
std::shared_ptr<EntranceShuffler> mEntranceShuffler;
|
std::shared_ptr<EntranceShuffler> mEntranceShuffler;
|
||||||
|
@ -1,56 +1,729 @@
|
|||||||
#include "hint.h"
|
#include "hint.h"
|
||||||
|
#include "map"
|
||||||
|
#include "string"
|
||||||
|
#include "context.h"
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include "static_data.h"
|
||||||
|
|
||||||
namespace Rando {
|
namespace Rando {
|
||||||
Hint::Hint() : text(std::move(Text())) {}
|
Hint::Hint(){}
|
||||||
Hint::Hint(Text text_): text(std::move(text_)) {}
|
|
||||||
Hint::Hint(Text text_, RandomizerCheck hintedLocation_, HintType hintType_, std::string distributionName_, RandomizerArea hintedArea_)
|
Hint::Hint(RandomizerHint ownKey_,
|
||||||
: text(std::move(text_)), hintedLocation(hintedLocation_), hintType(hintType_),
|
HintType hintType_,
|
||||||
hintedArea(hintedArea_), distribution(std::move(distributionName_)) {
|
std::string distribution_,
|
||||||
|
std::vector<RandomizerHintTextKey> hintKeys_,
|
||||||
|
std::vector<RandomizerCheck> locations_,
|
||||||
|
std::vector<RandomizerArea> areas_,
|
||||||
|
std::vector<TrialKey> trials_)
|
||||||
|
: ownKey(ownKey_), hintType(hintType_), distribution(std::move(distribution_)), hintKeys(hintKeys_), locations(locations_), areas(areas_), trials(trials_) {
|
||||||
|
FillGapsInData();
|
||||||
|
SetLocationsAsHinted();
|
||||||
|
NamesChosen();
|
||||||
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Text& Hint::GetText() const {
|
Hint::Hint(RandomizerHint ownKey_,
|
||||||
return text;
|
HintType hintType_,
|
||||||
|
std::vector<RandomizerHintTextKey> hintKeys_,
|
||||||
|
std::vector<RandomizerCheck> locations_,
|
||||||
|
std::vector<RandomizerArea> areas_,
|
||||||
|
std::vector<TrialKey> trials_,
|
||||||
|
bool yourPocket_,
|
||||||
|
int num_)
|
||||||
|
: ownKey(ownKey_), hintType(hintType_), hintKeys(hintKeys_), locations(locations_), areas(areas_), trials(trials_), yourPocket(yourPocket_), num(num_) {
|
||||||
|
FillGapsInData();
|
||||||
|
SetLocationsAsHinted();
|
||||||
|
NamesChosen();
|
||||||
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hint::SetHintedLocation(RandomizerCheck location) {
|
Hint::Hint(RandomizerHint ownKey_, std::vector<CustomMessage> messages_)
|
||||||
hintedLocation = location;
|
: ownKey(ownKey_), messages(messages_){
|
||||||
|
hintType = HINT_TYPE_MESSAGE;
|
||||||
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomizerCheck Hint::GetHintedLocation() {
|
Hint::Hint(RandomizerHint ownKey_, nlohmann::json json_){
|
||||||
return hintedLocation;
|
ownKey = ownKey_;
|
||||||
|
if (json_.contains("enabled") && !json_["enabled"].get<bool>()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
if (json_.contains("type")){
|
||||||
|
hintType = (HintType)StaticData::hintTypeNameToEnum[json_["type"].get<std::string>()];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintType == HINT_TYPE_MESSAGE){
|
||||||
|
if (json_.contains("messages")){
|
||||||
|
for (auto message: json_["messages"]){
|
||||||
|
messages.push_back(CustomMessage(message.get<std::string>()));
|
||||||
|
}
|
||||||
|
} else if (json_.contains("message")){
|
||||||
|
messages.push_back(CustomMessage(json_["message"].get<std::string>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("distribution")){
|
||||||
|
distribution = json_["distribution"].get<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("locations")){
|
||||||
|
for (auto loc: json_["locations"]){
|
||||||
|
locations.push_back(StaticData::locationNameToEnum[loc.get<std::string>()]);
|
||||||
|
}
|
||||||
|
} else if (json_.contains("location")){
|
||||||
|
locations.push_back(StaticData::locationNameToEnum[json_["location"].get<std::string>()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("itemNamesChosen")){
|
||||||
|
for (auto name: json_["itemNamesChosen"]){
|
||||||
|
itemNamesChosen.push_back(name.get<uint8_t>());
|
||||||
|
}
|
||||||
|
} else if (json_.contains("itemNameChosen")){
|
||||||
|
itemNamesChosen.push_back(json_["itemNameChosen"].get<uint8_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("areas")){
|
||||||
|
for (auto area: json_["areas"]){
|
||||||
|
areas.push_back((RandomizerArea)Rando::StaticData::areaNameToEnum[area]);
|
||||||
|
}
|
||||||
|
} else if (json_.contains("area")){
|
||||||
|
areas.push_back((RandomizerArea)Rando::StaticData::areaNameToEnum[json_["area"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("areaNamesChosen")){
|
||||||
|
for (auto name: json_["areaNamesChosen"]){
|
||||||
|
areaNamesChosen.push_back(name.get<uint8_t>());
|
||||||
|
}
|
||||||
|
} else if (json_.contains("areaNameChosen")){
|
||||||
|
areaNamesChosen.push_back(json_["areaNameChosen"].get<uint8_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("trials")){
|
||||||
|
for (auto trial: json_["trials"]){
|
||||||
|
trials.push_back((TrialKey)Rando::StaticData::trialNameToEnum[trial]);
|
||||||
|
}
|
||||||
|
} else if (json_.contains("trial")){
|
||||||
|
trials.push_back((TrialKey)Rando::StaticData::trialNameToEnum[json_["trial"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("hintKeys")){
|
||||||
|
for (auto hintKey: json_["hintKeys"]){
|
||||||
|
hintKeys.push_back((RandomizerHintTextKey)hintKey.get<uint32_t>());
|
||||||
|
}
|
||||||
|
} else if (json_.contains("hintKey")){
|
||||||
|
hintKeys.push_back((RandomizerHintTextKey)json_["hintKey"].get<uint32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("hintTextsChosen")){
|
||||||
|
for (auto name: json_["hintTextsChosen"]){
|
||||||
|
hintTextsChosen.push_back(name.get<uint8_t>());
|
||||||
|
}
|
||||||
|
} else if (json_.contains("hintTextChosen")){
|
||||||
|
hintTextsChosen.push_back(json_["hintTextChosen"].get<uint8_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_.contains("num")){
|
||||||
|
num = json_["num"].get<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
FillGapsInData();
|
||||||
|
SetLocationsAsHinted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hint::FillGapsInData(){
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
if (locations.size() == 0 && StaticData::staticHintInfoMap.contains(ownKey)){
|
||||||
|
locations = StaticData::staticHintInfoMap[ownKey].targetChecks;
|
||||||
|
}
|
||||||
|
bool fillAreas = true;
|
||||||
|
bool fillItems = true;
|
||||||
|
if (areas.size() > 0){
|
||||||
|
fillAreas = false;
|
||||||
|
}
|
||||||
|
if (items.size() > 0){
|
||||||
|
fillItems = false;
|
||||||
|
}
|
||||||
|
for(uint8_t c = 0; c < locations.size(); c++){
|
||||||
|
if (fillAreas){
|
||||||
|
areas.push_back(ctx->GetItemLocation(locations[c])->GetArea());
|
||||||
|
}
|
||||||
|
if (fillItems){
|
||||||
|
items.push_back(ctx->GetItemLocation(locations[c])->GetPlacedRandomizerGet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hint::SetLocationsAsHinted() const {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
for (uint8_t count = 0; count < locations.size(); count++){
|
||||||
|
ctx->GetItemLocation(locations[count])->AddHintedBy(ownKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t GetRandomHintTextEntry(const HintText hintText){
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
uint8_t size = 0;
|
||||||
|
if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS)){
|
||||||
|
size = hintText.GetAmbiguousSize();
|
||||||
|
} else if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_OBSCURE)){
|
||||||
|
size = hintText.GetObscureSize();
|
||||||
|
}
|
||||||
|
if (size > 0){
|
||||||
|
return Random(0, size);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hint::NamesChosen(){
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
std::vector<uint8_t> namesTemp = {};
|
||||||
|
bool saveNames = false;
|
||||||
|
uint8_t numMessages = GetNumberOfMessages();
|
||||||
|
for (uint8_t c = 0; c < numMessages; c++){
|
||||||
|
uint8_t selection = GetRandomHintTextEntry(GetHintText(c));
|
||||||
|
if (selection > 0){
|
||||||
|
saveNames = true;
|
||||||
|
}
|
||||||
|
namesTemp.push_back(selection);
|
||||||
|
}
|
||||||
|
if (saveNames) {
|
||||||
|
hintTextsChosen = namesTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_ITEM_AREA || hintType == HINT_TYPE_MERCHANT){
|
||||||
|
bool mysterious = hintType == HINT_TYPE_MERCHANT && ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_NO_HINT);
|
||||||
|
for(uint8_t c = 0; c < locations.size(); c++){
|
||||||
|
namesTemp = {};
|
||||||
|
saveNames = false;
|
||||||
|
uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c, mysterious));
|
||||||
|
if (selection > 0){
|
||||||
|
saveNames = true;
|
||||||
|
}
|
||||||
|
namesTemp.push_back(selection);
|
||||||
|
}
|
||||||
|
if (saveNames) {
|
||||||
|
itemNamesChosen = namesTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintType == HINT_TYPE_FOOLISH || hintType == HINT_TYPE_ITEM_AREA || hintType == HINT_TYPE_WOTH ||
|
||||||
|
hintType == HINT_TYPE_ALTAR_CHILD || hintType == HINT_TYPE_ALTAR_ADULT){
|
||||||
|
namesTemp = {};
|
||||||
|
saveNames = false;
|
||||||
|
for(uint8_t c = 0; c < areas.size(); c++){
|
||||||
|
uint8_t selection = GetRandomHintTextEntry(GetAreaHintText(c));
|
||||||
|
if (selection > 0){
|
||||||
|
saveNames = true;
|
||||||
|
}
|
||||||
|
namesTemp.push_back(selection);
|
||||||
|
}
|
||||||
|
if (saveNames) {
|
||||||
|
areaNamesChosen = namesTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Hint::GetNumberOfMessages() const {
|
||||||
|
size_t numMessages = std::max(messages.size(), hintKeys.size());
|
||||||
|
if (StaticData::staticHintInfoMap.contains(ownKey)){
|
||||||
|
numMessages = std::max(StaticData::staticHintInfoMap[ownKey].hintKeys.size(), numMessages);
|
||||||
|
}
|
||||||
|
if (numMessages == 0){
|
||||||
|
numMessages = 1; //RANDOTODO make std::max actually fucking work for 3 arguments
|
||||||
|
}
|
||||||
|
return numMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> Hint::GetAllMessageStrings(MessageFormat format) const {
|
||||||
|
std::vector<std::string> hintMessages = {};
|
||||||
|
uint8_t numMessages = GetNumberOfMessages();
|
||||||
|
for (int c = 0; c < numMessages; c++){
|
||||||
|
hintMessages.push_back(GetHintMessage(format, c).GetForCurrentLanguage(format));
|
||||||
|
}
|
||||||
|
return hintMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HintText Hint::GetHintText(uint8_t id) const {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
if (hintKeys.size() > id){
|
||||||
|
return StaticData::hintTextTable[hintKeys[id]];
|
||||||
|
}
|
||||||
|
// If a static hint, load default from staticHintInfoMap
|
||||||
|
if (StaticData::staticHintInfoMap.contains(ownKey) && StaticData::staticHintInfoMap[ownKey].hintKeys.size() > id){
|
||||||
|
return StaticData::hintTextTable[StaticData::staticHintInfoMap[ownKey].hintKeys[id]];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (hintType){
|
||||||
|
case HINT_TYPE_HINT_KEY:
|
||||||
|
return StaticData::hintTextTable[0];
|
||||||
|
break;
|
||||||
|
case HINT_TYPE_TRIAL:
|
||||||
|
if (ctx->GetTrial(trials[0])->IsRequired()) {
|
||||||
|
return StaticData::hintTextTable[RHT_TRIAL_ON];
|
||||||
|
} else {
|
||||||
|
return StaticData::hintTextTable[RHT_TRIAL_OFF];
|
||||||
|
}
|
||||||
|
case HINT_TYPE_WOTH:
|
||||||
|
return StaticData::hintTextTable[RHT_WAY_OF_THE_HERO];
|
||||||
|
case HINT_TYPE_FOOLISH:
|
||||||
|
return StaticData::hintTextTable[RHT_FOOLISH];
|
||||||
|
case HINT_TYPE_ITEM:
|
||||||
|
if (locations.size() > 0) {
|
||||||
|
return *StaticData::GetLocation(locations[0])->GetHint();
|
||||||
|
} else {
|
||||||
|
return CustomMessage("ERROR: ITEM HINT WITH NO LOCATIONS OR HINT KEY");
|
||||||
|
}
|
||||||
|
case HINT_TYPE_ITEM_AREA:
|
||||||
|
if (locations.size() > 0) {
|
||||||
|
if (StaticData::GetLocation(locations[0])->IsDungeon()) {
|
||||||
|
return StaticData::hintTextTable[RHT_HOARDS];
|
||||||
|
} else {
|
||||||
|
return StaticData::hintTextTable[RHT_CAN_BE_FOUND_AT];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return CustomMessage("ERROR: ITEM AREA HINT WITH NO LOCATION"); //RANDOTODO get isDungeon from area?
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return CustomMessage("ERROR: NO HINTKEY PROVIDED AND HINT TYPE HAS NO DEFAULT");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomMessage Hint::GetHintMessage(MessageFormat format, uint8_t id) const {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
CustomMessage hintText = CustomMessage("");
|
||||||
|
|
||||||
|
uint8_t chosenMessage = 0;
|
||||||
|
if (hintTextsChosen.size() > id){
|
||||||
|
chosenMessage = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintType == HINT_TYPE_MESSAGE){
|
||||||
|
if (id < messages.size()){
|
||||||
|
hintText = messages[id];
|
||||||
|
}
|
||||||
|
} else if (hintType == HINT_TYPE_ALTAR_CHILD){
|
||||||
|
if (ctx->GetOption(RSK_TOT_ALTAR_HINT)){
|
||||||
|
hintText = StaticData::hintTextTable[RHT_CHILD_ALTAR_STONES].GetHintMessage();
|
||||||
|
}
|
||||||
|
if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN)) {
|
||||||
|
hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN].GetHintMessage());
|
||||||
|
} else if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_SONGONLY)) {
|
||||||
|
hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY].GetHintMessage());
|
||||||
|
} else {
|
||||||
|
hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED].GetHintMessage());
|
||||||
|
}
|
||||||
|
} else if (hintType == HINT_TYPE_ALTAR_ADULT){
|
||||||
|
if (ctx->GetOption(RSK_TOT_ALTAR_HINT)){
|
||||||
|
hintText = StaticData::hintTextTable[RHT_ADULT_ALTAR_MEDALLIONS].GetHintMessage();
|
||||||
|
}
|
||||||
|
hintText += GetBridgeReqsText() + GetGanonBossKeyText() + StaticData::hintTextTable[RHT_ADULT_ALTAR_TEXT_END].GetHintMessage();
|
||||||
|
} else {
|
||||||
|
hintText = GetHintText(id).GetHintMessage(chosenMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CustomMessage> toInsert = {};
|
||||||
|
|
||||||
|
switch (hintType){
|
||||||
|
case HINT_TYPE_ITEM:{
|
||||||
|
//if we write items
|
||||||
|
for(uint8_t b = 0; b < locations.size(); b++){
|
||||||
|
toInsert.push_back(GetItemName(b));
|
||||||
|
}
|
||||||
|
break;}
|
||||||
|
case HINT_TYPE_MERCHANT:{
|
||||||
|
//if we write items, but need to adjust for merchants
|
||||||
|
bool mysterious = hintType == HINT_TYPE_MERCHANT && ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_NO_HINT);
|
||||||
|
for(uint8_t b = 0; b < locations.size(); b++){
|
||||||
|
toInsert.push_back(GetItemName(b, mysterious));
|
||||||
|
}
|
||||||
|
break;}
|
||||||
|
case HINT_TYPE_TRIAL:{
|
||||||
|
//If we write trials
|
||||||
|
for(uint8_t b = 0; b < trials.size(); b++){
|
||||||
|
toInsert.push_back(ctx->GetTrial(trials[b])->GetName());
|
||||||
|
}
|
||||||
|
break;}
|
||||||
|
case HINT_TYPE_ITEM_AREA:{
|
||||||
|
//If we write items and areas
|
||||||
|
for(uint8_t b = 0; b < items.size(); b++){
|
||||||
|
toInsert.push_back(GetItemName(b));
|
||||||
|
toInsert.push_back(GetAreaName(b));
|
||||||
|
}
|
||||||
|
break;}
|
||||||
|
case HINT_TYPE_ALTAR_CHILD:
|
||||||
|
case HINT_TYPE_ALTAR_ADULT:
|
||||||
|
case HINT_TYPE_AREA:
|
||||||
|
case HINT_TYPE_WOTH:
|
||||||
|
case HINT_TYPE_FOOLISH:{
|
||||||
|
//If we write areas
|
||||||
|
for(uint8_t b = 0; b < areas.size(); b++){
|
||||||
|
toInsert.push_back(GetAreaName(b));
|
||||||
|
}
|
||||||
|
break;}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hintText.InsertNames(toInsert);
|
||||||
|
|
||||||
|
if (num != 0){
|
||||||
|
hintText.InsertNumber(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == MF_FORMATTED){
|
||||||
|
hintText.Format();
|
||||||
|
} else if (format == MF_AUTO_FORMAT){
|
||||||
|
hintText.AutoFormat();
|
||||||
|
} else if (format == MF_CLEAN){
|
||||||
|
hintText.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hintText;
|
||||||
|
}
|
||||||
|
|
||||||
|
oJson Hint::toJSON() {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
nlohmann::ordered_json log = {};
|
||||||
|
if (enabled){
|
||||||
|
log["type"] = StaticData::hintTypeNames[hintType].GetForCurrentLanguage(MF_CLEAN);
|
||||||
|
|
||||||
|
std::vector<std::string> hintMessages = GetAllMessageStrings(MF_CLEAN);
|
||||||
|
if (hintMessages.size() == 1){
|
||||||
|
log["message"] = hintMessages[0];
|
||||||
|
} else if (hintMessages.size() > 1){
|
||||||
|
log["messages"] = hintMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distribution != ""){
|
||||||
|
log["distribution"] = distribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintType != HINT_TYPE_FOOLISH){
|
||||||
|
if (!(StaticData::staticHintInfoMap.contains(ownKey) &&
|
||||||
|
StaticData::staticHintInfoMap[ownKey].targetChecks.size() > 0)){
|
||||||
|
if (locations.size() == 1){
|
||||||
|
log["location"] = StaticData::GetLocation(locations[0])->GetName();//RANDOTODO change to CustomMessage when VB is done;
|
||||||
|
} else if (locations.size() > 1){
|
||||||
|
//If we have defaults, no need to write more
|
||||||
|
std::vector<std::string> locStrings = {};
|
||||||
|
for (size_t c = 0; c < locations.size(); c++){
|
||||||
|
locStrings.push_back(StaticData::GetLocation(locations[c])->GetName());//RANDOTODO change to CustomMessage when VB is done
|
||||||
|
}
|
||||||
|
log["locations"] = locStrings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(StaticData::staticHintInfoMap.contains(ownKey) &&
|
||||||
|
StaticData::staticHintInfoMap[ownKey].targetItems.size() > 0)){
|
||||||
|
if (items.size() == 1){
|
||||||
|
log["item"] = StaticData::GetItemTable()[items[0]].GetName().GetEnglish();//RANDOTODO change to CustomMessage;
|
||||||
|
} else if (items.size() > 1){
|
||||||
|
std::vector<std::string> itemStrings = {};
|
||||||
|
for (size_t c = 0; c < items.size(); c++){
|
||||||
|
itemStrings.push_back(StaticData::GetItemTable()[items[c]].GetName().GetEnglish());//RANDOTODO change to CustomMessage
|
||||||
|
}
|
||||||
|
log["items"] = itemStrings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemNamesChosen.size() == 1){
|
||||||
|
log["itemNameChosen"] = itemNamesChosen[0];
|
||||||
|
} else if (itemNamesChosen.size() > 1){
|
||||||
|
std::vector<uint8_t> nameNums = {};
|
||||||
|
for (size_t c = 0; c < itemNamesChosen.size(); c++){
|
||||||
|
nameNums.push_back(itemNamesChosen[c]);
|
||||||
|
}
|
||||||
|
log["itemNamesChosen"] = nameNums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (areas.size() == 1){
|
||||||
|
log["area"] = StaticData::hintTextTable[StaticData::areaNames[areas[0]]].GetClear().GetForCurrentLanguage(MF_CLEAN);
|
||||||
|
} else if (areas.size() > 0 &&
|
||||||
|
!(StaticData::staticHintInfoMap.contains(ownKey) && StaticData::staticHintInfoMap[ownKey].targetChecks.size() > 0)){
|
||||||
|
// If we got locations from defaults, areas are derived from them and don't need logging
|
||||||
|
std::vector<std::string> areaStrings = {};
|
||||||
|
for (size_t c = 0; c < areas.size(); c++){
|
||||||
|
areaStrings.push_back(StaticData::hintTextTable[StaticData::areaNames[areas[c]]].GetClear().GetForCurrentLanguage(MF_CLEAN));
|
||||||
|
}
|
||||||
|
log["areas"] = areaStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areaNamesChosen.size() == 1){
|
||||||
|
log["areaNameChosen"] = areaNamesChosen[0];
|
||||||
|
} else if (areaNamesChosen.size() > 1){
|
||||||
|
std::vector<uint8_t> nameNums = {};
|
||||||
|
for (size_t c = 0; c < areaNamesChosen.size(); c++){
|
||||||
|
nameNums.push_back(areaNamesChosen[c]);
|
||||||
|
}
|
||||||
|
log["areaNamesChosen"] = nameNums;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trials.size() == 1){
|
||||||
|
log["trial"] = ctx->GetTrial(trials[0])->GetName().GetForCurrentLanguage(MF_CLEAN);
|
||||||
|
} else if (trials.size() > 0){
|
||||||
|
std::vector<std::string> trialStrings = {};
|
||||||
|
for (size_t c = 0; c < trials.size(); c++){
|
||||||
|
trialStrings.push_back(ctx->GetTrial(trials[c])->GetName().GetForCurrentLanguage(MF_CLEAN));
|
||||||
|
}
|
||||||
|
log["trials"] = trialStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintKeys.size() == 1){
|
||||||
|
log["hintKey"] = hintKeys[0];
|
||||||
|
} else if (hintKeys.size() > 1){
|
||||||
|
std::vector<uint32_t> hintKeyNums = {};
|
||||||
|
for (size_t c = 0; c < hintKeys.size(); c++){
|
||||||
|
hintKeyNums.push_back(hintKeys[c]);
|
||||||
|
}
|
||||||
|
log["hintKeys"] = hintKeyNums;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hintTextsChosen.size() == 1){
|
||||||
|
log["hintTextChosen"] = hintTextsChosen[0];
|
||||||
|
} else if (hintTextsChosen.size() > 1){
|
||||||
|
std::vector<uint8_t> nameNums = {};
|
||||||
|
for (size_t c = 0; c < hintTextsChosen.size(); c++){
|
||||||
|
nameNums.push_back(hintTextsChosen[c]);
|
||||||
|
}
|
||||||
|
log["hintTextsChosen"] = nameNums;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num != 0){
|
||||||
|
log["num"] = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hint::logHint(oJson& jsonData){
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
std::string logMap = "Static Hints";
|
||||||
|
bool staticHint = true;
|
||||||
|
if (ownKey < RH_GANONDORF_HINT){
|
||||||
|
logMap = "Gossip Stone Hints";
|
||||||
|
staticHint = false;
|
||||||
|
}
|
||||||
|
if (enabled &&
|
||||||
|
(!(staticHint && (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_MERCHANT) && ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_CLEAR)))){
|
||||||
|
//skip if not enabled or if a static hint with no possible variance
|
||||||
|
jsonData[logMap][Rando::StaticData::hintNames[ownKey].GetForCurrentLanguage(MF_CLEAN)] = toJSON();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const HintText Hint::GetItemHintText(uint8_t slot, bool mysterious) const {
|
||||||
|
//RANDOTODO make unreliant on locations, or make Hint accept ItemLocation
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
RandomizerCheck hintedCheck = locations[slot];
|
||||||
|
RandomizerGet targetRG = ctx->GetItemLocation(hintedCheck)->GetPlacedRandomizerGet();
|
||||||
|
if (mysterious){
|
||||||
|
return StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM];
|
||||||
|
} else if (!ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS) && targetRG == RG_ICE_TRAP) { //RANDOTODO store in item hint instead of item
|
||||||
|
return HintText(CustomMessage({ctx->overrides[hintedCheck].GetTrickName()}));
|
||||||
|
} else {
|
||||||
|
return ctx->GetItemLocation(hintedCheck)->GetPlacedItem().GetHint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const HintText Hint::GetAreaHintText(uint8_t slot) const {
|
||||||
|
CustomMessage areaText;
|
||||||
|
if (yourPocket && (areas[slot] == RA_LINKS_POCKET || areas[slot] == RA_NONE)){
|
||||||
|
return StaticData::hintTextTable[RHT_YOUR_POCKET];
|
||||||
|
} else {
|
||||||
|
return StaticData::hintTextTable[Rando::StaticData::areaNames[areas[slot]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const CustomMessage Hint::GetItemName(uint8_t slot, bool mysterious) const {
|
||||||
|
uint8_t nameNum = 0;
|
||||||
|
if (itemNamesChosen.size() > slot){
|
||||||
|
nameNum = itemNamesChosen[slot];
|
||||||
|
}
|
||||||
|
return GetItemHintText(slot, mysterious).GetHintMessage(nameNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomMessage Hint::GetAreaName(uint8_t slot) const {
|
||||||
|
uint8_t nameNum = 0;
|
||||||
|
if (areaNamesChosen.size() > slot){
|
||||||
|
nameNum = areaNamesChosen[slot];
|
||||||
|
}
|
||||||
|
return GetAreaHintText(slot).GetHintMessage(nameNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CustomMessage Hint::GetBridgeReqsText() {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
CustomMessage bridgeMessage;
|
||||||
|
|
||||||
|
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN)) {
|
||||||
|
return StaticData::hintTextTable[RHT_BRIDGE_OPEN_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA)) {
|
||||||
|
return StaticData::hintTextTable[RHT_BRIDGE_VANILLA_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) {
|
||||||
|
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_STONES_HINT].GetHintMessage();
|
||||||
|
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) {
|
||||||
|
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT].GetHintMessage();
|
||||||
|
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) {
|
||||||
|
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_REWARDS_HINT].GetHintMessage();
|
||||||
|
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) {
|
||||||
|
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_DUNGEONS_HINT].GetHintMessage();
|
||||||
|
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) {
|
||||||
|
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_TOKENS_HINT].GetHintMessage();
|
||||||
|
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)) {
|
||||||
|
return StaticData::hintTextTable[RHT_BRIDGE_GREG_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
return bridgeMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMessage Hint::GetGanonBossKeyText() {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
|
CustomMessage ganonBossKeyMessage;
|
||||||
|
|
||||||
|
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_START_WITH_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_VANILLA_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_OWN_DUNGEON_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_ANY_DUNGEON_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_OVERWORLD_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_ANYWHERE_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_SKULLTULA_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_VANILLA)) {
|
||||||
|
return StaticData::hintTextTable[RHT_LACS_VANILLA_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) {
|
||||||
|
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_STONES_HINT].GetHintMessage();
|
||||||
|
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) {
|
||||||
|
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_MEDALLIONS_HINT].GetHintMessage();
|
||||||
|
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) {
|
||||||
|
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_REWARDS_HINT].GetHintMessage();
|
||||||
|
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) {
|
||||||
|
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_DUNGEONS_HINT].GetHintMessage();
|
||||||
|
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
|
||||||
|
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage();
|
||||||
|
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value<uint8_t>());
|
||||||
|
}
|
||||||
|
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) {
|
||||||
|
return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage();
|
||||||
|
}
|
||||||
|
return ganonBossKeyMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Hint::AddHintedLocation(RandomizerCheck location) {
|
||||||
|
locations.push_back(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RandomizerCheck> Hint::GetHintedLocations() const {
|
||||||
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hint::SetHintType(HintType type) {
|
void Hint::SetHintType(HintType type) {
|
||||||
hintType = type;
|
hintType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
HintType Hint::GetHintType() {
|
HintType Hint::GetHintType() const {
|
||||||
return hintType;
|
return hintType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hint::SetHintedArea(RandomizerArea area) {
|
void Hint::AddHintedArea(RandomizerArea area) {
|
||||||
hintedArea = area;
|
areas.push_back(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomizerArea Hint::GetHintedArea() {
|
std::vector<RandomizerArea> Hint::GetHintedAreas() const {
|
||||||
return hintedArea;
|
return areas;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hint::SetDistribution(std::string distributionName) {
|
void Hint::SetDistribution(std::string distributionName) {
|
||||||
distribution = distributionName;
|
distribution = distributionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Hint::GetDistribution() {
|
const std::string& Hint::GetDistribution() const {
|
||||||
return distribution;
|
return distribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Hint::IsEnabled() const{
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RandomizerHintTextKey> Hint::GetHintTextKeys() const{
|
||||||
|
return hintKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RandomizerGet> Hint::GetHintedItems() const{
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> Hint::GetItemNamesChosen() const{
|
||||||
|
return itemNamesChosen;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> Hint::GetHintTextsChosen() const{
|
||||||
|
return hintTextsChosen;
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> Hint::GetAreaTextsChosen() const{
|
||||||
|
return areaNamesChosen;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TrialKey> Hint::GetHintedTrials() const{
|
||||||
|
return trials;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Hint::GetNum(){
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
void Hint::ResetVariables() {
|
void Hint::ResetVariables() {
|
||||||
hintedLocation = RC_UNKNOWN_CHECK;
|
ownKey = RH_NONE;
|
||||||
text = Text{};
|
num = 0;
|
||||||
|
yourPocket = false;
|
||||||
|
messages = {};
|
||||||
|
hintKeys = {};
|
||||||
|
locations = {};
|
||||||
|
items = {};
|
||||||
|
trials = {};
|
||||||
|
hintType = HINT_TYPE_HINT_KEY;
|
||||||
|
areas = {};
|
||||||
distribution = "";
|
distribution = "";
|
||||||
hintedArea = RA_NONE;
|
enabled = false;
|
||||||
hintType = HINT_TYPE_STATIC;
|
itemNamesChosen = {};
|
||||||
addedToPool = false;
|
hintTextsChosen = {};
|
||||||
|
areaNamesChosen = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,33 +1,82 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "3drando/text.hpp"
|
#include "3drando/text.hpp"
|
||||||
|
#include "3drando/hints.hpp"
|
||||||
|
#include "../custom-message/CustomMessageManager.h"
|
||||||
#include "randomizerTypes.h"
|
#include "randomizerTypes.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
using oJson = nlohmann::ordered_json;
|
||||||
|
|
||||||
namespace Rando {
|
namespace Rando {
|
||||||
class Hint {
|
class Hint {
|
||||||
public:
|
public:
|
||||||
Hint();
|
Hint();
|
||||||
Hint(Text text_);
|
Hint(RandomizerHint ownKey_,
|
||||||
Hint(Text text_, RandomizerCheck hintedLocation_, HintType hintType_, std::string distributionName_, RandomizerArea hintedArea_);
|
HintType hintType_,
|
||||||
const Text& GetText() const;
|
std::string distributionName_,
|
||||||
RandomizerCheck GetHintedLocation();
|
std::vector<RandomizerHintTextKey> hintKeys_,
|
||||||
void SetHintedLocation (RandomizerCheck location);
|
std::vector<RandomizerCheck> locations_,
|
||||||
HintType GetHintType();
|
std::vector<RandomizerArea> areas_ = {},
|
||||||
|
std::vector<TrialKey> trials_ = {});
|
||||||
|
Hint(RandomizerHint ownKey_,
|
||||||
|
HintType hintType_,
|
||||||
|
std::vector<RandomizerHintTextKey> hintKeys_,
|
||||||
|
std::vector<RandomizerCheck> locations_ = {},
|
||||||
|
std::vector<RandomizerArea> areas_ = {},
|
||||||
|
std::vector<TrialKey> trials_ = {},
|
||||||
|
bool yourPocket_ = false,
|
||||||
|
int num_ = 0);
|
||||||
|
Hint(RandomizerHint ownKey_, std::vector<CustomMessage> messages_);
|
||||||
|
Hint(RandomizerHint ownKey_, nlohmann::json json_);
|
||||||
|
void FillGapsInData();
|
||||||
|
void SetLocationsAsHinted() const;
|
||||||
|
void NamesChosen();
|
||||||
|
uint8_t GetNumberOfMessages() const;
|
||||||
|
const std::vector<std::string> GetAllMessageStrings(MessageFormat format = MF_AUTO_FORMAT) const ;
|
||||||
|
const CustomMessage GetHintMessage(MessageFormat format = MF_AUTO_FORMAT, uint8_t id = 0) const ;
|
||||||
|
const HintText GetHintText(uint8_t id = 0) const;
|
||||||
|
oJson toJSON();
|
||||||
|
void logHint(oJson& jsonData);
|
||||||
|
const HintText GetItemHintText(uint8_t slot, bool mysterious) const;
|
||||||
|
const HintText GetAreaHintText(uint8_t slot) const;
|
||||||
|
const CustomMessage GetItemName(uint8_t slot, bool mysterious = false) const;
|
||||||
|
const CustomMessage GetAreaName(uint8_t slot) const;
|
||||||
|
static CustomMessage GetBridgeReqsText();
|
||||||
|
static CustomMessage GetGanonBossKeyText();
|
||||||
|
void AddHintedLocation (RandomizerCheck location);
|
||||||
|
std::vector<RandomizerCheck> GetHintedLocations() const;
|
||||||
void SetHintType (HintType type);
|
void SetHintType (HintType type);
|
||||||
RandomizerArea GetHintedArea();
|
HintType GetHintType() const;
|
||||||
void SetHintedArea (RandomizerArea area);
|
void AddHintedArea (RandomizerArea area);
|
||||||
const std::string& GetDistribution();
|
std::vector<RandomizerArea> GetHintedAreas() const;
|
||||||
void SetDistribution (std::string distribution);
|
void SetDistribution (std::string distribution);
|
||||||
|
const std::string& GetDistribution() const;
|
||||||
|
bool IsEnabled() const;
|
||||||
|
std::vector<RandomizerHintTextKey> GetHintTextKeys() const;
|
||||||
|
std::vector<RandomizerGet> GetHintedItems() const;
|
||||||
|
std::vector<uint8_t> GetItemNamesChosen() const;
|
||||||
|
std::vector<uint8_t> GetHintTextsChosen() const;
|
||||||
|
std::vector<uint8_t> GetAreaTextsChosen() const;
|
||||||
|
std::vector<TrialKey> GetHintedTrials() const;
|
||||||
|
int GetNum();
|
||||||
void ResetVariables();
|
void ResetVariables();
|
||||||
bool IsAddedToPool();
|
|
||||||
void AddToPool();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Text text = Text();
|
RandomizerHint ownKey = RH_NONE;
|
||||||
RandomizerCheck hintedLocation = RC_UNKNOWN_CHECK;
|
HintType hintType = HINT_TYPE_HINT_KEY;
|
||||||
HintType hintType = HINT_TYPE_STATIC;
|
|
||||||
RandomizerArea hintedArea = RA_NONE;
|
|
||||||
std::string distribution = "";
|
std::string distribution = "";
|
||||||
bool addedToPool = false;
|
std::vector<RandomizerHintTextKey> hintKeys = {};
|
||||||
|
std::vector<RandomizerCheck> locations = {};
|
||||||
|
std::vector<RandomizerArea> areas = {};
|
||||||
|
std::vector<TrialKey> trials = {};
|
||||||
|
bool yourPocket = false;
|
||||||
|
int num = 0;
|
||||||
|
std::vector<CustomMessage> messages = {};
|
||||||
|
std::vector<RandomizerGet> items = {};
|
||||||
|
bool enabled = false;
|
||||||
|
std::vector<uint8_t> itemNamesChosen = {};
|
||||||
|
std::vector<uint8_t> hintTextsChosen = {};
|
||||||
|
std::vector<uint8_t> areaNamesChosen = {};
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -378,7 +378,7 @@ RandomizerHintTextKey Item::GetHintKey() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HintText& Item::GetHint() const {
|
const HintText& Item::GetHint() const {
|
||||||
return ::Hint(hintKey);
|
return StaticData::hintTextTable[hintKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item::operator==(const Item& right) const {
|
bool Item::operator==(const Item& right) const {
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "3drando/text.hpp"
|
#include "3drando/text.hpp"
|
||||||
#include "3drando/hint_list.hpp"
|
|
||||||
#include "randomizerTypes.h"
|
#include "randomizerTypes.h"
|
||||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||||
|
#include "3drando/hints.hpp"
|
||||||
|
|
||||||
enum ItemType {
|
enum ItemType {
|
||||||
ITEMTYPE_ITEM,
|
ITEMTYPE_ITEM,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
using namespace Rando;
|
using namespace Rando;
|
||||||
|
|
||||||
std::array<Item, RG_MAX> Rando::StaticData::itemTable;
|
std::array<Item, RG_MAX> Rando::StaticData::itemTable;
|
||||||
std::unordered_map<std::string, RandomizerGet> Rando::StaticData::SpoilerfileItemNameToEnum;
|
std::unordered_map<std::string, RandomizerGet> Rando::StaticData::itemNameToEnum;
|
||||||
|
|
||||||
void Rando::StaticData::InitItemTable() {
|
void Rando::StaticData::InitItemTable() {
|
||||||
auto logic = Context::GetInstance()->GetLogic();
|
auto logic = Context::GetInstance()->GetLogic();
|
||||||
@ -322,15 +322,15 @@ void Rando::StaticData::InitItemTable() {
|
|||||||
itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbesserte Magieanzeige" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
|
itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbesserte Magieanzeige" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
|
||||||
itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce Piece" }, ITEMTYPE_ITEM, 0xDF, true, &logic->TriforcePieces, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce Piece" }, ITEMTYPE_ITEM, 0xDF, true, &logic->TriforcePieces, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||||
|
|
||||||
// Init SpoilerfileItemNameToEnum
|
// Init itemNameToEnum
|
||||||
for (auto& item : itemTable) {
|
for (auto& item : itemTable) {
|
||||||
// Easiest way to filter out all the empty values from the array, since we still technically want the 0/RG_NONE
|
// Easiest way to filter out all the empty values from the array, since we still technically want the 0/RG_NONE
|
||||||
// entry
|
// entry
|
||||||
if (item.GetName().english.empty()) {
|
if (item.GetName().english.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SpoilerfileItemNameToEnum[item.GetName().english] = item.GetRandomizerGet();
|
itemNameToEnum[item.GetName().english] = item.GetRandomizerGet();
|
||||||
SpoilerfileItemNameToEnum[item.GetName().french] = item.GetRandomizerGet();
|
itemNameToEnum[item.GetName().french] = item.GetRandomizerGet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,19 +121,19 @@ void ItemLocation::SetAsHintable() {
|
|||||||
isHintable = true;
|
isHintable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLocation::IsHintedAt() const {
|
bool ItemLocation::IsAHintAccessible() const {
|
||||||
return hintedAt;
|
return hintAccesible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLocation::SetAsHinted() {
|
void ItemLocation::SetHintAccesible() {
|
||||||
hintedAt = true;
|
hintAccesible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<RandomizerHintKey>& ItemLocation::GetHintedBy() const {
|
const std::vector<RandomizerHint>& ItemLocation::GetHintedBy() const {
|
||||||
return hintedBy;
|
return hintedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLocation::AddHintedBy(const RandomizerHintKey hintKey) {
|
void ItemLocation::AddHintedBy(const RandomizerHint hintKey) {
|
||||||
hintedBy.push_back(hintKey);
|
hintedBy.push_back(hintKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ void ItemLocation::ResetVariables() {
|
|||||||
placedItem = RG_NONE;
|
placedItem = RG_NONE;
|
||||||
delayedItem = RG_NONE;
|
delayedItem = RG_NONE;
|
||||||
isHintable = false;
|
isHintable = false;
|
||||||
hintedAt = false;
|
hintAccesible = false;
|
||||||
hintedBy = {};
|
hintedBy = {};
|
||||||
price = 0;
|
price = 0;
|
||||||
hasCustomPrice = false;
|
hasCustomPrice = false;
|
||||||
|
@ -36,10 +36,10 @@ class ItemLocation {
|
|||||||
void MarkAsNotObtained();
|
void MarkAsNotObtained();
|
||||||
bool IsHintable() const;
|
bool IsHintable() const;
|
||||||
void SetAsHintable();
|
void SetAsHintable();
|
||||||
bool IsHintedAt() const;
|
bool IsAHintAccessible() const;
|
||||||
void SetAsHinted();
|
void SetHintAccesible();
|
||||||
const std::vector<RandomizerHintKey>& GetHintedBy() const;
|
const std::vector<RandomizerHint>& GetHintedBy() const;
|
||||||
void AddHintedBy(RandomizerHintKey hintKey);
|
void AddHintedBy(RandomizerHint hintKey);
|
||||||
bool IsHidden() const;
|
bool IsHidden() const;
|
||||||
bool IsExcluded() const;
|
bool IsExcluded() const;
|
||||||
void AddExcludeOption();
|
void AddExcludeOption();
|
||||||
@ -55,8 +55,8 @@ class ItemLocation {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
RandomizerCheck rc;
|
RandomizerCheck rc;
|
||||||
std::vector<RandomizerHintKey> hintedBy = {};
|
std::vector<RandomizerHint> hintedBy = {};
|
||||||
bool hintedAt = false;
|
bool hintAccesible = false;
|
||||||
bool isHintable = false;
|
bool isHintable = false;
|
||||||
bool addedToPool = false;
|
bool addedToPool = false;
|
||||||
RandomizerGet placedItem = RG_NONE;
|
RandomizerGet placedItem = RG_NONE;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "location.h"
|
#include "location.h"
|
||||||
#include "3drando/hint_list.hpp"
|
#include "static_data.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
RandomizerCheck Rando::Location::GetRandomizerCheck() const {
|
RandomizerCheck Rando::Location::GetRandomizerCheck() const {
|
||||||
@ -47,7 +47,7 @@ RandomizerHintTextKey Rando::Location::GetHintKey() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HintText* Rando::Location::GetHint() {
|
HintText* Rando::Location::GetHint() {
|
||||||
return &hintTable[hintKey];
|
return &StaticData::hintTextTable[hintKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Rando::Location::GetName() const {
|
const std::string& Rando::Location::GetName() const {
|
||||||
@ -90,7 +90,7 @@ uint32_t Rando::Location::Getuint32_t() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HintText& Rando::Location::GetHint() const {
|
const HintText& Rando::Location::GetHint() const {
|
||||||
return Hint(hintKey);
|
return StaticData::hintTextTable[hintKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomizerGet Rando::Location::GetVanillaItem() const {
|
RandomizerGet Rando::Location::GetVanillaItem() const {
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#define TWO_ACTOR_PARAMS(a, b) (abs(a) << 16) | abs(b)
|
#define TWO_ACTOR_PARAMS(a, b) (abs(a) << 16) | abs(b)
|
||||||
|
|
||||||
std::array<Rando::Location, RC_MAX> Rando::StaticData::locationTable;
|
std::array<Rando::Location, RC_MAX> Rando::StaticData::locationTable;
|
||||||
std::unordered_map<std::string, RandomizerCheck> Rando::StaticData::SpoilerfileCheckNameToEnum;
|
|
||||||
std::multimap<std::tuple<s16, s16, s32>, RandomizerCheck> Rando::StaticData::CheckFromActorMultimap;
|
std::multimap<std::tuple<s16, s16, s32>, RandomizerCheck> Rando::StaticData::CheckFromActorMultimap;
|
||||||
|
|
||||||
std::vector<RandomizerCheck> KF_ShopLocations = {
|
std::vector<RandomizerCheck> KF_ShopLocations = {
|
||||||
@ -507,49 +506,49 @@ std::vector<RandomizerCheck> Rando::StaticData::overworldLocations = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector<RandomizerCheck> Rando::StaticData::gossipStoneLocations = {
|
std::vector<RandomizerCheck> Rando::StaticData::gossipStoneLocations = {
|
||||||
RC_COLOSSUS_GOSSIP_STONE,
|
|
||||||
RC_DMC_GOSSIP_STONE,
|
|
||||||
RC_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_DMT_GOSSIP_STONE,
|
|
||||||
RC_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_DODONGOS_CAVERN_GOSSIP_STONE,
|
|
||||||
RC_FAIRY_GOSSIP_STONE,
|
|
||||||
RC_GC_MAZE_GOSSIP_STONE,
|
|
||||||
RC_GC_MEDIGORON_GOSSIP_STONE,
|
|
||||||
RC_GV_GOSSIP_STONE,
|
|
||||||
RC_GY_GOSSIP_STONE,
|
|
||||||
RC_HC_MALON_GOSSIP_STONE,
|
|
||||||
RC_HC_ROCK_WALL_GOSSIP_STONE,
|
|
||||||
RC_HC_STORMS_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_HF_COW_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_HF_NEAR_MARKET_GOSSIP_STONE,
|
|
||||||
RC_HF_OPEN_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_HF_SOUTHEAST_GOSSIP_STONE,
|
|
||||||
RC_JABU_GOSSIP_STONE,
|
|
||||||
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
||||||
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
||||||
RC_KF_GOSSIP_STONE,
|
RC_KF_GOSSIP_STONE,
|
||||||
RC_KF_STORMS_GOSSIP_STONE,
|
RC_KF_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
RC_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_LH_LAB_GOSSIP_STONE,
|
|
||||||
RC_LH_SOUTHEAST_GOSSIP_STONE,
|
|
||||||
RC_LH_SOUTHWEST_GOSSIP_STONE,
|
|
||||||
RC_LW_GOSSIP_STONE,
|
RC_LW_GOSSIP_STONE,
|
||||||
RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE,
|
RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE,
|
||||||
RC_SFM_MAZE_LOWER_GOSSIP_STONE,
|
RC_SFM_MAZE_LOWER_GOSSIP_STONE,
|
||||||
RC_SFM_MAZE_UPPER_GOSSIP_STONE,
|
RC_SFM_MAZE_UPPER_GOSSIP_STONE,
|
||||||
RC_SFM_SARIA_GOSSIP_STONE,
|
RC_SFM_SARIA_GOSSIP_STONE,
|
||||||
|
RC_HF_COW_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_HF_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE,
|
||||||
RC_TOT_LEFT_CENTER_GOSSIP_STONE,
|
RC_TOT_LEFT_CENTER_GOSSIP_STONE,
|
||||||
RC_TOT_LEFT_GOSSIP_STONE,
|
RC_TOT_LEFTMOST_GOSSIP_STONE,
|
||||||
RC_TOT_RIGHT_CENTER_GOSSIP_STONE,
|
RC_TOT_RIGHT_CENTER_GOSSIP_STONE,
|
||||||
RC_TOT_RIGHT_GOSSIP_STONE,
|
RC_TOT_RIGHTMOST_GOSSIP_STONE,
|
||||||
RC_ZD_GOSSIP_STONE,
|
RC_HC_MALON_GOSSIP_STONE,
|
||||||
|
RC_HC_ROCK_WALL_GOSSIP_STONE,
|
||||||
|
RC_HC_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_GRAVEYARD_GOSSIP_STONE,
|
||||||
|
RC_DMT_GOSSIP_STONE,
|
||||||
|
RC_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_GC_MAZE_GOSSIP_STONE,
|
||||||
|
RC_GC_MEDIGORON_GOSSIP_STONE,
|
||||||
|
RC_DMC_GOSSIP_STONE,
|
||||||
|
RC_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
||||||
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
||||||
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
||||||
RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_ZD_GOSSIP_STONE,
|
||||||
|
RC_ZF_JABU_GOSSIP_STONE,
|
||||||
|
RC_ZF_FAIRY_GOSSIP_STONE,
|
||||||
|
RC_LH_LAB_GOSSIP_STONE,
|
||||||
|
RC_LH_SOUTHEAST_GOSSIP_STONE,
|
||||||
|
RC_LH_SOUTHWEST_GOSSIP_STONE,
|
||||||
|
RC_GV_GOSSIP_STONE,
|
||||||
|
RC_COLOSSUS_GOSSIP_STONE,
|
||||||
|
RC_DODONGOS_CAVERN_GOSSIP_STONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<RandomizerCheck> Rando::StaticData::otherHintLocations = {
|
std::vector<RandomizerCheck> Rando::StaticData::staticHintLocations = {
|
||||||
RC_GANONDORF_HINT,
|
RC_GANONDORF_HINT,
|
||||||
RC_SHEIK_HINT_GC,
|
RC_SHEIK_HINT_GC,
|
||||||
RC_SHEIK_HINT_MQ_GC,
|
RC_SHEIK_HINT_MQ_GC,
|
||||||
@ -1520,14 +1519,14 @@ void Rando::StaticData::InitLocationTable() { //
|
|||||||
locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 14353, 0x11, "Gossip Stone", "GV Gossip Stone", {});
|
locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 14353, 0x11, "Gossip Stone", "GV Gossip Stone", {});
|
||||||
locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14357, 0x15, "Maze Gossip Stone", "GC Maze Gossip Stone", {});
|
locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14357, 0x15, "Maze Gossip Stone", "GC Maze Gossip Stone", {});
|
||||||
locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14873, 0x19, "Medigoron Gossip Stone", "GC Medigoron Gossip Stone", {});
|
locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, 14873, 0x19, "Medigoron Gossip Stone", "GC Medigoron Gossip Stone", {});
|
||||||
locationTable[RC_GY_GOSSIP_STONE] = Location::HintStone(RC_GY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 14346, 0x0A, "Gossip Stone", "GY Gossip Stone", {});
|
locationTable[RC_GRAVEYARD_GOSSIP_STONE] = Location::HintStone(RC_GRAVEYARD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 14346, 0x0A, "Gossip Stone", "GY Gossip Stone", {});
|
||||||
locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14610, 0x12, "Malon Gossip Stone", "HC Malon Gossip Stone", {});
|
locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14610, 0x12, "Malon Gossip Stone", "HC Malon Gossip Stone", {});
|
||||||
locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14347, 0x0B, "Rock Wall Gossip Stone", "HC Rock Wall Gossip Stone", {});
|
locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, 14347, 0x0B, "Rock Wall Gossip Stone", "HC Rock Wall Gossip Stone", {});
|
||||||
locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, 0x13, "Storms Grotto Gossip Stone", "HC Storms Grotto Gossip Stone", {});
|
locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, 0x13, "Storms Grotto Gossip Stone", "HC Storms Grotto Gossip Stone", {});
|
||||||
locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14623, 0x1F, "Deku Tree Left Gossip Stone", "KF Deku Tree Left Gossip Stone", {});
|
locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14623, 0x1F, "Deku Tree Left Gossip Stone", "KF Deku Tree Left Gossip Stone", {});
|
||||||
locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14880, 0x20, "Deku Tree Right Gossip Stone", "KF Deku Tree Right Gossip Stone", {});
|
locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14880, 0x20, "Deku Tree Right Gossip Stone", "KF Deku Tree Right Gossip Stone", {});
|
||||||
locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14366, 0x1E, "Gossip Stone", "KF Gossip Stone", {});
|
locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 14366, 0x1E, "Gossip Stone", "KF Gossip Stone", {});
|
||||||
locationTable[RC_KF_STORMS_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, 0x3C, "Storms Gossip Stone", "KF Storms Gossip Stone", {});
|
locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, 0x3C, "Storms Gossip Stone", "KF Storms Gossip Stone", {});
|
||||||
locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14339, 0x03, "Lab Gossip Stone", "LH Lab Gossip Stone", {});
|
locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14339, 0x03, "Lab Gossip Stone", "LH Lab Gossip Stone", {});
|
||||||
locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14863, 0x0F, "Southeast Gossip Stone", "LH Southeast Gossip Stone", {});
|
locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14863, 0x0F, "Southeast Gossip Stone", "LH Southeast Gossip Stone", {});
|
||||||
locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14600, 0x08, "Southwest Gossip Stone", "LH Southwest Gossip Stone", {});
|
locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 14600, 0x08, "Southwest Gossip Stone", "LH Southwest Gossip Stone", {});
|
||||||
@ -1535,22 +1534,22 @@ void Rando::StaticData::InitLocationTable() { //
|
|||||||
locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14358, 0x16, "Maze Lower Gossip Stone", "SFM Maze Lower Gossip Stone", {});
|
locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14358, 0x16, "Maze Lower Gossip Stone", "SFM Maze Lower Gossip Stone", {});
|
||||||
locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14615, 0x17, "Maze Upper Gossip Stone", "SFM Maze Upper Gossip Stone", {});
|
locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14615, 0x17, "Maze Upper Gossip Stone", "SFM Maze Upper Gossip Stone", {});
|
||||||
locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14876, 0x1C, "Saria Gossip Stone", "SFM Saria Gossip Stone", {});
|
locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, 14876, 0x1C, "Saria Gossip Stone", "SFM Saria Gossip Stone", {});
|
||||||
locationTable[RC_TOT_LEFT_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x06, "ToT Left Gossip Stone", "ToT Left Gossip Stone", {});
|
locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x06, "ToT Left Gossip Stone", "ToT Left Gossip Stone", {});
|
||||||
locationTable[RC_TOT_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x07, "ToT Right Gossip Stone", "ToT Right Gossip Stone", {});
|
locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x07, "ToT Right Gossip Stone", "ToT Right Gossip Stone", {});
|
||||||
locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x10, "ToT Right Center Gossip Stone", "ToT Right Center Gossip Stone", {});
|
locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x10, "ToT Right Center Gossip Stone", "ToT Right Center Gossip Stone", {});
|
||||||
locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x0E, "ToT Left Center Gossip Stone", "ToT Left Center Gossip Stone", {});
|
locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, 0x0E, "ToT Left Center Gossip Stone", "ToT Left Center Gossip Stone", {});
|
||||||
locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 14345, 0x09, "Gossip Stone", "ZD Gossip Stone", {});
|
locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, 14345, 0x09, "Gossip Stone", "ZD Gossip Stone", {});
|
||||||
locationTable[RC_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x01, "Fairy Gossip Stone", "Fairy Gossip Stone", {});
|
locationTable[RC_ZF_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_ZF_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x01, "Fairy Gossip Stone", "Fairy Gossip Stone", {});
|
||||||
locationTable[RC_JABU_GOSSIP_STONE] = Location::HintStone(RC_JABU_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x02, "Jabu Gossip Stone", "Jabu Gossip Stone", {});
|
locationTable[RC_ZF_JABU_GOSSIP_STONE] = Location::HintStone(RC_ZF_JABU_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, 0x00, 0x02, "Jabu Gossip Stone", "Jabu Gossip Stone", {});
|
||||||
locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14605, 0x0D, "Near Grottos Gossip Stone", "ZR Near Grottos Gossip Stone", {});
|
locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14605, 0x0D, "Near Grottos Gossip Stone", "ZR Near Grottos Gossip Stone", {});
|
||||||
locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14860, 0x0C, "Near Domain Gossip Stone", "ZR Near Domain Gossip Stone", {});
|
locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 14860, 0x0C, "Near Domain Gossip Stone", "ZR Near Domain Gossip Stone", {});
|
||||||
locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, 0x1B, "Cow Grotto Gossip Stone", "HF Cow Grotto Gossip Stone", {});
|
locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, 0x1B, "Cow Grotto Gossip Stone", "HF Cow Grotto Gossip Stone", {});
|
||||||
locationTable[RC_HF_NEAR_MARKET_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, 0x30, "Near Market Gossip Stone", "HF Near Market Gossip Stone", {});
|
locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, 0x30, "Near Market Gossip Stone", "HF Near Market Gossip Stone", {});
|
||||||
locationTable[RC_HF_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, 0x32, "Southeast Gossip Stone", "HF Southeast Gossip Stone", {});
|
locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, 0x32, "Southeast Gossip Stone", "HF Southeast Gossip Stone", {});
|
||||||
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, 0x33, "Open Grotto Gossip Stone", "HF Open Grotto Gossip Stone", {});
|
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, 0x33, "Open Grotto Gossip Stone", "HF Open Grotto Gossip Stone", {});
|
||||||
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, 0x38, "Open Grotto Gossip Stone", "Kak Open Grotto Gossip Stone", {});
|
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, 0x38, "Open Grotto Gossip Stone", "Kak Open Grotto Gossip Stone", {});
|
||||||
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, 0x39, "Open Grotto Gossip Stone", "ZR Open Grotto Gossip Stone", {});
|
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, 0x39, "Open Grotto Gossip Stone", "ZR Open Grotto Gossip Stone", {});
|
||||||
locationTable[RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, 0x34, "Near Shortcuts Gossip Stone", "LW Near Shortcuts Gossip Stone", {});
|
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, 0x34, "Near Shortcuts Gossip Stone", "LW Near Shortcuts Gossip Stone", {});
|
||||||
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, 0x37, "Storms Grotto Gossip Stone", "DMT Storms Grotto Gossip Stone", {});
|
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, 0x37, "Storms Grotto Gossip Stone", "DMT Storms Grotto Gossip Stone", {});
|
||||||
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, 0x3A, "Upper Grotto Gossip Stone", "DMC Upper Grotto Gossip Stone", {});
|
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, 0x3A, "Upper Grotto Gossip Stone", "DMC Upper Grotto Gossip Stone", {});
|
||||||
|
|
||||||
@ -1568,12 +1567,12 @@ void Rando::StaticData::InitLocationTable() { //
|
|||||||
locationTable[RC_TRIFORCE_COMPLETED] = Location::Reward(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP);
|
locationTable[RC_TRIFORCE_COMPLETED] = Location::Reward(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// Init SpoilerfileCheckNameToEnum
|
// Init locationNameToEnum
|
||||||
SpoilerfileCheckNameToEnum["Invalid Location"] = RC_UNKNOWN_CHECK;
|
locationNameToEnum["Invalid Location"] = RC_UNKNOWN_CHECK;
|
||||||
SpoilerfileCheckNameToEnum["Link's Pocket"] = RC_LINKS_POCKET;
|
locationNameToEnum["Link's Pocket"] = RC_LINKS_POCKET;
|
||||||
|
|
||||||
for (auto& location : locationTable) {
|
for (auto& location : locationTable) {
|
||||||
SpoilerfileCheckNameToEnum[location.GetName()] = location.GetRandomizerCheck();
|
locationNameToEnum[location.GetName()] = location.GetRandomizerCheck();
|
||||||
CheckFromActorMultimap.emplace(std::make_tuple((int16_t)location.GetActorID(), (int16_t)location.GetScene(), location.GetActorParams()), location.GetRandomizerCheck());
|
CheckFromActorMultimap.emplace(std::make_tuple((int16_t)location.GetActorID(), (int16_t)location.GetScene(), location.GetActorParams()), location.GetRandomizerCheck());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,10 +501,13 @@ void Settings::CreateOptionDescriptions() {
|
|||||||
"Reading the Temple of Time altar as child will tell you the locations of the Spiritual Stones.\n"
|
"Reading the Temple of Time altar as child will tell you the locations of the Spiritual Stones.\n"
|
||||||
"Reading the Temple of Time altar as adult will tell you the locations of the Medallions, as well as the "
|
"Reading the Temple of Time altar as adult will tell you the locations of the Medallions, as well as the "
|
||||||
"conditions for building the Rainbow Bridge and getting the Boss Key for Ganon's Castle.";
|
"conditions for building the Rainbow Bridge and getting the Boss Key for Ganon's Castle.";
|
||||||
mOptionDescriptions[RSK_LIGHT_ARROWS_HINT] =
|
mOptionDescriptions[RSK_GANONDORF_HINT] =
|
||||||
"Talking to Ganondorf in his boss room or Sheik inside Ganon's Castle (when trials are enabled) will tell you "
|
"Talking to Ganondorf in his boss room will tell you the location of the Light Arrows and Master Sword."
|
||||||
"the location of the Light Arrows."
|
"If this option is enabled and Ganondorf is reachable without these items, Gossip Stones will never hint the "
|
||||||
"If this option is enabled and Ganondorf is reachable without Light Arrows, Gossip Stones will never hint the "
|
"appropriote items.";//RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add to navi?
|
||||||
|
mOptionDescriptions[RSK_SHEIK_LA_HINT] =
|
||||||
|
"Talking to Sheik inside Ganon's Castle will tell you the location of the Light Arrows."
|
||||||
|
"If this option is enabled and Sheik is reachable without Light Arrows, Gossip Stones will never hint the "
|
||||||
"Light Arrows.";
|
"Light Arrows.";
|
||||||
mOptionDescriptions[RSK_DAMPES_DIARY_HINT] =
|
mOptionDescriptions[RSK_DAMPES_DIARY_HINT] =
|
||||||
"Reading the diary of Dampé the gravekeeper as adult will tell you the location of one of the Hookshots.";
|
"Reading the diary of Dampé the gravekeeper as adult will tell you the location of one of the Hookshots.";
|
||||||
@ -544,7 +547,7 @@ void Settings::CreateOptionDescriptions() {
|
|||||||
mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] =
|
mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] =
|
||||||
"Ice Arrows act like Blue Fire, making them able to melt red ice. "
|
"Ice Arrows act like Blue Fire, making them able to melt red ice. "
|
||||||
"Item placement logic will respect this option, so it might be required to use this to progress.";
|
"Item placement logic will respect this option, so it might be required to use this to progress.";
|
||||||
mOptionDescriptions[RSK_LIGHT_ARROWS_HINT] =
|
mOptionDescriptions[RSK_SUNLIGHT_ARROWS] =
|
||||||
"Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. "
|
"Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. "
|
||||||
"Item placement logic will respect this option, so it might be required to use this to progress.";
|
"Item placement logic will respect this option, so it might be required to use this to progress.";
|
||||||
mOptionDescriptions[RSK_LOGIC_RULES] =
|
mOptionDescriptions[RSK_LOGIC_RULES] =
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <textures/icon_item_24_static/icon_item_24_static.h>
|
#include <textures/icon_item_24_static/icon_item_24_static.h>
|
||||||
#include "3drando/rando_main.hpp"
|
#include "3drando/rando_main.hpp"
|
||||||
#include "3drando/random.hpp"
|
#include "3drando/random.hpp"
|
||||||
|
#include "3drando/custom_messages.hpp"
|
||||||
#include "../../UIWidgets.hpp"
|
#include "../../UIWidgets.hpp"
|
||||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
@ -37,12 +38,12 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "soh/util.h"
|
#include "soh/util.h"
|
||||||
#include "fishsanity.h"
|
#include "fishsanity.h"
|
||||||
|
#include "randomizerTypes.h"
|
||||||
|
|
||||||
extern "C" uint32_t ResourceMgr_IsGameMasterQuest();
|
extern "C" uint32_t ResourceMgr_IsGameMasterQuest();
|
||||||
extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
|
extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
|
||||||
|
|
||||||
extern std::map<RandomizerCheckArea, std::string> rcAreaNames;
|
extern std::map<RandomizerCheckArea, std::string> rcAreaNames;
|
||||||
extern std::array<std::string, HINT_TYPE_MAX> hintTypeNames;
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
@ -136,8 +137,8 @@ Randomizer::Randomizer() {
|
|||||||
SpoilerfileAreaNameToEnum["the Graveyard"] = RCAREA_GRAVEYARD;
|
SpoilerfileAreaNameToEnum["the Graveyard"] = RCAREA_GRAVEYARD;
|
||||||
SpoilerfileAreaNameToEnum["Haunted Wasteland"] = RCAREA_WASTELAND;
|
SpoilerfileAreaNameToEnum["Haunted Wasteland"] = RCAREA_WASTELAND;
|
||||||
SpoilerfileAreaNameToEnum["outside Ganon's Castle"] = RCAREA_HYRULE_CASTLE;
|
SpoilerfileAreaNameToEnum["outside Ganon's Castle"] = RCAREA_HYRULE_CASTLE;
|
||||||
for (int c = 0; c < hintTypeNames.size(); c++) {
|
for (int c = 0; c < Rando::StaticData::hintTypeNames.size(); c++) {
|
||||||
SpoilerfileHintTypeNameToEnum[hintTypeNames[c]] = (HintType)c;
|
SpoilerfileHintTypeNameToEnum[Rando::StaticData::hintTypeNames[(HintType)c].GetEnglish(MF_CLEAN)] = (HintType)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,187 +226,10 @@ void Randomizer::LoadHintMessages() {
|
|||||||
CustomMessageManager::Instance->ClearMessageTable(Randomizer::hintMessageTableID);
|
CustomMessageManager::Instance->ClearMessageTable(Randomizer::hintMessageTableID);
|
||||||
CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::hintMessageTableID);
|
CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::hintMessageTableID);
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_ALTAR_CHILD,
|
|
||||||
CustomMessage(ctx->GetHint(RH_ALTAR_CHILD)->GetText(), TEXTBOX_TYPE_BLUE));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_ALTAR_ADULT,
|
|
||||||
CustomMessage(ctx->GetHint(RH_ALTAR_ADULT)->GetText(), TEXTBOX_TYPE_BLUE));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_GANONDORF,
|
|
||||||
CustomMessage(ctx->GetHint(RH_GANONDORF_HINT)->GetText()));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_GANONDORF_NOHINT,
|
|
||||||
CustomMessage(ctx->GetHint(RH_GANONDORF_NOHINT)->GetText()));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_SHEIK_NEED_HOOK,
|
|
||||||
CustomMessage("{{message}}", "{{message}}", "{{message}}"));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_SHEIK_HAVE_HOOK,
|
|
||||||
CustomMessage("{{message}}", "{{message}}", "{{message}}"));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, TEXT_SARIAS_SONG_FACE_TO_FACE,
|
|
||||||
CustomMessage(ctx->GetHint(RH_SARIA)->GetText(), TEXTBOX_TYPE_BLUE));
|
|
||||||
|
|
||||||
for (int i : Rando::StaticData::gossipStoneLocations) {
|
|
||||||
RandomizerHintKey rhk = RandomizerHintKey(i - RC_COLOSSUS_GOSSIP_STONE + 1);
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::hintMessageTableID, i, CustomMessage(ctx->GetHint(rhk)->GetText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Extra Hints
|
//Extra Hints
|
||||||
CustomMessageManager::Instance->ClearMessageTable(Randomizer::randoMiscHintsTableID);
|
CustomMessageManager::Instance->ClearMessageTable(Randomizer::randoMiscHintsTableID);
|
||||||
CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::randoMiscHintsTableID);
|
CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::randoMiscHintsTableID);
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_SKULLTULA_PEOPLE_IM_CURSED,
|
|
||||||
CustomMessage("Yeaaarrgh! I'm cursed!!^Please save me by destroying&%r{{params}} Spiders of the Curse%w&and I will give you my&%g{{item1}}%w!",
|
|
||||||
"Yeaaarrgh! Ich bin verflucht!^Bitte rette mich, indem du %r{{params}} Skulltulas&%wzerstörst und ich werde dir dafür&%g{{item1}} %wgeben!",
|
|
||||||
"Yeaaarrgh! Je suis maudit!^Détruit encore %r{{params}} Araignées de&la Malédiction%w et j'aurai quelque&chose à te donner!&%g({{item1}})")
|
|
||||||
);
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_DAMPES_DIARY,
|
|
||||||
CustomMessage(ctx->GetHint(RH_DAMPES_DIARY)->GetText())
|
|
||||||
);
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_CHEST_GAME_PROCEED,
|
|
||||||
CustomMessage(ctx->GetHint(RH_GREG_RUPEE)->GetText())
|
|
||||||
);
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_FROGS_UNDERWATER,
|
|
||||||
CustomMessage(ctx->GetHint(RH_FROGS)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_FROGS)->GetText().GetGerman(),
|
|
||||||
ctx->GetHint(RH_FROGS)->GetText().GetFrench(), TEXTBOX_TYPE_BLUE)
|
|
||||||
);
|
|
||||||
CustomMessageManager::Instance->CreateMessage(Randomizer::randoMiscHintsTableID, TEXT_WARP_MINUET_OF_FOREST,
|
|
||||||
CustomMessage(ctx->GetHint(RH_MINUET_WARP_LOC)->GetText().GetEnglish(),
|
|
||||||
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,
|
|
||||||
CustomMessage(ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetGerman(),
|
|
||||||
ctx->GetHint(RH_BOLERO_WARP_LOC)->GetText().GetFrench()));
|
|
||||||
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_SARIAS_SONG_FOREST_SOUNDS,
|
|
||||||
CustomMessage("{{message}}", "{{message}}", "{{message}}", TEXTBOX_TYPE_BLUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_BIGGORON_BETTER_AT_SMITHING,
|
|
||||||
CustomMessage("Arrrrrre you here to claim my finest&%g{{item1}}%w?&Shoooooow me your %rClaim Check.%w",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_GHOST_SHOP_CARD_HAS_POINTS,
|
|
||||||
CustomMessage("You have %g\x1E\x01%r Poe Points%w!&Reach 1000 and you'll get a&%g{{item1}}%w!",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK,
|
|
||||||
CustomMessage("You! Please!&Bring my Cucco's back to my pen!&I'll give you my %g{{item1}}%w!",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_OBSTICLE_COURSE,
|
|
||||||
CustomMessage("How about trying the %rObsticle Course?%w&If you beat my time I'll let you keep&my favourite cow Elsie and&her toy %g{{item1}}%w!^"
|
|
||||||
"Challenge the %rObsticle Course?&\x1B&%gLet's go&No thanks%w",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_HOW_IS_EPONA_DOING,
|
|
||||||
CustomMessage("@! You should come back &with Epona and try to beat my time&on the %rObsticle Course%w!^If you beat my time, I'll give you&my favourite %rcow%w Elsie and&her toy %g{{item1}}%w!",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_EVERYONE_TURNING_EVIL,
|
|
||||||
CustomMessage("@? Is that you? ^If I ran the ranch, I'd build an &%rObsticle Course%w, and whoever gets&the best time would win a %rcow%w!^Elsie loves sharing her %g{{item1}}%w&with new people, It'll be fun!^...But Ingo won't let me...",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED,
|
|
||||||
CustomMessage("@! You should come back in&the morning and try to beat my time&on the %rObsticle Course%w!^If you beat my time, I'll give you&my favourite %rcow%w Elsie and&her toy %g{{item1}}%w!",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_HBA_NOT_ON_HORSE,
|
|
||||||
CustomMessage("Hey, rookie!&Come back on your %rhorse%w&and take on the&%rHorseback Archery%w challenge!^Impress me with a high score of 1000&to win a %g{{item1}}%w&or score 1500 for my&%g{{item2}}%w!",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_HBA_INITIAL_EXPLAINATION,
|
|
||||||
CustomMessage("Hey, rookie!&Want to take on the&%rHorseback Archery%w challenge?^Impress me with a high score of 1000&to win a %g{{item1}}%w&or score 1500 for my&%g{{item2}}%w!\x0B",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_HBA_ALREADY_HAVE_1000,
|
|
||||||
CustomMessage("Hey, newcomer!&Want to take on the&%rHorseback Archery%w challenge?^Prove yourself to be a horsemaster&by scoring 1500 points to win &my %g{{item1}}%w!\x0B",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_GF_HBA_SIGN,
|
|
||||||
CustomMessage("%rHorseback Archery%w Range Prizes:&1000: %g{{item1}}%w&1500: %g{{item2}}%w^@'s Record: %g\x1E\x00%w",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_OBSTICLE_COURSE,
|
|
||||||
CustomMessage("How about trying your skill on the %rObsticle Course?%w& If you beat my time I'll let you keep my favourite cow Elsie and& her toy %g{{item1}}%w!&x1B&%gLet's go&No thanks%w",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_EVERYONE_TURNING_EVIL,
|
|
||||||
CustomMessage("@? Is that you? &If I ran the ranch, I'd build an %rObsticle Course%w, and whoever gets the best time would win a cow!& Elsie loves sharing her %g{{item1}}%w&with new people, It'll be fun!&...But Ingo won't let me...",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED,
|
|
||||||
CustomMessage("@! You should come back in the morning and try to beat my time on the %rObsticle Course%w!&If you beat my time, I'll let you keep Elsie and& her toy %g{{item1}}%w!",
|
|
||||||
"",
|
|
||||||
"")
|
|
||||||
);
|
|
||||||
|
|
||||||
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,
|
||||||
@ -413,19 +237,12 @@ void Randomizer::LoadHintMessages() {
|
|||||||
"Komm wieder sobald du deinen eigenen&Bogen hast, um einen %rspeziellen Preis%w zu&erhalten!",
|
"Komm wieder sobald du deinen eigenen&Bogen hast, um einen %rspeziellen Preis%w zu&erhalten!",
|
||||||
"J'aurai %rune autre récompense%w pour toi&lorsque tu auras ton propre arc."));
|
"J'aurai %rune autre récompense%w pour toi&lorsque tu auras ton propre arc."));
|
||||||
|
|
||||||
// Fishing pond pole hint
|
// Warp Song Mysterious text
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST,
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_FISHING_POND_START,
|
CustomMessage("Warp to&#a mysterious place?#&" + CustomMessages::TWO_WAY_CHOICE() + "#OK&No#",
|
||||||
CustomMessage(ctx->GetHint(RH_FISHING_POLE)->GetText().GetEnglish(),
|
"Zu&#ein mysteriöser Ort#?&" + CustomMessages::TWO_WAY_CHOICE() + "#OK&No#",
|
||||||
ctx->GetHint(RH_FISHING_POLE)->GetText().GetEnglish(),
|
"Se téléporter vers&#un endroit mystérieux#?&" + CustomMessages::TWO_WAY_CHOICE() + "#OK!&Non#",
|
||||||
ctx->GetHint(RH_FISHING_POLE)->GetText().GetFrench())
|
{QM_RED, QM_GREEN}));
|
||||||
);
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::randoMiscHintsTableID, TEXT_FISHING_POND_START_MET,
|
|
||||||
CustomMessage(ctx->GetHint(RH_FISHING_POLE)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_FISHING_POLE)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_FISHING_POLE)->GetText().GetFrench())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Lake Hylia water level system
|
// Lake Hylia water level system
|
||||||
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN,
|
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN,
|
||||||
@ -478,67 +295,38 @@ void Randomizer::LoadMerchantMessages() {
|
|||||||
|
|
||||||
// Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so adding a "free" variation here
|
// Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so adding a "free" variation here
|
||||||
CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE,
|
CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE,
|
||||||
CustomMessage("\x12\x38\x82" "All right! You win! In return for&sparing me, I will give you a&%g{{item}}%w!&Please, take it!\x07\x10\xA3",
|
CustomMessage("\x12\x38\x82" "All right! You win! In return for&sparing me, I will give you a&%g[[item]]%w!&Please, take it!\x07\x10\xA3",
|
||||||
"\x12\x38\x82" "In Ordnung! Du gewinnst! Im Austausch&dafür, dass du mich verschont hast,&werde ich dir einen &%g{{item}}%w geben!\x07\x10\xA3",
|
"\x12\x38\x82" "In Ordnung! Du gewinnst! Im Austausch&dafür, dass du mich verschont hast,&werde ich dir einen &%g[[item]]%w geben!\x07\x10\xA3",
|
||||||
"\x12\x38\x82" "J'me rends! Laisse-moi partir et en&échange, je te donne un &%g{{item}}%w! Vas-y prends le!\x07\x10\xA3"));
|
"\x12\x38\x82" "J'me rends! Laisse-moi partir et en&échange, je te donne un &%g[[item]]%w! Vas-y prends le!\x07\x10\xA3"));
|
||||||
CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM,
|
CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM,
|
||||||
CustomMessage("\x12\x38\x82" "All right! You win! In return for&sparing me, I will sell you a&%g{{item}}%w!&%r{{price}} Rupees%w it is!\x07\x10\xA3",
|
CustomMessage("\x12\x38\x82" "All right! You win! In return for&sparing me, I will sell you a&%g[[item]]%w!&%r[[price]] Rupees%w it is!\x07\x10\xA3",
|
||||||
"\x12\x38\x82" "Aufgeben! Ich verkaufe dir einen&%g{{item}}%w&für %r{{price}} Rubine%w!\x07\x10\xA3",
|
"\x12\x38\x82" "Aufgeben! Ich verkaufe dir einen&%g[[item]]%w&für %r[[price]] Rubine%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"));
|
"\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(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_10,
|
|
||||||
CustomMessage(ctx->GetHint(RH_BEAN_SALESMAN)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_BEAN_SALESMAN)->GetText().GetGerman(),
|
|
||||||
ctx->GetHint(RH_BEAN_SALESMAN)->GetText().GetFrench()));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100,
|
|
||||||
CustomMessage("I never thought I'd say this, but I'm &selling the last %rMagic Bean%w. %r99%w Rupees...\x1B&%gYes&No%w",
|
|
||||||
"\x1B&%gJa&Nein%w",
|
|
||||||
"Je te vends mon dernier %rHaricot&magique%w pour %r99 Rubis%w.\x1B&%gAcheter&Ne pas acheter%w"));
|
|
||||||
|
|
||||||
|
|
||||||
//Setup for merchant text boxes
|
|
||||||
//Medigoron
|
|
||||||
//RANDOTODO: Implement obscure/ambiguous hints
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_MEDIGORON,
|
|
||||||
CustomMessage(ctx->GetHint(RH_MEDIGORON)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_MEDIGORON)->GetText().GetGerman(),
|
|
||||||
ctx->GetHint(RH_MEDIGORON)->GetText().GetFrench()));
|
|
||||||
|
|
||||||
//Granny Shop
|
|
||||||
//RANDOTODO: Implement obscure/ambiguous hints
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_GRANNYS_SHOP,
|
|
||||||
CustomMessage(ctx->GetHint(RH_GRANNYS_SHOP)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_GRANNYS_SHOP)->GetText().GetGerman(),
|
|
||||||
ctx->GetHint(RH_GRANNYS_SHOP)->GetText().GetFrench()));
|
|
||||||
|
|
||||||
//Carpet Salesman
|
//Carpet Salesman
|
||||||
//RANDOTODO: Implement obscure/ambiguous hints
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
|
||||||
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_1,
|
|
||||||
CustomMessage(ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN)->GetText().GetEnglish(),
|
|
||||||
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN)->GetText().GetGerman(),
|
|
||||||
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN)->GetText().GetFrench()));
|
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_2,
|
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_2,
|
||||||
CustomMessage(ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST)->GetText().GetEnglish(),
|
CustomMessage("Finally! Now I can go back to being &an %rarms dealer%w!",
|
||||||
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST)->GetText().GetGerman(),
|
/*german*/"Endlich! Schon bald kann ich wieder &%rKrabbelminen-Händler%w sein!",
|
||||||
ctx->GetHint(RH_WASTELAND_BOMBCHU_SALESMAN_POST)->GetText().GetFrench()));
|
/*french*/ "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
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM,
|
Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM,
|
||||||
CustomMessage("\x08%r{{item}} {{price}} Rupees&%wSpecial deal! ONE LEFT!&Get it while it lasts!\x0A\x02",
|
CustomMessage("\x08%r[[item]] [[price]] Rupees&%wSpecial deal! ONE LEFT!&Get it while it lasts!\x0A\x02",
|
||||||
"\x08%r{{item}} {{price}} Rubine&%wSonderangebot! NUR NOCH EINES VERFÜGBAR!&Beeilen Sie sich!\x0A\x02",
|
"\x08%r[[item]] [[price]] Rubine&%wSonderangebot! NUR NOCH EINES VERFÜGBAR!&Beeilen Sie sich!\x0A\x02",
|
||||||
"\x08%r{{item}} {{price}} Rubis&%wOffre spéciale! DERNIER EN STOCK!&Faites vite!\x0A\x02"));
|
"\x08%r[[item]] [[price]] Rubis&%wOffre spéciale! DERNIER EN STOCK!&Faites vite!\x0A\x02"));
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM_CONFIRM,
|
Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM_CONFIRM,
|
||||||
CustomMessage("\x08{{item}} {{price}} Rupees\x09&&\x1B%gBuy&Don't buy%w\x09\x02",
|
CustomMessage("\x08[[item]] [[price]] Rupees\x09&&\x1B%gBuy&Don't buy%w\x09\x02",
|
||||||
"\x08{{item}} {{price}} Rubine\x09&&\x1B%gKaufen&Nicht kaufen%w\x09\x02",
|
"\x08[[item]] [[price]] Rubine\x09&&\x1B%gKaufen&Nicht kaufen%w\x09\x02",
|
||||||
"\x08{{item}} {{price}} Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02"));
|
"\x08[[item]] [[price]] Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02"));
|
||||||
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
|
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100,
|
||||||
|
CustomMessage("I never thought I'd say this, but I'm &selling the last %rMagic Bean%w. %r99%w Rupees...\x1B&%gYes&No%w",
|
||||||
|
"\x1B&%gJa&Nein%w",
|
||||||
|
"Je te vends mon dernier %rHaricot&magique%w pour %r99 Rubis%w.\x1B&%gAcheter&Ne pas acheter%w"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<s32, Rando::TrialKey> trialFlagToTrialKey = {
|
std::map<s32, Rando::TrialKey> trialFlagToTrialKey = {
|
||||||
@ -1655,7 +1443,7 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum,
|
|||||||
case SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS:
|
case SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS:
|
||||||
switch (actorParams) {
|
switch (actorParams) {
|
||||||
case 14342:
|
case 14342:
|
||||||
specialRc = RC_TOT_LEFT_GOSSIP_STONE;
|
specialRc = RC_TOT_LEFTMOST_GOSSIP_STONE;
|
||||||
break;
|
break;
|
||||||
case 14599:
|
case 14599:
|
||||||
specialRc = RC_TOT_LEFT_CENTER_GOSSIP_STONE;
|
specialRc = RC_TOT_LEFT_CENTER_GOSSIP_STONE;
|
||||||
@ -1664,7 +1452,7 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum,
|
|||||||
specialRc = RC_TOT_RIGHT_CENTER_GOSSIP_STONE;
|
specialRc = RC_TOT_RIGHT_CENTER_GOSSIP_STONE;
|
||||||
break;
|
break;
|
||||||
case 15120:
|
case 15120:
|
||||||
specialRc = RC_TOT_RIGHT_GOSSIP_STONE;
|
specialRc = RC_TOT_RIGHTMOST_GOSSIP_STONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1703,11 +1491,11 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum,
|
|||||||
switch (actorParams) {
|
switch (actorParams) {
|
||||||
case 15362:
|
case 15362:
|
||||||
case 14594:
|
case 14594:
|
||||||
specialRc = RC_JABU_GOSSIP_STONE;
|
specialRc = RC_ZF_JABU_GOSSIP_STONE;
|
||||||
break;
|
break;
|
||||||
case 14849:
|
case 14849:
|
||||||
case 14337:
|
case 14337:
|
||||||
specialRc = RC_FAIRY_GOSSIP_STONE;
|
specialRc = RC_ZF_FAIRY_GOSSIP_STONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2602,109 +2390,51 @@ void RandomizerSettingsWindow::UpdateElement() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage Randomizer::ReplaceWithItemName(CustomMessage message, std::string&& toReplace, RandomizerCheck hintedCheck){
|
|
||||||
auto ctx = Rando::Context::GetInstance();
|
|
||||||
RandomizerGet targetRG = ctx->GetItemLocation(hintedCheck)->GetPlacedRandomizerGet();
|
|
||||||
std::array<std::string, LANGUAGE_MAX> itemName;
|
|
||||||
if (targetRG == RG_ICE_TRAP) {
|
|
||||||
targetRG = ctx->overrides[hintedCheck].LooksLike();
|
|
||||||
itemName = {
|
|
||||||
ctx->overrides[hintedCheck].GetTrickName().english,
|
|
||||||
ctx->overrides[hintedCheck].GetTrickName().french,
|
|
||||||
ctx->overrides[hintedCheck].GetTrickName().english
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
itemName = {
|
|
||||||
Rando::StaticData::RetrieveItem(targetRG).GetName().english,
|
|
||||||
Rando::StaticData::RetrieveItem(targetRG).GetName().french,
|
|
||||||
Rando::StaticData::RetrieveItem(targetRG).GetName().english,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
message.Replace(std::move(toReplace), std::move(itemName[0]), std::move(itemName[1]), std::move(itemName[2]));
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CustomMessage Randomizer::GetMiscHintMessage(TextIDs textToGet, RandomizerCheck hintedCheck, RandomizerCheck otherCheck) {
|
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, textToGet);
|
|
||||||
messageEntry = ReplaceWithItemName(messageEntry, "{{item1}}", hintedCheck);
|
|
||||||
if (otherCheck != RC_UNKNOWN_CHECK){
|
|
||||||
messageEntry = ReplaceWithItemName(messageEntry, "{{item2}}", otherCheck);
|
|
||||||
}
|
|
||||||
return messageEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomMessage Randomizer::GetCursedSkullMessage(s16 params, RandomizerCheck hintedCheck) {
|
|
||||||
auto ctx = Rando::Context::GetInstance();
|
|
||||||
CustomMessage messageEntry = GetMiscHintMessage(TEXT_SKULLTULA_PEOPLE_IM_CURSED, hintedCheck);
|
|
||||||
messageEntry.Replace("{{params}}", std::to_string(params*10));
|
|
||||||
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;
|
||||||
switch (scene) {
|
switch (scene) {
|
||||||
case SCENE_TEMPLE_OF_TIME:
|
case SCENE_TEMPLE_OF_TIME:
|
||||||
if (originalTextId == TEXT_SHEIK_NEED_HOOK) {
|
if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, SCENE_GANONS_TOWER)) {
|
||||||
messageEntry.Replace("{{message}}",
|
messageEntry = CustomMessage(
|
||||||
"@,&meet me at %gGanon's Castle%w&once you obtain the %rkey to his lair%w.",
|
"@,&meet me at %gGanon's Castle%w&once you obtain the %rkey to his lair%w.",
|
||||||
"@, wir treffen uns bei %gGanons Schloß%w,&sobald Du den %rSchlüssel zu&seinem Verließ%w hast.",
|
"@, wir treffen uns bei %gGanons Schloß%w,&sobald Du den %rSchlüssel zu&seinem Verließ%w hast.",
|
||||||
"Retrouve-moi au %gChâteau de Ganon%w une&fois que tu auras obtenu la&Mrclé de son repaire%w.");
|
"Retrouve-moi au %gChâteau de Ganon%w une&fois que tu auras obtenu la&Mrclé de son repaire%w.");
|
||||||
} else {
|
} else {
|
||||||
messageEntry.Replace("{{message}}",
|
messageEntry = CustomMessage(
|
||||||
"The time has come. Prepare yourself.",
|
"The time has come. Prepare yourself.",
|
||||||
"Die Zeit ist gekommen.&Mach Dich bereit.",
|
"Die Zeit ist gekommen.&Mach Dich bereit.",
|
||||||
"Le moment est venu @.&Tu ferais bien de te préparer.");
|
"Le moment est venu @.&Tu ferais bien de te préparer.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCENE_INSIDE_GANONS_CASTLE:
|
case SCENE_INSIDE_GANONS_CASTLE:
|
||||||
if (originalTextId == TEXT_SHEIK_NEED_HOOK) {
|
if (ctx->GetOption(RSK_SHEIK_LA_HINT) && INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) {
|
||||||
//If MS shuffle is on, Sheik will hint both MS and LA as long as Link doesn't have both, to prevent hint lockout.
|
messageEntry = ctx->GetHint(RH_SHEIK_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
//Otherwise, she'll only give LA hint so only LA is required to move on.
|
} else if (!(CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT &&
|
||||||
bool needRequirements = GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) ?
|
CUR_CAPACITY(UPG_QUIVER) >= 30 && gSaveContext.isMagicAcquired)) {
|
||||||
(!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) || INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) :
|
messageEntry = CustomMessage("You are still ill-equipped to&face %rGanondorf%w."
|
||||||
(INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT);
|
|
||||||
if (needRequirements) {
|
|
||||||
messageEntry.Replace("{{message}}", ctx->GetHint(RH_SHEIK_LIGHT_ARROWS)->GetText().GetEnglish().c_str(), ctx->GetHint(RH_SHEIK_LIGHT_ARROWS)->GetText().GetEnglish().c_str(), ctx->GetHint(RH_SHEIK_LIGHT_ARROWS)->GetText().GetFrench().c_str());
|
|
||||||
} else {
|
|
||||||
messageEntry.Replace("{{message}}", "You are still ill-equipped to&face %rGanondorf%w."
|
|
||||||
"^Seek out the %cMaster Sword%w,&%rsomething to hold your arrows%w,&and %gmagic%w to summon the %ylight%w.",
|
"^Seek out the %cMaster Sword%w,&%rsomething to hold your arrows%w,&and %gmagic%w to summon the %ylight%w.",
|
||||||
"Du bist noch nicht gewappnet um Dich&%rGanondorf%w stellen zu können.^"
|
"Du bist noch nicht gewappnet um Dich&%rGanondorf%w stellen zu können.^"
|
||||||
"Begib Dich auf die Suche nach dem&%cMaster-Schwert%w, %retwas um deine Pfeilen&einen Sinn zu geben%w,^sowie %gdie Magie%w, um das %yLicht%w&herauf beschwören zu können.",
|
"Begib Dich auf die Suche nach dem&%cMaster-Schwert%w, %retwas um deine Pfeilen&einen Sinn zu geben%w,^sowie %gdie Magie%w, um das %yLicht%w&herauf beschwören zu können.",
|
||||||
"@, tu n'es toujours pas prêt à affronter&%rGanondorf%w.^"
|
"@, tu n'es toujours pas prêt à affronter&%rGanondorf%w.^"
|
||||||
"Cherche l'%cÉpée de Légende%w,&%rquelque chose pour ranger tes flèches%w&et de la %gmagie%w pour invoquer la&%ylumière%w.");
|
"Cherche l'%cÉpée de Légende%w,&%rquelque chose pour ranger tes flèches%w&et de la %gmagie%w pour invoquer la&%ylumière%w.");
|
||||||
}
|
} else if (!Flags_GetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER)){
|
||||||
} else {
|
messageEntry = CustomMessage(
|
||||||
if (!Flags_GetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER)) {
|
|
||||||
messageEntry.Replace("{{message}}",
|
|
||||||
"You may have what you need to defeat&%rthe Evil King%w, but the %cbarrier%w still&stands.^Complete the remaining %gtrials%w&to destroy it."
|
"You may have what you need to defeat&%rthe Evil King%w, but the %cbarrier%w still&stands.^Complete the remaining %gtrials%w&to destroy it."
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
messageEntry.Replace("{{message}}",
|
messageEntry = CustomMessage(
|
||||||
"If you're ready, then proceed.^Good luck.",
|
"If you're ready, then proceed.^Good luck.",
|
||||||
"Wenn Du bereit bist, so schreite&voran.^Viel Glück.",
|
"Wenn Du bereit bist, so schreite&voran.^Viel Glück.",
|
||||||
"Si tu es prêt, tu peux y aller.^Bonne chance.");
|
"Si tu es prêt, tu peux y aller.^Bonne chance.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage Randomizer::GetSariaMessage(u16 originalTextId) {
|
|
||||||
if (originalTextId == TEXT_SARIA_SFM || (originalTextId >= TEXT_SARIAS_SONG_FACE_TO_FACE && originalTextId <= TEXT_SARIAS_SONG_CHANNELING_POWER)) {
|
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_SARIAS_SONG_FACE_TO_FACE);
|
|
||||||
CustomMessage messageEntry2 = messageEntry;
|
|
||||||
std::string code = originalTextId == TEXT_SARIA_SFM ? "" : "\x0B";
|
|
||||||
messageEntry2.Replace("$C", std::move(code));
|
|
||||||
return messageEntry2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) {
|
CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) {
|
||||||
CustomMessage hintMessageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, TEXT_FISHING_POND_START);
|
auto ctx = Rando::Context::GetInstance();
|
||||||
CustomMessage messageEntry = CustomMessage(
|
CustomMessage messageEntry = CustomMessage(
|
||||||
"Sorry, but the pond is closed.&I've lost my good %rfishing pole%w...&Can't go fishing without it!",
|
"Sorry, but the pond is closed.&I've lost my good %rfishing pole%w...&Can't go fishing without it!",
|
||||||
"",
|
"",
|
||||||
@ -2712,7 +2442,7 @@ CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (Rando::Context::GetInstance()->GetOption(RSK_FISHING_POLE_HINT)) {
|
if (Rando::Context::GetInstance()->GetOption(RSK_FISHING_POLE_HINT)) {
|
||||||
messageEntry = messageEntry + hintMessageEntry;
|
messageEntry = messageEntry + CustomMessage(ctx->GetHint(RH_FISHING_POLE)->GetHintMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the fishing pond guy doesnt remember me i will cry :(
|
// if the fishing pond guy doesnt remember me i will cry :(
|
||||||
@ -2724,61 +2454,38 @@ CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) {
|
|||||||
) + messageEntry;
|
) + messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
messageEntry.Format();
|
messageEntry.Format(); //RANDOTODO why is this needed when it's not elsewhere....
|
||||||
|
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMessage Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious) {
|
CustomMessage Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious) {
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance(); //RANDOTODO If scrubs are allowed to have ambiguous hints, they need to be RandomiserHint objects for logging
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId);
|
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId);
|
||||||
RandomizerCheck rc = GetCheckFromRandomizerInf(randomizerInf);
|
RandomizerCheck rc = GetCheckFromRandomizerInf(randomizerInf);
|
||||||
RandomizerGet shopItemGet = ctx->GetItemLocation(rc)->GetPlacedRandomizerGet();
|
RandomizerGet shopItemGet = ctx->GetItemLocation(rc)->GetPlacedRandomizerGet();
|
||||||
std::array<std::string, LANGUAGE_MAX> shopItemName;
|
CustomMessage shopItemName;
|
||||||
if (mysterious) {
|
if (mysterious) {
|
||||||
shopItemName = {
|
shopItemName = Rando::StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM].GetHintMessage();
|
||||||
"mysterious item",
|
|
||||||
"mysteriösen Gegenstand",
|
|
||||||
"objet mystérieux"
|
|
||||||
};
|
|
||||||
// TODO: This should eventually be replaced with a full fledged trick model & trick name system
|
// TODO: This should eventually be replaced with a full fledged trick model & trick name system
|
||||||
} else if (shopItemGet == RG_ICE_TRAP) {
|
} else if (shopItemGet == RG_ICE_TRAP) {
|
||||||
shopItemGet = ctx->overrides[rc].LooksLike();
|
shopItemGet = ctx->overrides[rc].LooksLike();
|
||||||
shopItemName = {
|
shopItemName = CustomMessage(ctx->overrides[rc].GetTrickName());
|
||||||
std::string(ctx->overrides[rc].GetTrickName().english),
|
|
||||||
std::string(ctx->overrides[rc].GetTrickName().french),
|
|
||||||
std::string(ctx->overrides[rc].GetTrickName().english)
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
auto shopItem = Rando::StaticData::RetrieveItem(shopItemGet);
|
auto shopItem = Rando::StaticData::RetrieveItem(shopItemGet);
|
||||||
shopItemName = {
|
shopItemName = {shopItem.GetName()};
|
||||||
shopItem.GetName().english,
|
|
||||||
shopItem.GetName().french,
|
|
||||||
shopItem.GetName().english,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
u16 shopItemPrice = ctx->GetItemLocation(rc)->GetPrice();
|
u16 shopItemPrice = ctx->GetItemLocation(rc)->GetPrice();
|
||||||
|
|
||||||
if (textId == TEXT_SCRUB_RANDOM && shopItemPrice == 0) {
|
if (textId == TEXT_SCRUB_RANDOM && shopItemPrice == 0) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE);
|
||||||
} else if (textId == TEXT_GRANNYS_SHOP) {
|
|
||||||
// Capitalize the first letter for the item in Granny's text as the item is the first word presented
|
|
||||||
for (auto &itemName : shopItemName) {
|
|
||||||
itemName[0] = std::toupper(itemName[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messageEntry.Replace("{{item}}", std::move(shopItemName[0]), std::move(shopItemName[1]), std::move(shopItemName[2]));
|
messageEntry.Replace("[[item]]", shopItemName);
|
||||||
messageEntry.Replace("{{price}}", std::to_string(shopItemPrice));
|
messageEntry.Replace("[[price]]", std::to_string(shopItemPrice));
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* mapGetItemHints[3][2] = {
|
|
||||||
{ " It's ordinary.", " It's masterful!" },
|
|
||||||
{ "&Sieht aus wie immer.", " &Man kann darauf die Worte&%r\"Master Quest\"%w entziffern..." },
|
|
||||||
{ "&Elle vous semble %rordinaire%w.", "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus." },
|
|
||||||
};
|
|
||||||
|
|
||||||
CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) {
|
CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) {
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, itemEntry.getItemId);
|
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, itemEntry.getItemId);
|
||||||
int sceneNum;
|
int sceneNum;
|
||||||
@ -2819,11 +2526,11 @@ CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) {
|
|||||||
(GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER &&
|
(GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER &&
|
||||||
GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12)
|
GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12)
|
||||||
) {
|
) {
|
||||||
messageEntry.Replace("{{typeHint}}", "");
|
messageEntry.Replace("[[typeHint]]", "");
|
||||||
} else if (ResourceMgr_IsSceneMasterQuest(sceneNum)) {
|
} else if (ResourceMgr_IsSceneMasterQuest(sceneNum)) {
|
||||||
messageEntry.Replace("{{typeHint}}", mapGetItemHints[0][1], mapGetItemHints[1][1], mapGetItemHints[2][1]);
|
messageEntry.Replace("[[typeHint]]", Rando::StaticData::hintTextTable[RHT_DUNGEON_MASTERFUL].GetHintMessage());
|
||||||
} else {
|
} else {
|
||||||
messageEntry.Replace("{{typeHint}}", mapGetItemHints[0][0], mapGetItemHints[1][0], mapGetItemHints[2][0]);
|
messageEntry.Replace("[[typeHint]]", Rando::StaticData::hintTextTable[RHT_DUNGEON_ORDINARY].GetHintMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
@ -2849,16 +2556,16 @@ void CreateRupeeMessages() {
|
|||||||
for (u8 rupee : rupees) {
|
for (u8 rupee : rupees) {
|
||||||
switch (rupee) {
|
switch (rupee) {
|
||||||
case TEXT_BLUE_RUPEE:
|
case TEXT_BLUE_RUPEE:
|
||||||
rupeeText = "\x05\x03 5 {{rupee}}\x05\x00";
|
rupeeText = "\x05\x03 5 [[rupee]]\x05\x00";
|
||||||
break;
|
break;
|
||||||
case TEXT_RED_RUPEE:
|
case TEXT_RED_RUPEE:
|
||||||
rupeeText = "\x05\x01 20 {{rupee}}\x05\x00";
|
rupeeText = "\x05\x01 20 [[rupee]]\x05\x00";
|
||||||
break;
|
break;
|
||||||
case TEXT_PURPLE_RUPEE:
|
case TEXT_PURPLE_RUPEE:
|
||||||
rupeeText = "\x05\x05 50 {{rupee}}\x05\x00";
|
rupeeText = "\x05\x05 50 [[rupee]]\x05\x00";
|
||||||
break;
|
break;
|
||||||
case TEXT_HUGE_RUPEE:
|
case TEXT_HUGE_RUPEE:
|
||||||
rupeeText = "\x05\x06 200 {{rupee}}\x05\x00";
|
rupeeText = "\x05\x06 200 [[rupee]]\x05\x00";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
customMessageManager->CreateMessage(
|
customMessageManager->CreateMessage(
|
||||||
@ -2870,37 +2577,38 @@ void CreateRupeeMessages() {
|
|||||||
|
|
||||||
CustomMessage Randomizer::GetRupeeMessage(u16 rupeeTextId) {
|
CustomMessage Randomizer::GetRupeeMessage(u16 rupeeTextId) {
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::rupeeMessageTableID, rupeeTextId);
|
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::rupeeMessageTableID, rupeeTextId);
|
||||||
messageEntry.Replace("{{rupee}}", RandomElement(englishRupeeNames),
|
messageEntry.Replace("[[rupee]]", CustomMessage(RandomElement(englishRupeeNames),
|
||||||
RandomElement(germanRupeeNames), RandomElement(frenchRupeeNames));
|
RandomElement(germanRupeeNames),
|
||||||
|
RandomElement(frenchRupeeNames)));
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateTriforcePieceMessages() {
|
void CreateTriforcePieceMessages() {
|
||||||
CustomMessage TriforcePieceMessages[NUM_TRIFORCE_PIECE_MESSAGES] = {
|
CustomMessage TriforcePieceMessages[NUM_TRIFORCE_PIECE_MESSAGES] = {
|
||||||
|
|
||||||
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. It's a start!",
|
{ "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. It's a start!",
|
||||||
"Ein %yTriforce-Splitter%w! Du hast&%g{{current}}%w von %c{{required}}%w gefunden. Es ist ein&Anfang!",
|
"Ein %yTriforce-Splitter%w! Du hast&%g[[current]]%w von %c[[required]]%w gefunden. Es ist ein&Anfang!",
|
||||||
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. C'est un début!" },
|
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. C'est un début!" },
|
||||||
|
|
||||||
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. Progress!",
|
{ "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. Progress!",
|
||||||
"Ein %yTriforce-Splitter%w! Du hast&%g{{current}}%w von %c{{required}}%w gefunden. Es geht voran!",
|
"Ein %yTriforce-Splitter%w! Du hast&%g[[current]]%w von %c[[required]]%w gefunden. Es geht voran!",
|
||||||
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. Ça avance!" },
|
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. Ça avance!" },
|
||||||
|
|
||||||
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. Over half-way&there!",
|
{ "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. Over half-way&there!",
|
||||||
"Ein %yTriforce-Splitter%w! Du hast&schon %g{{current}}%w von %c{{required}}%w gefunden. Schon&über die Hälfte!",
|
"Ein %yTriforce-Splitter%w! Du hast&schon %g[[current]]%w von %c[[required]]%w gefunden. Schon&über die Hälfte!",
|
||||||
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. Il en reste un&peu moins que la moitié!" },
|
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. Il en reste un&peu moins que la moitié!" },
|
||||||
|
|
||||||
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. Almost done!",
|
{ "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. Almost done!",
|
||||||
"Ein %yTriforce-Splitter%w! Du hast&schon %g{{current}}%w von %c{{required}}%w gefunden. Fast&geschafft!",
|
"Ein %yTriforce-Splitter%w! Du hast&schon %g[[current]]%w von %c[[required]]%w gefunden. Fast&geschafft!",
|
||||||
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. C'est presque&terminé!" },
|
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. C'est presque&terminé!" },
|
||||||
|
|
||||||
{ "You completed the %yTriforce of&Courage%w! %gGG%w!",
|
{ "You completed the %yTriforce of&Courage%w! %gGG%w!",
|
||||||
"Das %yTriforce des Mutes%w! Du hast&alle Splitter gefunden. %gGut gemacht%w!",
|
"Das %yTriforce des Mutes%w! Du hast&alle Splitter gefunden. %gGut gemacht%w!",
|
||||||
"Vous avez complété la %yTriforce&du Courage%w! %gFélicitations%w!" },
|
"Vous avez complété la %yTriforce&du Courage%w! %gFélicitations%w!" },
|
||||||
|
|
||||||
{ "You found a spare %yTriforce Piece%w!&You only needed %c{{required}}%w, but you have %g{{current}}%w!",
|
{ "You found a spare %yTriforce Piece%w!&You only needed %c[[required]]%w, but you have %g[[current]]%w!",
|
||||||
"Ein übriger %yTriforce-Splitter%w! Du&hast nun %g{{current}}%w von %c{{required}}%w nötigen gefunden.",
|
"Ein übriger %yTriforce-Splitter%w! Du&hast nun %g[[current]]%w von %c[[required]]%w nötigen gefunden.",
|
||||||
"Vous avez trouvé un %yFragment de&Triforce%w en plus! Vous n'aviez besoin&que de %c{{required}}%w, mais vous en avez %g{{current}}%w en&tout!" },
|
"Vous avez trouvé un %yFragment de&Triforce%w en plus! Vous n'aviez besoin&que de %c[[required]]%w, mais vous en avez %g[[current]]%w en&tout!" },
|
||||||
};
|
};
|
||||||
CustomMessageManager* customMessageManager = CustomMessageManager::Instance;
|
CustomMessageManager* customMessageManager = CustomMessageManager::Instance;
|
||||||
customMessageManager->AddCustomMessageTable(Randomizer::triforcePieceMessageTableID);
|
customMessageManager->AddCustomMessageTable(Randomizer::triforcePieceMessageTableID);
|
||||||
@ -2933,9 +2641,9 @@ CustomMessage Randomizer::GetTriforcePieceMessage() {
|
|||||||
|
|
||||||
CustomMessage messageEntry =
|
CustomMessage messageEntry =
|
||||||
CustomMessageManager::Instance->RetrieveMessage(Randomizer::triforcePieceMessageTableID, messageIndex);
|
CustomMessageManager::Instance->RetrieveMessage(Randomizer::triforcePieceMessageTableID, messageIndex);
|
||||||
messageEntry.Replace("{{current}}", std::to_string(current), std::to_string(current), std::to_string(current));
|
messageEntry.Replace("[[current]]", std::to_string(current));
|
||||||
messageEntry.Replace("{{remaining}}", std::to_string(remaining), std::to_string(remaining), std::to_string(remaining));
|
messageEntry.Replace("[[remaining]]", std::to_string(remaining));
|
||||||
messageEntry.Replace("{{required}}", std::to_string(required), std::to_string(required), std::to_string(required));
|
messageEntry.Replace("[[required]]", std::to_string(required));
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3157,11 +2865,11 @@ void CreateFireTempleGoronMessages() {
|
|||||||
"je&ressemble à n'importe quel Goron?",
|
"je&ressemble à n'importe quel Goron?",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"How long has it been, do you know?^%r{{days}}%w days!?^Oh no, and it's %r\x1F%w?&I have to check on my "
|
"How long has it been, do you know?^%r[[days]]%w days!?^Oh no, and it's %r\x1F%w?&I have to check on my "
|
||||||
"cake!!",
|
"cake!!",
|
||||||
"Weißt du zufällig, wie viele Tage&vergangen sind?^%r{{days}}%w Tage!?^Oh je, und es ist %r\x1F%w Uhr? "
|
"Weißt du zufällig, wie viele Tage&vergangen sind?^%r[[days]]%w Tage!?^Oh je, und es ist %r\x1F%w Uhr? "
|
||||||
"Ich&muss dringend nach meinem Kuchen&sehen!!!",
|
"Ich&muss dringend nach meinem Kuchen&sehen!!!",
|
||||||
"Cela fait combien de temps que&je suis enfermé ici?&Non mais je ne vais pas crier.^COMBIEN?! %r{{days}}%w "
|
"Cela fait combien de temps que&je suis enfermé ici?&Non mais je ne vais pas crier.^COMBIEN?! %r[[days]]%w "
|
||||||
"JOURS!?^En plus il est %r\x1F%w...&Il faut vraiment que je rentre...",
|
"JOURS!?^En plus il est %r\x1F%w...&Il faut vraiment que je rentre...",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3183,11 +2891,11 @@ void CreateFireTempleGoronMessages() {
|
|||||||
"aller.&A plus tard.",
|
"aller.&A plus tard.",
|
||||||
},
|
},
|
||||||
{ "Do you know about %b\x9f%w?&It's this weird symbol that's been&in my dreams lately...^Apparently, you "
|
{ "Do you know about %b\x9f%w?&It's this weird symbol that's been&in my dreams lately...^Apparently, you "
|
||||||
"pressed it %b{{a_btn}}%w times.^Wow.",
|
"pressed it %b[[a_btn]]%w times.^Wow.",
|
||||||
"Weißt du über %b\x9f%w bescheid?&Es sind Symbole, die mir&in letzter Zeit öfter in&meinen Träumen "
|
"Weißt du über %b\x9f%w bescheid?&Es sind Symbole, die mir&in letzter Zeit öfter in&meinen Träumen "
|
||||||
"erschienen sind...^Es scheint, dass du sie schon&%b{{a_btn}}%w mal betätigt hast.^Faszinierend...",
|
"erschienen sind...^Es scheint, dass du sie schon&%b[[a_btn]]%w mal betätigt hast.^Faszinierend...",
|
||||||
"Tu as déjà entendu parler du&symbole %b\x9f%w?&C'est un symbole bizarre qui est&apparu dans mes rêves "
|
"Tu as déjà entendu parler du&symbole %b\x9f%w?&C'est un symbole bizarre qui est&apparu dans mes rêves "
|
||||||
"dernièrement...^Apparemment, tu as appuyé dessus&%b{{a_btn}}%w fois.^Wow..." },
|
"dernièrement...^Apparemment, tu as appuyé dessus&%b[[a_btn]]%w fois.^Wow..." },
|
||||||
{
|
{
|
||||||
"\x13\x1A"
|
"\x13\x1A"
|
||||||
"Boy, you must be hot!&Get yourself a bottle of&%rLon Lon Milk%w right away and cool&down, for only %g30%w "
|
"Boy, you must be hot!&Get yourself a bottle of&%rLon Lon Milk%w right away and cool&down, for only %g30%w "
|
||||||
@ -3224,8 +2932,8 @@ void CreateFireTempleGoronMessages() {
|
|||||||
|
|
||||||
CustomMessage Randomizer::GetGoronMessage(u16 index) {
|
CustomMessage Randomizer::GetGoronMessage(u16 index) {
|
||||||
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, goronIDs[index]);
|
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, goronIDs[index]);
|
||||||
messageEntry.Replace("{{days}}", std::to_string(gSaveContext.totalDays));
|
messageEntry.Replace("[[days]]", std::to_string(gSaveContext.totalDays));
|
||||||
messageEntry.Replace("{{a_btn}}", std::to_string(gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]));
|
messageEntry.Replace("[[a_btn]]", std::to_string(gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]));
|
||||||
return messageEntry;
|
return messageEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3378,45 +3086,45 @@ void Randomizer::CreateCustomMessages() {
|
|||||||
"Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"),
|
"Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"),
|
||||||
|
|
||||||
GIMESSAGE(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %gDeku Tree &%wMap!{{typeHint}}",
|
"You found the %gDeku Tree &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%gDeku-Baum%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%gDeku-Baum%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %rDodongo's Cavern &%wMap!{{typeHint}}",
|
"You found the %rDodongo's Cavern &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für&%rDodongos Höhle%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für&%rDodongos Höhle%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %bJabu Jabu's Belly &%wMap!{{typeHint}}",
|
"You found the %bJabu Jabu's Belly &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für&%bJabu-Jabus Bauch%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für&%bJabu-Jabus Bauch%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %gForest Temple &%wMap!{{typeHint}}",
|
"You found the %gForest Temple &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%gWaldtempel%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%gWaldtempel%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %rFire Temple &%wMap!{{typeHint}}",
|
"You found the %rFire Temple &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%rFeuertempel%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%rFeuertempel%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%rTemple du Feu%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %bWater Temple &%wMap!{{typeHint}}",
|
"You found the %bWater Temple &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%bWassertempel%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%bWassertempel%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %ySpirit Temple &%wMap!{{typeHint}}",
|
"You found the %ySpirit Temple &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%yGeistertempel%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%yGeistertempel%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %pShadow Temple &%wMap!{{typeHint}}",
|
"You found the %pShadow Temple &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%pSchattentempel%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%pSchattentempel%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %pBottom of the &Well %wMap!{{typeHint}}",
|
"You found the %pBottom of the &Well %wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für den&%pGrund des Brunnens%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für den&%pGrund des Brunnens%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wdu &%pPuits%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wdu &%pPuits%w![[typeHint]]"),
|
||||||
GIMESSAGE(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP,
|
GIMESSAGE(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP,
|
||||||
"You found the %cIce Cavern &%wMap!{{typeHint}}",
|
"You found the %cIce Cavern &%wMap![[typeHint]]",
|
||||||
"Du erhältst die %rKarte%w für die&%cEishöhle%w!{{typeHint}}",
|
"Du erhältst die %rKarte%w für die&%cEishöhle%w![[typeHint]]",
|
||||||
"Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!{{typeHint}}"),
|
"Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w![[typeHint]]"),
|
||||||
|
|
||||||
GIMESSAGE(RG_DEKU_TREE_COMPASS, ITEM_COMPASS,
|
GIMESSAGE(RG_DEKU_TREE_COMPASS, ITEM_COMPASS,
|
||||||
"You found the %gDeku Tree &%wCompass!",
|
"You found the %gDeku Tree &%wCompass!",
|
||||||
|
@ -59,13 +59,9 @@ class Randomizer {
|
|||||||
ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck);
|
ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck);
|
||||||
ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck);
|
ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck);
|
||||||
CustomMessage GetSheikMessage(s16 scene, u16 originalTextId);
|
CustomMessage GetSheikMessage(s16 scene, u16 originalTextId);
|
||||||
CustomMessage ReplaceWithItemName(CustomMessage message, std::string&& toReplace, RandomizerCheck hintedCheck);
|
|
||||||
CustomMessage GetMiscHintMessage(TextIDs textToGet, RandomizerCheck hintedCheck, RandomizerCheck otherCheck = RC_UNKNOWN_CHECK);
|
|
||||||
CustomMessage GetSariaMessage(u16 originalTextId);
|
|
||||||
CustomMessage GetFishingPondOwnerMessage(u16 originalTextId);
|
CustomMessage GetFishingPondOwnerMessage(u16 originalTextId);
|
||||||
CustomMessage GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false);
|
CustomMessage GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false);
|
||||||
RandomizerCheck GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams);
|
RandomizerCheck GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams);
|
||||||
CustomMessage GetCursedSkullMessage(s16 params, RandomizerCheck hintedCheck);
|
|
||||||
CustomMessage GetGoronMessage(u16 index);
|
CustomMessage GetGoronMessage(u16 index);
|
||||||
CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry);
|
CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry);
|
||||||
static void CreateCustomMessages();
|
static void CreateCustomMessages();
|
||||||
|
@ -38,14 +38,18 @@ typedef enum {
|
|||||||
} RandomizerCheckStatus;
|
} RandomizerCheckStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HINT_TYPE_STATIC,
|
HINT_TYPE_HINT_KEY,
|
||||||
|
HINT_TYPE_AREA,
|
||||||
|
HINT_TYPE_ITEM,
|
||||||
HINT_TYPE_TRIAL,
|
HINT_TYPE_TRIAL,
|
||||||
HINT_TYPE_WOTH, // Way of the Hero
|
|
||||||
HINT_TYPE_BARREN,
|
|
||||||
HINT_TYPE_ENTRANCE,
|
HINT_TYPE_ENTRANCE,
|
||||||
HINT_TYPE_ITEM_AREA,
|
HINT_TYPE_ITEM_AREA,
|
||||||
HINT_TYPE_ITEM_LOCATION,
|
HINT_TYPE_MERCHANT,
|
||||||
HINT_TYPE_JUNK,
|
HINT_TYPE_ALTAR_CHILD,
|
||||||
|
HINT_TYPE_ALTAR_ADULT,
|
||||||
|
HINT_TYPE_WOTH, // Way of the Hero
|
||||||
|
HINT_TYPE_FOOLISH,
|
||||||
|
HINT_TYPE_MESSAGE,
|
||||||
HINT_TYPE_MAX
|
HINT_TYPE_MAX
|
||||||
} HintType;
|
} HintType;
|
||||||
|
|
||||||
@ -90,6 +94,16 @@ typedef enum {
|
|||||||
RA_MAX
|
RA_MAX
|
||||||
} RandomizerArea;
|
} RandomizerArea;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TK_LIGHT_TRIAL,
|
||||||
|
TK_FOREST_TRIAL,
|
||||||
|
TK_FIRE_TRIAL,
|
||||||
|
TK_WATER_TRIAL,
|
||||||
|
TK_SPIRIT_TRIAL,
|
||||||
|
TK_SHADOW_TRIAL,
|
||||||
|
TK_MAX
|
||||||
|
} TrialKey;
|
||||||
|
|
||||||
// Check types based on main settings
|
// Check types based on main settings
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RCTYPE_STANDARD, // Base set of rando checks
|
RCTYPE_STANDARD, // Base set of rando checks
|
||||||
@ -105,9 +119,9 @@ typedef enum {
|
|||||||
RCTYPE_SHOP, // shops
|
RCTYPE_SHOP, // shops
|
||||||
RCTYPE_SCRUB, // scrubs
|
RCTYPE_SCRUB, // scrubs
|
||||||
RCTYPE_MERCHANT, // merchants
|
RCTYPE_MERCHANT, // merchants
|
||||||
RCTYPE_CHEST_GAME, // todo replace this once we implement it, just using it to exclude for now
|
RCTYPE_CHEST_GAME, // RANDOTODO replace this once we implement it, just using it to exclude for now
|
||||||
RCTYPE_LINKS_POCKET, // todo this feels hacky
|
RCTYPE_LINKS_POCKET, // RANDOTODO this feels hacky, replace with better starting items
|
||||||
RCTYPE_GOSSIP_STONE,
|
RCTYPE_GOSSIP_STONE, // RANDOTODO make these into event access
|
||||||
RCTYPE_SONG_LOCATION, // Song locations
|
RCTYPE_SONG_LOCATION, // Song locations
|
||||||
RCTYPE_BOSS_HEART_OR_OTHER_REWARD, // Boss heart container or lesser dungeon rewards (lens, ice arrow)
|
RCTYPE_BOSS_HEART_OR_OTHER_REWARD, // Boss heart container or lesser dungeon rewards (lens, ice arrow)
|
||||||
RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps)
|
RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps)
|
||||||
@ -1393,46 +1407,46 @@ typedef enum {
|
|||||||
RC_PIERRE,
|
RC_PIERRE,
|
||||||
RC_DELIVER_RUTOS_LETTER,
|
RC_DELIVER_RUTOS_LETTER,
|
||||||
RC_MASTER_SWORD_PEDESTAL,
|
RC_MASTER_SWORD_PEDESTAL,
|
||||||
RC_COLOSSUS_GOSSIP_STONE,
|
|
||||||
RC_DMC_GOSSIP_STONE,
|
|
||||||
RC_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_DMT_GOSSIP_STONE,
|
|
||||||
RC_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_DODONGOS_CAVERN_GOSSIP_STONE,
|
|
||||||
RC_FAIRY_GOSSIP_STONE,
|
|
||||||
RC_GC_MAZE_GOSSIP_STONE,
|
|
||||||
RC_GC_MEDIGORON_GOSSIP_STONE,
|
|
||||||
RC_GV_GOSSIP_STONE,
|
|
||||||
RC_GY_GOSSIP_STONE,
|
|
||||||
RC_HC_MALON_GOSSIP_STONE,
|
|
||||||
RC_HC_ROCK_WALL_GOSSIP_STONE,
|
|
||||||
RC_HC_STORMS_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_HF_COW_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_HF_NEAR_MARKET_GOSSIP_STONE,
|
|
||||||
RC_HF_OPEN_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_HF_SOUTHEAST_GOSSIP_STONE,
|
|
||||||
RC_JABU_GOSSIP_STONE,
|
|
||||||
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
||||||
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
||||||
RC_KF_GOSSIP_STONE,
|
RC_KF_GOSSIP_STONE,
|
||||||
RC_KF_STORMS_GOSSIP_STONE,
|
RC_KF_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
RC_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
|
||||||
RC_LH_LAB_GOSSIP_STONE,
|
|
||||||
RC_LH_SOUTHEAST_GOSSIP_STONE,
|
|
||||||
RC_LH_SOUTHWEST_GOSSIP_STONE,
|
|
||||||
RC_LW_GOSSIP_STONE,
|
RC_LW_GOSSIP_STONE,
|
||||||
RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE,
|
RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE,
|
||||||
RC_SFM_MAZE_LOWER_GOSSIP_STONE,
|
RC_SFM_MAZE_LOWER_GOSSIP_STONE,
|
||||||
RC_SFM_MAZE_UPPER_GOSSIP_STONE,
|
RC_SFM_MAZE_UPPER_GOSSIP_STONE,
|
||||||
RC_SFM_SARIA_GOSSIP_STONE,
|
RC_SFM_SARIA_GOSSIP_STONE,
|
||||||
|
RC_HF_COW_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_HF_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE,
|
||||||
RC_TOT_LEFT_CENTER_GOSSIP_STONE,
|
RC_TOT_LEFT_CENTER_GOSSIP_STONE,
|
||||||
RC_TOT_LEFT_GOSSIP_STONE,
|
RC_TOT_LEFTMOST_GOSSIP_STONE,
|
||||||
RC_TOT_RIGHT_CENTER_GOSSIP_STONE,
|
RC_TOT_RIGHT_CENTER_GOSSIP_STONE,
|
||||||
RC_TOT_RIGHT_GOSSIP_STONE,
|
RC_TOT_RIGHTMOST_GOSSIP_STONE,
|
||||||
RC_ZD_GOSSIP_STONE,
|
RC_HC_MALON_GOSSIP_STONE,
|
||||||
|
RC_HC_ROCK_WALL_GOSSIP_STONE,
|
||||||
|
RC_HC_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_GRAVEYARD_GOSSIP_STONE,
|
||||||
|
RC_DMT_GOSSIP_STONE,
|
||||||
|
RC_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_GC_MAZE_GOSSIP_STONE,
|
||||||
|
RC_GC_MEDIGORON_GOSSIP_STONE,
|
||||||
|
RC_DMC_GOSSIP_STONE,
|
||||||
|
RC_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
||||||
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
||||||
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
||||||
RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RC_ZD_GOSSIP_STONE,
|
||||||
|
RC_ZF_JABU_GOSSIP_STONE,
|
||||||
|
RC_ZF_FAIRY_GOSSIP_STONE,
|
||||||
|
RC_LH_LAB_GOSSIP_STONE,
|
||||||
|
RC_LH_SOUTHEAST_GOSSIP_STONE,
|
||||||
|
RC_LH_SOUTHWEST_GOSSIP_STONE,
|
||||||
|
RC_GV_GOSSIP_STONE,
|
||||||
|
RC_COLOSSUS_GOSSIP_STONE,
|
||||||
|
RC_DODONGOS_CAVERN_GOSSIP_STONE,
|
||||||
RC_KF_STORMS_GROTTO_BEEHIVE_LEFT,
|
RC_KF_STORMS_GROTTO_BEEHIVE_LEFT,
|
||||||
RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT,
|
RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT,
|
||||||
RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT,
|
RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT,
|
||||||
@ -2001,75 +2015,83 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RH_NONE,
|
RH_NONE,
|
||||||
RH_COLOSSUS_GOSSIP_STONE,
|
RH_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
||||||
RH_DMC_GOSSIP_STONE,
|
RH_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
||||||
RH_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
RH_KF_GOSSIP_STONE,
|
||||||
RH_DMT_GOSSIP_STONE,
|
RH_KF_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
RH_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
RH_LW_GOSSIP_STONE,
|
||||||
RH_DODONGOS_CAVERN_GOSSIP_STONE,
|
RH_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE,
|
||||||
RH_ZF_FAIRY_GOSSIP_STONE,
|
RH_SFM_MAZE_NEAR_LW_GOSSIP_STONE,
|
||||||
RH_GC_MAZE_GOSSIP_STONE,
|
RH_SFM_MAZE_CENTER_GOSSIP_STONE,
|
||||||
RH_GC_MEDIGORON_GOSSIP_STONE,
|
RH_SFM_SARIA_GOSSIP_STONE,
|
||||||
RH_GV_GOSSIP_STONE,
|
|
||||||
RH_GRAVEYARD_GOSSIP_STONE,
|
|
||||||
RH_HC_MALON_GOSSIP_STONE,
|
|
||||||
RH_HC_ROCK_WALL_GOSSIP_STONE,
|
|
||||||
RH_HC_STORMS_GROTTO_GOSSIP_STONE,
|
|
||||||
RH_HF_COW_GROTTO_GOSSIP_STONE,
|
RH_HF_COW_GROTTO_GOSSIP_STONE,
|
||||||
RH_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE,
|
RH_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE,
|
||||||
RH_HF_OPEN_GROTTO_GOSSIP_STONE,
|
RH_HF_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
RH_HF_SOUTHEAST_GROTTO_GOSSIP_STONE,
|
RH_HF_SOUTHEAST_GROTTO_GOSSIP_STONE,
|
||||||
RH_ZF_JABU_GOSSIP_STONE,
|
RH_TOT_LEFT_CENTER_GOSSIP_STONE,
|
||||||
RH_KF_DEKU_TREE_GOSSIP_STONE_LEFT,
|
RH_TOT_LEFTMOST_GOSSIP_STONE,
|
||||||
RH_KF_DEKU_TREE_GOSSIP_STONE_RIGHT,
|
RH_TOT_RIGHT_CENTER_GOSSIP_STONE,
|
||||||
RH_KF_GOSSIP_STONE,
|
RH_TOT_RIGHTMOST_GOSSIP_STONE,
|
||||||
RH_KF_STORMS_GROTTO_GOSSIP_STONE,
|
RH_HC_MALON_GOSSIP_STONE,
|
||||||
|
RH_HC_ROCK_WALL_GOSSIP_STONE,
|
||||||
|
RH_HC_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
RH_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
RH_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
RH_LH_LAB_GOSSIP_STONE,
|
RH_GRAVEYARD_GOSSIP_STONE,
|
||||||
RH_LH_SOUTHEAST_GOSSIP_STONE,
|
RH_DMT_GOSSIP_STONE,
|
||||||
RH_LH_SOUTHWEST_GOSSIP_STONE,
|
RH_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
RH_LW_GOSSIP_STONE,
|
RH_GC_MAZE_GOSSIP_STONE,
|
||||||
RH_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE,
|
RH_GC_MEDIGORON_GOSSIP_STONE,
|
||||||
RH_SFM_MAZE_GOSSIP_STONE_LOWER,
|
RH_DMC_GOSSIP_STONE,
|
||||||
RH_SFM_MAZE_GOSSIP_STONE_UPPER,
|
RH_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
||||||
RH_SFM_SARIA_GOSSIP_STONE,
|
|
||||||
RH_TOT_GOSSIP_STONE_LEFT_CENTER,
|
|
||||||
RH_TOT_GOSSIP_STONE_LEFT,
|
|
||||||
RH_TOT_GOSSIP_STONE_RIGHT_CENTER,
|
|
||||||
RH_TOT_GOSSIP_STONE_RIGHT,
|
|
||||||
RH_ZD_GOSSIP_STONE,
|
|
||||||
RH_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
RH_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
||||||
RH_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
RH_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
||||||
RH_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
RH_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_ZD_GOSSIP_STONE,
|
||||||
|
RH_ZF_JABU_GOSSIP_STONE,
|
||||||
|
RH_ZF_FAIRY_GOSSIP_STONE,
|
||||||
|
RH_LH_LAB_GOSSIP_STONE,
|
||||||
|
RH_LH_SOUTHEAST_GOSSIP_STONE,
|
||||||
|
RH_LH_SOUTHWEST_GOSSIP_STONE,
|
||||||
|
RH_GV_GOSSIP_STONE,
|
||||||
|
RH_COLOSSUS_GOSSIP_STONE,
|
||||||
|
RH_DODONGOS_CAVERN_GOSSIP_STONE,
|
||||||
RH_GANONDORF_HINT,
|
RH_GANONDORF_HINT,
|
||||||
RH_GANONDORF_NOHINT,
|
RH_GANONDORF_JOKE,
|
||||||
|
RH_SHEIK_HINT,
|
||||||
RH_DAMPES_DIARY,
|
RH_DAMPES_DIARY,
|
||||||
RH_GREG_RUPEE,
|
RH_GREG_RUPEE,
|
||||||
RH_BEAN_SALESMAN,
|
|
||||||
RH_MEDIGORON,
|
|
||||||
RH_GRANNYS_SHOP,
|
|
||||||
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_HINT,
|
||||||
RH_FISHING_POLE,
|
RH_FISHING_POLE,
|
||||||
RH_SHEIK_LIGHT_ARROWS,
|
|
||||||
RH_MINUET_WARP_LOC,
|
RH_MINUET_WARP_LOC,
|
||||||
RH_BOLERO_WARP_LOC,
|
RH_BOLERO_WARP_LOC,
|
||||||
RH_SERENADE_WARP_LOC,
|
RH_SERENADE_WARP_LOC,
|
||||||
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_MEDIGORON,
|
||||||
|
RH_CARPET_SALESMAN,
|
||||||
|
RH_BEAN_SALESMAN,
|
||||||
|
RH_GRANNY,
|
||||||
|
RH_HBA_HINT,
|
||||||
|
RH_MALON_HINT,
|
||||||
|
RH_CHICKENS_HINT,
|
||||||
|
RH_BIG_POES_HINT,
|
||||||
|
RH_BIGGORON_HINT,
|
||||||
|
RH_FROGS_HINT,
|
||||||
|
RH_KAK_10_SKULLS_HINT,
|
||||||
|
RH_KAK_20_SKULLS_HINT,
|
||||||
|
RH_KAK_30_SKULLS_HINT,
|
||||||
|
RH_KAK_40_SKULLS_HINT,
|
||||||
|
RH_KAK_50_SKULLS_HINT,
|
||||||
|
RH_KAK_100_SKULLS_HINT,
|
||||||
RH_MAX,
|
RH_MAX,
|
||||||
} RandomizerHintKey;
|
} RandomizerHint;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RHT_NONE,
|
RHT_NONE,
|
||||||
RHT_PREFIX,
|
|
||||||
RHT_WAY_OF_THE_HERO,
|
RHT_WAY_OF_THE_HERO,
|
||||||
RHT_PLUNDERING,
|
|
||||||
RHT_FOOLISH,
|
RHT_FOOLISH,
|
||||||
RHT_CAN_BE_FOUND_AT,
|
RHT_CAN_BE_FOUND_AT,
|
||||||
RHT_HOARDS,
|
RHT_HOARDS,
|
||||||
@ -3173,7 +3195,6 @@ 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_CHILD_WALLET,
|
RHT_CHILD_WALLET,
|
||||||
RHT_HOOKSHOT,
|
RHT_HOOKSHOT,
|
||||||
@ -3218,6 +3239,8 @@ typedef enum {
|
|||||||
RHT_BRONZE_SCALE,
|
RHT_BRONZE_SCALE,
|
||||||
RHT_FISHING_POLE,
|
RHT_FISHING_POLE,
|
||||||
RHT_EPONA,
|
RHT_EPONA,
|
||||||
|
RHT_HINT_MYSTERIOUS,
|
||||||
|
RHT_MYSTERIOUS_ITEM,
|
||||||
// Entrances
|
// Entrances
|
||||||
RHT_DESERT_COLOSSUS_TO_COLOSSUS_GROTTO,
|
RHT_DESERT_COLOSSUS_TO_COLOSSUS_GROTTO,
|
||||||
RHT_GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO,
|
RHT_GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO,
|
||||||
@ -3377,60 +3400,69 @@ typedef enum {
|
|||||||
// Trials
|
// Trials
|
||||||
RHT_SIX_TRIALS,
|
RHT_SIX_TRIALS,
|
||||||
RHT_ZERO_TRIALS,
|
RHT_ZERO_TRIALS,
|
||||||
RHT_FOUR_TO_FIVE_TRIALS,
|
RHT_TRIAL_OFF,
|
||||||
RHT_ONE_TO_THREE_TRIALS,
|
RHT_TRIAL_ON,
|
||||||
|
RHT_LIGHT_TRIAL,
|
||||||
|
RHT_FOREST_TRIAL,
|
||||||
|
RHT_FIRE_TRIAL,
|
||||||
|
RHT_WATER_TRIAL,
|
||||||
|
RHT_SPIRIT_TRIAL,
|
||||||
|
RHT_SHADOW_TRIAL,
|
||||||
// Altar
|
// Altar
|
||||||
RHT_SPIRITUAL_STONE_TEXT_START,
|
RHT_CHILD_ALTAR_STONES,
|
||||||
RHT_CHILD_ALTAR_TEXT_END_DOTOPEN,
|
RHT_CHILD_ALTAR_TEXT_END_DOTOPEN,
|
||||||
RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY,
|
RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY,
|
||||||
RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED,
|
RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED,
|
||||||
RHT_ADULT_ALTAR_TEXT_START,
|
RHT_ADULT_ALTAR_MEDALLIONS,
|
||||||
RHT_ADULT_ALTAR_TEXT_END,
|
RHT_ADULT_ALTAR_TEXT_END,
|
||||||
// Validation Line
|
// Static Item Hints
|
||||||
RHT_VALIDATION_LINE,
|
RHT_GANONDORF_HINT_LA_ONLY,
|
||||||
// Light Arrow Location
|
RHT_GANONDORF_HINT_MS_ONLY,
|
||||||
RHT_LIGHT_ARROW_LOCATION_HINT,
|
RHT_GANONDORF_HINT_LA_AND_MS,
|
||||||
RHT_SHEIK_LIGHT_ARROW_HINT,
|
RHT_SHEIK_HINT_LA_ONLY,
|
||||||
// Master Sword Location
|
RHT_DAMPE_DIARY,
|
||||||
RHT_MASTER_SWORD_LOCATION_HINT,
|
RHT_GREG_HINT,
|
||||||
RHT_SHEIK_MASTER_SWORD_LOCATION_HINT,
|
RHT_SARIA_TALK_HINT,
|
||||||
// Your Pocket
|
RHT_SARIA_SONG_HINT,
|
||||||
RHT_YOUR_POCKET,
|
RHT_FISHING_POLE_HINT,
|
||||||
// Other Hints
|
// Static Entrance Hints
|
||||||
RHT_DAMPE_DIARY01,
|
RHT_WARP_SONG,
|
||||||
RHT_DAMPE_DIARY02,
|
// Static Location Hints
|
||||||
RHT_GREG_HINT01,
|
RHT_MEDIGORON_HINT,
|
||||||
RHT_GREG_HINT02,
|
|
||||||
RHT_SARIA_TEXT01,
|
|
||||||
RHT_SARIA_TEXT02,
|
|
||||||
RHT_WARP_TO,
|
|
||||||
RHT_WARP_CHOICE,
|
|
||||||
RHT_FROGS_HINT01,
|
|
||||||
RHT_FROGS_HINT02,
|
|
||||||
RHT_FISHING_POLE_HINT01,
|
|
||||||
RHT_FISHING_POLE_HINT02,
|
|
||||||
// Ganon Line
|
|
||||||
RHT_GANON_LINE01,
|
|
||||||
RHT_GANON_LINE02,
|
|
||||||
RHT_GANON_LINE03,
|
|
||||||
RHT_GANON_LINE04,
|
|
||||||
RHT_GANON_LINE05,
|
|
||||||
RHT_GANON_LINE06,
|
|
||||||
RHT_GANON_LINE07,
|
|
||||||
RHT_GANON_LINE08,
|
|
||||||
RHT_GANON_LINE09,
|
|
||||||
RHT_GANON_LINE10,
|
|
||||||
RHT_GANON_LINE11,
|
|
||||||
// Merchants
|
|
||||||
RHT_BEAN_SALESMAN_FIRST,
|
|
||||||
RHT_BEAN_SALESMAN_SECOND,
|
|
||||||
RHT_MEDIGORON_DIALOG_FIRST,
|
|
||||||
RHT_MEDIGORON_DIALOG_SECOND,
|
|
||||||
RHT_CARPET_SALESMAN_DIALOG_FIRST,
|
RHT_CARPET_SALESMAN_DIALOG_FIRST,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS,
|
RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_HINTED,
|
RHT_CARPET_SALESMAN_DIALOG_HINTED,
|
||||||
RHT_CARPET_SALESMAN_DIALOG_FINAL,
|
RHT_BEAN_SALESMAN_HINT,
|
||||||
RHT_GRANNY_DIALOG,
|
RHT_GRANNY_HINT,
|
||||||
|
RHT_HBA_HINT_SIGN,
|
||||||
|
RHT_HBA_HINT_NOT_ON_HORSE,
|
||||||
|
RHT_HBA_HINT_INITIAL,
|
||||||
|
RHT_HBA_HINT_HAVE_1000,
|
||||||
|
RHT_MALON_HINT_HOW_IS_EPONA,
|
||||||
|
RHT_MALON_HINT_OBSTICLE_COURSE,
|
||||||
|
RHT_MALON_HINT_TURNING_EVIL,
|
||||||
|
RHT_MALON_HINT_INGO_TEMPTED,
|
||||||
|
RHT_CHICKENS_HINT,
|
||||||
|
RHT_BIG_POES_HINT,
|
||||||
|
RHT_BIGGORON_HINT,
|
||||||
|
RHT_FROGS_HINT,
|
||||||
|
RHT_SKULLS_HINT,
|
||||||
|
// Ganon Line
|
||||||
|
RHT_GANON_JOKE01,
|
||||||
|
RHT_GANON_JOKE02,
|
||||||
|
RHT_GANON_JOKE03,
|
||||||
|
RHT_GANON_JOKE04,
|
||||||
|
RHT_GANON_JOKE05,
|
||||||
|
RHT_GANON_JOKE06,
|
||||||
|
RHT_GANON_JOKE07,
|
||||||
|
RHT_GANON_JOKE08,
|
||||||
|
RHT_GANON_JOKE09,
|
||||||
|
RHT_GANON_JOKE10,
|
||||||
|
RHT_GANON_JOKE11,
|
||||||
|
// Misc utilities
|
||||||
|
RHT_YOUR_POCKET,
|
||||||
|
RHT_DUNGEON_ORDINARY,
|
||||||
|
RHT_DUNGEON_MASTERFUL,
|
||||||
RHT_MAX
|
RHT_MAX
|
||||||
} RandomizerHintTextKey;
|
} RandomizerHintTextKey;
|
||||||
|
|
||||||
@ -3563,7 +3595,8 @@ typedef enum {
|
|||||||
RSK_ICE_TRAPS,
|
RSK_ICE_TRAPS,
|
||||||
RSK_GOSSIP_STONE_HINTS,
|
RSK_GOSSIP_STONE_HINTS,
|
||||||
RSK_TOT_ALTAR_HINT,
|
RSK_TOT_ALTAR_HINT,
|
||||||
RSK_LIGHT_ARROWS_HINT,
|
RSK_GANONDORF_HINT,
|
||||||
|
RSK_SHEIK_LA_HINT,
|
||||||
RSK_DAMPES_DIARY_HINT,
|
RSK_DAMPES_DIARY_HINT,
|
||||||
RSK_GREG_HINT,
|
RSK_GREG_HINT,
|
||||||
RSK_SARIA_HINT,
|
RSK_SARIA_HINT,
|
||||||
@ -3593,7 +3626,6 @@ typedef enum {
|
|||||||
RSK_SKIP_CHILD_ZELDA,
|
RSK_SKIP_CHILD_ZELDA,
|
||||||
RSK_STARTING_CONSUMABLES,
|
RSK_STARTING_CONSUMABLES,
|
||||||
RSK_FULL_WALLETS,
|
RSK_FULL_WALLETS,
|
||||||
RSK_LANGUAGE,
|
|
||||||
RSK_SHUFFLE_CHEST_MINIGAME,
|
RSK_SHUFFLE_CHEST_MINIGAME,
|
||||||
RSK_CUCCO_COUNT,
|
RSK_CUCCO_COUNT,
|
||||||
RSK_BIG_POE_COUNT,
|
RSK_BIG_POE_COUNT,
|
||||||
@ -4104,3 +4136,5 @@ typedef enum {
|
|||||||
TH_MESSAGE_FINISHED,
|
TH_MESSAGE_FINISHED,
|
||||||
TH_MESSAGE_SURPLUS,
|
TH_MESSAGE_SURPLUS,
|
||||||
} TriforceHuntMessages;
|
} TriforceHuntMessages;
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +157,8 @@ void Settings::CreateOptions() {
|
|||||||
mOptions[RSK_HINT_CLARITY] = Option::U8("Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, "gRandomizeHintClarity", mOptionDescriptions[RSK_HINT_CLARITY], WidgetType::Combobox, RO_HINT_CLARITY_CLEAR, true, IMFLAG_INDENT);
|
mOptions[RSK_HINT_CLARITY] = Option::U8("Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, "gRandomizeHintClarity", mOptionDescriptions[RSK_HINT_CLARITY], WidgetType::Combobox, RO_HINT_CLARITY_CLEAR, true, IMFLAG_INDENT);
|
||||||
mOptions[RSK_HINT_DISTRIBUTION] = Option::U8("Hint Distribution", {"Useless", "Balanced", "Strong", "Very Strong"}, OptionCategory::Setting, "gRandomizeHintDistribution", mOptionDescriptions[RSK_HINT_DISTRIBUTION], WidgetType::Combobox, RO_HINT_DIST_BALANCED, true, IMFLAG_UNINDENT);
|
mOptions[RSK_HINT_DISTRIBUTION] = Option::U8("Hint Distribution", {"Useless", "Balanced", "Strong", "Very Strong"}, OptionCategory::Setting, "gRandomizeHintDistribution", mOptionDescriptions[RSK_HINT_DISTRIBUTION], WidgetType::Combobox, RO_HINT_DIST_BALANCED, true, IMFLAG_UNINDENT);
|
||||||
mOptions[RSK_TOT_ALTAR_HINT] = Option::Bool("ToT Altar Hint", {"Off", "On"}, OptionCategory::Setting, "gRandomizeAltarHint", mOptionDescriptions[RSK_TOT_ALTAR_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_INDENT);
|
mOptions[RSK_TOT_ALTAR_HINT] = Option::Bool("ToT Altar Hint", {"Off", "On"}, OptionCategory::Setting, "gRandomizeAltarHint", mOptionDescriptions[RSK_TOT_ALTAR_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_INDENT);
|
||||||
mOptions[RSK_LIGHT_ARROWS_HINT] = Option::Bool("Light Arrow Hint", {"Off", "On"}, OptionCategory::Setting, "gRandomizeLAHint", mOptionDescriptions[RSK_LIGHT_ARROWS_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_NONE);
|
mOptions[RSK_GANONDORF_HINT] = Option::Bool("Ganondorf Hint", {"Off", "On"}, OptionCategory::Setting, "gRandomizeGanondorfHint", mOptionDescriptions[RSK_GANONDORF_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_NONE);
|
||||||
|
mOptions[RSK_SHEIK_LA_HINT] = Option::Bool("Sheik Light Arrow Hint", {"Off", "On"}, OptionCategory::Setting, "gRandomizeSheikLAHint", mOptionDescriptions[RSK_SHEIK_LA_HINT], WidgetType::Checkbox, RO_GENERIC_ON, false, IMFLAG_NONE);
|
||||||
mOptions[RSK_DAMPES_DIARY_HINT] = Option::Bool("Dampe's Diary Hint", "gRandomizeDampeHint", mOptionDescriptions[RSK_DAMPES_DIARY_HINT], IMFLAG_NONE);
|
mOptions[RSK_DAMPES_DIARY_HINT] = Option::Bool("Dampe's Diary Hint", "gRandomizeDampeHint", mOptionDescriptions[RSK_DAMPES_DIARY_HINT], IMFLAG_NONE);
|
||||||
mOptions[RSK_GREG_HINT] = Option::Bool("Greg the Green Rupee Hint", "gRandomizeGregHint", mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE);
|
mOptions[RSK_GREG_HINT] = Option::Bool("Greg the Green Rupee Hint", "gRandomizeGregHint", mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE);
|
||||||
mOptions[RSK_SARIA_HINT] = Option::Bool("Saria's Hint", "gRandomizeSariaHint", mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE);
|
mOptions[RSK_SARIA_HINT] = Option::Bool("Saria's Hint", "gRandomizeSariaHint", mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE);
|
||||||
@ -207,8 +208,6 @@ void Settings::CreateOptions() {
|
|||||||
mOptions[RSK_ALL_LOCATIONS_REACHABLE] = Option::Bool("All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, "gRandomizeAllLocationsReachable", mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WidgetType::Checkbox, RO_GENERIC_ON);
|
mOptions[RSK_ALL_LOCATIONS_REACHABLE] = Option::Bool("All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, "gRandomizeAllLocationsReachable", mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WidgetType::Checkbox, RO_GENERIC_ON);
|
||||||
mOptions[RSK_SKULLS_SUNS_SONG] = Option::Bool("Night Skulltula's Expect Sun's Song", "gRandomizeGsExpectSunsSong", mOptionDescriptions[RSK_SKULLS_SUNS_SONG]);
|
mOptions[RSK_SKULLS_SUNS_SONG] = Option::Bool("Night Skulltula's Expect Sun's Song", "gRandomizeGsExpectSunsSong", mOptionDescriptions[RSK_SKULLS_SUNS_SONG]);
|
||||||
mOptions[RSK_DAMAGE_MULTIPLIER] = Option::U8("Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WidgetType::Slider, RO_DAMAGE_MULTIPLIER_DEFAULT);
|
mOptions[RSK_DAMAGE_MULTIPLIER] = Option::U8("Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WidgetType::Slider, RO_DAMAGE_MULTIPLIER_DEFAULT);
|
||||||
|
|
||||||
mOptions[RSK_LANGUAGE] = Option::U8("Language", {"English", "German", "French"}, OptionCategory::Setting, "gLanguages", "", WidgetType::Combobox, LANGUAGE_ENG);
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
mExcludeLocationsOptionsGroups.reserve(SPOILER_COLLECTION_GROUP_COUNT);
|
mExcludeLocationsOptionsGroups.reserve(SPOILER_COLLECTION_GROUP_COUNT);
|
||||||
@ -727,7 +726,8 @@ void Settings::CreateOptions() {
|
|||||||
}, false, WidgetContainerType::SECTION);
|
}, false, WidgetContainerType::SECTION);
|
||||||
mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup("Extra Hints", {
|
mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup("Extra Hints", {
|
||||||
&mOptions[RSK_TOT_ALTAR_HINT],
|
&mOptions[RSK_TOT_ALTAR_HINT],
|
||||||
&mOptions[RSK_LIGHT_ARROWS_HINT],
|
&mOptions[RSK_GANONDORF_HINT],
|
||||||
|
&mOptions[RSK_SHEIK_LA_HINT],
|
||||||
&mOptions[RSK_DAMPES_DIARY_HINT],
|
&mOptions[RSK_DAMPES_DIARY_HINT],
|
||||||
&mOptions[RSK_GREG_HINT],
|
&mOptions[RSK_GREG_HINT],
|
||||||
&mOptions[RSK_SARIA_HINT],
|
&mOptions[RSK_SARIA_HINT],
|
||||||
@ -954,7 +954,8 @@ void Settings::CreateOptions() {
|
|||||||
&mOptions[RSK_HINT_CLARITY],
|
&mOptions[RSK_HINT_CLARITY],
|
||||||
&mOptions[RSK_HINT_DISTRIBUTION],
|
&mOptions[RSK_HINT_DISTRIBUTION],
|
||||||
&mOptions[RSK_TOT_ALTAR_HINT],
|
&mOptions[RSK_TOT_ALTAR_HINT],
|
||||||
&mOptions[RSK_LIGHT_ARROWS_HINT],
|
&mOptions[RSK_GANONDORF_HINT],
|
||||||
|
&mOptions[RSK_SHEIK_LA_HINT],
|
||||||
&mOptions[RSK_DAMPES_DIARY_HINT],
|
&mOptions[RSK_DAMPES_DIARY_HINT],
|
||||||
&mOptions[RSK_GREG_HINT],
|
&mOptions[RSK_GREG_HINT],
|
||||||
&mOptions[RSK_SARIA_HINT],
|
&mOptions[RSK_SARIA_HINT],
|
||||||
@ -1171,7 +1172,8 @@ void Settings::CreateOptions() {
|
|||||||
{ "Miscellaneous Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS },
|
{ "Miscellaneous Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS },
|
||||||
{ "Miscellaneous Settings:Hint Clarity", RSK_HINT_CLARITY },
|
{ "Miscellaneous Settings:Hint Clarity", RSK_HINT_CLARITY },
|
||||||
{ "Miscellaneous Settings:ToT Altar Hint", RSK_TOT_ALTAR_HINT },
|
{ "Miscellaneous Settings:ToT Altar Hint", RSK_TOT_ALTAR_HINT },
|
||||||
{ "Miscellaneous Settings:Light Arrow Hint", RSK_LIGHT_ARROWS_HINT },
|
{ "Miscellaneous Settings:Ganondorf Hint", RSK_GANONDORF_HINT },
|
||||||
|
{ "Miscellaneous Settings:Sheik Light Arrow Hint", RSK_SHEIK_LA_HINT },
|
||||||
{ "Miscellaneous Settings:Dampe's Diary Hint", RSK_DAMPES_DIARY_HINT },
|
{ "Miscellaneous Settings:Dampe's Diary Hint", RSK_DAMPES_DIARY_HINT },
|
||||||
{ "Miscellaneous Settings:Greg the Rupee Hint", RSK_GREG_HINT },
|
{ "Miscellaneous Settings:Greg the Rupee Hint", RSK_GREG_HINT },
|
||||||
{ "Miscellaneous Settings:Saria's Hint", RSK_SARIA_HINT },
|
{ "Miscellaneous Settings:Saria's Hint", RSK_SARIA_HINT },
|
||||||
@ -2277,7 +2279,8 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
|
|||||||
case RSK_SUNLIGHT_ARROWS:
|
case RSK_SUNLIGHT_ARROWS:
|
||||||
case RSK_BOMBCHUS_IN_LOGIC:
|
case RSK_BOMBCHUS_IN_LOGIC:
|
||||||
case RSK_TOT_ALTAR_HINT:
|
case RSK_TOT_ALTAR_HINT:
|
||||||
case RSK_LIGHT_ARROWS_HINT:
|
case RSK_GANONDORF_HINT:
|
||||||
|
case RSK_SHEIK_LA_HINT:
|
||||||
case RSK_DAMPES_DIARY_HINT:
|
case RSK_DAMPES_DIARY_HINT:
|
||||||
case RSK_GREG_HINT:
|
case RSK_GREG_HINT:
|
||||||
case RSK_SARIA_HINT:
|
case RSK_SARIA_HINT:
|
||||||
@ -2640,7 +2643,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
|
|||||||
|
|
||||||
ctx->AddExcludedOptions();
|
ctx->AddExcludedOptions();
|
||||||
for (auto it = jsonExcludedLocations.begin(); it != jsonExcludedLocations.end(); ++it) {
|
for (auto it = jsonExcludedLocations.begin(); it != jsonExcludedLocations.end(); ++it) {
|
||||||
const RandomizerCheck rc = StaticData::SpoilerfileCheckNameToEnum[it.value()];
|
const RandomizerCheck rc = Rando::StaticData::locationNameToEnum[it.value()];
|
||||||
ctx->GetItemLocation(rc)->GetExcludedOption()->SetSelectedIndex(RO_GENERIC_ON);
|
ctx->GetItemLocation(rc)->GetExcludedOption()->SetSelectedIndex(RO_GENERIC_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
307
soh/soh/Enhancements/randomizer/static_data.cpp
Normal file
307
soh/soh/Enhancements/randomizer/static_data.cpp
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
#include <unordered_map>
|
||||||
|
#include "static_data.h"
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
namespace Rando {
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, CustomMessage> StaticData::hintTypeNames = {
|
||||||
|
{HINT_TYPE_HINT_KEY, CustomMessage("Message")},
|
||||||
|
{HINT_TYPE_AREA, CustomMessage("Area")},
|
||||||
|
{HINT_TYPE_ITEM, CustomMessage("Item")},
|
||||||
|
{HINT_TYPE_TRIAL, CustomMessage("Trial")},
|
||||||
|
{HINT_TYPE_ENTRANCE, CustomMessage("Entrance")},
|
||||||
|
{HINT_TYPE_ITEM_AREA, CustomMessage("Item Area")},
|
||||||
|
{HINT_TYPE_MERCHANT, CustomMessage("Merchant")},
|
||||||
|
{HINT_TYPE_ALTAR_CHILD, CustomMessage("Child Altar")},
|
||||||
|
{HINT_TYPE_ALTAR_ADULT, CustomMessage("Adult Altar")},
|
||||||
|
{HINT_TYPE_WOTH, CustomMessage("Way of the Hero")},
|
||||||
|
{HINT_TYPE_FOOLISH, CustomMessage("Foolish")},
|
||||||
|
{HINT_TYPE_MESSAGE, CustomMessage("Hardcoded Message")}
|
||||||
|
};
|
||||||
|
|
||||||
|
//RANDOTODO When dynamic grotto check names are done, apply it to these hints
|
||||||
|
//RANDOTODO Translations
|
||||||
|
std::unordered_map<uint32_t, CustomMessage> StaticData::hintNames = {
|
||||||
|
{RH_NONE, CustomMessage("ERROR HINT")},
|
||||||
|
{RH_KF_DEKU_TREE_LEFT_GOSSIP_STONE, CustomMessage("KF Left Near Deku Gossip Stone")}, //RANDOTODO find cardinal direction
|
||||||
|
{RH_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, CustomMessage("KF Right Near Deku Gossip Stone")},
|
||||||
|
{RH_KF_GOSSIP_STONE, CustomMessage("KF Gossip Stone")},
|
||||||
|
{RH_KF_STORMS_GROTTO_GOSSIP_STONE, CustomMessage("KF Storms Grotto Gossip Stone")},
|
||||||
|
{RH_LW_GOSSIP_STONE, CustomMessage("LW Gossip Stone")},
|
||||||
|
{RH_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, CustomMessage("LW Near Shortcuts Grotto Gossip Stone")},
|
||||||
|
{RH_SFM_MAZE_NEAR_LW_GOSSIP_STONE, CustomMessage("SFM Near LW Gossip Stone")},
|
||||||
|
{RH_SFM_MAZE_CENTER_GOSSIP_STONE, CustomMessage("SFM Center Gossip Stone")},
|
||||||
|
{RH_SFM_SARIA_GOSSIP_STONE, CustomMessage("SFM Near Saria Gossip Stone")},
|
||||||
|
{RH_HF_COW_GROTTO_GOSSIP_STONE, CustomMessage("HF Cow Grotto Gossip Stone")},
|
||||||
|
{RH_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, CustomMessage("HF Near Market Grotto Gossip Stone")},
|
||||||
|
{RH_HF_OPEN_GROTTO_GOSSIP_STONE, CustomMessage("HF Open Grotto Gossip Stone")},
|
||||||
|
{RH_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, CustomMessage("HF Southeast Grotto Gossip Stone")},
|
||||||
|
{RH_TOT_LEFT_CENTER_GOSSIP_STONE, CustomMessage("Market Left Center Gossip Stone")},
|
||||||
|
{RH_TOT_LEFTMOST_GOSSIP_STONE, CustomMessage("Market Leftmost Center Gossip Stone")},
|
||||||
|
{RH_TOT_RIGHT_CENTER_GOSSIP_STONE, CustomMessage("Market Right Center Gossip Stone")},
|
||||||
|
{RH_TOT_RIGHTMOST_GOSSIP_STONE, CustomMessage("Market Rightmost Gossip Stone")},
|
||||||
|
{RH_HC_MALON_GOSSIP_STONE, CustomMessage("HC Near Malon Gossip Stone")},
|
||||||
|
{RH_HC_ROCK_WALL_GOSSIP_STONE, CustomMessage("HC Rock Wall Gossip Stone")},
|
||||||
|
{RH_HC_STORMS_GROTTO_GOSSIP_STONE, CustomMessage("HC Storm Grotto Gossip Stone")},
|
||||||
|
{RH_KAK_OPEN_GROTTO_GOSSIP_STONE, CustomMessage("Kak Open Grotto Gossip Stone")},
|
||||||
|
{RH_GRAVEYARD_GOSSIP_STONE, CustomMessage("Graveyard Gossip Stone")},
|
||||||
|
{RH_DMT_GOSSIP_STONE, CustomMessage("DMT Gossip Stone")},
|
||||||
|
{RH_DMT_STORMS_GROTTO_GOSSIP_STONE, CustomMessage("DMT Storms Grotto Gossip Stone")},
|
||||||
|
{RH_GC_MAZE_GOSSIP_STONE, CustomMessage("GC Maze Gossip Stone")},
|
||||||
|
{RH_GC_MEDIGORON_GOSSIP_STONE, CustomMessage("GC Medigoron Gossip Stone")},
|
||||||
|
{RH_DMC_GOSSIP_STONE, CustomMessage("DMC Gossip Stone")},
|
||||||
|
{RH_DMC_UPPER_GROTTO_GOSSIP_STONE, CustomMessage("DMC Upper Grotto Gossip Stone")},
|
||||||
|
{RH_ZR_NEAR_DOMAIN_GOSSIP_STONE, CustomMessage("ZR Near Domain Gossip Stone")},
|
||||||
|
{RH_ZR_NEAR_GROTTOS_GOSSIP_STONE, CustomMessage("ZR Near Grottos Gossip Stone")},
|
||||||
|
{RH_ZR_OPEN_GROTTO_GOSSIP_STONE, CustomMessage("ZR Open Grotto Gossip Stone")},
|
||||||
|
{RH_ZD_GOSSIP_STONE, CustomMessage("ZD Gossip Stone")},
|
||||||
|
{RH_ZF_JABU_GOSSIP_STONE, CustomMessage("ZF Near Jabu Gossip Stone")},
|
||||||
|
{RH_ZF_FAIRY_GOSSIP_STONE, CustomMessage("ZF Near Fairy Gossip Stone")},
|
||||||
|
{RH_LH_LAB_GOSSIP_STONE, CustomMessage("LH Near Lab Gossip Stone")},
|
||||||
|
{RH_LH_SOUTHEAST_GOSSIP_STONE, CustomMessage("LH Southeast Gossip Stone")},
|
||||||
|
{RH_LH_SOUTHWEST_GOSSIP_STONE, CustomMessage("LH Southwest Gossip Stone")},
|
||||||
|
{RH_GV_GOSSIP_STONE, CustomMessage("Gerudo Valley Gossip Stone")},
|
||||||
|
{RH_COLOSSUS_GOSSIP_STONE, CustomMessage("Desert Collosus Gossip Stone")},
|
||||||
|
{RH_DODONGOS_CAVERN_GOSSIP_STONE, CustomMessage("Dodongo's Cavern Gossip Stone")},
|
||||||
|
{RH_GANONDORF_HINT, CustomMessage("Ganondorf Hint")},
|
||||||
|
{RH_GANONDORF_JOKE, CustomMessage("Ganondorf Joke")},
|
||||||
|
{RH_SHEIK_HINT, CustomMessage("Sheik in Ganons Castle Hint")},
|
||||||
|
{RH_DAMPES_DIARY, CustomMessage("Dampe's Diary Hint")},
|
||||||
|
{RH_GREG_RUPEE, CustomMessage("Treasure Chest Game Greg Hint")},
|
||||||
|
{RH_ALTAR_CHILD, CustomMessage("ToT Altar as Child")},
|
||||||
|
{RH_ALTAR_ADULT, CustomMessage("ToT Altar as Adult")},
|
||||||
|
{RH_SARIA_HINT, CustomMessage("Saria's Magic Hint")},
|
||||||
|
{RH_FISHING_POLE, CustomMessage("Fishing Pole Hint")},
|
||||||
|
{RH_MINUET_WARP_LOC, CustomMessage("Minuet of Forest Destination")},
|
||||||
|
{RH_BOLERO_WARP_LOC, CustomMessage("Bolero of Fire Destination")},
|
||||||
|
{RH_SERENADE_WARP_LOC, CustomMessage("Serenade of Water Destination")},
|
||||||
|
{RH_REQUIEM_WARP_LOC, CustomMessage("Requiem of Spirit Destination")},
|
||||||
|
{RH_NOCTURNE_WARP_LOC, CustomMessage("Nocturne of Shadow Destination")},
|
||||||
|
{RH_PRELUDE_WARP_LOC, CustomMessage("Prelude of Light Destination")},
|
||||||
|
{RH_MEDIGORON, CustomMessage("Medigoron Hint")},
|
||||||
|
{RH_CARPET_SALESMAN, CustomMessage("Carpet Salseman Hint")},
|
||||||
|
{RH_BEAN_SALESMAN, CustomMessage("Bean Salseman Hint")},
|
||||||
|
{RH_GRANNY, CustomMessage("Granny Hint")},
|
||||||
|
{RH_HBA_HINT, CustomMessage("Horseback Archery Hint")},
|
||||||
|
{RH_MALON_HINT, CustomMessage("Malon Hint")},
|
||||||
|
{RH_CHICKENS_HINT, CustomMessage("Anju's Child Chickens Hint")},
|
||||||
|
{RH_BIG_POES_HINT, CustomMessage("Big Poe Reward Hint")},
|
||||||
|
{RH_BIGGORON_HINT, CustomMessage("Biggoron Claim Check Hint")},
|
||||||
|
{RH_FROGS_HINT, CustomMessage("Final Frogs in River Hint")},
|
||||||
|
{RH_KAK_10_SKULLS_HINT, CustomMessage("10 Skulls Hint")},
|
||||||
|
{RH_KAK_20_SKULLS_HINT, CustomMessage("20 Skulls Hint")},
|
||||||
|
{RH_KAK_30_SKULLS_HINT, CustomMessage("30 Skulls Hint")},
|
||||||
|
{RH_KAK_40_SKULLS_HINT, CustomMessage("40 Skulls Hint")},
|
||||||
|
{RH_KAK_50_SKULLS_HINT, CustomMessage("50 Skulls Hint")},
|
||||||
|
{RH_KAK_100_SKULLS_HINT, CustomMessage("100 Skulls Hint")}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<RandomizerCheck, RandomizerHint> StaticData::gossipStoneCheckToHint {
|
||||||
|
{RC_COLOSSUS_GOSSIP_STONE, RH_COLOSSUS_GOSSIP_STONE},
|
||||||
|
{RC_DMC_GOSSIP_STONE, RH_DMC_GOSSIP_STONE},
|
||||||
|
{RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RH_DMC_UPPER_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_DMT_GOSSIP_STONE, RH_DMT_GOSSIP_STONE},
|
||||||
|
{RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RH_DMT_STORMS_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_DODONGOS_CAVERN_GOSSIP_STONE, RH_DODONGOS_CAVERN_GOSSIP_STONE},
|
||||||
|
{RC_ZF_FAIRY_GOSSIP_STONE, RH_ZF_FAIRY_GOSSIP_STONE},
|
||||||
|
{RC_GC_MAZE_GOSSIP_STONE, RH_GC_MAZE_GOSSIP_STONE},
|
||||||
|
{RC_GC_MEDIGORON_GOSSIP_STONE, RH_GC_MEDIGORON_GOSSIP_STONE},
|
||||||
|
{RC_GV_GOSSIP_STONE, RH_GV_GOSSIP_STONE},
|
||||||
|
{RC_GRAVEYARD_GOSSIP_STONE, RH_GRAVEYARD_GOSSIP_STONE},
|
||||||
|
{RC_HC_MALON_GOSSIP_STONE, RH_HC_MALON_GOSSIP_STONE},
|
||||||
|
{RC_HC_ROCK_WALL_GOSSIP_STONE, RH_HC_ROCK_WALL_GOSSIP_STONE},
|
||||||
|
{RC_HC_STORMS_GROTTO_GOSSIP_STONE, RH_HC_STORMS_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_HF_COW_GROTTO_GOSSIP_STONE, RH_HF_COW_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, RH_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_HF_OPEN_GROTTO_GOSSIP_STONE, RH_HF_OPEN_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, RH_HF_SOUTHEAST_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_ZF_JABU_GOSSIP_STONE, RH_ZF_JABU_GOSSIP_STONE},
|
||||||
|
{RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RH_KF_DEKU_TREE_LEFT_GOSSIP_STONE},
|
||||||
|
{RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RH_KF_DEKU_TREE_RIGHT_GOSSIP_STONE},
|
||||||
|
{RC_KF_GOSSIP_STONE, RH_KF_GOSSIP_STONE},
|
||||||
|
{RC_KF_STORMS_GROTTO_GOSSIP_STONE, RH_KF_STORMS_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RH_KAK_OPEN_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_LH_LAB_GOSSIP_STONE, RH_LH_LAB_GOSSIP_STONE},
|
||||||
|
{RC_LH_SOUTHEAST_GOSSIP_STONE, RH_LH_SOUTHEAST_GOSSIP_STONE},
|
||||||
|
{RC_LH_SOUTHWEST_GOSSIP_STONE, RH_LH_SOUTHWEST_GOSSIP_STONE},
|
||||||
|
{RC_LW_GOSSIP_STONE, RH_LW_GOSSIP_STONE},
|
||||||
|
{RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RH_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE},
|
||||||
|
{RC_SFM_MAZE_LOWER_GOSSIP_STONE, RH_SFM_MAZE_NEAR_LW_GOSSIP_STONE},
|
||||||
|
{RC_SFM_MAZE_UPPER_GOSSIP_STONE, RH_SFM_MAZE_CENTER_GOSSIP_STONE},
|
||||||
|
{RC_SFM_SARIA_GOSSIP_STONE, RH_SFM_SARIA_GOSSIP_STONE},
|
||||||
|
{RC_TOT_LEFT_CENTER_GOSSIP_STONE, RH_TOT_LEFT_CENTER_GOSSIP_STONE},
|
||||||
|
{RC_TOT_LEFTMOST_GOSSIP_STONE, RH_TOT_LEFTMOST_GOSSIP_STONE},
|
||||||
|
{RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RH_TOT_RIGHT_CENTER_GOSSIP_STONE},
|
||||||
|
{RC_TOT_RIGHTMOST_GOSSIP_STONE, RH_TOT_RIGHTMOST_GOSSIP_STONE},
|
||||||
|
{RC_ZD_GOSSIP_STONE, RH_ZD_GOSSIP_STONE},
|
||||||
|
{RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RH_ZR_NEAR_DOMAIN_GOSSIP_STONE},
|
||||||
|
{RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RH_ZR_NEAR_GROTTOS_GOSSIP_STONE},
|
||||||
|
{RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RH_ZR_OPEN_GROTTO_GOSSIP_STONE}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, RandomizerHintTextKey> StaticData::areaNames = { //RANDOTODO resolve None in area
|
||||||
|
{RA_NONE, RHT_LINKS_POCKET}, //explicit none in area hints usually means it's a starting item, so say Link's pocket
|
||||||
|
{RA_LINKS_POCKET, RHT_LINKS_POCKET},
|
||||||
|
{RA_KOKIRI_FOREST, RHT_KOKIRI_FOREST},
|
||||||
|
{RA_THE_LOST_WOODS, RHT_THE_LOST_WOODS},
|
||||||
|
{RA_SACRED_FOREST_MEADOW, RHT_SACRED_FOREST_MEADOW},
|
||||||
|
{RA_HYRULE_FIELD, RHT_HYRULE_FIELD},
|
||||||
|
{RA_LAKE_HYLIA, RHT_LAKE_HYLIA},
|
||||||
|
{RA_GERUDO_VALLEY, RHT_GERUDO_VALLEY},
|
||||||
|
{RA_GERUDO_FORTRESS, RHT_GERUDO_FORTRESS},
|
||||||
|
{RA_HAUNTED_WASTELAND, RHT_HAUNTED_WASTELAND},
|
||||||
|
{RA_DESERT_COLOSSUS, RHT_DESERT_COLOSSUS},
|
||||||
|
{RA_THE_MARKET, RHT_THE_MARKET},
|
||||||
|
{RA_TEMPLE_OF_TIME, RHT_TEMPLE_OF_TIME},
|
||||||
|
{RA_HYRULE_CASTLE, RHT_HYRULE_CASTLE},
|
||||||
|
{RA_OUTSIDE_GANONS_CASTLE, RHT_OUTSIDE_GANONS_CASTLE},
|
||||||
|
{RA_CASTLE_GROUNDS, RHT_CASTLE_GROUNDS},
|
||||||
|
{RA_KAKARIKO_VILLAGE, RHT_KAKARIKO_VILLAGE},
|
||||||
|
{RA_THE_GRAVEYARD, RHT_THE_GRAVEYARD},
|
||||||
|
{RA_DEATH_MOUNTAIN_TRAIL, RHT_DEATH_MOUNTAIN_TRAIL},
|
||||||
|
{RA_GORON_CITY, RHT_GORON_CITY},
|
||||||
|
{RA_DEATH_MOUNTAIN_CRATER, RHT_DEATH_MOUNTAIN_CRATER},
|
||||||
|
{RA_ZORAS_RIVER, RHT_ZORAS_RIVER},
|
||||||
|
{RA_ZORAS_DOMAIN, RHT_ZORAS_DOMAIN},
|
||||||
|
{RA_ZORAS_FOUNTAIN, RHT_ZORAS_FOUNTAIN},
|
||||||
|
{RA_LON_LON_RANCH, RHT_LON_LON_RANCH},
|
||||||
|
{RA_DEKU_TREE, RHT_DEKU_TREE},
|
||||||
|
{RA_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN},
|
||||||
|
{RA_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY},
|
||||||
|
{RA_FOREST_TEMPLE, RHT_FOREST_TEMPLE},
|
||||||
|
{RA_FIRE_TEMPLE, RHT_FIRE_TEMPLE},
|
||||||
|
{RA_WATER_TEMPLE, RHT_WATER_TEMPLE},
|
||||||
|
{RA_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE},
|
||||||
|
{RA_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE},
|
||||||
|
{RA_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL},
|
||||||
|
{RA_ICE_CAVERN, RHT_ICE_CAVERN},
|
||||||
|
{RA_GERUDO_TRAINING_GROUND, RHT_GERUDO_TRAINING_GROUND},
|
||||||
|
{RA_GANONS_CASTLE, RHT_GANONS_CASTLE}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, RandomizerHintTextKey> StaticData::trialData = {
|
||||||
|
{TK_LIGHT_TRIAL, RHT_LIGHT_TRIAL},
|
||||||
|
{TK_FOREST_TRIAL, RHT_FOREST_TRIAL},
|
||||||
|
{TK_FIRE_TRIAL, RHT_FIRE_TRIAL},
|
||||||
|
{TK_WATER_TRIAL, RHT_WATER_TRIAL},
|
||||||
|
{TK_SHADOW_TRIAL, RHT_SHADOW_TRIAL},
|
||||||
|
{TK_SPIRIT_TRIAL, RHT_SPIRIT_TRIAL}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<RandomizerHint, StaticHintInfo> StaticData::staticHintInfoMap = {
|
||||||
|
// RH_GANONDORF_HINT is special cased due to being different based on master sword shuffle
|
||||||
|
// Altar hints are special cased due to special hint marking rules
|
||||||
|
// warp song hints are special cased due to entrences not being done properly yet
|
||||||
|
// Ganondorf Joke is special Cased as the text is random
|
||||||
|
{RH_SHEIK_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SHEIK_HINT_LA_ONLY}, RSK_SHEIK_LA_HINT, true, {}, {RG_LIGHT_ARROWS}, {RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC}, true)},
|
||||||
|
{RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})},
|
||||||
|
{RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})},
|
||||||
|
{RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)},
|
||||||
|
{RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)},
|
||||||
|
{RH_MEDIGORON, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_MEDIGORON_HINT}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_GC_MEDIGORON})},
|
||||||
|
{RH_GRANNY, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_GRANNY_HINT}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_KAK_GRANNYS_SHOP})},
|
||||||
|
{RH_CARPET_SALESMAN, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_CARPET_SALESMAN_DIALOG_HINTED}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_WASTELAND_BOMBCHU_SALESMAN})},
|
||||||
|
{RH_BEAN_SALESMAN, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_BEAN_SALESMAN_HINT}, RSK_SHUFFLE_MAGIC_BEANS, true, {RC_ZR_MAGIC_BEAN_SALESMAN})},
|
||||||
|
{RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})},
|
||||||
|
{RH_MALON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_MALON_HINT_TURNING_EVIL, RHT_MALON_HINT_HOW_IS_EPONA, RHT_MALON_HINT_OBSTICLE_COURSE, RHT_MALON_HINT_INGO_TEMPTED},RSK_MALON_HINT, true, {RC_KF_LINKS_HOUSE_COW})},
|
||||||
|
{RH_BIG_POES_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_BIG_POES_HINT}, RSK_BIG_POES_HINT, true, {RC_MARKET_10_BIG_POES})},
|
||||||
|
{RH_CHICKENS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_CHICKENS_HINT}, RSK_CHICKENS_HINT, true, {RC_KAK_ANJU_AS_CHILD})},
|
||||||
|
{RH_BIGGORON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_BIGGORON_HINT}, RSK_BIGGORON_HINT, true, {RC_DMT_TRADE_CLAIM_CHECK})},
|
||||||
|
{RH_FROGS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_FROGS_HINT}, RSK_FROGS_HINT, true, {RC_ZR_FROGS_OCARINA_GAME})},
|
||||||
|
{RH_KAK_10_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_10_SKULLS_HINT, true, {RC_KAK_10_GOLD_SKULLTULA_REWARD}, {}, {}, false, 10)},
|
||||||
|
{RH_KAK_20_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_20_SKULLS_HINT, true, {RC_KAK_20_GOLD_SKULLTULA_REWARD}, {}, {}, false, 20)},
|
||||||
|
{RH_KAK_30_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_30_SKULLS_HINT, true, {RC_KAK_30_GOLD_SKULLTULA_REWARD}, {}, {}, false, 30)},
|
||||||
|
{RH_KAK_40_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_40_SKULLS_HINT, true, {RC_KAK_40_GOLD_SKULLTULA_REWARD}, {}, {}, false, 40)},
|
||||||
|
{RH_KAK_50_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_50_SKULLS_HINT, true, {RC_KAK_50_GOLD_SKULLTULA_REWARD}, {}, {}, false, 50)},
|
||||||
|
{RH_KAK_100_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_100_SKULLS_HINT, true, {RC_KAK_100_GOLD_SKULLTULA_REWARD}, {}, {}, false, 100)}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, uint32_t> StaticData::PopulateTranslationMap(std::unordered_map<uint32_t, CustomMessage> input){
|
||||||
|
std::unordered_map<std::string, uint32_t> output = {};
|
||||||
|
for (const auto& [key, message] : input) {
|
||||||
|
std::vector<std::string> strings = message.GetAllMessages();
|
||||||
|
for (std::string string: strings){
|
||||||
|
if (output.contains(string)){
|
||||||
|
if (output[string] != key){
|
||||||
|
SPDLOG_DEBUG("\tREPEATED STRING IN " + message.GetEnglish(MF_CLEAN) + "\n\n"); //RANDOTODO should this cause an error of some kind?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
output[string] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, uint32_t> StaticData::PopulateTranslationMap(std::unordered_map<uint32_t, RandomizerHintTextKey> input){
|
||||||
|
std::unordered_map<std::string, uint32_t> output = {};
|
||||||
|
for (const auto& [key, text] : input) {
|
||||||
|
std::vector<std::string> strings = hintTextTable[text].GetClear().GetAllMessages();
|
||||||
|
for (std::string string: strings){
|
||||||
|
if (output.contains(string)){
|
||||||
|
if (output[string] != key){
|
||||||
|
SPDLOG_DEBUG("\tREPEATED STRING WITH " + string + "\n\n"); //RANDOTODO should this cause an error of some kind?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
output[string] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, uint32_t> StaticData::hintNameToEnum = {};
|
||||||
|
std::unordered_map<std::string, uint32_t> StaticData::hintTypeNameToEnum = {};
|
||||||
|
std::unordered_map<std::string, uint32_t> StaticData::areaNameToEnum = {};
|
||||||
|
std::unordered_map<std::string, uint32_t> StaticData::trialNameToEnum = {};
|
||||||
|
std::unordered_map<std::string, RandomizerCheck> StaticData::locationNameToEnum = {}; //is filled in context based on location table, not touching that because of VB
|
||||||
|
|
||||||
|
std::unordered_map<u32, RandomizerHint> StaticData::stoneParamsToHint{
|
||||||
|
{0x1, RH_ZF_FAIRY_GOSSIP_STONE},
|
||||||
|
{0x2, RH_ZF_JABU_GOSSIP_STONE},
|
||||||
|
{0x3, RH_LH_LAB_GOSSIP_STONE},
|
||||||
|
{0x4, RH_DMT_GOSSIP_STONE},
|
||||||
|
{0x5, RH_DMC_GOSSIP_STONE},
|
||||||
|
{0x6, RH_TOT_LEFTMOST_GOSSIP_STONE},
|
||||||
|
{0x7, RH_TOT_LEFT_CENTER_GOSSIP_STONE},
|
||||||
|
{0x8, RH_LH_SOUTHWEST_GOSSIP_STONE},
|
||||||
|
{0x9, RH_ZD_GOSSIP_STONE},
|
||||||
|
{0xA, RH_GRAVEYARD_GOSSIP_STONE},
|
||||||
|
{0xB, RH_HC_ROCK_WALL_GOSSIP_STONE},
|
||||||
|
{0xC, RH_ZR_NEAR_DOMAIN_GOSSIP_STONE},
|
||||||
|
{0xD, RH_ZR_NEAR_GROTTOS_GOSSIP_STONE},
|
||||||
|
{0xE, RH_TOT_RIGHT_CENTER_GOSSIP_STONE },
|
||||||
|
{0xF, RH_LH_SOUTHEAST_GOSSIP_STONE},
|
||||||
|
{0x10, RH_TOT_RIGHTMOST_GOSSIP_STONE },
|
||||||
|
{0x11, RH_GV_GOSSIP_STONE},
|
||||||
|
{0x12, RH_HC_MALON_GOSSIP_STONE},
|
||||||
|
{0x13, RH_HC_STORMS_GROTTO_GOSSIP_STONE},
|
||||||
|
{0x14, RH_DODONGOS_CAVERN_GOSSIP_STONE},
|
||||||
|
{0x15, RH_GC_MAZE_GOSSIP_STONE},
|
||||||
|
{0x16, RH_SFM_MAZE_NEAR_LW_GOSSIP_STONE},
|
||||||
|
{0x17, RH_SFM_MAZE_CENTER_GOSSIP_STONE},
|
||||||
|
//generic grottos all use 0x18, grottoChestParamsToHint is used for conversion
|
||||||
|
{0x19, RH_GC_MEDIGORON_GOSSIP_STONE},
|
||||||
|
{0x1A, RH_COLOSSUS_GOSSIP_STONE},
|
||||||
|
{0x1B, RH_HF_COW_GROTTO_GOSSIP_STONE},
|
||||||
|
{0x1C, RH_SFM_SARIA_GOSSIP_STONE},
|
||||||
|
{0x1D, RH_LW_GOSSIP_STONE},
|
||||||
|
{0x1E, RH_KF_GOSSIP_STONE},
|
||||||
|
{0x1F, RH_KF_DEKU_TREE_LEFT_GOSSIP_STONE},
|
||||||
|
{0x20, RH_KF_DEKU_TREE_RIGHT_GOSSIP_STONE},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<u32, RandomizerHint> StaticData::grottoChestParamsToHint{
|
||||||
|
{22944, RH_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE},
|
||||||
|
{22978, RH_HF_SOUTHEAST_GROTTO_GOSSIP_STONE},
|
||||||
|
{22947, RH_HF_OPEN_GROTTO_GOSSIP_STONE},
|
||||||
|
{22964, RH_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE},
|
||||||
|
{23255, RH_DMT_STORMS_GROTTO_GOSSIP_STONE},
|
||||||
|
{22984, RH_KAK_OPEN_GROTTO_GOSSIP_STONE},
|
||||||
|
{22985, RH_ZR_OPEN_GROTTO_GOSSIP_STONE},
|
||||||
|
{23802, RH_DMC_UPPER_GROTTO_GOSSIP_STONE},
|
||||||
|
{22988, RH_KF_STORMS_GROTTO_GOSSIP_STONE}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<HintText, RHT_MAX> StaticData::hintTextTable = {};
|
||||||
|
}
|
@ -22,25 +22,47 @@ class StaticData {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static void InitItemTable();
|
static void InitItemTable();
|
||||||
|
static void HintTable_Init();
|
||||||
|
static void HintTable_Init_Item();
|
||||||
|
static void HintTable_Init_Exclude_Overworld();
|
||||||
|
static void HintTable_Init_Exclude_Dungeon();
|
||||||
static Item& RetrieveItem(const RandomizerGet rgid);
|
static Item& RetrieveItem(const RandomizerGet rgid);
|
||||||
static Item& ItemFromGIID(const int giid);
|
static Item& ItemFromGIID(const int giid);
|
||||||
static std::array<Item, RG_MAX>& GetItemTable();
|
static std::array<Item, RG_MAX>& GetItemTable();// is there a reason this is a function and not just an exposed table?
|
||||||
static void InitLocationTable();
|
static void InitLocationTable();
|
||||||
static Location* GetLocation(RandomizerCheck locKey);
|
static Location* GetLocation(RandomizerCheck locKey);
|
||||||
static std::array<Rando::Location, RC_MAX>& GetLocationTable();
|
static std::array<Rando::Location, RC_MAX>& GetLocationTable();
|
||||||
static std::unordered_map<std::string, RandomizerCheck> SpoilerfileCheckNameToEnum;
|
static std::unordered_map<std::string, uint32_t> PopulateTranslationMap(std::unordered_map<uint32_t, CustomMessage> input);
|
||||||
static std::unordered_map<std::string, RandomizerGet> SpoilerfileItemNameToEnum;
|
static std::unordered_map<std::string, uint32_t> PopulateTranslationMap(std::unordered_map<uint32_t, RandomizerHintTextKey> input);
|
||||||
static std::multimap<std::tuple<s16, s16, s32>, RandomizerCheck> CheckFromActorMultimap;
|
static std::multimap<std::tuple<s16, s16, s32>, RandomizerCheck> CheckFromActorMultimap;
|
||||||
static std::vector<RandomizerCheck> overworldLocations;
|
static std::vector<RandomizerCheck> overworldLocations;
|
||||||
static std::vector<RandomizerCheck> dungeonRewardLocations;
|
static std::vector<RandomizerCheck> dungeonRewardLocations;
|
||||||
static std::vector<std::vector<RandomizerCheck>> shopLocationLists;
|
static std::vector<std::vector<RandomizerCheck>> shopLocationLists;
|
||||||
static std::vector<RandomizerCheck> scrubLocations;
|
static std::vector<RandomizerCheck> scrubLocations;
|
||||||
static std::vector<RandomizerCheck> gossipStoneLocations;
|
static std::vector<RandomizerCheck> gossipStoneLocations;
|
||||||
static std::vector<RandomizerCheck> otherHintLocations;
|
static std::vector<RandomizerCheck> staticHintLocations;
|
||||||
static std::vector<RandomizerCheck> pondFishLocations;
|
static std::vector<RandomizerCheck> pondFishLocations;
|
||||||
static std::vector<RandomizerCheck> overworldFishLocations;
|
static std::vector<RandomizerCheck> overworldFishLocations;
|
||||||
static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish;
|
static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish;
|
||||||
static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap;
|
static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap;
|
||||||
|
static std::vector<RandomizerHint> oldVerHintOrder;
|
||||||
|
static uint16_t oldVerGossipStoneStart;
|
||||||
|
static std::unordered_map<std::string, RandomizerCheck> locationNameToEnum;
|
||||||
|
static std::unordered_map<std::string, RandomizerGet> itemNameToEnum;
|
||||||
|
static std::unordered_map<uint32_t, CustomMessage> hintNames;
|
||||||
|
static std::unordered_map<std::string, uint32_t> hintNameToEnum;
|
||||||
|
static std::unordered_map<uint32_t, CustomMessage> hintTypeNames;
|
||||||
|
static std::unordered_map<std::string, uint32_t> hintTypeNameToEnum;
|
||||||
|
static std::unordered_map<RandomizerCheck, RandomizerHint> gossipStoneCheckToHint;
|
||||||
|
static std::unordered_map<uint32_t, RandomizerHintTextKey> areaNames;
|
||||||
|
static std::unordered_map<std::string, uint32_t> areaNameToEnum;
|
||||||
|
static std::unordered_map<uint32_t, RandomizerHintTextKey> trialData;
|
||||||
|
static std::unordered_map<std::string, uint32_t> trialNameToEnum;
|
||||||
|
static std::unordered_map<RandomizerHint, StaticHintInfo> staticHintInfoMap;
|
||||||
|
static std::unordered_map<u32, RandomizerHint> stoneParamsToHint;
|
||||||
|
static std::unordered_map<u32, RandomizerHint> grottoChestParamsToHint;
|
||||||
|
static std::array<HintText, RHT_MAX> hintTextTable;
|
||||||
|
|
||||||
StaticData();
|
StaticData();
|
||||||
~StaticData();
|
~StaticData();
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
#include "trial.h"
|
#include "trial.h"
|
||||||
|
#include "static_data.h"
|
||||||
|
|
||||||
namespace Rando {
|
namespace Rando {
|
||||||
TrialInfo::TrialInfo(Text name_) : name(std::move(name_)) {}
|
TrialInfo::TrialInfo(RandomizerHintTextKey nameKey_, TrialKey trialKey_) : nameKey(std::move(nameKey_)), trialKey(std::move(trialKey_)) {}
|
||||||
TrialInfo::TrialInfo() = default;
|
TrialInfo::TrialInfo() = default;
|
||||||
TrialInfo::~TrialInfo() = default;
|
TrialInfo::~TrialInfo() = default;
|
||||||
|
|
||||||
Text TrialInfo::GetName() const {
|
CustomMessage TrialInfo::GetName() const {
|
||||||
return name;
|
return StaticData::hintTextTable[nameKey].GetHintMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomizerHintTextKey TrialInfo::GetNameKey() const {
|
||||||
|
return nameKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrialKey TrialInfo::GetTrialKey() const {
|
||||||
|
return trialKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrialInfo::IsSkipped() const {
|
bool TrialInfo::IsSkipped() const {
|
||||||
@ -26,12 +35,9 @@ void TrialInfo::SetAsSkipped() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Trials::Trials() {
|
Trials::Trials() {
|
||||||
mTrials[FOREST_TRIAL] = TrialInfo(Text{"the Forest Trial", "l'épreuve de la Forêt", "la prueba del bosque"});
|
for (const auto trial : StaticData::trialData){
|
||||||
mTrials[FIRE_TRIAL] = TrialInfo(Text{"the Fire Trial", "l'épreuve du Feu", "la prueba del fuego"});
|
mTrials[trial.first] = TrialInfo(trial.second, static_cast<TrialKey>(trial.first));
|
||||||
mTrials[WATER_TRIAL] = TrialInfo(Text{"the Water Trial", "l'épreuve de l'Eau", "la prueba del agua"});
|
}
|
||||||
mTrials[SPIRIT_TRIAL] = TrialInfo(Text{"the Spirit Trial", "l'épreuve de l'Esprit", "la prueba del espíritu"});
|
|
||||||
mTrials[SHADOW_TRIAL] = TrialInfo(Text{"the Shadow Trial", "l'épreuve de l'Ombre", "la prueba de las sombras"});
|
|
||||||
mTrials[LIGHT_TRIAL] = TrialInfo(Text{"the Light Trial", "l'épreuve de la Lumière", "la prueba de la luz"});
|
|
||||||
}
|
}
|
||||||
Trials::~Trials() = default;
|
Trials::~Trials() = default;
|
||||||
|
|
||||||
@ -51,10 +57,10 @@ void Trials::RequireAll() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<TrialInfo*, 6> Trials::GetTrialList() {
|
std::vector<TrialInfo*> Trials::GetTrialList() {
|
||||||
std::array<TrialInfo*, 6> trialList{};
|
std::vector<TrialInfo*> trialList{};
|
||||||
for (size_t i = 0; i < mTrials.size(); i++) {
|
for (size_t i = 0; i < mTrials.size(); i++) {
|
||||||
trialList[i] = &mTrials[i];
|
trialList.push_back(&mTrials[i]);
|
||||||
}
|
}
|
||||||
return trialList;
|
return trialList;
|
||||||
}
|
}
|
||||||
@ -62,6 +68,7 @@ std::array<TrialInfo*, 6> Trials::GetTrialList() {
|
|||||||
size_t Trials::GetTrialListSize() const {
|
size_t Trials::GetTrialListSize() const {
|
||||||
return mTrials.size();
|
return mTrials.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trials::ParseJson(nlohmann::json spoilerFileJson) {
|
void Trials::ParseJson(nlohmann::json spoilerFileJson) {
|
||||||
nlohmann::json trialsJson = spoilerFileJson["requiredTrials"];
|
nlohmann::json trialsJson = spoilerFileJson["requiredTrials"];
|
||||||
for (auto it = trialsJson.begin(); it != trialsJson.end(); ++it) {
|
for (auto it = trialsJson.begin(); it != trialsJson.end(); ++it) {
|
||||||
@ -75,4 +82,13 @@ void Trials::ParseJson(nlohmann::json spoilerFileJson) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, RandomizerHintTextKey> Trials::GetAllTrialHintHeys() const {
|
||||||
|
std::unordered_map<uint32_t, RandomizerHintTextKey> output = {};
|
||||||
|
for (auto trial: mTrials){
|
||||||
|
output[(uint32_t)trial.GetTrialKey()] = trial.GetNameKey();
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Rando
|
} // namespace Rando
|
@ -1,36 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "3drando/text.hpp"
|
#include "randomizerTypes.h"
|
||||||
|
#include "../custom-message/CustomMessageManager.h"
|
||||||
#include <array>
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include "static_data.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Rando {
|
namespace Rando {
|
||||||
class TrialInfo {
|
class TrialInfo {
|
||||||
public:
|
public:
|
||||||
explicit TrialInfo(Text name_);
|
explicit TrialInfo(RandomizerHintTextKey nameKey_, TrialKey key_);
|
||||||
TrialInfo();
|
TrialInfo();
|
||||||
~TrialInfo();
|
~TrialInfo();
|
||||||
|
|
||||||
Text GetName() const;
|
CustomMessage GetName() const;
|
||||||
|
RandomizerHintTextKey GetNameKey() const;
|
||||||
|
TrialKey GetTrialKey() const;
|
||||||
bool IsSkipped() const;
|
bool IsSkipped() const;
|
||||||
bool IsRequired() const;
|
bool IsRequired() const;
|
||||||
void SetAsRequired();
|
void SetAsRequired();
|
||||||
void SetAsSkipped();
|
void SetAsSkipped();
|
||||||
private:
|
private:
|
||||||
Text name;
|
RandomizerHintTextKey nameKey;
|
||||||
|
TrialKey trialKey;
|
||||||
bool skipped = true;
|
bool skipped = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LIGHT_TRIAL,
|
|
||||||
FOREST_TRIAL,
|
|
||||||
FIRE_TRIAL,
|
|
||||||
WATER_TRIAL,
|
|
||||||
SPIRIT_TRIAL,
|
|
||||||
SHADOW_TRIAL,
|
|
||||||
} TrialKey;
|
|
||||||
|
|
||||||
class Trials {
|
class Trials {
|
||||||
public:
|
public:
|
||||||
Trials();
|
Trials();
|
||||||
@ -38,10 +33,11 @@ class Trials {
|
|||||||
TrialInfo* GetTrial(TrialKey key);
|
TrialInfo* GetTrial(TrialKey key);
|
||||||
void SkipAll();
|
void SkipAll();
|
||||||
void RequireAll();
|
void RequireAll();
|
||||||
std::array<TrialInfo*, 6> GetTrialList();
|
std::vector<TrialInfo*> GetTrialList();
|
||||||
size_t GetTrialListSize() const;
|
size_t GetTrialListSize() const;
|
||||||
void ParseJson(nlohmann::json spoilerFileJson);
|
void ParseJson(nlohmann::json spoilerFileJson);
|
||||||
|
std::unordered_map<uint32_t, RandomizerHintTextKey> GetAllTrialHintHeys() const;
|
||||||
private:
|
private:
|
||||||
std::array<TrialInfo, 6> mTrials;
|
std::array<TrialInfo, TK_MAX> mTrials;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -350,8 +350,9 @@ OTRGlobals::OTRGlobals() {
|
|||||||
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryBackgroundV0>(), RESOURCE_FORMAT_BINARY, "Background", static_cast<uint32_t>(SOH::ResourceType::SOH_Background), 0);
|
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryBackgroundV0>(), RESOURCE_FORMAT_BINARY, "Background", static_cast<uint32_t>(SOH::ResourceType::SOH_Background), 0);
|
||||||
|
|
||||||
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
||||||
gRandoContext = Rando::Context::CreateInstance();
|
|
||||||
gRandoContext->InitStaticData();
|
gRandoContext->InitStaticData();
|
||||||
|
gRandoContext = Rando::Context::CreateInstance();
|
||||||
|
Rando::StaticData::InitItemTable();//RANDOTODO make this not rely on context's logic so it can be initialised in InitStaticData
|
||||||
gRandoContext->AddExcludedOptions();
|
gRandoContext->AddExcludedOptions();
|
||||||
gRandoContext->GetSettings()->CreateOptions();
|
gRandoContext->GetSettings()->CreateOptions();
|
||||||
gRandomizer = std::make_shared<Randomizer>();
|
gRandomizer = std::make_shared<Randomizer>();
|
||||||
@ -2247,8 +2248,8 @@ extern "C" float OTRGetDimensionFromRightEdge(float v) {
|
|||||||
return (SCREEN_WIDTH / 2 + SCREEN_HEIGHT / 2 * OTRGetAspectRatio() - (SCREEN_WIDTH - v));
|
return (SCREEN_WIDTH / 2 + SCREEN_HEIGHT / 2 * OTRGetAspectRatio() - (SCREEN_WIDTH - v));
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 floorf(f32 x);
|
f32 floorf(f32 x);// RANDOTODO False positive error "allowing all exceptions is incompatible with previous function"
|
||||||
f32 ceilf(f32 x);
|
f32 ceilf(f32 x); // This gets annoying
|
||||||
|
|
||||||
extern "C" int16_t OTRGetRectDimensionFromLeftEdge(float v) {
|
extern "C" int16_t OTRGetRectDimensionFromLeftEdge(float v) {
|
||||||
return ((int)floorf(OTRGetDimensionFromLeftEdge(v)));
|
return ((int)floorf(OTRGetDimensionFromLeftEdge(v)));
|
||||||
@ -2318,15 +2319,7 @@ extern "C" int GetEquipNowMessage(char* buffer, char* src, const int maxBufferSi
|
|||||||
"%w\x02");
|
"%w\x02");
|
||||||
customMessage.Format();
|
customMessage.Format();
|
||||||
|
|
||||||
std::string postfix;
|
std::string postfix = customMessage.GetForCurrentLanguage();
|
||||||
|
|
||||||
if (gSaveContext.language == LANGUAGE_FRA) {
|
|
||||||
postfix = customMessage.GetFrench();
|
|
||||||
} else if (gSaveContext.language == LANGUAGE_GER) {
|
|
||||||
postfix = customMessage.GetGerman();
|
|
||||||
} else {
|
|
||||||
postfix = customMessage.GetEnglish();
|
|
||||||
}
|
|
||||||
std::string str;
|
std::string str;
|
||||||
std::string FixedBaseStr(src);
|
std::string FixedBaseStr(src);
|
||||||
int RemoveControlChar = FixedBaseStr.find_first_of("\x02");
|
int RemoveControlChar = FixedBaseStr.find_first_of("\x02");
|
||||||
@ -2480,6 +2473,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
CustomMessage messageEntry;
|
CustomMessage messageEntry;
|
||||||
s16 actorParams = 0;
|
s16 actorParams = 0;
|
||||||
if (IS_RANDO) {
|
if (IS_RANDO) {
|
||||||
|
auto ctx = Rando::Context::GetInstance();
|
||||||
Player* player = GET_PLAYER(play);
|
Player* player = GET_PLAYER(play);
|
||||||
if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
|
if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
|
||||||
if (player->getItemEntry.getItemId == RG_ICE_TRAP) {
|
if (player->getItemEntry.getItemId == RG_ICE_TRAP) {
|
||||||
@ -2528,39 +2522,45 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
(Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == RO_GOSSIP_STONES_NEED_STONE && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) {
|
(Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == RO_GOSSIP_STONES_NEED_STONE && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) {
|
||||||
|
|
||||||
Actor* stone = GET_PLAYER(play)->targetActor;
|
Actor* stone = GET_PLAYER(play)->targetActor;
|
||||||
actorParams = stone->params;
|
RandomizerHint stoneHint = RH_NONE;
|
||||||
|
s16 hintParams = stone->params & 0xFF;
|
||||||
|
|
||||||
// if we're in a generic grotto
|
if (Rando::StaticData::stoneParamsToHint.contains(hintParams)){
|
||||||
if (play->sceneNum == SCENE_GROTTOS && actorParams == 14360) {
|
stoneHint = Rando::StaticData::stoneParamsToHint[hintParams];
|
||||||
|
} else if (hintParams == 0x18){
|
||||||
// look for the chest in the actorlist to determine
|
// look for the chest in the actorlist to determine
|
||||||
// which grotto we're in
|
// which grotto we're in
|
||||||
int numOfActorLists =
|
int numOfActorLists =
|
||||||
sizeof(play->actorCtx.actorLists) / sizeof(play->actorCtx.actorLists[0]);
|
sizeof(play->actorCtx.actorLists) / sizeof(play->actorCtx.actorLists[0]);
|
||||||
for (int i = 0; i < numOfActorLists; i++) {
|
for (int i = 0; i < numOfActorLists; i++) {
|
||||||
if (play->actorCtx.actorLists[i].length) {
|
if (play->actorCtx.actorLists[i].length) {
|
||||||
if (play->actorCtx.actorLists[i].head->id == 10) {
|
if (play->actorCtx.actorLists[i].head->id == 10 &&
|
||||||
// set the params for the hint check to be negative chest params
|
Rando::StaticData::grottoChestParamsToHint.contains(play->actorCtx.actorLists[i].head->params)) {
|
||||||
actorParams = 0 - play->actorCtx.actorLists[i].head->params;
|
//use the chest params to find the stone hint
|
||||||
|
stoneHint = Rando::StaticData::grottoChestParamsToHint[play->actorCtx.actorLists[i].head->params];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stoneHint == RH_NONE){
|
||||||
RandomizerCheck hintCheck =
|
messageEntry = CustomMessage("INVALID STONE. PARAMS: " + std::to_string(hintParams));
|
||||||
Randomizer_GetCheckFromActor(stone->id, play->sceneNum, actorParams);
|
} else {
|
||||||
|
messageEntry = ctx->GetHint(stoneHint)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, hintCheck);
|
}
|
||||||
} else if ((textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT)) {
|
} else if ((textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT)) {
|
||||||
// rando hints at altar
|
// rando hints at altar
|
||||||
messageEntry = (LINK_IS_ADULT)
|
messageEntry = (LINK_IS_ADULT) ? ctx->GetHint(RH_ALTAR_ADULT)->GetHintMessage() : ctx->GetHint(RH_ALTAR_CHILD)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
? CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_ADULT)
|
|
||||||
: CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_CHILD);
|
|
||||||
} else if (textId == TEXT_GANONDORF) {
|
} else if (textId == TEXT_GANONDORF) {
|
||||||
if ((INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) ||
|
if (ctx->GetOption(RSK_GANONDORF_HINT)){
|
||||||
!Randomizer_GetSettingValue(RSK_LIGHT_ARROWS_HINT)) {
|
if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)){
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF_NOHINT);
|
messageEntry = INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT ?
|
||||||
|
ctx->GetHint(RH_GANONDORF_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1):
|
||||||
|
ctx->GetHint(RH_GANONDORF_HINT)->GetHintMessage(MF_AUTO_FORMAT, 2);
|
||||||
} else {
|
} else {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF);
|
messageEntry = INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT ?
|
||||||
|
ctx->GetHint(RH_GANONDORF_JOKE)->GetHintMessage(MF_AUTO_FORMAT):
|
||||||
|
ctx->GetHint(RH_GANONDORF_HINT)->GetHintMessage(MF_AUTO_FORMAT, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (textId == TEXT_SHEIK_NEED_HOOK || textId == TEXT_SHEIK_HAVE_HOOK) {
|
} else if (textId == TEXT_SHEIK_NEED_HOOK || textId == TEXT_SHEIK_HAVE_HOOK) {
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetSheikMessage(gPlayState->sceneNum, textId);
|
messageEntry = OTRGlobals::Instance->gRandomizer->GetSheikMessage(gPlayState->sceneNum, textId);
|
||||||
@ -2587,74 +2587,131 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
} else if (CVarGetInteger("gRandoRelevantNavi", 1) && textId >= TEXT_NAVI_DEKU_TREE_SUMMONS && textId <= TEXT_NAVI_TRY_TO_KEEP_MOVING) {
|
} else if (CVarGetInteger("gRandoRelevantNavi", 1) && textId >= TEXT_NAVI_DEKU_TREE_SUMMONS && textId <= TEXT_NAVI_TRY_TO_KEEP_MOVING) {
|
||||||
u16 naviTextId = Random(0, NUM_NAVI_MESSAGES);
|
u16 naviTextId = Random(0, NUM_NAVI_MESSAGES);
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS) && textId == TEXT_BEAN_SALESMAN_BUY_FOR_10) {
|
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_10);
|
|
||||||
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && (textId == TEXT_MEDIGORON ||
|
|
||||||
(textId == TEXT_GRANNYS_SHOP && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) &&
|
|
||||||
(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_2 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)))) {
|
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId);
|
|
||||||
} else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) &&
|
|
||||||
(textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)) {
|
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
|
||||||
} else if (textId == TEXT_SKULLTULA_PEOPLE_IM_CURSED) {
|
|
||||||
actorParams = GET_PLAYER(play)->targetActor->params;
|
|
||||||
RandomizerSettingKey rsk = (RandomizerSettingKey)(RSK_KAK_10_SKULLS_HINT + (actorParams - 1));
|
|
||||||
if (Randomizer_GetSettingValue(rsk)) {
|
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetCursedSkullMessage(actorParams,
|
|
||||||
OTRGlobals::Instance->gRandomizer->GetCheckFromActor(ACTOR_EN_SSH, SCENE_HOUSE_OF_SKULLTULA, actorParams));
|
|
||||||
}
|
}
|
||||||
} else if (Randomizer_GetSettingValue(RSK_DAMPES_DIARY_HINT) && textId == TEXT_DAMPES_DIARY) {
|
else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_10 && ctx->GetOption(RSK_SHUFFLE_MAGIC_BEANS)) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, TEXT_DAMPES_DIARY);
|
messageEntry = ctx->GetHint(RH_BEAN_SALESMAN)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
} else if (play->sceneNum == SCENE_TREASURE_BOX_SHOP &&
|
}
|
||||||
Randomizer_GetSettingValue(RSK_GREG_HINT) &&
|
else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_100) {
|
||||||
(textId == TEXT_CHEST_GAME_PROCEED || textId == TEXT_CHEST_GAME_REAL_GAMBLER || textId == TEXT_CHEST_GAME_THANKS_A_LOT)) {
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100);
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, TEXT_CHEST_GAME_PROCEED);
|
}
|
||||||
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS) &&
|
else if (textId == TEXT_GRANNYS_SHOP && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
|
||||||
(textId >= TEXT_WARP_MINUET_OF_FOREST && textId <= TEXT_WARP_PRELUDE_OF_LIGHT)) {
|
(ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)){
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::randoMiscHintsTableID, textId);
|
messageEntry = messageEntry = ctx->GetHint(RH_GRANNY)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
} else if (textId == TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI || textId == TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN) {
|
}
|
||||||
|
else if (textId == TEXT_MEDIGORON && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){
|
||||||
|
messageEntry = messageEntry = ctx->GetHint(RH_MEDIGORON)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_CARPET_SALESMAN_1 && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){
|
||||||
|
messageEntry = messageEntry = ctx->GetHint(RH_CARPET_SALESMAN)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_CARPET_SALESMAN_2 && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){
|
||||||
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId);
|
||||||
|
}
|
||||||
|
else if ((textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)
|
||||||
|
&& ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)) {
|
||||||
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_SKULLTULA_PEOPLE_IM_CURSED) {
|
||||||
|
actorParams = GET_PLAYER(play)->targetActor->params;
|
||||||
|
if (actorParams == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){
|
||||||
|
messageEntry = ctx->GetHint(RH_KAK_10_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
} else if (actorParams == 2 && ctx->GetOption(RSK_KAK_20_SKULLS_HINT)){
|
||||||
|
messageEntry = ctx->GetHint(RH_KAK_20_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
} else if (actorParams == 3 && ctx->GetOption(RSK_KAK_30_SKULLS_HINT)){
|
||||||
|
messageEntry = ctx->GetHint(RH_KAK_30_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
} else if (actorParams == 4 && ctx->GetOption(RSK_KAK_40_SKULLS_HINT)){
|
||||||
|
messageEntry = ctx->GetHint(RH_KAK_40_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
} else if (ctx->GetOption(RSK_KAK_50_SKULLS_HINT)){
|
||||||
|
messageEntry = ctx->GetHint(RH_KAK_50_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
}
|
||||||
|
} else if (textId == TEXT_DAMPES_DIARY && ctx->GetOption(RSK_DAMPES_DIARY_HINT)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_DAMPES_DIARY)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
}
|
||||||
|
else if ((textId == TEXT_CHEST_GAME_PROCEED || textId == TEXT_CHEST_GAME_REAL_GAMBLER || textId == TEXT_CHEST_GAME_THANKS_A_LOT) &&
|
||||||
|
play->sceneNum == SCENE_TREASURE_BOX_SHOP && ctx->GetOption(RSK_GREG_HINT)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_GREG_RUPEE)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_WARP_MINUET_OF_FOREST && ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_MINUET_WARP_LOC)->GetHintMessage(MF_FORMATTED);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_WARP_BOLERO_OF_FIRE && ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_BOLERO_WARP_LOC)->GetHintMessage(MF_FORMATTED);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_WARP_SERENADE_OF_WATER && ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_SERENADE_WARP_LOC)->GetHintMessage(MF_FORMATTED);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_WARP_REQUIEM_OF_SPIRIT && ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_REQUIEM_WARP_LOC)->GetHintMessage(MF_FORMATTED);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_WARP_NOCTURNE_OF_SHADOW && ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_NOCTURNE_WARP_LOC)->GetHintMessage(MF_FORMATTED);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_WARP_PRELUDE_OF_LIGHT && ctx->GetOption(RSK_WARP_SONG_HINTS)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_PRELUDE_WARP_LOC)->GetHintMessage(MF_FORMATTED);
|
||||||
|
}
|
||||||
|
else if (textId >= TEXT_WARP_MINUET_OF_FOREST && textId <= TEXT_WARP_PRELUDE_OF_LIGHT
|
||||||
|
&& ctx->GetOption(RSK_SHUFFLE_WARP_SONGS)) {
|
||||||
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW);
|
||||||
} else if (textId == TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME || (textId >= TEXT_FIRE_TEMPLE_GORON_FALLING_DOORS_SECRET && textId <= TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET)) {
|
}
|
||||||
|
else if (textId == TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME || (textId >= TEXT_FIRE_TEMPLE_GORON_FALLING_DOORS_SECRET && textId <= TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET)) {
|
||||||
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) {
|
}
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_FROGS_UNDERWATER, RC_ZR_FROGS_OCARINA_GAME);
|
else if (textId == TEXT_FROGS_UNDERWATER && ctx->GetOption(RSK_FROGS_HINT)) {
|
||||||
} else if (Randomizer_GetSettingValue(RSK_FISHING_POLE_HINT) && !Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND) &&
|
messageEntry = ctx->GetHint(RH_FROGS_HINT)->GetHintMessage(MF_AUTO_FORMAT), TEXTBOX_TYPE_BLUE;
|
||||||
(textId == TEXT_FISHING_POND_START || textId == TEXT_FISHING_POND_START_MET)) {
|
}
|
||||||
|
else if ((textId == TEXT_FISHING_POND_START || textId == TEXT_FISHING_POND_START_MET) &&
|
||||||
|
ctx->GetOption(RSK_SHUFFLE_FISHING_POLE) && !Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND)) {
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetFishingPondOwnerMessage(textId);
|
messageEntry = OTRGlobals::Instance->gRandomizer->GetFishingPondOwnerMessage(textId);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_SARIA_HINT) &&
|
}
|
||||||
(gPlayState->sceneNum == SCENE_SACRED_FOREST_MEADOW && textId == TEXT_SARIA_SFM) || (textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER)) {
|
else if (textId == TEXT_SARIA_SFM && gPlayState->sceneNum == SCENE_SACRED_FOREST_MEADOW && ctx->GetOption(RSK_SARIA_HINT)){
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetSariaMessage(textId);
|
messageEntry = ctx->GetHint(RH_SARIA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 0);
|
||||||
} else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_100) {
|
}
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100);
|
else if ((textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER) && ctx->GetOption(RSK_SARIA_HINT)){
|
||||||
} else if (Randomizer_GetSettingValue(RSK_BIGGORON_HINT) && (textId == TEXT_BIGGORON_BETTER_AT_SMITHING || textId == TEXT_BIGGORON_WAITING_FOR_YOU || textId == TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS)) {
|
messageEntry = ctx->GetHint(RH_SARIA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1);
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_BIGGORON_BETTER_AT_SMITHING, RC_DMT_TRADE_CLAIM_CHECK);
|
}
|
||||||
} else if (Randomizer_GetSettingValue(RSK_BIG_POES_HINT) && (textId == TEXT_GHOST_SHOP_EXPLAINATION || textId == TEXT_GHOST_SHOP_CARD_HAS_POINTS)) {
|
else if (ctx->GetOption(RSK_BIGGORON_HINT) && (textId == TEXT_BIGGORON_BETTER_AT_SMITHING || textId == TEXT_BIGGORON_WAITING_FOR_YOU ||
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_GHOST_SHOP_CARD_HAS_POINTS, RC_MARKET_10_BIG_POES);
|
textId == TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS || textId == TEXT_BIGGORON_I_MAAAADE_THISSSS)) {
|
||||||
} else if (Randomizer_GetSettingValue(RSK_CHICKENS_HINT) && (textId >= TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK && textId <= TEXT_ANJU_PLEASE_BRING_1_CUCCO)) {
|
messageEntry = ctx->GetHint(RH_BIGGORON_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK, RC_KAK_ANJU_AS_CHILD);
|
}
|
||||||
} else if (Randomizer_GetSettingValue(RSK_MALON_HINT) && (textId == TEXT_MALON_EVERYONE_TURNING_EVIL || textId == TEXT_MALON_I_SING_THIS_SONG)) {
|
else if (ctx->GetOption(RSK_BIG_POES_HINT) && (textId == TEXT_GHOST_SHOP_EXPLAINATION || textId == TEXT_GHOST_SHOP_CARD_HAS_POINTS)) {
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_MALON_EVERYONE_TURNING_EVIL, RC_KF_LINKS_HOUSE_COW);
|
messageEntry = ctx->GetHint(RH_BIG_POES_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_MALON_HINT) && textId == TEXT_MALON_HOW_IS_EPONA_DOING) {
|
}
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_MALON_HOW_IS_EPONA_DOING, RC_KF_LINKS_HOUSE_COW);
|
else if (ctx->GetOption(RSK_CHICKENS_HINT) && (textId >= TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK && textId <= TEXT_ANJU_PLEASE_BRING_1_CUCCO)) {
|
||||||
} else if (Randomizer_GetSettingValue(RSK_MALON_HINT) && textId == TEXT_MALON_OBSTICLE_COURSE) {
|
messageEntry = ctx->GetHint(RH_CHICKENS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_MALON_OBSTICLE_COURSE, RC_KF_LINKS_HOUSE_COW);
|
}
|
||||||
} else if (Randomizer_GetSettingValue(RSK_MALON_HINT) && textId == TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED) {
|
else if ((textId == TEXT_MALON_EVERYONE_TURNING_EVIL || textId == TEXT_MALON_I_SING_THIS_SONG)&& ctx->GetOption(RSK_MALON_HINT)){
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED, RC_KF_LINKS_HOUSE_COW);
|
messageEntry = ctx->GetHint(RH_MALON_HINT)->GetHintMessage(MF_AUTO_FORMAT, 0);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_KAK_100_SKULLS_HINT) && textId == TEXT_SKULLTULA_PEOPLE_MAKE_YOU_VERY_RICH) {
|
}
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetCursedSkullMessage(10, RC_KAK_100_GOLD_SKULLTULA_REWARD);
|
else if (textId == TEXT_MALON_HOW_IS_EPONA_DOING && ctx->GetOption(RSK_MALON_HINT)){
|
||||||
} else if (Randomizer_GetSettingValue(RSK_HBA_HINT) && textId == TEXT_GF_HBA_SIGN) {
|
messageEntry = ctx->GetHint(RH_MALON_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1);
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_GF_HBA_SIGN, RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS);
|
}
|
||||||
} else if (Randomizer_GetSettingValue(RSK_HBA_HINT) && textId == TEXT_HBA_NOT_ON_HORSE) {
|
else if (textId == TEXT_MALON_OBSTICLE_COURSE && ctx->GetOption(RSK_MALON_HINT)){
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_HBA_NOT_ON_HORSE, RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS);
|
messageEntry = ctx->GetHint(RH_MALON_HINT)->GetHintMessage(MF_AUTO_FORMAT, 2);
|
||||||
} else if (Randomizer_GetSettingValue(RSK_HBA_HINT) && textId == TEXT_HBA_INITIAL_EXPLAINATION) {
|
}
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_HBA_INITIAL_EXPLAINATION, RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS);
|
else if (textId == TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED && ctx->GetOption(RSK_MALON_HINT)){
|
||||||
} else if (Randomizer_GetSettingValue(RSK_HBA_HINT) && textId == TEXT_HBA_ALREADY_HAVE_1000) {
|
messageEntry = ctx->GetHint(RH_MALON_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3);
|
||||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMiscHintMessage(TEXT_HBA_ALREADY_HAVE_1000, RC_GF_HBA_1500_POINTS);
|
}
|
||||||
|
else if (ctx->GetOption(RSK_KAK_100_SKULLS_HINT) && textId == TEXT_SKULLTULA_PEOPLE_MAKE_YOU_VERY_RICH) {
|
||||||
|
messageEntry = ctx->GetHint(RH_KAK_100_SKULLS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_GF_HBA_SIGN && ctx->GetOption(RSK_HBA_HINT)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 0);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_HBA_NOT_ON_HORSE && ctx->GetOption(RSK_HBA_HINT)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_HBA_INITIAL_EXPLAINATION && ctx->GetOption(RSK_HBA_HINT)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 2);
|
||||||
|
}
|
||||||
|
else if (textId == TEXT_HBA_ALREADY_HAVE_1000 && ctx->GetOption(RSK_HBA_HINT)) {
|
||||||
|
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (textId == TEXT_GS_NO_FREEZE || textId == TEXT_GS_FREEZE) {
|
if (textId == TEXT_GS_NO_FREEZE || textId == TEXT_GS_FREEZE) {
|
||||||
@ -2676,16 +2733,16 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
// In rando we need to bump the token count by one to show the correct count
|
// In rando we need to bump the token count by one to show the correct count
|
||||||
s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0);
|
s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0);
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
||||||
messageEntry.Replace("{{gsCount}}", std::to_string(gsCount));
|
messageEntry.Replace("[[gsCount]]", std::to_string(gsCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (textId == TEXT_HEART_CONTAINER && CVarGetInteger("gInjectItemCounts", 0)) {
|
if (textId == TEXT_HEART_CONTAINER && CVarGetInteger("gInjectItemCounts", 0)) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER);
|
||||||
messageEntry.Replace("{{heartContainerCount}}", std::to_string(gSaveContext.sohStats.heartContainers + 1));
|
messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.sohStats.heartContainers + 1));
|
||||||
}
|
}
|
||||||
if (textId == TEXT_HEART_PIECE && CVarGetInteger("gInjectItemCounts", 0)) {
|
if (textId == TEXT_HEART_PIECE && CVarGetInteger("gInjectItemCounts", 0)) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE);
|
||||||
messageEntry.Replace("{{heartPieceCount}}", std::to_string(gSaveContext.sohStats.heartPieces + 1));
|
messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.sohStats.heartPieces + 1));
|
||||||
}
|
}
|
||||||
if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger("gMarketSneak", 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
|
if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger("gMarketSneak", 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
|
||||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT);
|
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT);
|
||||||
@ -2697,14 +2754,14 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||||||
switch (gSaveContext.language) {
|
switch (gSaveContext.language) {
|
||||||
case LANGUAGE_FRA:
|
case LANGUAGE_FRA:
|
||||||
return msgCtx->msgLength = font->msgLength =
|
return msgCtx->msgLength = font->msgLength =
|
||||||
CopyStringToCharBuffer(messageEntry.GetFrench(), buffer, maxBufferSize);
|
CopyStringToCharBuffer(messageEntry.GetFrench(MF_RAW), buffer, maxBufferSize);
|
||||||
case LANGUAGE_GER:
|
case LANGUAGE_GER:
|
||||||
return msgCtx->msgLength = font->msgLength =
|
return msgCtx->msgLength = font->msgLength =
|
||||||
CopyStringToCharBuffer(messageEntry.GetGerman(), buffer, maxBufferSize);
|
CopyStringToCharBuffer(messageEntry.GetGerman(MF_RAW), buffer, maxBufferSize);
|
||||||
case LANGUAGE_ENG:
|
case LANGUAGE_ENG:
|
||||||
default:
|
default:
|
||||||
return msgCtx->msgLength = font->msgLength =
|
return msgCtx->msgLength = font->msgLength =
|
||||||
CopyStringToCharBuffer(messageEntry.GetEnglish(), buffer, maxBufferSize);
|
CopyStringToCharBuffer(messageEntry.GetEnglish(MF_RAW), buffer, maxBufferSize);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "Enhancements/randomizer/dungeon.h"
|
#include "Enhancements/randomizer/dungeon.h"
|
||||||
#include "Enhancements/randomizer/trial.h"
|
#include "Enhancements/randomizer/trial.h"
|
||||||
#include "soh/util.h"
|
#include "soh/util.h"
|
||||||
|
#include "Enhancements/randomizer/hint.h"
|
||||||
|
#include "Enhancements/randomizer/item.h"
|
||||||
|
|
||||||
#include "z64.h"
|
#include "z64.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
@ -57,6 +59,51 @@ std::filesystem::path SaveManager::GetFileTempName(int fileNum) {
|
|||||||
return sSavePath / ("file" + std::to_string(fileNum + 1) + ".temp");
|
return sSavePath / ("file" + std::to_string(fileNum + 1) + ".temp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<RandomizerHint> Rando::StaticData::oldVerHintOrder {
|
||||||
|
RH_COLOSSUS_GOSSIP_STONE,
|
||||||
|
RH_DMC_GOSSIP_STONE,
|
||||||
|
RH_DMC_UPPER_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_DMT_GOSSIP_STONE,
|
||||||
|
RH_DMT_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_DODONGOS_CAVERN_GOSSIP_STONE,
|
||||||
|
RH_ZF_FAIRY_GOSSIP_STONE,
|
||||||
|
RH_GC_MAZE_GOSSIP_STONE,
|
||||||
|
RH_GC_MEDIGORON_GOSSIP_STONE,
|
||||||
|
RH_GV_GOSSIP_STONE,
|
||||||
|
RH_GRAVEYARD_GOSSIP_STONE,
|
||||||
|
RH_HC_MALON_GOSSIP_STONE,
|
||||||
|
RH_HC_ROCK_WALL_GOSSIP_STONE,
|
||||||
|
RH_HC_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_HF_COW_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_HF_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_HF_SOUTHEAST_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_ZF_JABU_GOSSIP_STONE,
|
||||||
|
RH_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
||||||
|
RH_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
||||||
|
RH_KF_GOSSIP_STONE,
|
||||||
|
RH_KF_STORMS_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_KAK_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_LH_LAB_GOSSIP_STONE,
|
||||||
|
RH_LH_SOUTHEAST_GOSSIP_STONE,
|
||||||
|
RH_LH_SOUTHWEST_GOSSIP_STONE,
|
||||||
|
RH_LW_GOSSIP_STONE,
|
||||||
|
RH_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE,
|
||||||
|
RH_SFM_MAZE_NEAR_LW_GOSSIP_STONE,
|
||||||
|
RH_SFM_MAZE_CENTER_GOSSIP_STONE,
|
||||||
|
RH_SFM_SARIA_GOSSIP_STONE,
|
||||||
|
RH_TOT_LEFT_CENTER_GOSSIP_STONE,
|
||||||
|
RH_TOT_LEFTMOST_GOSSIP_STONE,
|
||||||
|
RH_TOT_RIGHT_CENTER_GOSSIP_STONE,
|
||||||
|
RH_TOT_RIGHTMOST_GOSSIP_STONE,
|
||||||
|
RH_ZD_GOSSIP_STONE,
|
||||||
|
RH_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
||||||
|
RH_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
||||||
|
RH_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t Rando::StaticData::oldVerGossipStoneStart = 740;
|
||||||
|
|
||||||
SaveManager::SaveManager() {
|
SaveManager::SaveManager() {
|
||||||
coreSectionIDsByName["base"] = SECTION_ID_BASE;
|
coreSectionIDsByName["base"] = SECTION_ID_BASE;
|
||||||
coreSectionIDsByName["randomizer"] = SECTION_ID_RANDOMIZER;
|
coreSectionIDsByName["randomizer"] = SECTION_ID_RANDOMIZER;
|
||||||
@ -106,6 +153,7 @@ SaveManager::SaveManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RANDOTODO should we just have dummy functions that raise warnings instead if these aren't supported?
|
||||||
void SaveManager::LoadRandomizerVersion1() {
|
void SaveManager::LoadRandomizerVersion1() {
|
||||||
auto randoContext = Rando::Context::GetInstance();
|
auto randoContext = Rando::Context::GetInstance();
|
||||||
RandomizerCheck location = RC_UNKNOWN_CHECK;
|
RandomizerCheck location = RC_UNKNOWN_CHECK;
|
||||||
@ -140,32 +188,33 @@ void SaveManager::LoadRandomizerVersion1() {
|
|||||||
for (int j = 0; j < ARRAY_COUNT(hintText); j++) {
|
for (int j = 0; j < ARRAY_COUNT(hintText); j++) {
|
||||||
SaveManager::Instance->LoadData("ht" + std::to_string(i) + "-" + std::to_string(j), hintText[j]);
|
SaveManager::Instance->LoadData("ht" + std::to_string(i) + "-" + std::to_string(j), hintText[j]);
|
||||||
}
|
}
|
||||||
randoContext->AddHint(RandomizerHintKey(check - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
RandomizerHint stoneHint = Rando::StaticData::oldVerHintOrder[Rando::StaticData::oldVerGossipStoneStart];
|
||||||
|
randoContext->AddHint(stoneHint, Rando::Hint(stoneHint, {CustomMessage(hintText)}));
|
||||||
}
|
}
|
||||||
|
|
||||||
char childAltarText[250];
|
char childAltarText[250];
|
||||||
for (int i = 0; i < ARRAY_COUNT(childAltarText); i++) {
|
for (int i = 0; i < ARRAY_COUNT(childAltarText); i++) {
|
||||||
SaveManager::Instance->LoadData("cat" + std::to_string(i), childAltarText[i]);
|
SaveManager::Instance->LoadData("cat" + std::to_string(i), childAltarText[i]);
|
||||||
}
|
}
|
||||||
randoContext->AddHint(RH_ALTAR_CHILD, Text(childAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_ALTAR_CHILD, Rando::Hint(RH_ALTAR_CHILD, {CustomMessage(childAltarText)}));
|
||||||
|
|
||||||
char adultAltarText[750];
|
char adultAltarText[750];
|
||||||
for (int i = 0; i < ARRAY_COUNT(adultAltarText); i++) {
|
for (int i = 0; i < ARRAY_COUNT(adultAltarText); i++) {
|
||||||
SaveManager::Instance->LoadData("aat" + std::to_string(i), adultAltarText[i]);
|
SaveManager::Instance->LoadData("aat" + std::to_string(i), adultAltarText[i]);
|
||||||
}
|
}
|
||||||
randoContext->AddHint(RH_ALTAR_ADULT, Text(adultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_ALTAR_ADULT, Rando::Hint(RH_ALTAR_ADULT, {CustomMessage(adultAltarText)}));
|
||||||
|
|
||||||
char ganonHintText[150];
|
char ganonHintText[150];
|
||||||
for (int i = 0; i < ARRAY_COUNT(ganonHintText); i++) {
|
for (int i = 0; i < ARRAY_COUNT(ganonHintText); i++) {
|
||||||
SaveManager::Instance->LoadData("ght" + std::to_string(i), ganonHintText[i]);
|
SaveManager::Instance->LoadData("ght" + std::to_string(i), ganonHintText[i]);
|
||||||
}
|
}
|
||||||
randoContext->AddHint(RH_GANONDORF_HINT, Text(ganonHintText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_GANONDORF_HINT, Rando::Hint(RH_GANONDORF_HINT, {CustomMessage(ganonHintText)}));
|
||||||
|
|
||||||
char ganonText[250];
|
char ganonText[250];
|
||||||
for (int i = 0; i < ARRAY_COUNT(ganonText); i++) {
|
for (int i = 0; i < ARRAY_COUNT(ganonText); i++) {
|
||||||
SaveManager::Instance->LoadData("gt" + std::to_string(i), ganonText[i]);
|
SaveManager::Instance->LoadData("gt" + std::to_string(i), ganonText[i]);
|
||||||
}
|
}
|
||||||
randoContext->AddHint(RH_GANONDORF_NOHINT, Text(ganonText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, {CustomMessage(ganonText)}));
|
||||||
|
|
||||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||||
|
|
||||||
@ -193,6 +242,7 @@ void SaveManager::LoadRandomizerVersion1() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//RANDOTODO if we actually support this, be less lazy
|
||||||
void SaveManager::LoadRandomizerVersion2() {
|
void SaveManager::LoadRandomizerVersion2() {
|
||||||
auto randoContext = Rando::Context::GetInstance();
|
auto randoContext = Rando::Context::GetInstance();
|
||||||
SaveManager::Instance->LoadArray("itemLocations", RC_MAX, [&](size_t i) {
|
SaveManager::Instance->LoadArray("itemLocations", RC_MAX, [&](size_t i) {
|
||||||
@ -244,56 +294,57 @@ void SaveManager::LoadRandomizerVersion2() {
|
|||||||
if (rc != RC_UNKNOWN_CHECK) {
|
if (rc != RC_UNKNOWN_CHECK) {
|
||||||
std::string hintText;
|
std::string hintText;
|
||||||
SaveManager::Instance->LoadData("hintText", hintText);
|
SaveManager::Instance->LoadData("hintText", hintText);
|
||||||
randoContext->AddHint(RandomizerHintKey(rc - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
RandomizerHint stoneHint = Rando::StaticData::oldVerHintOrder[Rando::StaticData::oldVerGossipStoneStart];
|
||||||
|
randoContext->AddHint(stoneHint, Rando::Hint(stoneHint, {CustomMessage(hintText)}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
std::string childAltarText;
|
std::string childAltarText;
|
||||||
SaveManager::Instance->LoadData("childAltarText", childAltarText);
|
SaveManager::Instance->LoadData("childAltarText", childAltarText);
|
||||||
randoContext->AddHint(RH_ALTAR_CHILD, Text(childAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_ALTAR_CHILD, Rando::Hint(RH_ALTAR_CHILD, {CustomMessage(childAltarText)}));
|
||||||
std::string adultAltarText;
|
std::string adultAltarText;
|
||||||
SaveManager::Instance->LoadData("adultAltarText", adultAltarText);
|
SaveManager::Instance->LoadData("adultAltarText", adultAltarText);
|
||||||
randoContext->AddHint(RH_ALTAR_ADULT, Text(adultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_ALTAR_ADULT, Rando::Hint(RH_ALTAR_ADULT, {CustomMessage(adultAltarText)}));
|
||||||
std::string ganonHintText;
|
std::string ganonHintText;
|
||||||
SaveManager::Instance->LoadData("ganonHintText", ganonHintText);
|
SaveManager::Instance->LoadData("ganonHintText", ganonHintText);
|
||||||
randoContext->AddHint(RH_GANONDORF_HINT, Text(ganonHintText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_GANONDORF_HINT, Rando::Hint(RH_GANONDORF_HINT, {CustomMessage(ganonHintText)}));
|
||||||
std::string ganonText;
|
std::string ganonText;
|
||||||
SaveManager::Instance->LoadData("ganonText", ganonText);
|
SaveManager::Instance->LoadData("ganonText", ganonText);
|
||||||
randoContext->AddHint(RH_GANONDORF_NOHINT, Text(ganonText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, {CustomMessage(ganonText)}));
|
||||||
std::string dampeText;
|
std::string dampeText;
|
||||||
SaveManager::Instance->LoadData("dampeText", dampeText);
|
SaveManager::Instance->LoadData("dampeText", dampeText);
|
||||||
randoContext->AddHint(RH_DAMPES_DIARY, Text(dampeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_DAMPES_DIARY, Rando::Hint(RH_DAMPES_DIARY, {CustomMessage(dampeText)}));
|
||||||
std::string gregHintText;
|
std::string gregHintText;
|
||||||
SaveManager::Instance->LoadData("gregHintText", gregHintText);
|
SaveManager::Instance->LoadData("gregHintText", gregHintText);
|
||||||
randoContext->AddHint(RH_GREG_RUPEE, Text(gregHintText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_GREG_RUPEE, Rando::Hint(RH_GREG_RUPEE, {CustomMessage(gregHintText)}));
|
||||||
std::string sheikText;
|
std::string sheikText;
|
||||||
SaveManager::Instance->LoadData("sheikText", sheikText);
|
SaveManager::Instance->LoadData("sheikText", sheikText);
|
||||||
randoContext->AddHint(RH_SHEIK_LIGHT_ARROWS, Text(sheikText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_SHEIK_HINT, Rando::Hint(RH_SHEIK_HINT, {CustomMessage(sheikText)}));
|
||||||
std::string sariaText;
|
std::string sariaText;
|
||||||
SaveManager::Instance->LoadData("sariaText", sariaText);
|
SaveManager::Instance->LoadData("sariaText", sariaText);
|
||||||
randoContext->AddHint(RH_SARIA, Text(sariaText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_SARIA_HINT, Rando::Hint(RH_SARIA_HINT, {CustomMessage(sariaText)}));
|
||||||
std::string fishingPoleText;
|
std::string fishingPoleText;
|
||||||
SaveManager::Instance->LoadData("fishingPoleText", fishingPoleText);
|
SaveManager::Instance->LoadData("fishingPoleText", fishingPoleText);
|
||||||
randoContext->AddHint(RH_FISHING_POLE, Text(fishingPoleText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
randoContext->AddHint(RH_FISHING_POLE, Rando::Hint(RH_FISHING_POLE, {CustomMessage(fishingPoleText)}));
|
||||||
std::string warpMinuetText;
|
std::string warpMinuetText;
|
||||||
SaveManager::Instance->LoadData("warpMinuetText", warpMinuetText);
|
SaveManager::Instance->LoadData("warpMinuetText", warpMinuetText);
|
||||||
randoContext->AddHint(RH_MINUET_WARP_LOC, Text(warpMinuetText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", randoContext->GetAreaFromString(warpMinuetText));
|
randoContext->AddHint(RH_MINUET_WARP_LOC, Rando::Hint(RH_MINUET_WARP_LOC, {CustomMessage(warpMinuetText)}));
|
||||||
std::string warpBoleroText;
|
std::string warpBoleroText;
|
||||||
SaveManager::Instance->LoadData("warpBoleroText", warpBoleroText);
|
SaveManager::Instance->LoadData("warpBoleroText", warpBoleroText);
|
||||||
randoContext->AddHint(RH_BOLERO_WARP_LOC, Text(warpBoleroText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", randoContext->GetAreaFromString(warpBoleroText));
|
randoContext->AddHint(RH_BOLERO_WARP_LOC, Rando::Hint(RH_BOLERO_WARP_LOC, {CustomMessage(warpBoleroText)}));
|
||||||
std::string warpSerenadeText;
|
std::string warpSerenadeText;
|
||||||
SaveManager::Instance->LoadData("warpSerenadeText", warpSerenadeText);
|
SaveManager::Instance->LoadData("warpSerenadeText", warpSerenadeText);
|
||||||
randoContext->AddHint(RH_SERENADE_WARP_LOC, Text(warpSerenadeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", randoContext->GetAreaFromString(warpSerenadeText));
|
randoContext->AddHint(RH_SERENADE_WARP_LOC, Rando::Hint(RH_SERENADE_WARP_LOC, {CustomMessage(warpSerenadeText)}));
|
||||||
std::string warpRequiemText;
|
std::string warpRequiemText;
|
||||||
SaveManager::Instance->LoadData("warpRequiemText", warpRequiemText);
|
SaveManager::Instance->LoadData("warpRequiemText", warpRequiemText);
|
||||||
randoContext->AddHint(RH_REQUIEM_WARP_LOC, Text(warpRequiemText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", randoContext->GetAreaFromString(warpRequiemText));
|
randoContext->AddHint(RH_REQUIEM_WARP_LOC, Rando::Hint(RH_REQUIEM_WARP_LOC, {CustomMessage(warpRequiemText)}));
|
||||||
std::string warpNocturneText;
|
std::string warpNocturneText;
|
||||||
SaveManager::Instance->LoadData("warpNocturneText", warpNocturneText);
|
SaveManager::Instance->LoadData("warpNocturneText", warpNocturneText);
|
||||||
randoContext->AddHint(RH_NOCTURNE_WARP_LOC, Text(warpNocturneText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", randoContext->GetAreaFromString(warpNocturneText));
|
randoContext->AddHint(RH_NOCTURNE_WARP_LOC, Rando::Hint(RH_NOCTURNE_WARP_LOC, {CustomMessage(warpNocturneText)}));
|
||||||
std::string warpPreludeText;
|
std::string warpPreludeText;
|
||||||
SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText);
|
SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText);
|
||||||
randoContext->AddHint(RH_PRELUDE_WARP_LOC, Text(warpPreludeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", randoContext->GetAreaFromString(warpPreludeText));
|
randoContext->AddHint(RH_PRELUDE_WARP_LOC, Rando::Hint(RH_PRELUDE_WARP_LOC, {CustomMessage(warpPreludeText)}));
|
||||||
|
|
||||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||||
|
|
||||||
@ -393,23 +444,10 @@ void SaveManager::LoadRandomizerVersion3() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
SaveManager::Instance->LoadArray("hintLocations", RH_MAX, [&](size_t i) {
|
SaveManager::Instance->LoadArray("hintLocations", RH_MAX, [&](size_t i) {
|
||||||
SaveManager::Instance->LoadStruct("", [&]() {
|
auto hint = RandomizerHint(i);
|
||||||
RandomizerHintKey rhk = RH_NONE;
|
nlohmann::ordered_json json;
|
||||||
SaveManager::Instance->LoadData("hintKey", rhk);
|
SaveManager::Instance->LoadData("", json);
|
||||||
std::string english, french, german;
|
randoContext->AddHint(hint, Rando::Hint(hint, json));
|
||||||
SaveManager::Instance->LoadStruct("hintText", [&]() {
|
|
||||||
SaveManager::Instance->LoadData("english", english);
|
|
||||||
SaveManager::Instance->LoadData("french", french);
|
|
||||||
SaveManager::Instance->LoadData("german", german);
|
|
||||||
});
|
|
||||||
RandomizerCheck rc = RC_UNKNOWN_CHECK;
|
|
||||||
SaveManager::Instance->LoadData("hintedCheck", rc);
|
|
||||||
HintType ht = HINT_TYPE_STATIC;
|
|
||||||
SaveManager::Instance->LoadData("hintType", ht);
|
|
||||||
RandomizerArea savedArea;
|
|
||||||
SaveManager::Instance->LoadData("hintedArea", savedArea);
|
|
||||||
randoContext->AddHint(rhk, Text(english, french, /*spanish*/"", german), rc, ht, "Unknown", savedArea);//RANDOTODO, maybe store and load distrabution, but it's a string...
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||||
@ -485,17 +523,68 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
|
|||||||
});
|
});
|
||||||
|
|
||||||
SaveManager::Instance->SaveArray("hintLocations", RH_MAX, [&](size_t i) {
|
SaveManager::Instance->SaveArray("hintLocations", RH_MAX, [&](size_t i) {
|
||||||
|
auto hint = randoContext->GetHint(RandomizerHint(i));
|
||||||
|
// RANDOTODO a way for saveData to accept a raw JSON would make maintaining hint code nicer.
|
||||||
|
// save manager forces code rewrites between the spoiler log and internal saves, when the code needs to do the exact same thing
|
||||||
|
// in cases where data needs to be loaded in from the spoiler log for plando mode.
|
||||||
|
// fails as push_back is ambiguous
|
||||||
|
// SaveManager::Instance->SaveData(Rando::StaticData::hintNames[(uint32_t)hint].GetEnglish(), hint->toJSON());
|
||||||
SaveManager::Instance->SaveStruct("", [&]() {
|
SaveManager::Instance->SaveStruct("", [&]() {
|
||||||
auto hint = randoContext->GetHint(RandomizerHintKey(i));
|
bool enabled = hint->IsEnabled();
|
||||||
SaveManager::Instance->SaveData("hintKey", RandomizerHintKey(i));
|
SaveManager::Instance->SaveData("enabled", enabled);
|
||||||
SaveManager::Instance->SaveStruct("hintText", [&]() {
|
if (enabled){
|
||||||
SaveManager::Instance->SaveData("english", hint->GetText().GetEnglish());
|
std::vector<std::string> messages = hint->GetAllMessageStrings(MF_RAW);
|
||||||
SaveManager::Instance->SaveData("french", hint->GetText().GetFrench());
|
SaveManager::Instance->SaveArray("messages", messages.size(), [&](size_t i) {
|
||||||
SaveManager::Instance->SaveData("german", hint->GetText().GetGerman());
|
SaveManager::Instance->SaveData("", messages[i]);
|
||||||
});
|
});
|
||||||
SaveManager::Instance->SaveData("hintedCheck", hint->GetHintedLocation());
|
|
||||||
SaveManager::Instance->SaveData("hintType", hint->GetHintType());
|
SaveManager::Instance->SaveData("distribution", hint->GetDistribution());
|
||||||
SaveManager::Instance->SaveData("hintedArea", hint->GetHintedArea());
|
SaveManager::Instance->SaveData("type", Rando::StaticData::hintTypeNames[hint->GetHintType()].GetEnglish(MF_CLEAN));
|
||||||
|
|
||||||
|
std::vector<RandomizerHintTextKey> hintKeys = hint->GetHintTextKeys();
|
||||||
|
SaveManager::Instance->SaveArray("hintKeys", hintKeys.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", hintKeys[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<RandomizerCheck> locations = hint->GetHintedLocations();
|
||||||
|
SaveManager::Instance->SaveArray("locations", locations.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", Rando::StaticData::GetLocation(locations[i])->GetName());
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<RandomizerGet> items = hint->GetHintedItems();
|
||||||
|
SaveManager::Instance->SaveArray("items", items.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", Rando::StaticData::GetItemTable()[items[i]].GetName().GetEnglish());
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<uint8_t> itemNamesChosen = hint->GetItemNamesChosen();
|
||||||
|
SaveManager::Instance->SaveArray("itemNamesChosen", itemNamesChosen.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", itemNamesChosen[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<uint8_t> hintTextsChosen = hint->GetHintTextsChosen();
|
||||||
|
SaveManager::Instance->SaveArray("hintTextsChosen", hintTextsChosen.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", hintTextsChosen[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<uint8_t> areaTextsChosen = hint->GetAreaTextsChosen();
|
||||||
|
SaveManager::Instance->SaveArray("areaTextsChosen", areaTextsChosen.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", areaTextsChosen[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<RandomizerArea> areas = hint->GetHintedAreas();
|
||||||
|
SaveManager::Instance->SaveArray("areas", areas.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", Rando::StaticData::hintTextTable[Rando::StaticData::areaNames[areas[i]]].GetClear().GetForCurrentLanguage(MF_CLEAN));
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<TrialKey> trials = hint->GetHintedTrials();
|
||||||
|
SaveManager::Instance->SaveArray("trials", trials.size(), [&](size_t i) {
|
||||||
|
SaveManager::Instance->SaveData("", randoContext->GetTrial(trials[i])->GetName().GetForCurrentLanguage(MF_CLEAN));
|
||||||
|
});
|
||||||
|
|
||||||
|
SaveManager::Instance->SaveData("num", hint->GetNum());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -183,6 +183,7 @@ class SaveManager {
|
|||||||
nlohmann::json* currentJsonContext = nullptr;
|
nlohmann::json* currentJsonContext = nullptr;
|
||||||
nlohmann::json::iterator currentJsonArrayContext;
|
nlohmann::json::iterator currentJsonArrayContext;
|
||||||
std::shared_ptr<BS::thread_pool> smThreadPool;
|
std::shared_ptr<BS::thread_pool> smThreadPool;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -137,19 +137,19 @@ extern "C" void OTRMessage_Init()
|
|||||||
CustomMessageManager::Instance->AddCustomMessageTable(customMessageTableID);
|
CustomMessageManager::Instance->AddCustomMessageTable(customMessageTableID);
|
||||||
CustomMessageManager::Instance->CreateGetItemMessage(
|
CustomMessageManager::Instance->CreateGetItemMessage(
|
||||||
customMessageTableID, (GetItemID)TEXT_GS_NO_FREEZE, ITEM_SKULL_TOKEN,
|
customMessageTableID, (GetItemID)TEXT_GS_NO_FREEZE, ITEM_SKULL_TOKEN,
|
||||||
CustomMessage("You got a %rGold Skulltula Token%w!&You've collected %r{{gsCount}}%w tokens&in total!\x0E\x3C",
|
CustomMessage("You got a %rGold Skulltula Token%w!&You've collected %r[[gsCount]]%w tokens&in total!\x0E\x3C",
|
||||||
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r{{gsCount}}&%wGoldene "
|
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r[[gsCount]]&%wGoldene "
|
||||||
"Skulltula-Symbole&gesammelt!\x0E\x3C",
|
"Skulltula-Symbole&gesammelt!\x0E\x3C",
|
||||||
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r{{gsCount}}%w symboles en "
|
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r[[gsCount]]%w symboles en "
|
||||||
"tout!\x0E\x3C",
|
"tout!\x0E\x3C",
|
||||||
TEXTBOX_TYPE_BLUE));
|
TEXTBOX_TYPE_BLUE));
|
||||||
CustomMessageManager::Instance->CreateGetItemMessage(
|
CustomMessageManager::Instance->CreateGetItemMessage(
|
||||||
customMessageTableID, (GetItemID)TEXT_GS_FREEZE, ITEM_SKULL_TOKEN,
|
customMessageTableID, (GetItemID)TEXT_GS_FREEZE, ITEM_SKULL_TOKEN,
|
||||||
CustomMessage(
|
CustomMessage(
|
||||||
"You got a %rGold Skulltula Token%w!&You've collected %r{{gsCount}}%w tokens&in total!",
|
"You got a %rGold Skulltula Token%w!&You've collected %r[[gsCount]]%w tokens&in total!",
|
||||||
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r{{gsCount}}&%wGoldene "
|
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r[[gsCount]]&%wGoldene "
|
||||||
"Skulltula-Symbole&gesammelt!",
|
"Skulltula-Symbole&gesammelt!",
|
||||||
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r{{gsCount}}%w symboles en tout!",
|
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r[[gsCount]]%w symboles en tout!",
|
||||||
TEXTBOX_TYPE_BLUE));
|
TEXTBOX_TYPE_BLUE));
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
customMessageTableID, TEXT_BUY_BOMBCHU_10_DESC,
|
customMessageTableID, TEXT_BUY_BOMBCHU_10_DESC,
|
||||||
@ -168,14 +168,14 @@ extern "C" void OTRMessage_Init()
|
|||||||
CustomMessageManager::Instance->CreateGetItemMessage(
|
CustomMessageManager::Instance->CreateGetItemMessage(
|
||||||
customMessageTableID, (GetItemID)TEXT_HEART_CONTAINER, ITEM_HEART_CONTAINER,
|
customMessageTableID, (GetItemID)TEXT_HEART_CONTAINER, ITEM_HEART_CONTAINER,
|
||||||
CustomMessage(
|
CustomMessage(
|
||||||
"You got a %rHeart Container%w!&You've collected %r{{heartContainerCount}}%w containers&in total!",
|
"You got a %rHeart Container%w!&You've collected %r[[heartContainerCount]]%w containers&in total!",
|
||||||
"Ein %rHerzcontainer%w!&Du hast nun insgesamt %r{{heartContainerCount}}%w&Herzcontainer gesammelt!",
|
"Ein %rHerzcontainer%w!&Du hast nun insgesamt %r[[heartContainerCount]]%w&Herzcontainer gesammelt!",
|
||||||
"Vous obtenez un %rCoeur&d'Energie%w! Vous en avez&collecté %r{{heartContainerCount}}%w en tout!"));
|
"Vous obtenez un %rCoeur&d'Energie%w! Vous en avez&collecté %r[[heartContainerCount]]%w en tout!"));
|
||||||
CustomMessageManager::Instance->CreateGetItemMessage(
|
CustomMessageManager::Instance->CreateGetItemMessage(
|
||||||
customMessageTableID, (GetItemID)TEXT_HEART_PIECE, ITEM_HEART_PIECE,
|
customMessageTableID, (GetItemID)TEXT_HEART_PIECE, ITEM_HEART_PIECE,
|
||||||
CustomMessage("You got a %rHeart Piece%w!&You've collected %r{{heartPieceCount}}%w pieces&in total!",
|
CustomMessage("You got a %rHeart Piece%w!&You've collected %r[[heartPieceCount]]%w pieces&in total!",
|
||||||
"Ein %rHerzteil%w!&Du hast nun insgesamt %r{{heartPieceCount}}%w&Herteile gesammelt!",
|
"Ein %rHerzteil%w!&Du hast nun insgesamt %r[[heartPieceCount]]%w&Herteile gesammelt!",
|
||||||
"Vous obtenez un %rQuart de&Coeur%w! Vous en avez collecté&%r{{heartPieceCount}}%w en tout!",
|
"Vous obtenez un %rQuart de&Coeur%w! Vous en avez collecté&%r[[heartPieceCount]]%w en tout!",
|
||||||
TEXTBOX_TYPE_BLUE));
|
TEXTBOX_TYPE_BLUE));
|
||||||
CustomMessageManager::Instance->CreateMessage(
|
CustomMessageManager::Instance->CreateMessage(
|
||||||
customMessageTableID, TEXT_MARKET_GUARD_NIGHT,
|
customMessageTableID, TEXT_MARKET_GUARD_NIGHT,
|
||||||
|
@ -17,9 +17,6 @@
|
|||||||
|
|
||||||
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
|
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
|
||||||
|
|
||||||
#define TEXT_SHEIK_NEED_HOOK 0x700F
|
|
||||||
#define TEXT_SHEIK_HAVE_HOOK 0x7010
|
|
||||||
|
|
||||||
void EnXc_Init(Actor* thisx, PlayState* play);
|
void EnXc_Init(Actor* thisx, PlayState* play);
|
||||||
void EnXc_Destroy(Actor* thisx, PlayState* play);
|
void EnXc_Destroy(Actor* thisx, PlayState* play);
|
||||||
void EnXc_Update(Actor* thisx, PlayState* play);
|
void EnXc_Update(Actor* thisx, PlayState* play);
|
||||||
@ -2217,28 +2214,12 @@ void EnXc_SetupDialogueAction(EnXc* this, PlayState* play) {
|
|||||||
if (Actor_ProcessTalkRequest(&this->actor, play)) {
|
if (Actor_ProcessTalkRequest(&this->actor, play)) {
|
||||||
this->action = SHEIK_ACTION_IN_DIALOGUE;
|
this->action = SHEIK_ACTION_IN_DIALOGUE;
|
||||||
} else {
|
} else {
|
||||||
this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY;
|
this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY; //this arrangment is cute but I would rather handle all message selection in ship code
|
||||||
if (IS_RANDO && gPlayState->sceneNum == SCENE_TEMPLE_OF_TIME) {
|
|
||||||
if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, SCENE_GANONS_TOWER)) {
|
|
||||||
this->actor.textId = TEXT_SHEIK_NEED_HOOK;
|
|
||||||
} else {
|
|
||||||
this->actor.textId = TEXT_SHEIK_HAVE_HOOK;
|
|
||||||
}
|
|
||||||
} else if (IS_RANDO && gPlayState->sceneNum == SCENE_INSIDE_GANONS_CASTLE) {
|
|
||||||
if (CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT &&
|
|
||||||
CUR_CAPACITY(UPG_QUIVER) >= 30 && gSaveContext.isMagicAcquired) {
|
|
||||||
this->actor.textId = TEXT_SHEIK_HAVE_HOOK;
|
|
||||||
} else {
|
|
||||||
this->actor.textId = TEXT_SHEIK_NEED_HOOK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (INV_CONTENT(ITEM_HOOKSHOT) != ITEM_NONE) {
|
if (INV_CONTENT(ITEM_HOOKSHOT) != ITEM_NONE) {
|
||||||
this->actor.textId = 0x7010; //"You have what you need"
|
this->actor.textId = 0x7010; //"You have what you need"
|
||||||
} else {
|
} else {
|
||||||
this->actor.textId = 0x700F; //"You need another skill"
|
this->actor.textId = 0x700F; //"You need another skill"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
func_8002F2F4(&this->actor, play);
|
func_8002F2F4(&this->actor, play);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user