From dca4761aea13aa816f98b778d0abfd3a34aa6d8c Mon Sep 17 00:00:00 2001 From: Ihnatus Date: Wed, 1 Jun 2022 23:26:45 +0300 Subject: [PATCH] Create buildings in cities by Lua in the same manner as it is done in editor. I.e., move great wonders if they are present. See OSDN#44696 Signed-off-by: Ihnatus --- server/citytools.c | 29 +++++++++++++++++++++++++++++ server/citytools.h | 3 +++ server/edithand.c | 27 +++++++++------------------ server/scripting/api_server_edit.c | 29 ++++++++++++----------------- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/server/citytools.c b/server/citytools.c index 14f4347a3c..854589a502 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -2839,6 +2839,35 @@ void do_sell_building(struct player *pplayer, struct city *pcity, } } +/************************************************************************//** + Creates an improvement in a city. If the improvement is a present wonder, + moves it from a city it is in now, returns that city and tells its owner. + It's up to the caller to update the necessary cities. + FIXME: it is not checked if the improvement is obsolete or obsoletes + other building, should we? +****************************************************************************/ +struct city +*build_or_move_building(struct city *pcity, struct impr_type *pimprove, + struct player **old_city_owner) +{ + struct city *oldcity = NULL; + + fc_assert_ret_val(!city_has_building(pcity, pimprove), NULL); + if (is_great_wonder(pimprove)) { + oldcity = city_from_great_wonder(pimprove); + } else if (is_small_wonder(pimprove)) { + oldcity = city_from_small_wonder(pplayer, pimprove); + } + if (oldcity) { + fc_assert_ret_val(oldcity != pcity, NULL); + *old_city_owner = city_owner(oldcity); + city_remove_improvement(oldcity, pimprove); + } + + city_add_improvement(pcity, pimprove); + return oldcity; +} + /************************************************************************//** Remove building from the city. Emits lua signal. ****************************************************************************/ diff --git a/server/citytools.h b/server/citytools.h index 339af2dea7..a96c99e848 100644 --- a/server/citytools.h +++ b/server/citytools.h @@ -77,6 +77,9 @@ bool city_illness_strike(struct city *pcity); void do_sell_building(struct player *pplayer, struct city *pcity, struct impr_type *pimprove, const char *reason); +struct city +*build_or_move_building(struct city *pcity, struct impr_type *pimprove, + struct player **old_city_owner); bool building_removed(struct city *pcity, const struct impr_type *pimprove, const char *reason, struct unit *destroyer); void building_lost(struct city *pcity, const struct impr_type *pimprove, diff --git a/server/edithand.c b/server/edithand.c index eed7016502..b7409fa90c 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -790,30 +790,21 @@ void handle_edit_city(struct connection *pc, } else if (!city_has_building(pcity, pimprove) && packet->built[id] >= 0) { + struct player *old_owner = NULL; - if (is_great_wonder(pimprove)) { - oldcity = city_from_great_wonder(pimprove); - if (oldcity != pcity) { - BV_SET(need_player_info, player_index(pplayer)); - } - if (NULL != oldcity && city_owner(oldcity) != pplayer) { - /* Great wonders make more changes. */ - need_game_info = TRUE; - BV_SET(need_player_info, player_index(city_owner(oldcity))); - } - } else if (is_small_wonder(pimprove)) { - oldcity = city_from_small_wonder(pplayer, pimprove); - if (oldcity != pcity) { - BV_SET(need_player_info, player_index(pplayer)); - } + oldcity = build_or_move_building(pcity, pimprove, &old_owner); + if (oldcity != pcity) { + BV_SET(need_player_info, player_index(pplayer)); + } + if (oldcity && old_owner != pplayer) { + /* Great wonders make more changes. */ + need_game_info = TRUE; + BV_SET(need_player_info, player_index(old_owner)); } if (oldcity) { - city_remove_improvement(oldcity, pimprove); city_refresh_queue_add(oldcity); } - - city_add_improvement(pcity, pimprove); changed = TRUE; } } improvement_iterate_end; diff --git a/server/scripting/api_server_edit.c b/server/scripting/api_server_edit.c index 609aa9a0e7..db5b11fbe3 100644 --- a/server/scripting/api_server_edit.c +++ b/server/scripting/api_server_edit.c @@ -686,34 +686,29 @@ void api_edit_create_building(lua_State *L, City *pcity, Building_Type *impr) if (!city_has_building(pcity, impr)) { bool need_game_info = FALSE; bool need_plr_info = FALSE; + struct player *old_owner = NULL, *pplayer = city_owner(pcity); + struct city *oldcity; - if (is_great_wonder(impr)) { - if (city_from_great_wonder(impr) != NULL) { - /* Can't rebuild great wonders */ - return; - } - - need_game_info = TRUE; + oldcity = build_or_move_building(pcity, impr, &old_owner); + if (oldcity != pcity) { need_plr_info = TRUE; - } else if (is_small_wonder(impr)) { - struct city *oldcity = city_from_small_wonder(city_owner(pcity), impr); + } + if (oldcity && old_owner != pplayer) { + /* Great wonders make more changes. */ + need_game_info = TRUE; + } - /* Since we already checked that pcity does not have the building, - * we can be sure it's not the same as oldcity. */ - city_remove_improvement(oldcity, impr); + if (oldcity) { send_city_info(NULL, oldcity); - - need_plr_info = TRUE; } - city_add_improvement(pcity, impr); send_city_info(NULL, pcity); - if (need_game_info) { send_game_info(NULL); + send_player_info_c(old_owner, NULL); } if (need_plr_info) { - send_player_info_c(city_owner(pcity), NULL); + send_player_info_c(pplayer, NULL); } } } -- 2.34.1