handle duplicate set event IDs properly

This commit is contained in:
Martin Michelsen
2024-03-30 13:38:17 -07:00
parent 9630b06284
commit 33483bbfbf
3 changed files with 22 additions and 16 deletions
+14 -8
View File
@@ -1480,23 +1480,29 @@ void Map::add_event(uint32_t event_id, uint16_t flags, uint8_t floor, uint16_t s
ev.flags = flags; ev.flags = flags;
ev.floor = floor; ev.floor = floor;
ev.action_stream_offset = action_stream_offset; ev.action_stream_offset = action_stream_offset;
uint64_t k = (static_cast<uint64_t>(floor) << 32) | event_id;
if (!this->floor_and_event_id_to_index.emplace(k, index).second) {
this->log.warning("Duplicate event ID: W-%02hhX-%" PRIX32, floor, event_id);
}
uint64_t k = (static_cast<uint64_t>(floor) << 32) | event_id;
this->floor_and_event_id_to_index.emplace(k, index);
k = section_index_key(floor, section, wave_number); k = section_index_key(floor, section, wave_number);
this->floor_section_and_wave_number_to_event_index.emplace(k, index); this->floor_section_and_wave_number_to_event_index.emplace(k, index);
} }
Map::Event& Map::get_event(uint8_t floor, uint32_t event_id) { vector<Map::Event*> Map::get_events(uint8_t floor, uint32_t event_id) {
uint64_t k = (static_cast<uint64_t>(floor) << 32) | event_id; uint64_t k = (static_cast<uint64_t>(floor) << 32) | event_id;
return this->events.at(this->floor_and_event_id_to_index.at(k)); vector<Event*> ret;
for (auto its = this->floor_and_event_id_to_index.equal_range(k); its.first != its.second; its.first++) {
ret.emplace_back(&this->events.at(its.first->second));
}
return ret;
} }
const Map::Event& Map::get_event(uint8_t floor, uint32_t event_id) const { vector<const Map::Event*> Map::get_events(uint8_t floor, uint32_t event_id) const {
uint64_t k = (static_cast<uint64_t>(floor) << 32) | event_id; uint64_t k = (static_cast<uint64_t>(floor) << 32) | event_id;
return this->events.at(this->floor_and_event_id_to_index.at(k)); vector<const Event*> ret;
for (auto its = this->floor_and_event_id_to_index.equal_range(k); its.first != its.second; its.first++) {
ret.emplace_back(&this->events.at(its.first->second));
}
return ret;
} }
void Map::add_events_from_map_data(uint8_t floor, const void* data, size_t size) { void Map::add_events_from_map_data(uint8_t floor, const void* data, size_t size) {
+3 -3
View File
@@ -330,8 +330,8 @@ struct Map {
uint16_t section, uint16_t section,
uint16_t wave_number, uint16_t wave_number,
uint32_t action_stream_offset); uint32_t action_stream_offset);
Event& get_event(uint8_t floor, uint32_t event_id); std::vector<Event*> get_events(uint8_t floor, uint32_t event_id);
const Event& get_event(uint8_t floor, uint32_t event_id) const; std::vector<const Event*> get_events(uint8_t floor, uint32_t event_id) const;
void add_events_from_map_data(uint8_t floor, const void* data, size_t size); void add_events_from_map_data(uint8_t floor, const void* data, size_t size);
struct DATSectionsForFloor { struct DATSectionsForFloor {
@@ -373,7 +373,7 @@ struct Map {
std::vector<size_t> rare_enemy_indexes; std::vector<size_t> rare_enemy_indexes;
std::vector<Event> events; std::vector<Event> events;
std::string event_action_stream; std::string event_action_stream;
std::map<uint64_t, size_t> floor_and_event_id_to_index; std::multimap<uint64_t, size_t> floor_and_event_id_to_index;
std::unordered_multimap<uint64_t, size_t> floor_section_and_group_to_object_index; std::unordered_multimap<uint64_t, size_t> floor_section_and_group_to_object_index;
std::unordered_multimap<uint64_t, size_t> floor_section_and_wave_number_to_enemy_index; std::unordered_multimap<uint64_t, size_t> floor_section_and_wave_number_to_enemy_index;
std::unordered_multimap<uint64_t, size_t> floor_section_and_wave_number_to_event_index; std::unordered_multimap<uint64_t, size_t> floor_section_and_wave_number_to_event_index;
+5 -5
View File
@@ -2924,12 +2924,12 @@ static void on_trigger_set_event(shared_ptr<Client> c, uint8_t command, uint8_t
const auto& cmd = check_size_t<G_TriggerSetEvent_6x67>(data, size); const auto& cmd = check_size_t<G_TriggerSetEvent_6x67>(data, size);
if (l->map) { if (l->map) {
try { auto events = l->map->get_events(cmd.floor, cmd.event_id);
l->map->get_event(cmd.floor, cmd.event_id).flags |= 0x04; for (auto* event : events) {
l->log.info("Client triggered set event W-%02" PRIX32 "-%" PRIX32, cmd.floor.load(), cmd.event_id.load()); event->flags |= 0x04;
} catch (const out_of_range&) {
l->log.warning("Client triggered missing set event W-%02" PRIX32 "-%" PRIX32, cmd.floor.load(), cmd.event_id.load());
} }
l->log.info("Client triggered set event W-%02" PRIX32 "-%" PRIX32 " (%zu events)",
cmd.floor.load(), cmd.event_id.load(), events.size());
} }
forward_subcommand(c, command, flag, data, size); forward_subcommand(c, command, flag, data, size);