fixed crash on tomb unassignment (caused by incorrect params passed to formatted string)

develop
Najeeb Al-Shabibi 2023-09-29 13:11:13 +01:00
parent 986e64aed0
commit 2a145d06b6
1 changed files with 13 additions and 9 deletions

@ -70,6 +70,7 @@ static void update_tomb_assignments(color_ostream& out);
void onUnitDeath(color_ostream& out, void* ptr); void onUnitDeath(color_ostream& out, void* ptr);
DFhackCExport command_result plugin_init(color_ostream &out, std::vector <PluginCommand> &commands) { DFhackCExport command_result plugin_init(color_ostream &out, std::vector <PluginCommand> &commands) {
tomb_assignments.clear();
return CR_OK; return CR_OK;
} }
@ -77,6 +78,7 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector <Plugin
EventManager::EventHandler assign_tomb_handler(onUnitDeath, 0); EventManager::EventHandler assign_tomb_handler(onUnitDeath, 0);
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) { DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) {
tomb_assignments.clear();
if (!Core::getInstance().isWorldLoaded()) { if (!Core::getInstance().isWorldLoaded()) {
out.printerr("Cannot enable %s without a loaded world.\n", plugin_name); out.printerr("Cannot enable %s without a loaded world.\n", plugin_name);
return CR_FAILURE; return CR_FAILURE;
@ -126,6 +128,7 @@ DFhackCExport command_result plugin_load_data (color_ostream &out) {
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) { DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) {
if (event == DFHack::SC_WORLD_UNLOADED) { if (event == DFHack::SC_WORLD_UNLOADED) {
tomb_assignments.clear();
if (is_enabled) { if (is_enabled) {
DEBUG(config,out).print("world unloaded; disabling %s\n", DEBUG(config,out).print("world unloaded; disabling %s\n",
plugin_name); plugin_name);
@ -197,26 +200,27 @@ static void update_tomb_assignments(color_ostream &out) {
} }
// now check our civzones for unassignment / deleted zone / // now check our civzones for unassignment / deleted zone /
std::erase_if(tomb_assignments, [&](const std::pair<int32_t, int32_t>& pair){ for (auto it = tomb_assignments.begin(); it != tomb_assignments.end(); ++it){
const auto &[unit_id, building_id] = pair; auto &[unit_id, building_id] = *it;
const size_t tomb_idx = binsearch_index(world->buildings.other.ZONE_TOMB, building_id); const size_t tomb_idx = binsearch_index(world->buildings.other.ZONE_TOMB, building_id);
if (tomb_idx == -1) { if (tomb_idx == -1) {
out.print("%s tomb missing: %d - removing\n", plugin_name, building_id); out.print("%s tomb missing: %d - removing\n", plugin_name, building_id);
return true; it = tomb_assignments.erase(it);
continue;
} }
const auto tomb = virtual_cast<df::building_civzonest>(world->buildings.other.ZONE_TOMB[tomb_idx]); const auto tomb = virtual_cast<df::building_civzonest>(world->buildings.other.ZONE_TOMB[tomb_idx]);
if (!tomb || !tomb->flags.bits.exists) { if (!tomb || !tomb->flags.bits.exists) {
out.print("%s tomb missing: %d - removing\n", plugin_name, building_id); out.print("%s tomb missing: %d - removing\n", plugin_name, building_id);
return true; it = tomb_assignments.erase(it);
continue;
} }
if (tomb->assigned_unit_id != unit_id) { if (tomb->assigned_unit_id != unit_id) {
out.print("%s unassigned unit %d from tomb %d - removing\n", unit_id, building_id); out.print("%s unassigned unit %d from tomb %d - removing\n", plugin_name, unit_id, building_id);
return true; it = tomb_assignments.erase(it);
continue;
} }
}
return false;
});
} }