From 7329284c9a58f35e6130dcc819e8c7ed6a60d6b7 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 14 May 2022 11:08:48 +0300 Subject: [PATCH 14/14] Lua create_city(): Check validity of city creation - Only create the city if it's legal - Revive the player assigned as city owner, if dead - Reveal the city tile for the city owner Reported by ihnatus See osdn #44508 Signed-off-by: Marko Lindqvist --- server/citytools.c | 29 +++++++++++++++++++++++++++++ server/citytools.h | 2 ++ server/edithand.c | 16 ++++------------ server/scripting/api_server_edit.c | 2 +- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/server/citytools.c b/server/citytools.c index f7af92bdc0..465053f5f5 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -166,6 +166,35 @@ void city_freeze_workers_queue(struct city *pcity) } } +/**************************************************************************** + Create city for player, doing necessary checks and adjustments. + + Return whether it was legal to create the city. If not, city was not + created. +****************************************************************************/ +bool create_city_for_player(struct player *pplayer, struct tile *ptile, + const char *name) +{ + if (is_enemy_unit_tile(ptile, pplayer) != NULL + || !city_can_be_built_here(ptile, NULL)) { + return FALSE; + } + + if (!pplayer->is_alive) { + pplayer->is_alive = TRUE; + send_player_info_c(pplayer, NULL); + } + + if (name == NULL || name[0] == '\0') { + name = city_name_suggestion(pplayer, ptile); + } + + map_show_tile(pplayer, ptile); + create_city(pplayer, ptile, name, pplayer); + + return TRUE; +} + /**************************************************************************** Remove a city from the queue for later calls to auto_arrange_workers(). Reterns TRUE if the city was found in the queue. diff --git a/server/citytools.h b/server/citytools.h index 3abbf3e04b..a11ca689d2 100644 --- a/server/citytools.h +++ b/server/citytools.h @@ -65,6 +65,8 @@ void city_build_free_buildings(struct city *pcity); void create_city(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality); +bool create_city_for_player(struct player *pplayer, struct tile *ptile, + const char *name); void remove_city(struct city *pcity); struct trade_route *remove_trade_route(struct city *pc1, diff --git a/server/edithand.c b/server/edithand.c index d85d675e4b..795e77a65f 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -681,25 +681,17 @@ void handle_edit_city_create(struct connection *pc, int owner, int tile, } + conn_list_do_buffer(game.est_connections); - if (is_enemy_unit_tile(ptile, pplayer) != NULL - || !city_can_be_built_here(ptile, NULL)) { + if (!create_city_for_player(pplayer, ptile, NULL)) { notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor, /* TRANS: ..." at ." */ _("A city may not be built at %s."), tile_link(ptile)); - return; - } + conn_list_do_unbuffer(game.est_connections); - if (!pplayer->is_alive) { - pplayer->is_alive = TRUE; - send_player_info_c(pplayer, NULL); + return; } - conn_list_do_buffer(game.est_connections); - - map_show_tile(pplayer, ptile); - create_city(pplayer, ptile, city_name_suggestion(pplayer, ptile), - pplayer); pcity = tile_city(ptile); if (size > 1) { diff --git a/server/scripting/api_server_edit.c b/server/scripting/api_server_edit.c index 385eb82474..56396c04b4 100644 --- a/server/scripting/api_server_edit.c +++ b/server/scripting/api_server_edit.c @@ -274,7 +274,7 @@ void api_edit_create_city(lua_State *L, Player *pplayer, Tile *ptile, } /* TODO: Allow initial citizen to be of nationality other than owner */ - create_city(pplayer, ptile, name, pplayer); + create_city_for_player(pplayer, ptile, name); } /***************************************************************************** -- 2.35.1