From 8328c182c512c8653ae2ac7db7345dc83f7fe1dd Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Thu, 14 Apr 2022 18:38:47 +0300 Subject: [PATCH 46/46] Cancel also unit orders when the activity has turned illegal Unify (i.e. call shared functions) handling of cases where unit activity has turned illegal. The main behavior difference this makes is that now all orders (which the activity was part of) are cancelled in all the situations where the current activity might get cancelled. Previously most callers did not do that. See osdn #44370 Signed-off-by: Marko Lindqvist --- server/citytools.c | 10 +++----- server/maphand.c | 9 +++---- server/srv_main.c | 8 +++---- server/techtools.c | 10 +------- server/unithand.c | 11 +++++---- server/unittools.c | 60 ++++++++++++++++++++++++++++------------------ server/unittools.h | 4 +++- 7 files changed, 57 insertions(+), 55 deletions(-) diff --git a/server/citytools.c b/server/citytools.c index ada6227b22..d0ec2b29af 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -1613,7 +1613,7 @@ void create_city(struct player *pplayer, struct tile *ptile, /* Catch fortress building, transforming into ocean, etc. */ if (!can_unit_continue_current_activity(punit)) { - unit_activity_handling(punit, ACTIVITY_IDLE); + unit_activities_cancel(punit); } /* Update happiness (the unit may no longer cause unrest). */ @@ -1884,12 +1884,8 @@ void remove_city(struct city *pcity) sync_cities(); - unit_list_iterate(pcenter->units, punit) { - /* At least sentried helicopters need to go idle, maybe others. */ - if (!can_unit_continue_current_activity(punit)) { - unit_activity_handling(punit, ACTIVITY_IDLE); - } - } unit_list_iterate_end; + /* At least sentried helicopters need to go idle, maybe others. */ + unit_activities_cancel_all_illegal_tile(pcenter); } /************************************************************************//** diff --git a/server/maphand.c b/server/maphand.c index 7ef9dc4b65..7f24c474ab 100644 --- a/server/maphand.c +++ b/server/maphand.c @@ -209,7 +209,7 @@ void climate_change(bool warming, int effect) if (punit->activity == ACTIVITY_CULTIVATE || punit->activity == ACTIVITY_PLANT || punit->activity == ACTIVITY_TRANSFORM) { - unit_activity_handling(punit, ACTIVITY_IDLE); + unit_activities_cancel(punit); } } } unit_list_iterate_end; @@ -220,11 +220,8 @@ void climate_change(bool warming, int effect) update_tile_knowledge(ptile); /* Check the unit activities. */ - unit_list_iterate(ptile->units, punit) { - if (!can_unit_continue_current_activity(punit)) { - unit_activity_handling(punit, ACTIVITY_IDLE); - } - } unit_list_iterate_end; + unit_activities_cancel_all_illegal_tile(ptile); + } else if (old == new) { /* This counts toward a climate change although nothing is changed. */ effect--; diff --git a/server/srv_main.c b/server/srv_main.c index 8eb0fcfcb2..806ebc793b 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -1652,9 +1652,9 @@ static void end_turn(void) /* Unit activities at the target tile and its neighbors may now * be illegal because of present reqs. */ - unit_activities_cancel_all_illegal(ptile); + unit_activities_cancel_all_illegal_tile(ptile); adjc_iterate(&(wld.map), ptile, n_tile) { - unit_activities_cancel_all_illegal(n_tile); + unit_activities_cancel_all_illegal_tile(n_tile); } adjc_iterate_end; } } whole_map_iterate_end; @@ -1683,9 +1683,9 @@ static void end_turn(void) /* Unit activities at the target tile and its neighbors may now * be illegal because of !present reqs. */ - unit_activities_cancel_all_illegal(ptile); + unit_activities_cancel_all_illegal_tile(ptile); adjc_iterate(&(wld.map), ptile, n_tile) { - unit_activities_cancel_all_illegal(n_tile); + unit_activities_cancel_all_illegal_tile(n_tile); } adjc_iterate_end; } } whole_map_iterate_end; diff --git a/server/techtools.c b/server/techtools.c index 76384f376d..a2680cd856 100644 --- a/server/techtools.c +++ b/server/techtools.c @@ -838,15 +838,7 @@ static void research_tech_lost(struct research *presearch, Tech_type_id tech) } /* Check all units for valid activities. */ - unit_list_iterate(pplayer->units, punit) { - if (!can_unit_continue_current_activity(punit)) { - log_debug("lost technology for activity of unit %s of %s (%d, %d)", - unit_name_translation(punit), player_name(pplayer), - TILE_XY(unit_tile(punit))); - set_unit_activity(punit, ACTIVITY_IDLE); - send_unit_info(NULL, punit); - } - } unit_list_iterate_end; + unit_activities_cancel_all_illegal_plr(pplayer); /* Check city production */ city_list_iterate(pplayer->cities, pcity) { diff --git a/server/unithand.c b/server/unithand.c index 90ac93e0de..8afd40a564 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -3933,13 +3933,14 @@ void unit_change_homecity_handling(struct unit *punit, struct city *new_pcity, if (!can_unit_continue_current_activity(punit)) { /* This is mainly for cases where unit owner changes to one not knowing - * Railroad tech when unit is already building railroad. */ - set_unit_activity(punit, ACTIVITY_IDLE); + * Railroad tech when unit is already building railroad. + * Does also send_unit_info() */ + unit_activities_cancel(punit); + } else { + /* Send info to players and observers. */ + send_unit_info(NULL, punit); } - /* Send info to players and observers. */ - send_unit_info(NULL, punit); - if (new_pcity != NULL) { city_refresh(new_pcity); send_city_info(new_owner, new_pcity); diff --git a/server/unittools.c b/server/unittools.c index 26380e24bd..1ecd7d591e 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -797,23 +797,43 @@ static void unit_convert(struct unit *punit) } /**********************************************************************//** - Cancel all illegal activities done by units at the specified tile. + Cancel activities, and orders that it might be part of. **************************************************************************/ -void unit_activities_cancel_all_illegal(const struct tile *ptile) +void unit_activities_cancel(struct unit *punit) { - unit_list_iterate(ptile->units, punit2) { - if (!can_unit_continue_current_activity(punit2)) { - if (unit_has_orders(punit2)) { - notify_player(unit_owner(punit2), unit_tile(punit2), - E_UNIT_ORDERS, ftc_server, - _("Orders for %s aborted because activity " - "is no longer available."), - unit_link(punit2)); - free_unit_orders(punit2); - } + if (unit_has_orders(punit)) { + notify_player(unit_owner(punit), unit_tile(punit), + E_UNIT_ORDERS, ftc_server, + _("Orders for %s aborted because activity " + "is no longer available."), + unit_link(punit)); + free_unit_orders(punit); + } - set_unit_activity(punit2, ACTIVITY_IDLE); - send_unit_info(NULL, punit2); + set_unit_activity(punit, ACTIVITY_IDLE); + send_unit_info(NULL, punit); +} + +/**********************************************************************//** + Cancel all illegal activities done by units of the specified owner. +**************************************************************************/ +void unit_activities_cancel_all_illegal_plr(const struct player *pplayer) +{ + unit_list_iterate(pplayer->units, punit) { + if (!can_unit_continue_current_activity(punit)) { + unit_activities_cancel(punit); + } + } unit_list_iterate_end; +} + +/**********************************************************************//** + Cancel all illegal activities done by units at the specified tile. +**************************************************************************/ +void unit_activities_cancel_all_illegal_tile(const struct tile *ptile) +{ + unit_list_iterate(ptile->units, punit) { + if (!can_unit_continue_current_activity(punit)) { + unit_activities_cancel(punit); } } unit_list_iterate_end; } @@ -990,17 +1010,11 @@ static void update_unit_activity(struct unit *punit) * used for extras. */ unit_list_iterate(ptile->units, punit2) { if (punit2->activity == activity) { - set_unit_activity(punit2, ACTIVITY_IDLE); - send_unit_info(NULL, punit2); + unit_activities_cancel(punit2); } } unit_list_iterate_end; } else { - unit_list_iterate(ptile->units, punit2) { - if (!can_unit_continue_current_activity(punit2)) { - set_unit_activity(punit2, ACTIVITY_IDLE); - send_unit_info(NULL, punit2); - } - } unit_list_iterate_end; + unit_activities_cancel_all_illegal_tile(ptile); } tile_changing_activities_iterate(act) { @@ -1009,7 +1023,7 @@ static void update_unit_activity(struct unit *punit) * such as building irrigation if we removed the only source * of water from them. */ adjc_iterate(&(wld.map), ptile, ptile2) { - unit_activities_cancel_all_illegal(ptile2); + unit_activities_cancel_all_illegal_tile(ptile2); } adjc_iterate_end; break; } diff --git a/server/unittools.h b/server/unittools.h index 7d0d596b94..b981de90b5 100644 --- a/server/unittools.h +++ b/server/unittools.h @@ -174,7 +174,9 @@ void unit_did_action(struct unit *punit); bool unit_can_be_retired(struct unit *punit); -void unit_activities_cancel_all_illegal(const struct tile *ptile); +void unit_activities_cancel(struct unit *punit); +void unit_activities_cancel_all_illegal_plr(const struct player *pplayer); +void unit_activities_cancel_all_illegal_tile(const struct tile *ptile); void unit_get_goods(struct unit *punit); -- 2.35.1