include DAR in generated drop tables

This commit is contained in:
Martin Michelsen
2025-10-08 21:29:55 -07:00
parent a777dc8236
commit 093c25fce4
3 changed files with 22 additions and 10 deletions
+5 -3
View File
@@ -2098,6 +2098,7 @@ Action a_convert_rare_item_set(
s->load_text_index(); s->load_text_index();
s->load_item_definitions(); s->load_item_definitions();
s->load_item_name_indexes(); s->load_item_name_indexes();
s->load_drop_tables();
string input_filename = args.get<string>(1, false); string input_filename = args.get<string>(1, false);
if (input_filename.empty() || (input_filename == "-")) { if (input_filename.empty() || (input_filename == "-")) {
@@ -2144,7 +2145,8 @@ Action a_convert_rare_item_set(
string data = rs->serialize_afs(is_v1); string data = rs->serialize_afs(is_v1);
write_output_data(args, data.data(), data.size(), nullptr); write_output_data(args, data.data(), data.size(), nullptr);
} else if (output_filename_lower.ends_with(".html")) { } else if (output_filename_lower.ends_with(".html")) {
bool is_v1 = ::is_v1(get_cli_version(args, Version::BB_V4)); Version cli_version = get_cli_version(args, Version::BB_V4);
bool is_v1 = ::is_v1(cli_version);
static const array<GameMode, 4> modes = {GameMode::NORMAL, GameMode::BATTLE, GameMode::CHALLENGE, GameMode::SOLO}; static const array<GameMode, 4> modes = {GameMode::NORMAL, GameMode::BATTLE, GameMode::CHALLENGE, GameMode::SOLO};
for (GameMode mode : modes) { for (GameMode mode : modes) {
static const array<Episode, 3> episodes = {Episode::EP1, Episode::EP2, Episode::EP4}; static const array<Episode, 3> episodes = {Episode::EP1, Episode::EP2, Episode::EP4};
@@ -2153,8 +2155,8 @@ Action a_convert_rare_item_set(
if (!rs->has_entries_for_game_config(mode, episode, difficulty)) { if (!rs->has_entries_for_game_config(mode, episode, difficulty)) {
continue; continue;
} }
auto item_name_index = s->item_name_index(get_cli_version(args, Version::BB_V4)); auto item_name_index = s->item_name_index(cli_version);
string data = rs->serialize_html(mode, episode, difficulty, item_name_index); string data = rs->serialize_html(mode, episode, difficulty, item_name_index, s->common_item_set(cli_version, nullptr));
string out_filename = output_filename.substr(0, output_filename.size() - 5) + "." + name_for_mode(mode) + "." + abbreviation_for_episode(episode) + "." + abbreviation_for_difficulty(difficulty) + output_filename.substr(output_filename.size() - 5); string out_filename = output_filename.substr(0, output_filename.size() - 5) + "." + name_for_mode(mode) + "." + abbreviation_for_episode(episode) + "." + abbreviation_for_difficulty(difficulty) + output_filename.substr(output_filename.size() - 5);
phosg::save_file(out_filename, data); phosg::save_file(out_filename, data);
phosg::log_info_f("... {}", out_filename); phosg::log_info_f("... {}", out_filename);
+14 -6
View File
@@ -430,7 +430,8 @@ string RareItemSet::serialize_html(
GameMode mode, GameMode mode,
Episode episode, Episode episode,
uint8_t difficulty, uint8_t difficulty,
shared_ptr<const ItemNameIndex> name_index) const { shared_ptr<const ItemNameIndex> name_index,
shared_ptr<const CommonItemSet> common_item_set) const {
struct ZoneTypes { struct ZoneTypes {
const char* name; const char* name;
@@ -683,7 +684,7 @@ string RareItemSet::serialize_html(
blocks.emplace_back("</tr>"); blocks.emplace_back("</tr>");
}; };
auto add_specs_row = [&](const char* loc_name, bool is_box, const array<vector<ExpandedDrop>, 10>& specs_lists) -> void { auto add_specs_row = [&](const EnemyTypeDefinition* type_def, const char* loc_name, bool is_box, const array<vector<ExpandedDrop>, 10>& specs_lists) -> void {
bool any_list_nonempty = false; bool any_list_nonempty = false;
for (const auto& specs_list : specs_lists) { for (const auto& specs_list : specs_lists) {
any_list_nonempty |= !specs_list.empty(); any_list_nonempty |= !specs_list.empty();
@@ -703,6 +704,13 @@ string RareItemSet::serialize_html(
auto frac = phosg::reduce_fraction<uint64_t>(spec.probability, 0x100000000); auto frac = phosg::reduce_fraction<uint64_t>(spec.probability, 0x100000000);
if (common_item_set && type_def && type_def->rt_index != 0xFF) {
auto table = common_item_set->get_table(episode, mode, difficulty, section_id);
frac.first *= table->enemy_type_drop_probs.at(type_def->rt_index);
frac.second *= 100;
frac = phosg::reduce_fraction<uint64_t>(frac.first, frac.second);
}
ItemData example_item = spec.data; ItemData example_item = spec.data;
if (example_item.can_be_encoded_in_rel_rare_table()) { if (example_item.can_be_encoded_in_rel_rare_table()) {
// Apparently Return to Ragol has a patch that allows it to use the // Apparently Return to Ragol has a patch that allows it to use the
@@ -726,8 +734,8 @@ string RareItemSet::serialize_html(
float denom = static_cast<float>(frac.second) / static_cast<double>(frac.first); float denom = static_cast<float>(frac.second) / static_cast<double>(frac.first);
string denom_token = (floor(denom) == denom) string denom_token = (floor(denom) == denom)
? std::format("1 / {:g}", denom) ? std::format("1 / {:.0f}", denom)
: std::format("1 / %.02f", denom); : std::format("1 / {:.02f}", denom);
tokens.emplace_back(std::format( tokens.emplace_back(std::format(
"<span class=\"rate\" title=\"Exact rate: {} / {}\">{}</span>", "<span class=\"rate\" title=\"Exact rate: {} / {}\">{}</span>",
frac.first, frac.second, denom_token)); frac.first, frac.second, denom_token));
@@ -754,7 +762,7 @@ string RareItemSet::serialize_html(
} }
const auto& type_def = type_definition_for_enemy(type); const auto& type_def = type_definition_for_enemy(type);
const char* name = (difficulty == 3 && type_def.ultimate_name) ? type_def.ultimate_name : type_def.in_game_name; const char* name = (difficulty == 3 && type_def.ultimate_name) ? type_def.ultimate_name : type_def.in_game_name;
add_specs_row(name, false, specs_lists); add_specs_row(&type_def, name, false, specs_lists);
} }
for (uint8_t floor : zone_type.floors) { for (uint8_t floor : zone_type.floors) {
const auto& floor_def = FloorDefinition::get(episode, floor); const auto& floor_def = FloorDefinition::get(episode, floor);
@@ -766,7 +774,7 @@ string RareItemSet::serialize_html(
specs_lists[section_id] = this->get_box_specs(mode, episode, difficulty, section_id, floor_def.drop_area_norm); specs_lists[section_id] = this->get_box_specs(mode, episode, difficulty, section_id, floor_def.drop_area_norm);
} }
auto loc_name = std::format("{} (box)", floor_def.in_game_name); auto loc_name = std::format("{} (box)", floor_def.in_game_name);
add_specs_row(loc_name.c_str(), true, specs_lists); add_specs_row(nullptr, loc_name.c_str(), true, specs_lists);
} }
} }
blocks.emplace_back("</table></div></body></html>"); blocks.emplace_back("</table></div></body></html>");
+3 -1
View File
@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "AFSArchive.hh" #include "AFSArchive.hh"
#include "CommonItemSet.hh"
#include "GSLArchive.hh" #include "GSLArchive.hh"
#include "ItemNameIndex.hh" #include "ItemNameIndex.hh"
#include "StaticGameData.hh" #include "StaticGameData.hh"
@@ -45,7 +46,8 @@ public:
GameMode mode, GameMode mode,
Episode episode, Episode episode,
uint8_t difficulty, uint8_t difficulty,
std::shared_ptr<const ItemNameIndex> name_index = nullptr) const; std::shared_ptr<const ItemNameIndex> name_index = nullptr,
std::shared_ptr<const CommonItemSet> common_item_set = nullptr) const;
phosg::JSON json(std::shared_ptr<const ItemNameIndex> name_index = nullptr) const; phosg::JSON json(std::shared_ptr<const ItemNameIndex> name_index = nullptr) const;
void multiply_all_rates(double factor); void multiply_all_rates(double factor);