From 52546bfa204ce01f959c6928d1680e28a8694285 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 4 Jan 2023 18:02:03 +0200 Subject: [PATCH 27/27] 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 6b5e1ca217..e092e86a7a 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -1926,7 +1926,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 c58ba90721..7c90741ac2 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. */ @@ -2589,3 +2588,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 fb506d65fb..4faa3bc5f1 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 1d0a06e954..9d8e8235cb 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -1708,9 +1708,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; @@ -1736,9 +1736,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 616a8a0008..258eb56257 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1065,12 +1065,13 @@ 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