clean up random enemy generation

This commit is contained in:
Martin Michelsen
2023-11-12 12:19:37 -08:00
parent 53451c2d45
commit afba337575
+16 -16
View File
@@ -421,16 +421,16 @@ void Map::add_enemies_from_map_data(
} }
struct DATParserRandomState { struct DATParserRandomState {
PSOV2Encryption global_random_crypt; PSOV2Encryption random;
PSOV2Encryption local_random_crypt; PSOV2Encryption location_table_random;
std::array<uint32_t, 0x20> location_index_table; std::array<uint32_t, 0x20> location_index_table;
uint32_t location_indexes_populated; uint32_t location_indexes_populated;
uint32_t location_indexes_used; uint32_t location_indexes_used;
uint32_t location_entries_base_offset; uint32_t location_entries_base_offset;
DATParserRandomState(uint32_t rare_seed) DATParserRandomState(uint32_t rare_seed)
: global_random_crypt(rare_seed), : random(rare_seed),
local_random_crypt(0), location_table_random(0),
location_indexes_populated(0), location_indexes_populated(0),
location_indexes_used(0), location_indexes_used(0),
location_entries_base_offset(0) { location_entries_base_offset(0) {
@@ -439,7 +439,7 @@ struct DATParserRandomState {
size_t rand_int_biased(size_t min_v, size_t max_v) { size_t rand_int_biased(size_t min_v, size_t max_v) {
float max_f = static_cast<float>(max_v + 1); float max_f = static_cast<float>(max_v + 1);
uint32_t crypt_v = this->global_random_crypt.next(); uint32_t crypt_v = this->random.next();
fprintf(stderr, "(global) => %08" PRIX32 "\n", crypt_v); fprintf(stderr, "(global) => %08" PRIX32 "\n", crypt_v);
float det_f = static_cast<float>(crypt_v); float det_f = static_cast<float>(crypt_v);
return max<size_t>(floorf((max_f * det_f) / UINT32_MAX_AS_FLOAT), min_v); return max<size_t>(floorf((max_f * det_f) / UINT32_MAX_AS_FLOAT), min_v);
@@ -484,7 +484,7 @@ struct DATParserRandomState {
for (size_t z = 0; z < 4; z++) { for (size_t z = 0; z < 4; z++) {
for (size_t x = 0; x < sec.count; x++) { for (size_t x = 0; x < sec.count; x++) {
uint32_t crypt_v = this->local_random_crypt.next(); uint32_t crypt_v = this->location_table_random.next();
fprintf(stderr, "(local?) => %08" PRIX32 "\n", crypt_v); fprintf(stderr, "(local?) => %08" PRIX32 "\n", crypt_v);
size_t choice = floorf((static_cast<float>(sec.count) * static_cast<float>(crypt_v)) / UINT32_MAX_AS_FLOAT); size_t choice = floorf((static_cast<float>(sec.count) * static_cast<float>(crypt_v)) / UINT32_MAX_AS_FLOAT);
uint32_t t = this->location_index_table[x]; uint32_t t = this->location_index_table[x];
@@ -535,7 +535,7 @@ void Map::add_random_enemies_from_map_data(
size_t remaining_waves = random.rand_int_biased(1, entry.max_waves); size_t remaining_waves = random.rand_int_biased(1, entry.max_waves);
entry_log.info("Chose %zu waves (max=%hu)", remaining_waves, entry.max_waves.load()); entry_log.info("Chose %zu waves (max=%hu)", remaining_waves, entry.max_waves.load());
// BP 0080E125 EAX is wave count // Trace: at 0080E125 EAX is wave count
uint32_t wave_number = entry.wave_number; uint32_t wave_number = entry.wave_number;
while (remaining_waves) { while (remaining_waves) {
@@ -544,14 +544,14 @@ void Map::add_random_enemies_from_map_data(
size_t remaining_enemies = random.rand_int_biased(entry.min_enemies, entry.max_enemies); size_t remaining_enemies = random.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); wave_log.info("Chose %zu enemies (range=[%hhu, %hhu])", remaining_enemies, entry.min_enemies, entry.max_enemies);
// BP 0080E208 EDI is enemy count // Trace: at 0080E208 EDI is enemy count
random.generate_shuffled_location_table(locations_header, locations_segment_r, entry.section); random.generate_shuffled_location_table(locations_header, locations_segment_r, entry.section);
wave_log.info("Generated shuffled location table"); wave_log.info("Generated shuffled location table");
for (size_t z = 0; z < random.location_indexes_populated; z++) { for (size_t z = 0; z < random.location_indexes_populated; z++) {
wave_log.info(" table[%zX] = %" PRIX32, z, random.location_index_table[z]); wave_log.info(" table[%zX] = %" PRIX32, z, random.location_index_table[z]);
} }
// BP 0080EBB0 *(EBP + 4) points to table (0x20 uint32_ts) // Trace: at 0080EBB0 *(EBP + 4) points to table (0x20 uint32_ts)
while (remaining_enemies) { while (remaining_enemies) {
remaining_enemies--; remaining_enemies--;
@@ -563,11 +563,11 @@ void Map::add_random_enemies_from_map_data(
while (!weights_r.eof()) { while (!weights_r.eof()) {
weight_total += weights_r.get<RandomEnemyWeight>().weight; weight_total += weights_r.get<RandomEnemyWeight>().weight;
} }
// BP 0080E2C2 EBX is weight_total // Trace: at 0080E2C2 EBX is weight_total
size_t det = random.rand_int_biased(0, weight_total - 1); size_t det = random.rand_int_biased(0, weight_total - 1);
enemy_log.info("weight_total=%zX, det=%zX", weight_total, det); enemy_log.info("weight_total=%zX, det=%zX", weight_total, det);
// BP 0080E300 EDX is det // Trace: at 0080E300 EDX is det
weights_r.go(0); weights_r.go(0);
while (!weights_r.eof()) { while (!weights_r.eof()) {
@@ -617,7 +617,7 @@ void Map::add_random_enemies_from_map_data(
e.z_angle = loc.z_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()); enemy_log.info("Creating enemy with base_type %04hX fparam2 %g uparam1 %04hX", e.base_type.load(), e.fparam2.load(), e.uparam1.load());
// BP 0080E6FE CX is base_type // Trace: at 0080E6FE CX is base_type
this->add_enemy(episode, difficulty, event, 0, e, rare_rates); this->add_enemy(episode, difficulty, event, 0, e, rare_rates);
} else { } else {
enemy_log.info("Cannot create enemy: parameters are missing"); enemy_log.info("Cannot create enemy: parameters are missing");
@@ -630,16 +630,16 @@ void Map::add_random_enemies_from_map_data(
} }
if (remaining_waves) { if (remaining_waves) {
// We don't generate the event stream here, but the client does, and in // We don't generate the event stream here, but the client does, and in
// doing so, it uses one value from global_random_crypt to determine the // doing so, it uses one value from random to determine the delay
// delay parameter of the event. To keep our state in sync with what the // parameter of the event. To keep our state in sync with what the
// client would do, we skip a random value here. // client would do, we skip a random value here.
random.global_random_crypt.next(); random.random.next();
wave_number++; wave_number++;
} }
} }
// For the same reason as above, we need to skip another random value here. // For the same reason as above, we need to skip another random value here.
random.global_random_crypt.next(); random.random.next();
} }
} }