support generating v1 rare item sets

This commit is contained in:
Martin Michelsen
2023-12-26 07:04:30 -08:00
parent 2cdebd5f20
commit 5382e12b8d
3 changed files with 17 additions and 14 deletions
+5 -2
View File
@@ -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<bool>("pc-patch")) {
return Version::PC_PATCH;
} else if (args.get<bool>("bb-patch")) {
@@ -118,6 +118,8 @@ Version get_cli_version(Arguments& args) {
return Version::GC_EP3;
} else if (args.get<bool>("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");
+9 -9
View File
@@ -115,7 +115,7 @@ void RareItemSet::ParsedRELData::parse_t(StringReader r, bool is_v1) {
}
template <bool IsBigEndian>
std::string RareItemSet::ParsedRELData::serialize_t() const {
std::string RareItemSet::ParsedRELData::serialize_t(bool is_v1) const {
using U32T = typename std::conditional<IsBigEndian, be_uint32_t, le_uint32_t>::type;
using U16T = typename std::conditional<IsBigEndian, be_uint16_t, le_uint16_t>::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<true>();
return this->serialize_t<true>(is_v1);
} else {
return this->serialize_t<false>();
return this->serialize_t<false>(is_v1);
}
}
@@ -378,12 +378,12 @@ RareItemSet::RareItemSet(const JSON& json, Version version, shared_ptr<const Ite
}
}
std::string RareItemSet::serialize_afs() const {
std::string RareItemSet::serialize_afs(bool is_v1) const {
vector<string> 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
}
+3 -3
View File
@@ -35,7 +35,7 @@ public:
std::vector<ExpandedDrop> get_enemy_specs(GameMode mode, Episode episode, uint8_t difficulty, uint8_t secid, uint8_t rt_index) const;
std::vector<ExpandedDrop> 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<const ItemNameIndex> 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 <bool IsBigEndian>
void parse_t(StringReader r, bool is_v1);
template <bool IsBigEndian>
std::string serialize_t() const;
std::string serialize_t(bool is_v1) const;
SpecCollection as_collection() const;
};