#include "hint.h" #include "map" #include "string" #include "context.h" #include #include "static_data.h" namespace Rando { Hint::Hint() { } Hint::Hint(RandomizerHint ownKey_, HintType hintType_, std::string distribution_, std::vector hintKeys_, std::vector locations_, std::vector areas_, std::vector trials_) : ownKey(ownKey_), hintType(hintType_), distribution(std::move(distribution_)), hintKeys(hintKeys_), locations(locations_), areas(areas_), trials(trials_) { FillGapsInData(); SetLocationsAsHinted(); NamesChosen(); enabled = true; } Hint::Hint(RandomizerHint ownKey_, HintType hintType_, std::vector hintKeys_, std::vector locations_, std::vector areas_, std::vector 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; } Hint::Hint(RandomizerHint ownKey_, std::vector messages_) : ownKey(ownKey_), messages(messages_) { hintType = HINT_TYPE_MESSAGE; enabled = true; } Hint::Hint(RandomizerHint ownKey_, nlohmann::json json_) { ownKey = ownKey_; if (json_.contains("enabled") && !json_["enabled"].get()) { return; } enabled = true; if (json_.contains("type")) { hintType = (HintType)StaticData::hintTypeNameToEnum[json_["type"].get()]; } if (hintType == HINT_TYPE_MESSAGE) { if (json_.contains("messages")) { for (auto message : json_["messages"]) { messages.push_back(CustomMessage(message.get())); } } else if (json_.contains("message")) { messages.push_back(CustomMessage(json_["message"].get())); } } if (json_.contains("distribution")) { distribution = json_["distribution"].get(); } if (json_.contains("locations")) { for (auto loc : json_["locations"]) { locations.push_back(StaticData::locationNameToEnum[loc.get()]); } } else if (json_.contains("location")) { locations.push_back(StaticData::locationNameToEnum[json_["location"].get()]); } if (json_.contains("itemNamesChosen")) { for (auto name : json_["itemNamesChosen"]) { itemNamesChosen.push_back(name.get()); } } else if (json_.contains("itemNameChosen")) { itemNamesChosen.push_back(json_["itemNameChosen"].get()); } 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()); } } else if (json_.contains("areaNameChosen")) { areaNamesChosen.push_back(json_["areaNameChosen"].get()); } 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()); } } else if (json_.contains("hintKey")) { hintKeys.push_back((RandomizerHintTextKey)json_["hintKey"].get()); } if (json_.contains("hintTextsChosen")) { for (auto name : json_["hintTextsChosen"]) { hintTextsChosen.push_back(name.get()); } } else if (json_.contains("hintTextChosen")) { hintTextsChosen.push_back(json_["hintTextChosen"].get()); } if (json_.contains("num")) { num = json_["num"].get(); } 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 area matters for the hint, it should be specified and not left to this if (fillAreas) { areas.push_back(ctx->GetItemLocation(locations[c])->GetFirstArea()); } 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 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) { for (uint8_t c = 0; c < locations.size(); c++) { namesTemp = {}; saveNames = false; uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c)); 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 } // RANDOTODO will number of messages always be u8? return static_cast(numMessages); } const std::vector Hint::GetAllMessageStrings(MessageFormat format) const { std::vector 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 HintText(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 HintText( CustomMessage("ERROR: ITEM AREA HINT WITH NO LOCATION")); // RANDOTODO get isDungeon from area? } default: return HintText(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 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_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 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 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().GetForCurrentLanguage( MF_RAW); // RANDOTODO change to CustomMessage; } else if (items.size() > 1) { std::vector itemStrings = {}; for (size_t c = 0; c < items.size(); c++) { itemStrings.push_back(StaticData::GetItemTable()[items[c]].GetName().GetForCurrentLanguage( MF_RAW)); // RANDOTODO change to CustomMessage } log["items"] = itemStrings; } } if (itemNamesChosen.size() == 1) { log["itemNameChosen"] = itemNamesChosen[0]; } else if (itemNamesChosen.size() > 1) { std::vector 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 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 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 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 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 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) && 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) { 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).Get()); } 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).Get()); } 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).Get()); } 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).Get()); } 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).Get()); } 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_TRIFORCE_HUNT)) { return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage(); } 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).Get()); } 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).Get()); } 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).Get()); } 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).Get()); } 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).Get()); } return ganonBossKeyMessage; } void Hint::AddHintedLocation(RandomizerCheck location) { locations.push_back(location); } std::vector Hint::GetHintedLocations() const { return locations; } void Hint::SetHintType(HintType type) { hintType = type; } HintType Hint::GetHintType() const { return hintType; } void Hint::AddHintedArea(RandomizerArea area) { areas.push_back(area); } std::vector Hint::GetHintedAreas() const { return areas; } void Hint::SetDistribution(std::string distributionName) { distribution = distributionName; } const std::string& Hint::GetDistribution() const { return distribution; } bool Hint::IsEnabled() const { return enabled; } std::vector Hint::GetHintTextKeys() const { return hintKeys; } std::vector Hint::GetHintedItems() const { return items; } std::vector Hint::GetItemNamesChosen() const { return itemNamesChosen; } std::vector Hint::GetHintTextsChosen() const { return hintTextsChosen; } std::vector Hint::GetAreaTextsChosen() const { return areaNamesChosen; } std::vector Hint::GetHintedTrials() const { return trials; } int Hint::GetNum() { return num; } void Hint::ResetVariables() { ownKey = RH_NONE; num = 0; yourPocket = false; messages = {}; hintKeys = {}; locations = {}; items = {}; trials = {}; hintType = HINT_TYPE_HINT_KEY; areas = {}; distribution = ""; enabled = false; itemNamesChosen = {}; hintTextsChosen = {}; areaNamesChosen = {}; } } // namespace Rando