From e409eddb38acc47ab76094ab345de0363c981775 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 8 Jul 2023 10:20:11 +0300 Subject: [PATCH 14/14] 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 | 18 ++++++++++ common/fc_interface.h | 21 +++++++++++ common/game.c | 20 +---------- common/game.h | 21 ----------- common/unit.c | 75 +++++++++++++++++++++++++++------------ common/unit.h | 18 +++++++++- server/advisors/advgoto.c | 25 +++++++------ 8 files changed, 127 insertions(+), 77 deletions(-) diff --git a/common/aicore/pf_tools.c b/common/aicore/pf_tools.c index 2290de8411..cbeb45614f 100644 --- a/common/aicore/pf_tools.c +++ b/common/aicore/pf_tools.c @@ -800,7 +800,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; } @@ -842,7 +842,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; } @@ -894,7 +894,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 cef7890651..9ed5915bf5 100644 --- a/common/fc_interface.c +++ b/common/fc_interface.c @@ -40,6 +40,8 @@ const struct functions *fc_funcs = NULL; available via fc_funcs. */ bool fc_funcs_defined = FALSE; +bool am_i_server = FALSE; + /************************************************************************** Return the function pointer. Only possible before interface_init() was called (fc_funcs_defined FALSE). @@ -51,6 +53,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. With check_fc_interface, also tests and initialize the functions. diff --git a/common/fc_interface.h b/common/fc_interface.h index 3546c0bc97..bf13601545 100644 --- a/common/fc_interface.h +++ b/common/fc_interface.h @@ -59,6 +59,27 @@ 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 bb4db02087..58b22b9c11 100644 --- a/common/game.c +++ b/common/game.c @@ -57,26 +57,8 @@ struct civ_game game; struct world wld; -bool am_i_server = 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. **************************************************************************/ @@ -110,7 +92,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) diff --git a/common/game.h b/common/game.h index 236ab5851c..9a2336b004 100644 --- a/common/game.h +++ b/common/game.h @@ -289,27 +289,6 @@ struct civ_game { } callbacks; }; -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 */ -} - void game_init(bool keep_ruleset_value); void game_map_init(void); void game_free(void); diff --git a/common/unit.c b/common/unit.c index 9a69b06e68..e678632f26 100644 --- a/common/unit.c +++ b/common/unit.c @@ -1414,21 +1414,59 @@ 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) +{ + square_iterate(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 - client-specific features, like FoW and the fact that the client cannot + 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) +bool is_plr_zoc_client(const struct player *pplayer, const struct tile *ptile0) { - struct terrain *pterrain; - bool srv = is_server(); - square_iterate(ptile0, 1, ptile) { + struct terrain *pterrain; struct city *pcity; pterrain = tile_terrain(ptile); @@ -1439,27 +1477,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 020deaf8f4..8f7cc68210 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 "terrain.h" /* enum tile_special_type */ #include "unittype.h" @@ -408,7 +409,22 @@ 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); +bool is_plr_zoc_srv(const struct player *unit_owner, const struct tile *ptile); +bool is_plr_zoc_client(const struct player *unit_owner, const struct tile *ptile); + +/************************************************************************** + 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) +{ + return is_server() + ? is_plr_zoc_srv(unit_owner, ptile) : is_plr_zoc_client(unit_owner, ptile); +} + 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 7dff8f9357..75ef629f17 100644 --- a/server/advisors/advgoto.c +++ b/server/advisors/advgoto.c @@ -182,28 +182,33 @@ 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; + + 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(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; } @@ -422,8 +427,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) - || is_non_allied_unit_tile(ptile, param->owner))) { + || !is_plr_zoc_srv(param->owner, ptile) + || is_non_allied_unit_tile(ptile, param->owner))) { /* We could become stuck. */ risk += risk_cost->enemy_zoc_cost; } -- 2.40.1