From c51ccf8543159bf07c3fcfd9dbabbea8016ee13a Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 8 Jul 2023 10:04:07 +0300 Subject: [PATCH 26/26] Split is_my_zoc() to server and client versions See osdn #47794 Signed-off-by: Marko Lindqvist --- common/aicore/pf_tools.c | 6 ++-- common/fc_interface.c | 16 +++++++++ common/fc_interface.h | 22 ++++++++++++ common/game.c | 19 +--------- common/game.h | 21 ----------- common/unit.c | 76 +++++++++++++++++++++++++++------------ common/unit.h | 22 ++++++++++-- server/advisors/advgoto.c | 28 +++++++++------ 8 files changed, 132 insertions(+), 78 deletions(-) diff --git a/common/aicore/pf_tools.c b/common/aicore/pf_tools.c index eed7a2c2e7..1bc840dcee 100644 --- a/common/aicore/pf_tools.c +++ b/common/aicore/pf_tools.c @@ -811,7 +811,7 @@ static inline void pft_fill_parameter(struct pf_parameter *parameter, } if (!unit_type_really_ignores_zoc(punittype)) { - parameter->get_zoc = is_my_zoc; + parameter->get_zoc = is_server() ? is_plr_zoc_srv : is_plr_zoc_client; } else { parameter->get_zoc = NULL; } @@ -853,7 +853,7 @@ static void pft_fill_overlap_param(struct pf_parameter *parameter, parameter->ignore_none_scopes = FALSE; if (!unit_type_really_ignores_zoc(punittype)) { - parameter->get_zoc = is_my_zoc; + parameter->get_zoc = is_server() ? is_plr_zoc_srv : is_plr_zoc_client; } else { parameter->get_zoc = NULL; } @@ -904,7 +904,7 @@ static void pft_fill_attack_param(struct pf_parameter *parameter, parameter->actions &= ~PF_AA_CITY_ATTACK; if (!unit_type_really_ignores_zoc(punittype)) { - parameter->get_zoc = is_my_zoc; + parameter->get_zoc = is_server() ? is_plr_zoc_srv : is_plr_zoc_client; } else { parameter->get_zoc = NULL; } diff --git a/common/fc_interface.c b/common/fc_interface.c index af9747b262..89f0119485 100644 --- a/common/fc_interface.c +++ b/common/fc_interface.c @@ -51,6 +51,22 @@ struct functions *fc_interface_funcs(void) return &fc_functions; } +/************************************************************************//** + Set program type to server. +****************************************************************************/ +void i_am_server(void) +{ + am_i_server = TRUE; +} + +/************************************************************************//** + Set program type to client. +****************************************************************************/ +void i_am_client(void) +{ + am_i_server = FALSE; +} + /************************************************************************//** Initialize libfreeciv. diff --git a/common/fc_interface.h b/common/fc_interface.h index 3546c0bc97..75df5902b8 100644 --- a/common/fc_interface.h +++ b/common/fc_interface.h @@ -59,6 +59,28 @@ struct functions *fc_interface_funcs(void); void libfreeciv_init(bool check_fc_interface); void libfreeciv_free(void); +extern bool am_i_server; + + +/**********************************************************************//** + Is the program type server? +**************************************************************************/ +static inline bool is_server(void) +{ + return am_i_server; +} + +void i_am_server(void); +void i_am_client(void); + +/**********************************************************************//** + Set program type to tool. +**************************************************************************/ +static inline void i_am_tool(void) +{ + i_am_server(); /* No difference between a tool and server at the moment */ +} + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/common/game.c b/common/game.c index bf724563ad..770d7a12bb 100644 --- a/common/game.c +++ b/common/game.c @@ -68,22 +68,6 @@ bool _ruleset_compat_mode = FALSE; static void game_defaults(bool keep_ruleset_value); -/**********************************************************************//** - Set program type to server. -**************************************************************************/ -void i_am_server(void) -{ - am_i_server = TRUE; -} - -/**********************************************************************//** - Set program type to client. -**************************************************************************/ -void i_am_client(void) -{ - am_i_server = FALSE; -} - /**********************************************************************//** Count the # of thousand citizen in a civilisation. **************************************************************************/ @@ -117,7 +101,7 @@ struct city *game_city_by_name(const char *name) /**********************************************************************//** Often used function to get a city pointer from a city ID. - City may be any city in the game. This now always uses fast idex + City may be any city in the game. This now always uses fast idex method, instead of looking through all cities of all players. **************************************************************************/ struct city *game_city_by_number(int id) @@ -125,7 +109,6 @@ struct city *game_city_by_number(int id) return idex_lookup_city(&wld, id); } - /**********************************************************************//** Find unit out of all units in game: now uses fast idex method, instead of looking through all units of all players. diff --git a/common/game.h b/common/game.h index afebf863b9..116ceb987c 100644 --- a/common/game.h +++ b/common/game.h @@ -300,29 +300,8 @@ struct civ_game { } callbacks; }; -extern bool am_i_server; - extern struct civ_game game; -/**********************************************************************//** - Is the program type server? -**************************************************************************/ -static inline bool is_server(void) -{ - return am_i_server; -} - -void i_am_server(void); -void i_am_client(void); - -/**********************************************************************//** - Set program type to tool. -**************************************************************************/ -static inline void i_am_tool(void) -{ - i_am_server(); /* No difference between a tool and server at the moment */ -} - #ifdef FREECIV_WEB /**********************************************************************//** Is there currently any connections from web-client(s) diff --git a/common/unit.c b/common/unit.c index 7f2fc56846..fc2621091e 100644 --- a/common/unit.c +++ b/common/unit.c @@ -1364,22 +1364,61 @@ struct unit *unit_occupies_tile(const struct tile *ptile, } /**********************************************************************//** - Is this square controlled by the pplayer? + Is this square controlled by the pplayer? Function to be used on + server side only. - Here "is_my_zoc" means essentially a square which is *not* adjacent to an + Here "plr zoc" means essentially a square which is *not* adjacent to an enemy unit (that has a ZOC) on a terrain that has zoc rules. +**************************************************************************/ +bool is_plr_zoc_srv(const struct player *pplayer, const struct tile *ptile0, + const struct civ_map *zmap) +{ + square_iterate(zmap, ptile0, 1, ptile) { + struct terrain *pterrain; + struct city *pcity; + + pterrain = tile_terrain(ptile); + if (terrain_has_flag(pterrain, TER_NO_ZOC)) { + continue; + } + + pcity = tile_non_allied_city(ptile, pplayer); + if (pcity != NULL) { + if (unit_list_size(ptile->units) > 0) { + /* Occupied enemy city, it doesn't matter if units inside have + * UTYF_NOZOC or not. Fogged city is assumed to be occupied. */ + return FALSE; + } + } else { + unit_list_iterate(ptile->units, punit) { + if (!unit_transported_server(punit) + && !pplayers_allied(unit_owner(punit), pplayer) + && !unit_has_type_flag(punit, UTYF_NOZOC)) { + return FALSE; + } + } unit_list_iterate_end; + } + } square_iterate_end; + + return TRUE; +} + +/**********************************************************************//** + Is this square controlled by the pplayer? Function to be used on + client side only. - Since this function is also used in the client, it has to deal with some + Here "plr zoc" means essentially a square which is *not* adjacent to an + enemy unit (that has a ZOC) on a terrain that has zoc rules. + + Since this function is used in the client, it has to deal with some client-specific features, like FoW and the fact that the client cannot see units inside enemy cities. **************************************************************************/ -bool is_my_zoc(const struct player *pplayer, const struct tile *ptile0, - const struct civ_map *zmap) +bool is_plr_zoc_client(const struct player *pplayer, const struct tile *ptile0, + const struct civ_map *zmap) { - struct terrain *pterrain; - bool srv = is_server(); - square_iterate(zmap, ptile0, 1, ptile) { + struct terrain *pterrain; struct city *pcity; pterrain = tile_terrain(ptile); @@ -1390,27 +1429,18 @@ bool is_my_zoc(const struct player *pplayer, const struct tile *ptile0, pcity = tile_non_allied_city(ptile, pplayer); if (pcity != NULL) { - if ((srv && unit_list_size(ptile->units) > 0) - || (!srv && (pcity->client.occupied - || TILE_KNOWN_UNSEEN == tile_get_known(ptile, pplayer)))) { + if (pcity->client.occupied + || TILE_KNOWN_UNSEEN == tile_get_known(ptile, pplayer)) { /* Occupied enemy city, it doesn't matter if units inside have * UTYF_NOZOC or not. Fogged city is assumed to be occupied. */ return FALSE; } } else { unit_list_iterate(ptile->units, punit) { - if (srv) { - if (!unit_transported_server(punit) - && !pplayers_allied(unit_owner(punit), pplayer) - && !unit_has_type_flag(punit, UTYF_NOZOC)) { - return FALSE; - } - } else { - if (!unit_transported_client(punit) - && !pplayers_allied(unit_owner(punit), pplayer) - && !unit_has_type_flag(punit, UTYF_NOZOC)) { - return FALSE; - } + if (!unit_transported_client(punit) + && !pplayers_allied(unit_owner(punit), pplayer) + && !unit_has_type_flag(punit, UTYF_NOZOC)) { + return FALSE; } } unit_list_iterate_end; } diff --git a/common/unit.h b/common/unit.h index fb8c557fc1..c7f9d44a22 100644 --- a/common/unit.h +++ b/common/unit.h @@ -22,6 +22,7 @@ extern "C" { /* common */ #include "base.h" +#include "fc_interface.h" #include "fc_types.h" #include "map_types.h" #include "terrain.h" /* enum tile_special_type */ @@ -447,8 +448,25 @@ static inline bool is_non_attack_unit_tile(const struct tile *ptile, struct unit *unit_occupies_tile(const struct tile *ptile, const struct player *pplayer); -bool is_my_zoc(const struct player *unit_owner, const struct tile *ptile, - const struct civ_map *zmap); +bool is_plr_zoc_srv(const struct player *unit_owner, const struct tile *ptile, + const struct civ_map *zmap); +bool is_plr_zoc_client(const struct player *unit_owner, const struct tile *ptile, + const struct civ_map *zmap); + +/**********************************************************************//** + Is this square controlled by the unit_owner? This function can be + used both by the server and the client side. + + Here "is_my_zoc" means essentially a square which is *not* adjacent to an + enemy unit (that has a ZOC) on a terrain that has zoc rules. +**************************************************************************/ +static inline bool is_my_zoc(const struct player *unit_owner, const struct tile *ptile, + const struct civ_map *zmap) +{ + return is_server() + ? is_plr_zoc_srv(unit_owner, ptile, zmap) : is_plr_zoc_client(unit_owner, ptile, zmap); +} + bool unit_being_aggressive(const struct unit *punit); bool unit_type_really_ignores_zoc(const struct unit_type *punittype); diff --git a/server/advisors/advgoto.c b/server/advisors/advgoto.c index 077a546b67..db215452f8 100644 --- a/server/advisors/advgoto.c +++ b/server/advisors/advgoto.c @@ -311,28 +311,34 @@ static bool adv_unit_move(struct unit *punit, struct tile *ptile) /**********************************************************************//** Similar to is_my_zoc(), but with some changes: - - destination (x0,y0) need not be adjacent? + - destination (x0, y0) need not be adjacent? - don't care about some directions? - Fix to bizarre did-not-find bug. Thanks, Katvrr -- Syela + Fix to bizarre did-not-find bug. Thanks, Katvrr -- Syela **************************************************************************/ static bool adv_could_be_my_zoc(struct unit *myunit, struct tile *ptile) { - if (same_pos(ptile, unit_tile(myunit))) { - return FALSE; /* can't be my zoc */ + struct tile *utile = unit_tile(myunit); + struct player *owner; + struct civ_map *cmap = &(wld.map); + + if (same_pos(ptile, utile)) { + return FALSE; /* Can't be my zoc */ } - if (is_tiles_adjacent(ptile, unit_tile(myunit)) - && !is_non_allied_unit_tile(ptile, unit_owner(myunit))) { + + owner = unit_owner(myunit); + if (is_tiles_adjacent(ptile, utile) + && !is_non_allied_unit_tile(ptile, owner)) { return FALSE; } - adjc_iterate(&(wld.map), ptile, atile) { + adjc_iterate(cmap, ptile, atile) { if (!terrain_has_flag(tile_terrain(atile), TER_NO_ZOC) - && is_non_allied_unit_tile(atile, unit_owner(myunit))) { + && is_non_allied_unit_tile(atile, owner)) { return FALSE; } } adjc_iterate_end; - + return TRUE; } @@ -550,8 +556,8 @@ static unsigned stack_risk(const struct tile *ptile, * if we enter or try to enter the tile. */ if (risk_cost->enemy_zoc_cost != 0 && (is_non_allied_city_tile(ptile, param->owner) - || !is_my_zoc(param->owner, ptile, param->map) - || is_non_allied_unit_tile(ptile, param->owner))) { + || !is_plr_zoc_srv(param->owner, ptile, param->map) + || is_non_allied_unit_tile(ptile, param->owner))) { /* We could become stuck. */ risk += risk_cost->enemy_zoc_cost; } -- 2.40.1