From bf76589c9fc55aca0cb7655d1e9037f1895f0c77 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Tue, 11 Jul 2023 23:17:09 +0300 Subject: [PATCH 30/30] Make is_square_threatened() to take map as parameter Pass map as a parameter around in the autosettlers code. See osdn #48396 Signed-off-by: Marko Lindqvist --- ai/classic/classicai.c | 10 +++--- ai/default/daicity.c | 6 ++-- ai/default/daisettler.c | 24 +++++++++------ ai/default/daisettler.h | 6 ++-- ai/tex/texai.c | 11 +++++-- ai/tex/texaicity.c | 3 +- common/unit.c | 11 ++++--- common/unit.h | 5 +-- server/advisors/autoworkers.c | 57 ++++++++++++++++++++--------------- server/advisors/autoworkers.h | 15 ++++++--- 10 files changed, 90 insertions(+), 58 deletions(-) diff --git a/ai/classic/classicai.c b/ai/classic/classicai.c index 21c65ac8e5..71d68b8d53 100644 --- a/ai/classic/classicai.c +++ b/ai/classic/classicai.c @@ -408,23 +408,25 @@ static void cai_auto_settler_reset(struct player *pplayer) /**********************************************************************//** Call default ai with classic ai type as parameter. **************************************************************************/ -static void cai_auto_settler_run(struct player *pplayer, struct unit *punit, +static void cai_auto_settler_run(struct player *pplayer, + struct unit *punit, struct settlermap *state) { struct ai_type *deftype = classic_ai_get_self(); - dai_auto_settler_run(deftype, pplayer, punit, state); + dai_auto_settler_run(deftype, &(wld.map), pplayer, punit, state); } /**********************************************************************//** Call default ai with classic ai type as parameter. **************************************************************************/ -static void cai_auto_settler_cont(struct player *pplayer, struct unit *punit, +static void cai_auto_settler_cont(struct player *pplayer, + struct unit *punit, struct settlermap *state) { struct ai_type *deftype = classic_ai_get_self(); - dai_auto_settler_cont(deftype, pplayer, punit, state); + dai_auto_settler_cont(deftype, &(wld.map), pplayer, punit, state); } /**********************************************************************//** diff --git a/ai/default/daicity.c b/ai/default/daicity.c index 0a8ad0a73a..a5df56bae1 100644 --- a/ai/default/daicity.c +++ b/ai/default/daicity.c @@ -740,7 +740,7 @@ static int unit_foodbox_cost(struct unit *punit) /**********************************************************************//** Estimates the want for a terrain improver (aka worker) by creating a - virtual unit and feeding it to settler_evaluate_improvements. + virtual unit and feeding it to settler_evaluate_improvements(). TODO: AI does not ship UTYF_SETTLERS around, only UTYF_CITIES - Per **************************************************************************/ @@ -760,6 +760,7 @@ static void contemplate_terrain_improvements(struct ai_type *ait, Continent_id place = tile_continent(pcenter); struct ai_city *city_data = def_ai_city_data(pcity, ait); struct dai_private_data *private = (struct dai_private_data *)ait->private; + const struct civ_map *nmap = &(wld.map); if (!private->contemplace_workers) { /* AI type uses custom method to set worker want and type. */ @@ -780,7 +781,8 @@ static void contemplate_terrain_improvements(struct ai_type *ait, /* Advisors data space not allocated as it's not needed in the lifetime of the virtualunit. */ unit_tile_set(virtualunit, pcenter); - want = settler_evaluate_improvements(virtualunit, &best_act, &best_target, + want = settler_evaluate_improvements(nmap, virtualunit, + &best_act, &best_target, &best_tile, NULL, NULL); if (unit_type_get(virtualunit)->pop_cost >= city_size_get(pcity)) { diff --git a/ai/default/daisettler.c b/ai/default/daisettler.c index 92546a3b71..83793cae60 100644 --- a/ai/default/daisettler.c +++ b/ai/default/daisettler.c @@ -1010,17 +1010,18 @@ void dai_auto_settler_init(struct ai_plr *ai) /*************************************************************************//** Auto settler that can also build cities. *****************************************************************************/ -void dai_auto_settler_run(struct ai_type *ait, struct player *pplayer, +void dai_auto_settler_run(struct ai_type *ait, const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state) { - adv_want best_impr = 0; /* value of best terrain improvement we can do */ + adv_want best_impr = 0; /* Value of best terrain improvement we can do */ enum unit_activity best_act; struct extra_type *best_target; struct tile *best_tile = NULL; struct pf_path *path = NULL; struct city *pcity = NULL; - /* time it will take worker to complete its given task */ + /* Time it will take worker to complete its given task */ int completion_time = 0; CHECK_UNIT(punit); @@ -1033,13 +1034,13 @@ BUILD_CITY: struct tile *ptile = punit->goto_tile; int sanity = punit->id; - /* Check that the mission is still possible. If the tile has become + /* Check that the mission is still possible. If the tile has become * unavailable, call it off. */ if (!city_can_be_built_here(ptile, punit)) { dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); set_unit_activity(punit, ACTIVITY_IDLE); send_unit_info(NULL, punit); - return; /* avoid recursion at all cost */ + return; /* Avoid recursion at all cost */ } else { /* Go there */ if ((!dai_gothere(ait, pplayer, punit, ptile) @@ -1059,7 +1060,7 @@ BUILD_CITY: /* Only known way to end in here is that hut turned in to a city * when settler entered tile. So this is not going to lead in any * serious recursion. */ - dai_auto_settler_run(ait, pplayer, punit, state); + dai_auto_settler_run(ait, nmap, pplayer, punit, state); } return; @@ -1097,7 +1098,8 @@ BUILD_CITY: } if (pcity == NULL) { - best_impr = settler_evaluate_improvements(punit, &best_act, &best_target, + best_impr = settler_evaluate_improvements(nmap, punit, + &best_act, &best_target, &best_tile, &path, state); if (path) { completion_time = pf_path_last_position(path)->turn; @@ -1163,7 +1165,7 @@ BUILD_CITY: } if (best_tile != NULL - && auto_settler_setup_work(pplayer, punit, state, 0, path, + && auto_settler_setup_work(nmap, pplayer, punit, state, 0, path, best_tile, best_act, &best_target, completion_time)) { if (pcity != NULL) { @@ -1181,10 +1183,12 @@ CLEANUP: /*************************************************************************//** Auto settler continuing its work. *****************************************************************************/ -void dai_auto_settler_cont(struct ai_type *ait, struct player *pplayer, +void dai_auto_settler_cont(struct ai_type *ait, const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state) { - if (!adv_settler_safe_tile(pplayer, punit, unit_tile(punit))) { + if (!adv_settler_safe_tile(nmap, pplayer, punit, + unit_tile(punit))) { unit_activity_handling(punit, ACTIVITY_IDLE); } } diff --git a/ai/default/daisettler.h b/ai/default/daisettler.h index 756b0fcbc5..88029491e6 100644 --- a/ai/default/daisettler.h +++ b/ai/default/daisettler.h @@ -29,9 +29,11 @@ void dai_auto_settler_init(struct ai_plr *ai); void dai_auto_settler_free(struct ai_plr *ai); void dai_auto_settler_reset(struct ai_type *ait, struct player *pplayer); -void dai_auto_settler_run(struct ai_type *ait, struct player *pplayer, +void dai_auto_settler_run(struct ai_type *ait, const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state); -void dai_auto_settler_cont(struct ai_type *ait, struct player *pplayer, +void dai_auto_settler_cont(struct ai_type *ait, const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state); void contemplate_new_city(struct ai_type *ait, struct city *pcity); diff --git a/ai/tex/texai.c b/ai/tex/texai.c index 635409a1fa..f95859abc9 100644 --- a/ai/tex/texai.c +++ b/ai/tex/texai.c @@ -390,11 +390,14 @@ static void texwai_auto_settler_reset(struct player *pplayer) /**********************************************************************//** Call default ai with tex ai type as parameter. **************************************************************************/ -static void texwai_auto_settler_run(struct player *pplayer, struct unit *punit, +static void texwai_auto_settler_run(struct player *pplayer, + struct unit *punit, struct settlermap *state) { TEXAI_AIT; - TEXAI_DFUNC(dai_auto_settler_run, pplayer, punit, state); + + /* TODO: Operate on tex map */ + TEXAI_DFUNC(dai_auto_settler_run, &(wld.map), pplayer, punit, state); } /**********************************************************************//** @@ -405,7 +408,9 @@ static void texwai_auto_settler_cont(struct player *pplayer, struct settlermap *state) { TEXAI_AIT; - TEXAI_DFUNC(dai_auto_settler_cont, pplayer, punit, state); + + /* TODO: Operate on tex map */ + TEXAI_DFUNC(dai_auto_settler_cont, &(wld.map), pplayer, punit, state); } /**********************************************************************//** diff --git a/ai/tex/texaicity.c b/ai/tex/texaicity.c index 253efbeb1c..423e3a302a 100644 --- a/ai/tex/texaicity.c +++ b/ai/tex/texaicity.c @@ -369,7 +369,8 @@ static void texai_tile_worker_task_select(struct player *pplayer, } } - extra = adv_settlers_road_bonus(ptile, proad) * mc_multiplier / mc_divisor; + extra = adv_settlers_road_bonus(&(wld.map), ptile, proad) + * mc_multiplier / mc_divisor; if (removing) { extra = -extra; diff --git a/common/unit.c b/common/unit.c index 5d142316fb..25215d1530 100644 --- a/common/unit.c +++ b/common/unit.c @@ -385,10 +385,11 @@ bool unit_can_do_action_sub_result(const struct unit *punit, /**********************************************************************//** Return TRUE iff this tile is threatened from any unit within 2 tiles. **************************************************************************/ -bool is_square_threatened(const struct player *pplayer, - const struct tile *ptile, bool omniscient) +bool is_square_threatened(const struct civ_map *nmap, + const struct player *pplayer, + const struct tile *ptile, bool omniscient) { - square_iterate(&(wld.map), ptile, 2, ptile1) { + square_iterate(nmap, ptile, 2, ptile1) { unit_list_iterate(ptile1->units, punit) { if ((omniscient || can_player_see_unit(pplayer, punit)) @@ -396,9 +397,9 @@ bool is_square_threatened(const struct player *pplayer, && utype_acts_hostile(unit_type_get(punit)) && (is_native_tile(unit_type_get(punit), ptile) || (can_attack_non_native(unit_type_get(punit)) - && is_native_near_tile(&(wld.map), + && is_native_near_tile(nmap, unit_class_get(punit), ptile)))) { - return TRUE; + return TRUE; } } unit_list_iterate_end; } square_iterate_end; diff --git a/common/unit.h b/common/unit.h index 47f91ab36f..c6f4d89cb6 100644 --- a/common/unit.h +++ b/common/unit.h @@ -364,9 +364,10 @@ bool unit_can_do_action_result(const struct unit *punit, enum action_result result); bool unit_can_do_action_sub_result(const struct unit *punit, enum action_sub_result sub_result); -bool is_square_threatened(const struct player *pplayer, +bool is_square_threatened(const struct civ_map *nmap, + const struct player *pplayer, const struct tile *ptile, bool omniscient); -bool is_field_unit(const struct unit *punit); /* ships+aero */ +bool is_field_unit(const struct unit *punit); bool is_hiding_unit(const struct unit *punit); bool unit_can_add_or_build_city(const struct unit *punit); diff --git a/server/advisors/autoworkers.c b/server/advisors/autoworkers.c index 6e09fb9360..32a3bba92e 100644 --- a/server/advisors/autoworkers.c +++ b/server/advisors/autoworkers.c @@ -129,7 +129,8 @@ void auto_settlers_ruleset_init(void) This calculates the overall benefit of connecting the civilization; this is independent from the local tile (trade) bonus granted by the road. **************************************************************************/ -adv_want adv_settlers_road_bonus(struct tile *ptile, struct road_type *proad) +adv_want adv_settlers_road_bonus(const struct civ_map *nmap, + struct tile *ptile, struct road_type *proad) { #define MAX_DEP_ROADS 5 @@ -160,7 +161,7 @@ adv_want adv_settlers_road_bonus(struct tile *ptile, struct road_type *proad) index_to_map_pos(&x, &y, tile_index(ptile)); for (i = 0; i < 12; i++) { - struct tile *tile1 = map_pos_to_tile(&(wld.map), x + dx[i], y + dy[i]); + struct tile *tile1 = map_pos_to_tile(nmap, x + dx[i], y + dy[i]); if (!tile1) { real_road[i] = FALSE; @@ -300,7 +301,7 @@ adv_want adv_settlers_road_bonus(struct tile *ptile, struct road_type *proad) /**********************************************************************//** Compares the best known tile improvement action with improving ptile - with activity act. Calculates the value of improving the tile by + with activity act. Calculates the value of improving the tile by discounting the total value by the time it would take to do the work and multiplying by some factor. **************************************************************************/ @@ -420,21 +421,22 @@ autosettler_tile_behavior(const struct tile *ptile, /**********************************************************************//** Finds tiles to improve, using punit. - The returned value is the goodness of the best tile and action found. If - this return value is > 0, then best_tile indicates the tile chosen, + The returned value is the goodness of the best tile and action found. + If this return value is > 0, then best_tile indicates the tile chosen, bestact indicates the activity it wants to do, and path (if not NULL) - indicates the path to follow for the unit. If 0 is returned + indicates the path to follow for the unit. If 0 is returned then there are no worthwhile activities available. completion_time is the time that would be taken by punit to travel to and complete work at best_tile state contains, for each tile, the unit id of the worker en route, - and the eta of this worker (if any). This information + and the eta of this worker (if any). This information is used to possibly displace this previously assigned worker. if this array is NULL, workers are never displaced. **************************************************************************/ -adv_want settler_evaluate_improvements(struct unit *punit, +adv_want settler_evaluate_improvements(const struct civ_map *nmap, + struct unit *punit, enum unit_activity *best_act, struct extra_type **best_target, struct tile **best_tile, @@ -454,7 +456,7 @@ adv_want settler_evaluate_improvements(struct unit *punit, int best_extra = 0; int best_delay = 0; - /* closest worker, if any, headed towards target tile */ + /* Closest worker, if any, headed towards target tile */ struct unit *enroute = NULL; pft_fill_unit_parameter(¶meter, punit); @@ -465,7 +467,7 @@ adv_want settler_evaluate_improvements(struct unit *punit, city_list_iterate(pplayer->cities, pcity) { struct tile *pcenter = city_tile(pcity); - /* try to work near the city */ + /* Try to work near the city */ city_tile_iterate_index(city_map_radius_sq_get(pcity), pcenter, ptile, cindex) { bool consider = TRUE; @@ -476,7 +478,7 @@ adv_want settler_evaluate_improvements(struct unit *punit, continue; } - if (!adv_settler_safe_tile(pplayer, punit, ptile)) { + if (!adv_settler_safe_tile(nmap, pplayer, punit, ptile)) { /* Too dangerous place */ continue; } @@ -676,7 +678,8 @@ adv_want settler_evaluate_improvements(struct unit *punit, } } - extra = adv_settlers_road_bonus(ptile, proad) * mc_multiplier / mc_divisor; + extra = adv_settlers_road_bonus(nmap, ptile, proad) + * mc_multiplier / mc_divisor; } else { extra = 0; @@ -909,7 +912,8 @@ struct city *settler_evaluate_city_requests(struct unit *punit, Find some work for our settlers and/or workers. **************************************************************************/ #define LOG_SETTLER LOG_DEBUG -void auto_settler_findwork(struct player *pplayer, +void auto_settler_findwork(const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion) @@ -957,7 +961,7 @@ void auto_settler_findwork(struct player *pplayer, best_target = best_task->tgt; - if (auto_settler_setup_work(pplayer, punit, state, recursion, + if (auto_settler_setup_work(nmap, pplayer, punit, state, recursion, path, best_task->ptile, best_task->act, &best_target, completion_time)) { clear_worker_task(taskcity, best_task); @@ -974,7 +978,7 @@ void auto_settler_findwork(struct player *pplayer, if (unit_has_type_flag(punit, UTYF_SETTLERS)) { TIMING_LOG(AIT_WORKERS, TIMER_START); - settler_evaluate_improvements(punit, &best_act, &best_target, + settler_evaluate_improvements(nmap, punit, &best_act, &best_target, &best_tile, &path, state); if (path) { completion_time = pf_path_last_position(path)->turn; @@ -983,7 +987,7 @@ void auto_settler_findwork(struct player *pplayer, adv_unit_new_task(punit, AUT_AUTO_SETTLER, best_tile); - auto_settler_setup_work(pplayer, punit, state, recursion, path, + auto_settler_setup_work(nmap, pplayer, punit, state, recursion, path, best_tile, best_act, &best_target, completion_time); @@ -997,7 +1001,8 @@ void auto_settler_findwork(struct player *pplayer, Setup our settler to do the work it has found. Returns TRUE if started actual work. **************************************************************************/ -bool auto_settler_setup_work(struct player *pplayer, struct unit *punit, +bool auto_settler_setup_work(const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion, struct pf_path *path, struct tile *best_tile, @@ -1046,7 +1051,7 @@ bool auto_settler_setup_work(struct player *pplayer, struct unit *punit, struct tile *old_pos = unit_tile(punit); displaced->goto_tile = NULL; - auto_settler_findwork(pplayer, displaced, state, recursion + 1); + auto_settler_findwork(nmap, pplayer, displaced, state, recursion + 1); if (NULL == player_unit_by_number(pplayer, saved_id)) { /* Actions of the displaced settler somehow caused this settler * to die. (maybe by recursively giving control back to this unit) @@ -1128,7 +1133,8 @@ bool auto_settler_setup_work(struct player *pplayer, struct unit *punit, /**********************************************************************//** Do we consider tile safe for autosettler to work? **************************************************************************/ -bool adv_settler_safe_tile(const struct player *pplayer, struct unit *punit, +bool adv_settler_safe_tile(const struct civ_map *nmap, + const struct player *pplayer, struct unit *punit, struct tile *ptile) { unit_list_iterate(ptile->units, defender) { @@ -1137,7 +1143,8 @@ bool adv_settler_safe_tile(const struct player *pplayer, struct unit *punit, } } unit_list_iterate_end; - if (is_square_threatened(pplayer, ptile, !has_handicap(pplayer, H_FOG))) { + if (is_square_threatened(nmap, pplayer, ptile, + !has_handicap(pplayer, H_FOG))) { return FALSE; } @@ -1151,6 +1158,7 @@ bool adv_settler_safe_tile(const struct player *pplayer, struct unit *punit, void auto_settlers_player(struct player *pplayer) { struct settlermap *state; + const struct civ_map *nmap = &(wld.map); state = fc_calloc(MAP_INDEX_SIZE, sizeof(*state)); @@ -1163,7 +1171,7 @@ void auto_settlers_player(struct player *pplayer) citymap_turn_init(pplayer); } - whole_map_iterate(&(wld.map), ptile) { + whole_map_iterate(nmap, ptile) { state[tile_index(ptile)].enroute = -1; state[tile_index(ptile)].eta = FC_INFINITY; } whole_map_iterate_end; @@ -1188,7 +1196,7 @@ void auto_settlers_player(struct player *pplayer) pplayer->ai_common.frost, game.info.nuclearwinter); /* Auto-settle with a settler unit if it's under AI control (e.g. human - * player auto-settler mode) or if the player is an AI. But don't + * player auto-settler mode) or if the player is an AI. But don't * auto-settle with a unit under orders even for an AI player - these come * from the human player and take precedence. */ unit_list_iterate_safe(pplayer->units, punit) { @@ -1210,7 +1218,8 @@ void auto_settlers_player(struct player *pplayer) } if (punit->activity != ACTIVITY_IDLE) { if (!is_ai(pplayer)) { - if (!adv_settler_safe_tile(pplayer, punit, unit_tile(punit))) { + if (!adv_settler_safe_tile(nmap, pplayer, punit, + unit_tile(punit))) { unit_activity_handling(punit, ACTIVITY_IDLE); } } else { @@ -1219,7 +1228,7 @@ void auto_settlers_player(struct player *pplayer) } if (punit->activity == ACTIVITY_IDLE) { if (!is_ai(pplayer)) { - auto_settler_findwork(pplayer, punit, state, 0); + auto_settler_findwork(nmap, pplayer, punit, state, 0); } else { CALL_PLR_AI_FUNC(settler_run, pplayer, pplayer, punit, state); } diff --git a/server/advisors/autoworkers.h b/server/advisors/autoworkers.h index 7a7620c6b5..d5432749cd 100644 --- a/server/advisors/autoworkers.h +++ b/server/advisors/autoworkers.h @@ -25,12 +25,14 @@ void adv_settlers_free(void); void auto_settlers_player(struct player *pplayer); -void auto_settler_findwork(struct player *pplayer, +void auto_settler_findwork(const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion); -bool auto_settler_setup_work(struct player *pplayer, struct unit *punit, +bool auto_settler_setup_work(const struct civ_map *nmap, + struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion, struct pf_path *path, struct tile *best_tile, @@ -38,7 +40,8 @@ bool auto_settler_setup_work(struct player *pplayer, struct unit *punit, struct extra_type **best_target, int completion_time); -adv_want settler_evaluate_improvements(struct unit *punit, +adv_want settler_evaluate_improvements(const struct civ_map *nmap, + struct unit *punit, enum unit_activity *best_act, struct extra_type **best_target, struct tile **best_tile, @@ -53,10 +56,12 @@ struct city *settler_evaluate_city_requests(struct unit *punit, void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile); -bool adv_settler_safe_tile(const struct player *pplayer, struct unit *punit, +bool adv_settler_safe_tile(const struct civ_map *nmap, + const struct player *pplayer, struct unit *punit, struct tile *ptile); -adv_want adv_settlers_road_bonus(struct tile *ptile, struct road_type *proad); +adv_want adv_settlers_road_bonus(const struct civ_map *nmap, + struct tile *ptile, struct road_type *proad); bool auto_settlers_speculate_can_act_at(const struct unit *punit, enum unit_activity activity, -- 2.40.1