Skip to content

Commit

Permalink
Merge pull request #5108 from myk002/myk_preserve_incoming
Browse files Browse the repository at this point in the history
[preserve-rooms] fix handling of incoming and offloaded units
  • Loading branch information
myk002 authored Dec 19, 2024
2 parents 6abab0a + 4126a80 commit 00c0bf2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 25 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ 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
- `preserve-rooms`: handle case where unit records are culled by DF immediately after a unit leaves the map

## Misc Improvements

Expand Down
46 changes: 21 additions & 25 deletions plugins/preserve-rooms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,16 @@ static void scrub_reservations(color_ostream &out) {
vector<int32_t> 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);
Expand Down Expand Up @@ -436,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_civzonest>(df::building::find(zone_id));
if (!zone)
Expand All @@ -473,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) {
Expand All @@ -489,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() : "");

Expand Down

0 comments on commit 00c0bf2

Please sign in to comment.