From 6bb99fe37272d3ac1de55fccbd5f8165ac37454a Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Thu, 14 Apr 2022 18:50:53 +0300 Subject: [PATCH 20/20] 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 f5cd9d36cf..e2e57d3472 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -1583,7 +1583,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). */ @@ -1841,12 +1841,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 6e21368c95..08f860f345 100644 --- a/server/maphand.c +++ b/server/maphand.c @@ -209,7 +209,7 @@ void climate_change(bool warming, int effect) if (punit->activity == ACTIVITY_IRRIGATE || punit->activity == ACTIVITY_MINE || 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 d27239ecbe..0e16b5b440 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -1586,9 +1586,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(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; @@ -1617,9 +1617,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(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 eaaa1a293c..8991044032 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 2586ed3d9b..34ae97e10a 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -3136,13 +3136,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); - city_refresh(new_pcity); send_city_info(new_owner, new_pcity); diff --git a/server/unittools.c b/server/unittools.c index d4adc7541b..26e729a264 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -771,23 +771,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; } @@ -967,17 +987,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); } for (i = 0; tile_changing_actions[i] != ACTIVITY_LAST; i++) { @@ -986,7 +1000,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(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 594f95e8ca..1161847c2e 100644 --- a/server/unittools.h +++ b/server/unittools.h @@ -166,7 +166,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