diff --git a/src/Main.cc b/src/Main.cc index 415b0bd2..0fc9ade8 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -89,7 +89,7 @@ void drop_privileges(const string& username) { config_log.info("Switched to user %s (%d:%d)", username.c_str(), pw->pw_uid, pw->pw_gid); } -Version get_cli_version(Arguments& args) { +Version get_cli_version(Arguments& args, Version default_value = Version::UNKNOWN) { if (args.get("pc-patch")) { return Version::PC_PATCH; } else if (args.get("bb-patch")) { @@ -118,6 +118,8 @@ Version get_cli_version(Arguments& args) { return Version::GC_EP3; } else if (args.get("bb")) { return Version::BB_V4; + } else if (default_value != Version::UNKNOWN) { + return default_value; } else { throw runtime_error("a version option is required"); } @@ -1313,7 +1315,8 @@ Action a_convert_rare_item_set( string data = rs->serialize_gsl(true); write_output_data(args, data.data(), data.size(), nullptr); } else if (ends_with(output_filename, ".afs")) { - string data = rs->serialize_afs(); + bool is_v1 = ::is_v1(get_cli_version(args, Version::GC_V3)); + string data = rs->serialize_afs(is_v1); write_output_data(args, data.data(), data.size(), nullptr); } else { throw runtime_error("cannot determine output format; use a filename ending with .json, .gsl, .gslb, or .afs"); diff --git a/src/RareItemSet.cc b/src/RareItemSet.cc index 317f9556..29ad4d01 100644 --- a/src/RareItemSet.cc +++ b/src/RareItemSet.cc @@ -115,7 +115,7 @@ void RareItemSet::ParsedRELData::parse_t(StringReader r, bool is_v1) { } template -std::string RareItemSet::ParsedRELData::serialize_t() const { +std::string RareItemSet::ParsedRELData::serialize_t(bool is_v1) const { using U32T = typename std::conditional::type; using U16T = typename std::conditional::type; @@ -129,7 +129,7 @@ std::string RareItemSet::ParsedRELData::serialize_t() const { for (const auto& drop : this->monster_rares) { w.put(PackedDrop(drop)); } - while (w.size() < root.monster_rares_offset + 0x65 * sizeof(PackedDrop)) { + while (w.size() < root.monster_rares_offset + (is_v1 ? 0x33 : 0x65) * sizeof(PackedDrop)) { w.put(empty_drop); } root.box_areas_offset = w.size(); @@ -198,11 +198,11 @@ RareItemSet::ParsedRELData::ParsedRELData(const SpecCollection& collection) { } } -std::string RareItemSet::ParsedRELData::serialize(bool big_endian) const { +std::string RareItemSet::ParsedRELData::serialize(bool big_endian, bool is_v1) const { if (big_endian) { - return this->serialize_t(); + return this->serialize_t(is_v1); } else { - return this->serialize_t(); + return this->serialize_t(is_v1); } } @@ -378,12 +378,12 @@ RareItemSet::RareItemSet(const JSON& json, Version version, shared_ptr files; for (uint8_t difficulty = 0; difficulty < 4; difficulty++) { for (uint8_t section_id = 0; section_id < 10; section_id++) { ParsedRELData rel(this->get_collection(GameMode::NORMAL, Episode::EP1, difficulty, section_id)); - files.emplace_back(rel.serialize(false)); + files.emplace_back(rel.serialize(false, is_v1)); } } return AFSArchive::generate(files, false); @@ -399,7 +399,7 @@ std::string RareItemSet::serialize_gsl(bool big_endian) const { try { string filename = this->gsl_entry_name_for_table(GameMode::NORMAL, episode, difficulty, section_id); ParsedRELData rel(this->get_collection(GameMode::NORMAL, episode, difficulty, section_id)); - files.emplace(filename, rel.serialize(big_endian)); + files.emplace(filename, rel.serialize(big_endian, false)); } catch (const out_of_range&) { // Collection does not exist; skip it } @@ -412,7 +412,7 @@ std::string RareItemSet::serialize_gsl(bool big_endian) const { try { string filename = this->gsl_entry_name_for_table(GameMode::CHALLENGE, Episode::EP1, difficulty, section_id); ParsedRELData rel(this->get_collection(GameMode::CHALLENGE, Episode::EP1, difficulty, section_id)); - files.emplace(filename, rel.serialize(big_endian)); + files.emplace(filename, rel.serialize(big_endian, false)); } catch (const out_of_range&) { // Collection does not exist; skip it } diff --git a/src/RareItemSet.hh b/src/RareItemSet.hh index 8570516d..ac3d6ab5 100644 --- a/src/RareItemSet.hh +++ b/src/RareItemSet.hh @@ -35,7 +35,7 @@ public: std::vector get_enemy_specs(GameMode mode, Episode episode, uint8_t difficulty, uint8_t secid, uint8_t rt_index) const; std::vector get_box_specs(GameMode mode, Episode episode, uint8_t difficulty, uint8_t secid, uint8_t area) const; - std::string serialize_afs() const; + std::string serialize_afs(bool is_v1) const; std::string serialize_gsl(bool big_endian) const; std::string serialize_json(Version version, std::shared_ptr name_index = nullptr) const; @@ -86,12 +86,12 @@ protected: ParsedRELData() = default; ParsedRELData(StringReader r, bool big_endian, bool is_v1); explicit ParsedRELData(const SpecCollection& collection); - std::string serialize(bool big_endian) const; + std::string serialize(bool big_endian, bool is_v1) const; template void parse_t(StringReader r, bool is_v1); template - std::string serialize_t() const; + std::string serialize_t(bool is_v1) const; SpecCollection as_collection() const; };