handles when units disappear from their assignments compared to the last scan
| 428 | |
| 429 | // handles when units disappear from their assignments compared to the last scan |
| 430 | static void handle_missing_assignments(color_ostream &out, |
| 431 | const unordered_set<int32_t> & active_unit_ids, |
| 432 | ZoneAssignments::iterator *pit, |
| 433 | const ZoneAssignments::iterator & it_end, |
| 434 | bool share_with_spouse, |
| 435 | int32_t next_zone_id) |
| 436 | { |
| 437 | for (auto & it = *pit; it != it_end && (next_zone_id == -1 || it->first <= next_zone_id); ++it) { |
| 438 | int32_t zone_id = it->first; |
| 439 | if (noble_zones.contains(zone_id)) { |
| 440 | // let noble assignment logic handle the noble zones |
| 441 | continue; |
| 442 | } |
| 443 | int32_t hfid = it->second.first; |
| 444 | int32_t spouse_hfid = it->second.second; |
| 445 | auto hf = df::historical_figure::find(hfid); |
| 446 | // if the historical figure was culled, is dead, or was expelled, don't keep a reservation |
| 447 | if (!hf || hf->died_year > -1 || was_expelled(hf)) |
| 448 | continue; |
| 449 | if (auto unit = df::unit::find(hf->unit_id)) { |
| 450 | if (Units::isActive(unit) && !Units::isDead(unit) && active_unit_ids.contains(unit->id)) { |
| 451 | // unit is still alive on the map; assume the unassigment was intentional/expected |
| 452 | continue; |
| 453 | } |
| 454 | } |
| 455 | auto zone = virtual_cast<df::building_civzonest>(df::building::find(zone_id)); |
| 456 | if (!zone) |
| 457 | continue; |
| 458 | // unit is off-map or is dead; if we can assign room to spouse then we don't need to reserve the room |
| 459 | auto spouse_hf = df::historical_figure::find(spouse_hfid); |
| 460 | auto spouse = spouse_hf ? df::unit::find(spouse_hf->unit_id) : nullptr; |
| 461 | if (spouse_hf && share_with_spouse) { |
| 462 | if (spouse && Units::isActive(spouse) && !Units::isDead(spouse) && active_unit_ids.contains(spouse->id)) |
| 463 | { |
| 464 | DEBUG(cycle,out).print("assigning zone {} ({}) to spouse {}\n", |
| 465 | zone_id, ENUM_KEY_STR(civzone_type, zone->type), |
| 466 | DF2CONSOLE(Units::getReadableName(spouse))); |
| 467 | Buildings::setOwner(zone, spouse); |
| 468 | continue; |
| 469 | } |
| 470 | } |
| 471 | if (hf->died_year > -1) |
| 472 | continue; |
| 473 | // register the hf ids for reassignment and reserve the room |
| 474 | DEBUG(cycle,out).print("registering primary unit for reassignment to zone {} ({}): {} {}\n", |
| 475 | zone_id, ENUM_KEY_STR(civzone_type, zone->type), hf->unit_id, |
| 476 | DF2CONSOLE(Units::getReadableName(hf))); |
| 477 | pending_reassignment[hfid].push_back(zone_id); |
| 478 | reserved_zones[zone_id].push_back(hfid); |
| 479 | if (share_with_spouse && spouse) { |
| 480 | DEBUG(cycle,out).print("registering spouse unit for reassignment to zone {} ({}): hfid={}\n", |
| 481 | zone_id, ENUM_KEY_STR(civzone_type, zone->type), spouse_hfid); |
| 482 | pending_reassignment[spouse_hfid].push_back(zone_id); |
| 483 | reserved_zones[zone_id].push_back(spouse_hfid); |
| 484 | } |
| 485 | INFO(cycle,out).print("preserve-rooms: reserving {} for the return of {}{}\n", |
| 486 | toLower_cp437(ENUM_KEY_STR(civzone_type, zone->type)), |
| 487 | DF2CONSOLE(Units::getReadableName(hf)), |
no test coverage detected