#pragma once #include #include #include #include "keys.hpp" #include "text.hpp" #include "random.hpp" #include "settings.hpp" #include enum class HintType { Trial, Always, Woth, //Way of the Hero Barren, Entrance, Sometimes, Random, Item, Song, Overworld, Dungeon, Junk, NamedItem, MaxCount, }; struct HintDistributionSetting { HintType type; uint8_t order; size_t weight; uint8_t fixed; uint8_t copies; }; struct HintSetting { using DistributionTable = std::array(HintType::MaxCount)>; uint8_t dungeonsWothLimit; uint8_t dungeonsBarrenLimit; bool namedItemsRequired; DistributionTable distTable; }; enum class HintCategory { Item, Always, Sometimes, Exclude, Entrance, Region, Junk, DungeonName, Boss, Bridge, GanonsBossKey, LACS, Altar, Validation, LightArrow, GanonLine, MerchantsDialogs, }; class HintText { public: HintText() = default; HintText(std::vector obscureText_, std::vector ambiguousText_, Text clearText_, HintCategory type_) : obscureText(std::move(obscureText_)), ambiguousText(std::move(ambiguousText_)), clearText(std::move(clearText_)), type(type_) {} static auto Item(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Item}; } static auto Always(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Always}; } static auto Sometimes(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Sometimes}; } static auto Exclude(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Exclude}; } static auto Entrance(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Entrance}; } static auto Region(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Region}; } static auto Junk(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Junk}; } static auto DungeonName(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::DungeonName}; } static auto Boss(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Boss}; } static auto Bridge(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Bridge}; } static auto GanonsBossKey(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonsBossKey}; } static auto LACS(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LACS}; } static auto Altar(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Altar}; } static auto Validation(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Validation}; } static auto LightArrow(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LightArrow}; } static auto GanonLine(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine}; } static auto MerchantsDialogs(std::vector&& obscureText, std::vector&& 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 { if (Settings::ClearerHints.Is(HINTMODE_OBSCURE)) { return GetObscure(); } else if (Settings::ClearerHints.Is(HINTMODE_AMBIGUOUS)){ return GetAmbiguous(); } else { return GetClear(); } } const Text GetTextCopy() const { if (Settings::ClearerHints.Is(HINTMODE_OBSCURE)) { return GetObscure(); } else if (Settings::ClearerHints.Is(HINTMODE_AMBIGUOUS)){ return GetAmbiguous(); } else { return GetClear(); } } 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: std::vector obscureText = {}; std::vector ambiguousText = {}; Text clearText; HintCategory type; }; using ConditionalAlwaysHint = std::pair>; //10 dungeons as GTG and GC are excluded extern std::array dungeonInfoData; extern std::array conditionalAlwaysHints; extern uint32_t GetHintRegionHintKey(const uint32_t area); extern void CreateAllHints(); extern void CreateMerchantsHints(); Text& GetChildAltarText(); Text& GetAdultAltarText(); Text& GetGanonText(); Text& GetGanonHintText(); Text& GetWarpMinuetText(); Text& GetWarpBoleroText(); Text& GetWarpSerenadeText(); Text& GetWarpRequiemText(); Text& GetWarpNocturneText(); Text& GetWarpPreludeText();