99#include " modules/Units.h"
1010#include " modules/World.h"
1111
12+ #include " df/army.h"
13+ #include " df/army_controller.h"
1214#include " df/building_civzonest.h"
1315#include " df/historical_figure.h"
16+ #include " df/historical_figure_info.h"
1417#include " df/histfig_hf_link.h"
18+ #include " df/state_profilest.h"
1519#include " df/unit.h"
1620#include " df/world.h"
1721
@@ -404,6 +408,15 @@ static void scrub_reservations(color_ostream &out) {
404408 pending_reassignment.erase (hfid);
405409}
406410
411+ static bool was_expelled (df::historical_figure *hf) {
412+ if (!hf || !hf->info || !hf->info ->whereabouts )
413+ return false ;
414+ auto army = df::army::find (hf->info ->whereabouts ->army_id );
415+ if (!army || !army->controller )
416+ return false ;
417+ return army->controller ->goal == df::army_controller_goal_type::MOVE_TO_SITE;
418+ }
419+
407420// handles when units disappear from their assignments compared to the last scan
408421static void handle_missing_assignments (color_ostream &out,
409422 const unordered_set<int32_t > & active_unit_ids,
@@ -421,6 +434,10 @@ static void handle_missing_assignments(color_ostream &out,
421434 int32_t hfid = it->second .first ;
422435 int32_t spouse_hfid = it->second .second ;
423436 auto hf = df::historical_figure::find (hfid);
437+ if (!hf) {
438+ // if the historical figure was culled, bail
439+ continue ;
440+ }
424441 auto unit = df::unit::find (hf->unit_id );
425442 if (!unit) {
426443 // if unit data is completely gone, then they're not likely to come back
@@ -430,8 +447,14 @@ static void handle_missing_assignments(color_ostream &out,
430447 // unit is still alive on the map; assume the unassigment was intentional/expected
431448 continue ;
432449 }
433- if (!Units::isCitizen (unit, true ) && !Units::isResident (unit, true ))
450+ if (!Units::isCitizen (unit, true ) && !Units::isResident (unit, true )) {
451+ // ignore units that are not members of the fort
452+ continue ;
453+ }
454+ if (was_expelled (hf)) {
455+ // ignore expelled units
434456 continue ;
457+ }
435458 auto zone = virtual_cast<df::building_civzonest>(df::building::find (zone_id));
436459 if (!zone)
437460 continue ;
0 commit comments