From ee96d82f2fc69b62b32b98ab7df21f642d9147a8 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 4 Jan 2023 18:05:06 +0200 Subject: [PATCH 10/10] Check "Tile_Workable" effect after tile changes Make cities to stop working tiles that they no longer can work after terrain or extra change. Reported by ihnatus See osdn #44706 Signed-off-by: Marko Lindqvist --- server/citytools.c | 2 +- server/maphand.c | 24 ++++++++++++++++++++++-- server/maphand.h | 5 ++++- server/srv_main.c | 8 ++++---- server/unittools.c | 5 +++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/server/citytools.c b/server/citytools.c index 4df06b2050..5ce828e143 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -1875,7 +1875,7 @@ void remove_city(struct city *pcity) /* At least sentried helicopters need to go idle, maybe others. * In alien ruleset, city center might have provided water source * for adjacent tile. */ - unit_activities_cancel_all_illegal_area(pcenter); + tile_change_side_effects(pcenter); } /************************************************************************** diff --git a/server/maphand.c b/server/maphand.c index d8702da7e4..34905cfb8d 100644 --- a/server/maphand.c +++ b/server/maphand.c @@ -223,8 +223,7 @@ void climate_change(bool warming, int effect) check_terrain_change(ptile, old); update_tile_knowledge(ptile); - /* Check the unit activities. */ - unit_activities_cancel_all_illegal_area(ptile); + tile_change_side_effects(ptile); } else if (old == new) { /* This counts toward a climate change although nothing is changed. */ @@ -2529,3 +2528,24 @@ void give_distorted_map(struct player *pfrom, struct player *pto, unbuffer_shared_vision(pto); } + +/**********************************************************************//** + Handle various side effects of the change on tile. + If a city was working the tile, that city might need refresh + after this call. + + @param ptile tile that has changed +**************************************************************************/ +void tile_change_side_effects(struct tile *ptile) +{ + struct city *pcity = ptile->worked; + + /* Check the unit activities. */ + unit_activities_cancel_all_illegal_area(ptile); + + if (pcity != NULL && !is_free_worked(pcity, ptile) + && get_city_tile_output_bonus(pcity, ptile, NULL, EFT_TILE_WORKABLE) <= 0) { + city_map_update_empty(pcity, ptile); + pcity->specialists[DEFAULT_SPECIALIST]++; + } +} diff --git a/server/maphand.h b/server/maphand.h index affa680ca7..f151a8d89c 100644 --- a/server/maphand.h +++ b/server/maphand.h @@ -141,4 +141,7 @@ void destroy_extra(struct tile *ptile, struct extra_type *pextra); void give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities); -#endif /* FC__MAPHAND_H */ +void tile_change_side_effects(struct tile *ptile) + fc__attribute((nonnull (1))); + +#endif /* FC__MAPHAND_H */ diff --git a/server/srv_main.c b/server/srv_main.c index d74ab9beba..0fb12a0e56 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -1600,9 +1600,9 @@ static void end_turn(void) tile_link(ptile)); } - /* Unit activities at the target tile and its neighbors may now + /* Activities at the target tile and its neighbors may now * be illegal because of present reqs. */ - unit_activities_cancel_all_illegal_area(ptile); + tile_change_side_effects(ptile); } } whole_map_iterate_end; } extra_type_by_rmcause_iterate_end; @@ -1628,9 +1628,9 @@ static void end_turn(void) tile_link(ptile)); } - /* Unit activities at the target tile and its neighbors may now + /* Activities at the target tile and its neighbors may now * be illegal because of !present reqs. */ - unit_activities_cancel_all_illegal_area(ptile); + tile_change_side_effects(ptile); } } whole_map_iterate_end; } extra_type_by_cause_iterate_end; diff --git a/server/unittools.c b/server/unittools.c index 2a65095cb1..1660439bc2 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1007,13 +1007,14 @@ static void update_unit_activity(struct unit *punit) && punit2->activity_target == act_tgt) { /* This unit was helping with the work just finished. * Mark it idle (already finished) so its "current" - * activity is not considered illegal below. */ + * activity is not considered illegal + * in tile_change_side_effects() . */ set_unit_activity(punit2, ACTIVITY_IDLE); } } unit_list_iterate_end; } - unit_activities_cancel_all_illegal_area(ptile); + tile_change_side_effects(ptile); } if (activity == ACTIVITY_FORTIFYING) { -- 2.39.0