From 514cba07e0d337600cfa7846f92f4453411e40c7 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 17 Dec 2022 14:01:05 +0200 Subject: [PATCH 28/28] AI: Don't consider negative EFT_GROWTH_FOOD effective Several places were checking if the EFT_GROWTH_VALUE is exactly 0. Turned those to consider negative values similar way (actual effect is clipped between 0 ... 100) See osdn #46290 Signed-off-by: Marko Lindqvist --- ai/default/daicity.c | 6 +++--- ai/default/daieffects.c | 2 ++ server/cityturn.c | 22 ++++++++++++---------- server/cityturn.h | 1 + 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/ai/default/daicity.c b/ai/default/daicity.c index 57b0875b60..83e28ade1f 100644 --- a/ai/default/daicity.c +++ b/ai/default/daicity.c @@ -604,7 +604,7 @@ static void dai_spend_gold(struct ai_type *ait, struct player *pplayer) if (is_unit_choice_type(bestchoice.type) && utype_is_cityfounder(bestchoice.value.utype)) { - if (get_city_bonus(pcity, EFT_GROWTH_FOOD) == 0 + if (get_city_bonus(pcity, EFT_GROWTH_FOOD) <= 0 && bestchoice.value.utype->pop_cost > 0 && city_size_get(pcity) <= bestchoice.value.utype->pop_cost) { /* Don't buy settlers in cities that cannot afford the population cost. */ @@ -720,8 +720,8 @@ static int unit_foodbox_cost(struct unit *punit) int cost = 0; int i; - /* The default is to lose 100%. The growth bonus reduces this. */ - int foodloss_pct = 100 - get_city_bonus(pcity, EFT_GROWTH_FOOD); + /* The default is to lose 100%. The growth bonus reduces this. */ + int foodloss_pct = 100 - city_granary_savings(pcity); foodloss_pct = CLIP(0, foodloss_pct, 100); fc_assert_ret_val(pcity != NULL, -1); diff --git a/ai/default/daieffects.c b/ai/default/daieffects.c index c9086b3cc0..e42845c56e 100644 --- a/ai/default/daieffects.c +++ b/ai/default/daieffects.c @@ -292,6 +292,8 @@ adv_want dai_effect_value(struct player *pplayer, * amount / 100; break; case EFT_GROWTH_FOOD: + /* FIXME: As total value is clipped 0 ... 100, single + * effect should have no value at all in some cases. */ v += c * 4 + (amount / 7) * pcity->surplus[O_FOOD]; break; case EFT_POPCOST_FREE: diff --git a/server/cityturn.c b/server/cityturn.c index 7a5e0de79c..cf76aca406 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -506,7 +506,7 @@ static void city_turn_notify(const struct city *pcity, turns_growth = (city_granary_size(city_size_get(pcity)) - pcity->food_stock - 1) / pcity->surplus[O_FOOD]; - if (0 == get_city_bonus(pcity, EFT_GROWTH_FOOD) + if (get_city_bonus(pcity, EFT_GROWTH_FOOD) <= 0 && 0 < get_current_construction_bonus(pcity, EFT_GROWTH_FOOD, RPT_CERTAIN) && 0 < pcity->surplus[O_SHIELD]) { @@ -854,7 +854,7 @@ void city_repair_size(struct city *pcity, int change) Normally this value is 0% but this can be increased by EFT_GROWTH_FOOD effects. **************************************************************************/ -static int granary_savings(const struct city *pcity) +int city_granary_savings(const struct city *pcity) { int savings = get_city_bonus(pcity, EFT_GROWTH_FOOD); @@ -870,8 +870,9 @@ static int granary_savings(const struct city *pcity) static void city_reset_foodbox(struct city *pcity, int new_size) { fc_assert_ret(pcity != NULL); + pcity->food_stock = (city_granary_size(new_size) - * granary_savings(pcity)) / 100; + * city_granary_savings(pcity)) / 100; } /**********************************************************************//** @@ -882,16 +883,16 @@ static void city_reset_foodbox(struct city *pcity, int new_size) static bool city_increase_size(struct city *pcity, struct player *nationality) { int new_food; - int savings_pct = granary_savings(pcity); + int savings_pct = city_granary_savings(pcity); bool have_square = FALSE; - bool rapture_grow = city_rapture_grow(pcity); /* check before size increase! */ + bool rapture_grow = city_rapture_grow(pcity); /* Check before size increase! */ struct tile *pcenter = city_tile(pcity); struct player *powner = city_owner(pcity); const struct impr_type *pimprove = pcity->production.value.building; int saved_id = pcity->id; if (!city_can_grow_to(pcity, city_size_get(pcity) + 1)) { - /* need improvement */ + /* Need improvement */ if (get_current_construction_bonus(pcity, EFT_SIZE_ADJ, RPT_CERTAIN) > 0 || get_current_construction_bonus(pcity, EFT_SIZE_UNLIMIT, RPT_CERTAIN) > 0) { notify_player(powner, city_tile(pcity), E_CITY_AQ_BUILDING, ftc_server, @@ -938,7 +939,7 @@ static bool city_increase_size(struct city *pcity, struct player *nationality) && is_city_option_set(pcity, CITYO_SCIENCE_SPECIALISTS)) { pcity->specialists[best_specialist(O_SCIENCE, pcity)]++; } else if ((pcity->surplus[O_FOOD] >= 2 || !have_square) - && is_city_option_set(pcity, CITYO_GOLD_SPECIALISTS)) { + && is_city_option_set(pcity, CITYO_GOLD_SPECIALISTS)) { pcity->specialists[best_specialist(O_GOLD, pcity)]++; } else { pcity->specialists[DEFAULT_SPECIALIST]++; /* or else city is !sane */ @@ -1070,7 +1071,8 @@ static void city_populate(struct city *pcity, struct player *nationality) if (city_exist(saved_id)) { city_reset_foodbox(pcity, city_size_get(pcity)); } - return; + + return; } } unit_list_iterate_safe_end; if (city_size_get(pcity) > 1) { @@ -1081,8 +1083,8 @@ static void city_populate(struct city *pcity, struct player *nationality) } else { notify_player(city_owner(pcity), city_tile(pcity), E_CITY_FAMINE, ftc_server, - _("Famine destroys %s entirely."), - city_link(pcity)); + _("Famine destroys %s entirely."), + city_link(pcity)); } city_reset_foodbox(pcity, city_size_get(pcity) - 1); if (city_reduce_size(pcity, 1, NULL, "famine")) { diff --git a/server/cityturn.h b/server/cityturn.h index 42b63c46cd..6984e52f36 100644 --- a/server/cityturn.h +++ b/server/cityturn.h @@ -37,6 +37,7 @@ bool city_reduce_size(struct city *pcity, citizens pop_loss, void city_repair_size(struct city *pcity, int change); bool city_empty_food_stock(struct city *pcity); +int city_granary_savings(const struct city *pcity); void send_city_turn_notifications(struct connection *pconn); void update_city_activities(struct player *pplayer); -- 2.35.1