From 85ad521b88a3c86287ac1ec80cbaf8fe72e5345a Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 19 Dec 2024 03:19:53 -0800 Subject: [PATCH 1/2] don't consider incoming units to be dead --- docs/changelog.txt | 1 + plugins/preserve-rooms.cpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index d0a8099984..baff62e02b 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -56,6 +56,7 @@ Template for new versions: ## New Features ## Fixes +- `preserve-rooms`: don't erroneously release reservations for units that have returned from their missions but have not yet entered the fort map ## Misc Improvements diff --git a/plugins/preserve-rooms.cpp b/plugins/preserve-rooms.cpp index d4519402bb..e8cb616362 100644 --- a/plugins/preserve-rooms.cpp +++ b/plugins/preserve-rooms.cpp @@ -394,8 +394,16 @@ static void scrub_reservations(color_ostream &out) { vector hfids_to_scrub; for (auto &[hfid, zone_ids] : pending_reassignment) { auto hf = df::historical_figure::find(hfid); - if (hf && hf->died_year == -1 && hf->info && hf->info->whereabouts && hf->info->whereabouts->army_id > -1) - continue; + if (hf) { + // don't scrub alive units that are still in traveling armies + if (hf->died_year == -1 && hf->info && hf->info->whereabouts && hf->info->whereabouts->army_id > -1) + continue; + // don't scrub units that have returned but are not yet active + if (auto unit = df::unit::find(hf->unit_id)) { + if (unit->flags1.bits.incoming) + continue; + } + } DEBUG(cycle,out).print("removed reservation for dead, culled, or non-army hfid %d: %s\n", hfid, hf ? DF2CONSOLE(Units::getReadableName(hf)).c_str() : "culled"); hfids_to_scrub.push_back(hfid); From 4126a80abe1410569cf0273778aa3797c3313738 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Thu, 19 Dec 2024 03:42:51 -0800 Subject: [PATCH 2/2] don't depend on unit structure after unit leaves the map can be culled by saving also remove check for citizenship/residency since I believe that case is now handled by the was_expelled check --- docs/changelog.txt | 1 + plugins/preserve-rooms.cpp | 34 +++++++++++----------------------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index baff62e02b..caf9bec8ee 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -57,6 +57,7 @@ Template for new versions: ## Fixes - `preserve-rooms`: don't erroneously release reservations for units that have returned from their missions but have not yet entered the fort map +- `preserve-rooms`: handle case where unit records are culled by DF immediately after a unit leaves the map ## Misc Improvements diff --git a/plugins/preserve-rooms.cpp b/plugins/preserve-rooms.cpp index e8cb616362..a22f8fcfeb 100644 --- a/plugins/preserve-rooms.cpp +++ b/plugins/preserve-rooms.cpp @@ -444,26 +444,14 @@ static void handle_missing_assignments(color_ostream &out, int32_t hfid = it->second.first; int32_t spouse_hfid = it->second.second; auto hf = df::historical_figure::find(hfid); - if (!hf) { - // if the historical figure was culled, bail - continue; - } - auto unit = df::unit::find(hf->unit_id); - if (!unit) { - // if unit data is completely gone, then they're not likely to come back - continue; - } - if (Units::isActive(unit) && !Units::isDead(unit) && active_unit_ids.contains(unit->id)) { - // unit is still alive on the map; assume the unassigment was intentional/expected - continue; - } - if (!Units::isCitizen(unit, true) && !Units::isResident(unit, true)) { - // ignore units that are not members of the fort - continue; - } - if (was_expelled(hf)) { - // ignore expelled units + // if the historical figure was culled, is dead, or was expelled, don't keep a reservation + if (!hf || hf->died_year > -1 || was_expelled(hf)) continue; + if (auto unit = df::unit::find(hf->unit_id)) { + if (Units::isActive(unit) && !Units::isDead(unit) && active_unit_ids.contains(unit->id)) { + // unit is still alive on the map; assume the unassigment was intentional/expected + continue; + } } auto zone = virtual_cast(df::building::find(zone_id)); if (!zone) @@ -481,12 +469,12 @@ static void handle_missing_assignments(color_ostream &out, continue; } } - if (Units::isDead(unit)) + if (hf->died_year > -1) continue; // register the hf ids for reassignment and reserve the room DEBUG(cycle,out).print("registering primary unit for reassignment to zone %d (%s): %d %s\n", - zone_id, ENUM_KEY_STR(civzone_type, zone->type).c_str(), unit->id, - DF2CONSOLE(Units::getReadableName(unit)).c_str()); + zone_id, ENUM_KEY_STR(civzone_type, zone->type).c_str(), hf->unit_id, + DF2CONSOLE(Units::getReadableName(hf)).c_str()); pending_reassignment[hfid].push_back(zone_id); reserved_zones[zone_id].push_back(hfid); if (share_with_spouse && spouse) { @@ -497,7 +485,7 @@ static void handle_missing_assignments(color_ostream &out, } INFO(cycle,out).print("preserve-rooms: reserving %s for the return of %s%s%s\n", toLower_cp437(ENUM_KEY_STR(civzone_type, zone->type)).c_str(), - DF2CONSOLE(Units::getReadableName(unit)).c_str(), + DF2CONSOLE(Units::getReadableName(hf)).c_str(), spouse_hf ? " or their spouse, " : "", spouse_hf ? DF2CONSOLE(Units::getReadableName(spouse_hf)).c_str() : "");