From fe2541400c100aa0d3ac1031cdf1de7219a92c70 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 23 Nov 2022 03:28:28 +0200 Subject: [PATCH 29/29] AI: Turn magic military emergency want values to macros Also fixes dai_unit_consider_bodyguard() bug that very high want is considered military emergency even when it's not. See osdn #46091 Signed-off-by: Marko Lindqvist --- ai/default/daicity.c | 7 +++---- ai/default/daimilitary.c | 21 ++++++++++++--------- ai/default/daimilitary.h | 3 +++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/ai/default/daicity.c b/ai/default/daicity.c index e20e4ccb36..6bd3236372 100644 --- a/ai/default/daicity.c +++ b/ai/default/daicity.c @@ -230,8 +230,8 @@ static void dai_barbarian_choose_build(struct player *pplayer, /* If found anything, put it into the choice */ if (bestunit) { choice->value.utype = bestunit; - /* FIXME: 101 is the "overriding military emergency" indicator */ - choice->want = 101; + /* "Overriding military emergency" indicator */ + choice->want = DAI_WANT_MILITARY_EMERGENCY; choice->type = CT_ATTACKER; adv_choice_set_use(choice, "barbarian"); } else { @@ -264,8 +264,7 @@ static void dai_city_choose_build(struct ai_type *ait, struct player *pplayer, if (is_barbarian(pplayer)) { dai_barbarian_choose_build(pplayer, pcity, &(city_data->choice)); } else { - /* FIXME: 101 is the "overriding military emergency" indicator */ - if ((city_data->choice.want <= 100 + if ((city_data->choice.want < DAI_WANT_MILITARY_EMERGENCY || city_data->urgency == 0) && !(dai_on_war_footing(ait, pplayer) && city_data->choice.want > 0 && pcity->id != adv->wonder_city)) { diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index 7c918350b2..19a536464a 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -424,7 +424,7 @@ void dai_assess_danger_player(struct ai_type *ait, struct player *pplayer, Set (overwrite) our want for a building. Syela tries to explain: My first attempt to allow ng_wa >= 200 led to stupidity in cities - with no defenders and danger = 0 but danger > 0. Capping ng_wa at + with no defenders and danger = 0 but danger > 0. Capping ng_wa at 100 + urgency led to a failure to buy walls as required. Allowing want > 100 with !urgency led to the AI spending too much gold and falling behind on science. I'm trying again, but this will require @@ -511,6 +511,7 @@ static unsigned int assess_danger(struct ai_type *ait, struct city *pcity, unit_type_iterate(utype) { int idx = utype_index(utype); + defense_bonuses_pct[idx] = 0; defender_type_handled[idx] = FALSE; best_non_scramble[idx] = -1; @@ -1464,7 +1465,8 @@ cleanup: /**********************************************************************//** This function should assign a value to choice and want and type, - where want is a value between 1 and 100. + where want is a value between 0.0 and + DAI_WANT_MILITARY_EMERGENCY (not inclusive) if want is 0 this advisor doesn't want anything **************************************************************************/ static void dai_unit_consider_bodyguard(struct ai_type *ait, @@ -1480,7 +1482,7 @@ static void dai_unit_consider_bodyguard(struct ai_type *ait, virtualunit = unit_virtual_create(pplayer, pcity, punittype, city_production_unit_veteran_level(pcity, punittype)); - if (choice->want < 100) { + if (choice->want < DAI_WANT_MILITARY_EMERGENCY) { const adv_want want = look_for_charge(ait, pplayer, virtualunit, &aunit, &acity); if (want > choice->want) { @@ -1622,7 +1624,7 @@ struct adv_choice *military_advisor_choose_build(struct ai_type *ait, * nobody behind them. */ if (dai_process_defender_want(ait, pplayer, pcity, danger, choice, martial_value)) { - choice->want = 100 + danger; + choice->want = DAI_WANT_BELOW_MIL_EMERGENCY + danger; adv_choice_set_use(choice, "first defender"); build_walls = FALSE; def_unit_selected = TRUE; @@ -1643,10 +1645,10 @@ struct adv_choice *military_advisor_choose_build(struct ai_type *ait, pimprove = improvement_by_number(wall_id); if (wall_id != B_LAST - && pcity->server.adv->building_want[wall_id] != 0 && our_def != 0 + && pcity->server.adv->building_want[wall_id] != 0 && our_def != 0 && can_city_build_improvement_now(pcity, pimprove) && (danger < 101 || num_defenders > 1 - || (city_data->grave_danger == 0 + || (city_data->grave_danger == 0 && pplayer->economic.gold > impr_buy_gold_cost(pcity, pimprove, pcity->shield_stock))) && ai_fuzzy(pplayer, TRUE)) { @@ -1657,8 +1659,8 @@ struct adv_choice *military_advisor_choose_build(struct ai_type *ait, choice->want = pcity->server.adv->building_want[wall_id]; choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER, pplayer) / TRAIT_DEFAULT_VALUE / 2)); - if (urgency == 0 && choice->want > 100) { - choice->want = 100; + if (urgency == 0 && choice->want > DAI_WANT_BELOW_MIL_EMERGENCY) { + choice->want = DAI_WANT_BELOW_MIL_EMERGENCY; } choice->type = CT_BUILDING; adv_choice_set_use(choice, "defense building"); @@ -1747,7 +1749,8 @@ struct adv_choice *military_advisor_choose_build(struct ai_type *ait, /* If we are in severe danger, don't consider attackers. This is probably too general. In many cases we will want to buy attackers to counterattack. -- Per */ - if (choice->want - martial_value > 100 && city_data->grave_danger > 0) { + if (choice->want - martial_value >= DAI_WANT_MILITARY_EMERGENCY + && city_data->grave_danger > 0) { CITY_LOG(LOGLEVEL_BUILD, pcity, "severe danger (want " ADV_WANT_PRINTF "), force defender", choice->want); diff --git a/ai/default/daimilitary.h b/ai/default/daimilitary.h index 3612fdb09f..3db2e1e15d 100644 --- a/ai/default/daimilitary.h +++ b/ai/default/daimilitary.h @@ -31,6 +31,9 @@ struct civ_map; to finish them off. */ #define FINISH_HIM_CITY_COUNT 5 +#define DAI_WANT_BELOW_MIL_EMERGENCY 100 +#define DAI_WANT_MILITARY_EMERGENCY (DAI_WANT_BELOW_MIL_EMERGENCY + 1) + typedef struct unit_list *(player_unit_list_getter)(struct player *pplayer); struct unit_type *dai_choose_defender_versus(struct city *pcity, -- 2.35.1