Project

General

Profile

Feature #1377 ยป 0042-daicity.-ch-Improve-coding-style.patch

Marko Lindqvist, 05/09/2025 09:32 PM

View differences:

ai/default/daicity.c
(pcity->surplus[O_SHIELD] < 0 || city_unhappy(pcity) \
|| pcity->food_stock + pcity->surplus[O_FOOD] < 0)
static void dai_city_sell_noncritical(struct city *pcity, bool redundant_only);
static void resolve_city_emergency(struct ai_type *ait, struct player *pplayer,
static void dai_city_sell_noncritical(struct city *pcity,
bool redundant_only);
static void resolve_city_emergency(struct ai_type *ait,
struct player *pplayer,
struct city *pcity);
/**********************************************************************//**
......
/* The conversion factor was determined by experiment,
* and might need adjustment. See also dai_tech_effect_values()
*/
const adv_want tech_want = building_want * def_ai_city_data(pcity, ait)->building_wait
* 14 / 8;
const adv_want tech_want
= building_want * def_ai_city_data(pcity, ait)->building_wait * 14 / 8;
#if 0
/* This logging is relatively expensive,
* so activate it only while necessary. */
TECH_LOG(LOG_DEBUG, pplayer, tech,
"wanted by %s for building: %d -> %d",
city_name_get(pcity), improvement_rule_name(pimprove),
building_want, tech_want);
"wanted by %s for building: %d -> %d",
city_name_get(pcity), improvement_rule_name(pimprove),
building_want, tech_want);
#endif /* 0 */
if (tech) {
def_ai_player_data(pplayer, ait)->tech_want[advance_index(tech)] += tech_want;
def_ai_player_data(pplayer, ait)->tech_want[advance_index(tech)]
+= tech_want;
}
}
......
TODO: Move this into daimilitary.c
TODO: It will be called for each city but doesn't depend on the city,
maybe cache it? Although barbarians don't normally have many cities,
maybe cache it? Although barbarians don't normally have many cities,
so can be a bigger bother to cache it.
**************************************************************************/
static void dai_barbarian_choose_build(struct player *pplayer,
static void dai_barbarian_choose_build(struct player *pplayer,
struct city *pcity,
struct adv_choice *choice)
{
struct unit_type *bestunit = NULL;
struct unit_type *bestunit = nullptr;
int i, bestattack = 0;
const struct civ_map *nmap = &(wld.map);
......
}
/**********************************************************************//**
Chooses what the city will build. Is called after the military advisor
Chooses what the city will build. Is called after the military advisor
put it's choice into pcity->server.ai.choice and "settler advisor" put
settler want into pcity->founder_*.
Note that AI cheats -- it suffers no penalty for switching from unit to
improvement, etc.
**************************************************************************/
static void dai_city_choose_build(struct ai_type *ait, struct player *pplayer,
static void dai_city_choose_build(struct ai_type *ait,
struct player *pplayer,
struct city *pcity)
{
struct adv_choice *newchoice;
struct adv_data *adv = adv_data_get(pplayer, NULL);
struct adv_data *adv = adv_data_get(pplayer, nullptr);
struct ai_city *city_data = def_ai_city_data(pcity, ait);
const struct civ_map *nmap = &(wld.map);
......
&& !(dai_on_war_footing(ait, pplayer) && city_data->choice.want > 0
&& pcity->id != adv->wonder_city)) {
newchoice = domestic_advisor_choose_build(ait, pplayer, pcity);
adv_choice_copy(&(city_data->choice), adv_better_choice(&(city_data->choice), newchoice));
adv_choice_copy(&(city_data->choice),
adv_better_choice(&(city_data->choice), newchoice));
adv_free_choice(newchoice);
}
}
......
break;
};
change_build_target(pplayer, pcity, &build_new, E_CITY_PRODUCTION_CHANGED);
change_build_target(pplayer, pcity, &build_new,
E_CITY_PRODUCTION_CHANGED);
}
}
......
{
improvement_iterate(pimprove) {
if (can_city_sell_building(pcity, pimprove)
&& !building_has_effect(pimprove, EFT_DEFEND_BONUS)) {
/* selling walls to buy defenders is counterproductive -- Syela */
&& !building_has_effect(pimprove, EFT_DEFEND_BONUS)) {
/* Selling walls to buy defenders is counterproductive -- Syela */
really_handle_city_sell(pplayer, pcity, pimprove);
break;
}
......
}
/**********************************************************************//**
Increase maxbuycost. This variable indicates (via ai_gold_reserve) to
Increase maxbuycost. This variable indicates (via ai_gold_reserve) to
the tax selection code how much money do we need for buying stuff.
**************************************************************************/
static void increase_maxbuycost(struct player *pplayer, int new_value)
......
action_array_end(upgrade_actions, i);
}
dai_calc_data(pplayer, NULL, &expenses, NULL);
dai_calc_data(pplayer, nullptr, &expenses, nullptr);
unit_list_iterate(pcity->tile->units, punit) {
if (pcity->owner == punit->owner) {
/* Only upgrade units you own, not allied ones */
const struct unit_type *old_type = unit_type_get(punit);
const struct unit_type *punittype = can_upgrade_unittype(pplayer, old_type);
const struct unit_type *punittype
= can_upgrade_unittype(pplayer, old_type);
if (military && !IS_ATTACKER(old_type)) {
/* Only upgrade military units this round */
......
continue;
}
if (punittype == NULL) {
if (punittype == nullptr) {
continue;
}
......
int cost = unit_upgrade_price(pplayer, old_type, punittype);
int real_limit = limit;
/* Sinking Triremes are DANGEROUS!! We'll do anything to upgrade 'em. */
/* Sinking Triremes are DANGEROUS!!
* We'll do anything to upgrade 'em. */
/* FIXME: This assumes rules to be quite close to civ/2.
* Of the supplied rulesets those are the only ones with
* UTYF_COAST unit, but... */
......
&& is_action_enabled_unit_on_city(nmap, ACTION_HELP_WONDER,
punit, tgt_city)) {
if (unit_perform_action(owner, punit->id, tgt_city->id,
0, NULL, ACTION_HELP_WONDER, requester)) {
0, nullptr, ACTION_HELP_WONDER, requester)) {
/* No shields wasted. The unit did Help Wonder. */
return;
}
......
&& is_action_enabled_unit_on_city(nmap, ACTION_DISBAND_UNIT_RECOVER,
punit, tgt_city)) {
if (unit_perform_action(owner, punit->id, tgt_city->id,
0, NULL, ACTION_DISBAND_UNIT_RECOVER, requester)) {
0, nullptr, ACTION_DISBAND_UNIT_RECOVER,
requester)) {
/* The unit did Disband Unit Recover. 50% of the shields wasted. */
return;
}
......
if (unit_can_do_action(punit, ACTION_DISBAND_UNIT)) {
if (is_action_enabled_unit_on_self(nmap, ACTION_DISBAND_UNIT, punit)) {
if (unit_perform_action(owner, punit->id, punit->id,
0, NULL, ACTION_DISBAND_UNIT, requester)) {
0, nullptr, ACTION_DISBAND_UNIT, requester)) {
/* All shields wasted. The unit did Disband Unit. */
return;
}
......
int expenses;
bool war_footing = dai_on_war_footing(ait, pplayer);
/* Disband explorers that are at home but don't serve a purpose.
/* Disband explorers that are at home but don't serve a purpose.
* FIXME: This is a hack, and should be removed once we
* learn how to ferry explorers to new land. */
city_list_iterate(pplayer->cities, pcity) {
......
} unit_list_iterate_safe_end;
} city_list_iterate_end;
dai_calc_data(pplayer, NULL, &expenses, NULL);
dai_calc_data(pplayer, nullptr, &expenses, nullptr);
do {
bool expensive; /* don't buy when it costs x2 unless we must */
bool expensive; /* Don't buy when it costs x2 unless we must */
int buycost;
int limit = cached_limit; /* cached_limit is our gold reserve */
struct city *pcity = NULL;
struct city *pcity = nullptr;
struct ai_city *city_data;
/* Find highest wanted item on the buy list */
......
} city_list_iterate_end;
/* We found nothing, so we're done */
if (pcity == NULL) {
if (pcity == nullptr) {
break;
}
......
if (get_city_bonus(pcity, EFT_SHRINK_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. */
/* Don't buy settlers in cities that cannot afford
* the population cost. */
/* This used to check also if city is about to grow to required size
* next turn and allow buying of settlers in that case, but current
* order of end/start turn activities is such that settler building
......
}
} else {
/* We are not a settler. Therefore we increase the cash need we
* balance our buy desire with to keep cash at hand for emergencies
* balance our buy desire with to keep cash at hand for emergencies
* and for upgrades */
limit *= 2;
}
......
|| (pplayer->economic.gold - buycost < limit);
if (bestchoice.type == CT_ATTACKER
&& buycost
> utype_build_shield_cost(pcity, NULL, bestchoice.value.utype) * 2
&& buycost
> utype_build_shield_cost(pcity, nullptr,
bestchoice.value.utype) * 2
&& !war_footing) {
/* Too expensive for an offensive unit */
continue;
......
* to sell everything in it of non-military value */
if (pplayer->economic.gold - expenses >= buycost
&& (!expensive
&& (!expensive
|| (city_data->grave_danger != 0
&& assess_defense(ait, pcity) == 0)
|| (bestchoice.want > 200 && city_data->urgency > 1))) {
/* Buy stuff */
CITY_LOG(LOG_BUY, pcity, "Crash buy of %s for %d (want " ADV_WANT_PRINTF ")",
CITY_LOG(LOG_BUY, pcity,
"Crash buy of %s for %d (want " ADV_WANT_PRINTF ")",
adv_choice_rule_name(&bestchoice),
buycost,
bestchoice.want);
really_handle_city_buy(pplayer, pcity);
} else if (city_data->grave_danger != 0
} else if (city_data->grave_danger != 0
&& bestchoice.type == CT_DEFENDER
&& assess_defense(ait, pcity) == 0) {
/* We have no gold but MUST have a defender */
......
} city_list_iterate_end;
}
log_base(LOG_BUY, "%s wants to keep %d in reserve (tax factor %d)",
player_name(pplayer), cached_limit, pplayer->ai_common.maxbuycost);
log_base(LOG_BUY, "%s wants to keep %d in reserve (tax factor %d)",
player_name(pplayer), cached_limit,
pplayer->ai_common.maxbuycost);
}
/**********************************************************************//**
......
int foodloss_pct = 100 - city_shrink_granary_savings(pcity);
foodloss_pct = CLIP(0, foodloss_pct, 100);
fc_assert_ret_val(pcity != NULL, -1);
fc_assert_ret_val(pcity != nullptr, -1);
fc_assert(size >= pop_cost);
for (i = pop_cost; i > 0 ; i--) {
......
int want;
enum unit_activity best_act;
struct extra_type *best_target;
struct tile *best_tile = NULL; /* May be accessed by log_*() calls. */
struct tile *best_tile = nullptr; /* May be accessed by log_*() calls. */
struct tile *pcenter = city_tile(pcity);
struct player *pplayer = city_owner(pcity);
struct adv_data *adv = adv_data_get(pplayer, NULL);
struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
struct adv_data *adv = adv_data_get(pplayer, nullptr);
struct ai_plr *ai = dai_plr_data_get(ait, pplayer, nullptr);
struct unit_type *utype;
Continent_id place = tile_continent(pcenter);
struct ai_city *city_data = def_ai_city_data(pcity, ait);
......
return;
}
city_data->worker_want = 0; /* Make sure old want does not stay if we don't want now */
city_data->worker_want = 0; /* Make sure old want does not stay if
* we don't want now */
utype = dai_role_utype_for_terrain_class(pcity, UTYF_WORKERS, TC_LAND);
if (utype == NULL) {
if (utype == nullptr) {
log_debug("No UTYF_WORKERS role unit available");
return;
}
......
want = worker_evaluate_improvements(nmap, virtualunit,
&best_act, &best_target,
&best_tile,
NULL, NULL);
nullptr, nullptr);
if (unit_type_get(virtualunit)->pop_cost >= city_size_get(pcity)) {
/* We don't like disbanding the city as a side effect */
unit_virtual_destroy(virtualunit);
......
want /= MAX(1, ai->stats.workers[place] / (adv->stats.cities[place] + 1));
want -= ai->stats.workers[place];
} else {
want /= MAX(1, ai->stats.ocean_workers[-place] / (adv->stats.ocean_cities[-place] + 1));
want /= MAX(1, ai->stats.ocean_workers[-place]
/ (adv->stats.ocean_cities[-place] + 1));
want -= ai->stats.ocean_workers[-place];
}
want = MAX(want, 0);
......
want,
get_activity_text(best_act),
TILE_XY(best_tile),
ai->stats.workers[place],
ai->stats.workers[place],
adv->stats.cities[place]);
} else {
CITY_LOG(LOG_DEBUG, pcity, "wants %s with want %d to do %s at (%d,%d), "
......
fc_assert(want >= 0);
city_data->worker_want = want;
city_data->worker_type = dai_role_utype_for_terrain_class(pcity, UTYF_WORKERS,
place >= 0 ? TC_LAND : TC_OCEAN);
city_data->worker_type
= dai_role_utype_for_terrain_class(pcity, UTYF_WORKERS,
place >= 0 ? TC_LAND : TC_OCEAN);
}
/**********************************************************************//**
......
if (CITY_EMERGENCY(pcity)
|| city_granary_size(city_size_get(pcity)) == pcity->food_stock) {
/* Having a full granary isn't an emergency, but we want to rearrange */
auto_arrange_workers(pcity); /* this usually helps */
auto_arrange_workers(pcity); /* This usually helps */
}
if (CITY_EMERGENCY(pcity)) {
/* Fix critical shortages or unhappiness */
......
if (city_data->choice.want <= 0) {
/* Note that this function mungs the seamap, but we don't care */
TIMING_LOG(AIT_CITY_MILITARY, TIMER_START);
choice = military_advisor_choose_build(ait, &(wld.map), pplayer, pcity, NULL);
choice = military_advisor_choose_build(ait, &(wld.map), pplayer, pcity,
nullptr);
adv_choice_copy(&(city_data->choice), choice);
adv_free_choice(choice);
TIMING_LOG(AIT_CITY_MILITARY, TIMER_STOP);
......
if (dai_on_war_footing(ait, pplayer) && city_data->choice.want > 0) {
city_data->worker_want = 0;
city_data->founder_want = 0;
city_data->founder_turn = game.info.turn; /* Do not consider zero we set here
* valid value, if real want is needed.
* Recalculate immediately in such situation. */
city_data->founder_turn = game.info.turn; /* Do not consider zero we set
* here a valid value,
* if real want is needed.
* Recalculate immediately
* in such situation. */
continue; /* Go, soldiers! */
}
/* Will record its findings in pcity->worker_want */
/* Will record its findings in pcity->worker_want */
TIMING_LOG(AIT_CITY_TERRAIN, TIMER_START);
contemplate_terrain_improvements(ait, pcity);
TIMING_LOG(AIT_CITY_TERRAIN, TIMER_STOP);
TIMING_LOG(AIT_CITY_SETTLERS, TIMER_START);
if (city_data->founder_turn <= game.info.turn) {
/* Will record its findings in pcity->founder_want */
/* Will record its findings in pcity->founder_want */
contemplate_new_city(ait, pcity);
/* Avoid recalculating all the time.. */
/* This means AI is not very opportunistic if there happens to open up spot for
* a new city. */
city_data->founder_turn =
game.info.turn + fc_rand(AI_CITY_RECALC_SPEED) + AI_CITY_RECALC_SPEED;
/* This means AI is not very opportunistic if there happens to open up
* spot for a new city. */
city_data->founder_turn
= game.info.turn + fc_rand(AI_CITY_RECALC_SPEED) + AI_CITY_RECALC_SPEED;
} else if (pcity->server.debug) {
/* recalculate every turn */
/* Recalculate every turn */
contemplate_new_city(ait, pcity);
}
TIMING_LOG(AIT_CITY_SETTLERS, TIMER_STOP);
......
struct impr_type *pimprove,
const struct city *pcity)
{
#if 0 /* This check will become more complicated now. */
#if 0 /* This check will become more complicated now. */
if (ai_wants_no_science(plr)
&& building_has_effect(pimprove, EFT_SCIENCE_BONUS)) {
return FALSE;
}
#endif
#endif /* 0 */
if (building_has_effect(pimprove, EFT_DEFEND_BONUS)
/* selling city walls is really, really dumb -- Syela */
|| is_improvement_productive(pcity, pimprove)) {
......
gain);
do_sell_building(pplayer, pcity, pimprove, "sold");
return; /* max 1 building each turn */
return; /* Max 1 building each turn */
}
} city_built_iterate_end;
}
......
Syela is wrong. It happens quite too often, mostly due to unhappiness.
Also, most of the time we are unable to resolve the situation.
**************************************************************************/
static void resolve_city_emergency(struct ai_type *ait, struct player *pplayer,
static void resolve_city_emergency(struct ai_type *ait,
struct player *pplayer,
struct city *pcity)
{
struct tile *pcenter = city_tile(pcity);
......
{
struct ai_city *city_data = def_ai_city_data(pcity, ait);
if (city_data != NULL) {
if (city_data != nullptr) {
adv_deinit_choice(&(city_data->choice));
city_set_ai_data(pcity, ait, NULL);
city_set_ai_data(pcity, ait, nullptr);
FC_FREE(city_data);
}
}
......
{
struct ai_city *city_data = def_ai_city_data(pcity, ait);
/* FIXME: remove this when the urgency is properly recalculated. */
secfile_insert_int(file, city_data->urgency, "%s.%s.urgency", citystr, aitstr);
/* FIXME: Remove this when the urgency is properly recalculated. */
secfile_insert_int(file, city_data->urgency, "%s.%s.urgency",
citystr, aitstr);
/* avoid fc_rand recalculations on subsequent reload. */
/* Avoid fc_rand() recalculations on subsequent reload. */
secfile_insert_int(file, city_data->building_turn, "%s.%s.building_turn",
citystr, aitstr);
secfile_insert_int(file, city_data->building_wait, "%s.%s.building_wait",
citystr, aitstr);
/* avoid fc_rand and expensive recalculations on subsequent reload. */
/* Avoid fc_rand() and expensive recalculations on subsequent reload. */
secfile_insert_int(file, city_data->founder_turn, "%s.%s.founder_turn",
citystr, aitstr);
secfile_insert_int(file, city_data->founder_want, "%s.%s.founder_want",
......
{
struct ai_city *city_data = def_ai_city_data(pcity, ait);
/* FIXME: remove this when the urgency is properly recalculated. */
/* FIXME: Remove this when the urgency is properly recalculated. */
city_data->urgency
= secfile_lookup_int_default(file, 0, "%s.%s.urgency", citystr, aitstr);
/* avoid fc_rand recalculations on subsequent reload. */
/* Avoid fc_rand() recalculations on subsequent reload. */
city_data->building_turn
= secfile_lookup_int_default(file, 0, "%s.%s.building_turn", citystr,
aitstr);
......
= secfile_lookup_int_default(file, BUILDING_WAIT_MINIMUM,
"%s.%s.building_wait", citystr, aitstr);
/* avoid fc_rand and expensive recalculations on subsequent reload. */
/* Avoid fc_rand() and expensive recalculations on subsequent reload. */
city_data->founder_turn
= secfile_lookup_int_default(file, 0, "%s.%s.founder_turn", citystr,
aitstr);
......
impr_vector_init(&needed_improvements);
requirement_vector_iterate(&pimprove->reqs, preq) {
const bool active = is_req_active(&context, NULL, preq, RPT_POSSIBLE);
const bool active = is_req_active(&context, nullptr, preq, RPT_POSSIBLE);
if (VUT_ADVANCE == preq->source.kind && preq->present && !active) {
/* Found a missing technology requirement for this improvement. */
tech_vector_append(&needed_techs, preq->source.value.advance);
} else if (VUT_IMPROVEMENT == preq->source.kind && preq->present && !active) {
} else if (VUT_IMPROVEMENT == preq->source.kind && preq->present
&& !active) {
/* Found a missing improvement requirement for this improvement.
* For example, in the default ruleset a city must have a Library
* before it can have a University. */
......
int i;
for (i = 0; i < n_needed_improvements; i++) {
const struct impr_type *needed_impr = *impr_vector_get(&needed_improvements, i);
const struct impr_type *needed_impr
= *impr_vector_get(&needed_improvements, i);
/* TODO: increase the want for the needed_impr,
* if we can build it now */
/* Recurse */
......
}
/**********************************************************************//**
Calculates city want from some input values. Set pimprove to NULL when
nothing in the city has changed, and you just want to know the
base want of a city.
Calculates city want from some input values. Set pimprove to nullptr
when nothing in the city has changed, and you just want to know
the base want of a city.
**************************************************************************/
adv_want dai_city_want(struct player *pplayer, struct city *acity,
adv_want dai_city_want(struct player *pplayer, struct city *acity,
struct adv_data *adv, struct impr_type *pimprove)
{
adv_want want = 0;
......
const struct civ_map *nmap = &(wld.map);
memset(prod, 0, O_LAST * sizeof(*prod));
if (NULL != pimprove
&& adv->impr_calc[improvement_index(pimprove)] == ADV_IMPR_CALCULATE_FULL) {
if (pimprove != nullptr
&& adv->impr_calc[improvement_index(pimprove)]
== ADV_IMPR_CALCULATE_FULL) {
struct tile *acenter = city_tile(acity);
bool celebrating = base_city_celebrating(acity);
......
prod[O_GOLD] += get_city_tithes_bonus(acity);
output_type_iterate(o) {
bonus[o] = get_final_city_output_bonus(acity, o);
waste[o] = city_waste(acity, o, prod[o] * bonus[o] / 100, NULL);
waste[o] = city_waste(acity, o, prod[o] * bonus[o] / 100, nullptr);
} output_type_iterate_end;
add_tax_income(pplayer,
prod[O_TRADE] * bonus[O_TRADE] / 100 - waste[O_TRADE],
prod);
prod[O_TRADE] * bonus[O_TRADE] / 100 - waste[O_TRADE],
prod);
output_type_iterate(o) {
prod[o] = prod[o] * bonus[o] / 100 - waste[o];
} output_type_iterate_end;
......
/* Increased tax rate indicates that we've had gold shortage which
* we are trying to fill with taxes. Consider gold more critical
* than usually.
* Smallest tax rate we can have here is 60% -> factor (60 - 40) / 14.0 = 1.43 */
want += prod[O_GOLD] * adv->gold_priority * (pplayer->economic.tax - 40) / 14.0;
* Smallest tax rate we can have here is
* 60% -> factor (60 - 40) / 14.0 = 1.43 */
want += prod[O_GOLD] * adv->gold_priority
* (pplayer->economic.tax - 40) / 14.0;
} else {
want += prod[O_GOLD] * adv->gold_priority;
}
......
static adv_want base_want(struct ai_type *ait, struct player *pplayer,
struct city *pcity, struct impr_type *pimprove)
{
struct adv_data *adv = adv_data_get(pplayer, NULL);
struct adv_data *adv = adv_data_get(pplayer, nullptr);
adv_want final_want = 0;
int wonder_player_id = WONDER_NOT_OWNED;
int wonder_city_id = WONDER_NOT_BUILT;
......
if (!can_city_build_improvement_now(pcity, pimprove)
|| (is_small_wonder(pimprove)
&& NULL != city_from_small_wonder(pplayer, pimprove))) {
&& city_from_small_wonder(pplayer, pimprove) != nullptr)) {
return 0;
}
......
improvements. Consequently adjust the desirability of those improvements
or the technologies that would make them possible.
This function may (indeed, should) be called even for improvements that a city
already has, or can not (yet) build. For existing improvements,
This function may (indeed, should) be called even for improvements that
a city already has, or can not (yet) build. For existing improvements,
it will discourage research of technologies that would make the improvement
obsolete or reduce its effectiveness, and encourages technologies that would
improve its effectiveness. For improvements that the city can not yet build
......
adv_want v = 0;
int cities[REQ_RANGE_COUNT];
int nplayers = normal_player_count();
struct adv_data *ai = adv_data_get(pplayer, NULL);
struct adv_data *ai = adv_data_get(pplayer, nullptr);
bool capital = is_capital(pcity);
bool can_build = TRUE;
struct universal source = {
......
/* Base want is calculated above using a more direct approach. */
v += base_want(ait, pplayer, pcity, pimprove);
if (v != 0) {
CITY_LOG(LOG_DEBUG, pcity, "%s base_want is " ADV_WANT_PRINTF " (range=%d)",
CITY_LOG(LOG_DEBUG, pcity,
"%s base_want is " ADV_WANT_PRINTF " (range=%d)",
improvement_rule_name(pimprove),
v,
ai->impr_range[improvement_index(pimprove)]);
......
continue;
}
if (!is_req_active(&effect_ctxt, NULL, preq, RPT_POSSIBLE)) {
if (!is_req_active(&effect_ctxt, nullptr, preq, RPT_POSSIBLE)) {
active = FALSE;
if (VUT_ADVANCE == preq->source.kind && preq->present) {
/* This missing requirement is a missing tech requirement.
......
if (!present) {
/* Building removes the effect */
/* Currently v1 is (v + delta). Make it (v - delta) instead */
/* Currently v1 is (v + delta). Make it (v - delta) instead */
v1 = -v1;
}
if (active) {
v += v1;
v += v1;
} else if (v1 > 0) {
/* If value of the effect is negative, do not hold it against
* the tech - having the tech wont force one to build the
* building. */
/* We might want the technology that will enable this
* (additional) effect.
* The better the effect, the more we want the technology.
/* We might want the technology that will enable this
* (additional) effect.
* The better the effect, the more we want the technology.
* We are more interested in (additional) effects that enhance
* buildings we already have.
*/
* buildings we already have.
*/
const int a = already? 5: 4; /* WAG */
const adv_want dv = v1 * a / (4 * n_needed_techs);
......
/* Is it possible to do the action to the city right now?
*
* (DiplRel requirements are ignored since actor_player is NULL) */
is_possible = is_action_possible_on_city(act_id, NULL, pcity);
* (DiplRel requirements are ignored since actor_player is nullptr) */
is_possible = is_action_possible_on_city(act_id, nullptr, pcity);
/* Will it be possible to do the action to the city if the building is
* built? */
......
active = FALSE;
break;
}
} else if (!is_req_active(&actenabler_ctxt, NULL, preq, RPT_POSSIBLE)) {
} else if (!is_req_active(&actenabler_ctxt, nullptr,
preq, RPT_POSSIBLE)) {
active = FALSE;
break;
}
......
/* Increase the want for technologies that will enable
* construction of this improvement, if necessary.
*/
const bool all_met = adjust_wants_for_reqs(ait, pplayer, pcity, pimprove, v);
const bool all_met
= adjust_wants_for_reqs(ait, pplayer, pcity, pimprove, v);
can_build = can_build && all_met;
}
......
**************************************************************************/
void dai_build_adv_init(struct ai_type *ait, struct player *pplayer)
{
struct adv_data *ai = adv_data_get(pplayer, NULL);
struct adv_data *ai = adv_data_get(pplayer, nullptr);
/* Find current worth of cities and cache this. */
city_list_iterate(pplayer->cities, pcity) {
def_ai_city_data(pcity, ait)->worth = dai_city_want(pplayer, pcity, ai, NULL);
def_ai_city_data(pcity, ait)->worth = dai_city_want(pplayer, pcity, ai,
nullptr);
} city_list_iterate_end;
}
......
city_list_iterate(pplayer->cities, pcity) {
improvement_iterate(pimprove) {
if (pcity->server.adv->building_want[improvement_index(pimprove)] != 0) {
CITY_LOG(LOG_DEBUG, pcity, "want to build %s with " ADV_WANT_PRINTF,
CITY_LOG(LOG_DEBUG, pcity, "want to build %s with " ADV_WANT_PRINTF,
improvement_rule_name(pimprove),
pcity->server.adv->building_want[improvement_index(pimprove)]);
}
......
struct ai_city *city_data = def_ai_city_data(pcity, ait);
if (city_data->building_turn <= game.info.turn) {
/* This will spread recalcs out so that no one turn end is
/* This will spread recalcs out so that no one turn end is
* much longer than others */
city_data->building_wait = fc_rand(AI_BA_RECALC_SPEED) + AI_BA_RECALC_SPEED;
city_data->building_turn = game.info.turn
+ city_data->building_wait;
city_data->building_wait
= fc_rand(AI_BA_RECALC_SPEED) + AI_BA_RECALC_SPEED;
city_data->building_turn
= game.info.turn + city_data->building_wait;
}
} city_list_iterate_end;
}
......
/**********************************************************************//**
Is it ok for advisor code to consider given city as wonder city?
**************************************************************************/
void dai_consider_wonder_city(struct ai_type *ait, struct city *pcity, bool *result)
void dai_consider_wonder_city(struct ai_type *ait, struct city *pcity,
bool *result)
{
if (def_ai_city_data(pcity, ait)->grave_danger > 0) {
*result = FALSE;
......
case VUT_TERRFLAG:
case VUT_TERRAINALTER:
case VUT_CITYTILE:
return !is_req_active(context, NULL, req, RPT_POSSIBLE);
return !is_req_active(context, nullptr, req, RPT_POSSIBLE);
default:
return is_req_preventing(context, NULL, req, RPT_POSSIBLE) > REQUCH_NO;
return is_req_preventing(context, nullptr, req, RPT_POSSIBLE) > REQUCH_NO;
}
}
......
pimprove)) {
return FALSE;
}
/* Check for requirements that aren't met and that are unchanging (so
* they can never be met). */
/* Check for requirements that aren't met and that are unchanging
* (so they can never be met). */
requirement_vector_iterate(&pimprove->reqs, preq) {
if (dai_cant_help_req(&city_ctxt, preq)) {
return FALSE;
......
if (!valid_improvement(pimprove)) {
return FALSE;
}
if (improvement_obsolete(p, pimprove, NULL)) {
if (improvement_obsolete(p, pimprove, nullptr)) {
return FALSE;
}
if (is_great_wonder(pimprove) && !great_wonder_is_available(pimprove)) {
......
return FALSE;
}
/* Check for requirements that aren't met and that are unchanging (so
* they can never be met). */
/* Check for requirements that aren't met and that are unchanging
* (so they can never be met). */
requirement_vector_iterate(&pimprove->reqs, preq) {
if (preq->range >= REQ_RANGE_PLAYER
&& dai_cant_help_req(&context, preq)) {
......
const struct unit_type *utype)
{
int greatest_value = 0;
const struct impr_type *best_building = NULL;
const struct impr_type *best_building = nullptr;
const struct req_context context = {
.player = city_owner(pcity),
.city = pcity,
......
effect_list_iterate(get_effects(effect_type), peffect) {
if (peffect->value > greatest_value) {
const struct impr_type *building = NULL;
const struct impr_type *building = nullptr;
bool wrong_unit = FALSE;
requirement_vector_iterate(&peffect->reqs, preq) {
......
if (!can_city_build_improvement_now(pcity, building)
|| !is_improvement(building)) {
building = NULL;
building = nullptr;
break;
}
} else if (VUT_IMPR_FLAG == preq->source.kind && preq->present) {
......
if (improvement_has_flag(impr, preq->source.value.impr_flag)) {
if (can_city_build_improvement_now(pcity, impr)
&& is_improvement(impr)) {
if (building == NULL) {
if (building == nullptr) {
building = impr;
break;
}
......
}
} improvement_iterate_end;
if (building == NULL) {
if (building == nullptr) {
break;
}
} else if (utype != NULL
&& !is_req_active(&context, NULL, preq, RPT_POSSIBLE)) {
/* Effect requires other kind of unit than what we are interested about */
} else if (utype != nullptr
&& !is_req_active(&context, nullptr, preq, RPT_POSSIBLE)) {
/* Effect requires other kind of unit than what we are
* interested about */
wrong_unit = TRUE;
break;
}
} requirement_vector_iterate_end;
if (!wrong_unit && building != NULL) {
if (!wrong_unit && building != nullptr) {
best_building = building;
greatest_value = peffect->value;
greatest_value = peffect->value;
}
}
} effect_list_iterate_end;
......
if (best_building) {
return improvement_number(best_building);
}
return B_LAST;
}
ai/default/daicity.h
struct ai_city {
adv_want worth; /* Cache city worth here, sum of all weighted incomes */
int building_turn; /* only recalculate every Nth turn */
int building_wait; /* for weighting values */
int building_turn; /* Only recalculate every Nth turn */
int building_wait; /* For weighting values */
#define BUILDING_WAIT_MINIMUM (1)
struct adv_choice choice; /* to spend gold in the right place only */
struct adv_choice choice; /* To spend gold in the right place only */
struct ai_invasion invasion;
int attack, bcost; /* This is also for invasion - total power and value of
* all units coming to kill us. */
unsigned int danger; /* danger to be compared to assess_defense */
unsigned int grave_danger; /* danger, should show positive feedback */
unsigned int urgency; /* how close the danger is; if zero,
unsigned int danger; /* Danger to be compared to assess_defense */
unsigned int grave_danger; /* Danger, should show positive feedback */
unsigned int urgency; /* How close the danger is; if zero,
bodyguards can leave */
int wallvalue; /* how much it helps for defenders to be
int wallvalue; /* How much it helps for defenders to be
ground units */
int distance_to_wonder_city; /* wondercity will set this for us,
int distance_to_wonder_city; /* Wondercity will set this for us,
avoiding paradox */
bool celebrate; /* try to celebrate in this city */
bool diplomat_threat; /* enemy diplomat or spy is near the city */
bool has_diplomat; /* this city has diplomat or spy defender */
bool celebrate; /* Try to celebrate in this city */
bool diplomat_threat; /* Enemy diplomat or spy is near the city */
bool has_diplomat; /* This city has diplomat or spy defender */
/* These values are for builder (UTYF_WORKERS) and founder (UTYF_CITIES) units.
* Negative values indicate that the city needs a boat first;
......
enum effect_type effect_type,
const struct unit_type *utype);
adv_want dai_city_want(struct player *pplayer, struct city *acity,
adv_want dai_city_want(struct player *pplayer, struct city *acity,
struct adv_data *adv, struct impr_type *pimprove);
#endif /* FC__DAICITY_H */
    (1-1/1)