From 86545557771080ed1df8cb2ae47012864d18310e Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 8 Dec 2023 18:08:47 -0800 Subject: [PATCH] recreate map on challenge mode restart --- TODO.md | 1 + src/Map.cc | 11 +---------- src/ReceiveCommands.cc | 19 ++++++++++++++++++- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/TODO.md b/TODO.md index 499067fb..46a802e4 100644 --- a/TODO.md +++ b/TODO.md @@ -26,3 +26,4 @@ - Test all quest item subcommands - Check if Commander Blade effect works and implement it if not - Figure out which quest flags are required for solo quests and write appropriate JSON files +- Figure out why Pouilly Slime EXP doesn't work diff --git a/src/Map.cc b/src/Map.cc index 9ef100ac..c646bbdf 100644 --- a/src/Map.cc +++ b/src/Map.cc @@ -730,11 +730,9 @@ void Map::add_random_enemies_from_map_data( for (size_t wave_entry_index = 0; wave_entry_index < wave_events_header.entry_count; wave_entry_index++) { auto entry_log = static_game_data_log.sub(string_printf("(Entry %zu/%" PRIu32 ") ", wave_entry_index, wave_events_header.entry_count.load())); - entry_log.info("Start"); const auto& entry = wave_events_segment_r.get(); size_t remaining_waves = random_state->rand_int_biased(1, entry.max_waves); - entry_log.info("Chose %zu waves (max=%hu)", remaining_waves, entry.max_waves.load()); // Trace: at 0080E125 EAX is wave count uint32_t wave_number = entry.wave_number; @@ -743,14 +741,9 @@ void Map::add_random_enemies_from_map_data( auto wave_log = entry_log.sub(string_printf("(Wave %zu) ", remaining_waves)); size_t remaining_enemies = random_state->rand_int_biased(entry.min_enemies, entry.max_enemies); - wave_log.info("Chose %zu enemies (range=[%hhu, %hhu])", remaining_enemies, entry.min_enemies, entry.max_enemies); // Trace: at 0080E208 EDI is enemy count random_state->generate_shuffled_location_table(locations_header, locations_segment_r, entry.section); - wave_log.info("Generated shuffled location table"); - for (size_t z = 0; z < random_state->location_indexes_populated; z++) { - wave_log.info(" table[%zX] = %" PRIX32, z, random_state->location_index_table[z]); - } // Trace: at 0080EBB0 *(EBP + 4) points to table (0x20 uint32_ts) while (remaining_enemies) { @@ -766,7 +759,6 @@ void Map::add_random_enemies_from_map_data( // Trace: at 0080E2C2 EBX is weight_total size_t det = random_state->rand_int_biased(0, weight_total - 1); - enemy_log.info("weight_total=%zX, det=%zX", weight_total, det); // Trace: at 0080E300 EDX is det weights_r.go(0); @@ -817,11 +809,10 @@ void Map::add_random_enemies_from_map_data( e.y_angle = loc.y_angle; e.z_angle = loc.z_angle; - enemy_log.info("Creating enemy with base_type %04hX fparam2 %g uparam1 %04hX", e.base_type.load(), e.fparam2.load(), e.uparam1.load()); // Trace: at 0080E6FE CX is base_type this->add_enemy(episode, difficulty, event, floor, 0, e, rare_rates); } else { - enemy_log.info("Cannot create enemy: parameters are missing"); + enemy_log.warning("Cannot create enemy: parameters are missing"); } break; } else { diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 3d9d5ef1..691304da 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -3450,9 +3450,15 @@ static void on_DF_BB(shared_ptr c, uint16_t command, uint32_t, string& d if (!l->quest) { throw runtime_error("challenge mode character template config command sent in non-challenge game"); } - if (l->quest->challenge_template_index != static_cast(cmd.template_index)) { + auto vq = l->quest->version(Version::BB_V4, c->language()); + if (vq->challenge_template_index != static_cast(cmd.template_index)) { throw runtime_error("challenge template index in quest metadata does not match index sent by client"); } + + if (l->item_creator) { + l->item_creator->clear_destroyed_entities(); + } + for (auto lc : l->clients) { if (lc) { lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table); @@ -3460,6 +3466,17 @@ static void on_DF_BB(shared_ptr c, uint16_t command, uint32_t, string& d l->assign_inventory_and_bank_item_ids(lc); } } + + auto dat_contents = prs_decompress(*vq->dat_contents); + l->map->clear(); + l->map->add_enemies_and_objects_from_quest_data( + l->episode, + l->difficulty, + l->event, + dat_contents.data(), + dat_contents.size(), + l->random_seed, + l->rare_enemy_rates ? l->rare_enemy_rates : Map::NO_RARE_ENEMIES); break; }