#pragma once #include #include #include #include #include #include "Version.hh" enum class QuestCategory { UNKNOWN = -1, RETRIEVAL = 0, EXTERMINATION, EVENT, SHOP, VR, TOWER, GOVERNMENT_EPISODE_1, GOVERNMENT_EPISODE_2, GOVERNMENT_EPISODE_4, DOWNLOAD, BATTLE, CHALLENGE, SOLO, EPISODE_3, }; bool category_is_mode(QuestCategory category); const char* name_for_category(QuestCategory category); class Quest { public: enum class FileFormat { BIN_DAT = 0, BIN_DAT_UNCOMPRESSED, BIN_DAT_GCI, BIN_DAT_DLQ, QST, }; int64_t internal_id; uint32_t menu_item_id; QuestCategory category; uint8_t episode; // 0 = ep1, 1 = ep2, 2 = ep4, 0xFF = ep3 bool is_dcv1; bool joinable; GameVersion version; std::string file_basename; // we append -. when reading FileFormat file_format; bool has_mnm_extension; std::u16string name; std::u16string short_description; std::u16string long_description; Quest(const std::string& file_basename); Quest(const Quest&) = default; Quest(Quest&&) = default; Quest& operator=(const Quest&) = default; Quest& operator=(Quest&&) = default; std::string bin_filename() const; std::string dat_filename() const; std::shared_ptr bin_contents() const; std::shared_ptr dat_contents() const; std::shared_ptr create_download_quest() const; static std::string decode_gci( const std::string& filename, ssize_t find_seed_num_threads = -1, int64_t known_seed = -1); static std::string decode_dlq(const std::string& filename); static std::pair decode_qst(const std::string& filename); private: // these are populated when requested mutable std::shared_ptr bin_contents_ptr; mutable std::shared_ptr dat_contents_ptr; }; struct QuestIndex { std::string directory; std::map, std::shared_ptr> version_menu_item_id_to_quest; std::map>> category_to_quests; std::map> gba_file_contents; QuestIndex(const std::string& directory); std::shared_ptr get(GameVersion version, uint32_t id) const; std::shared_ptr get_gba(const std::string& name) const; std::vector> filter(GameVersion version, bool is_dcv1, QuestCategory category) const; };