Freeciv-3.2: /fast/freeciv/nightly/S3_2/ai/default/daieffects.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
daieffects.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* common */
19#include "city.h"
20#include "effects.h"
21#include "game.h"
22#include "government.h"
23#include "map.h"
24#include "movement.h"
25#include "multipliers.h"
26#include "player.h"
27#include "research.h"
28#include "specialist.h"
29#include "traderoutes.h"
30#include "victory.h"
31
32/* server */
33#include "plrhand.h"
34
35/* server/advisors */
36#include "advdata.h"
37#include "advtools.h"
38
39/* ai */
40#include "aitraits.h"
41#include "handicaps.h"
42
43
44#include "daieffects.h"
45
46/**********************************************************************/
60 static int get_entertainers(const struct city *pcity)
61{
62 int providers = 0;
63
64 specialist_type_iterate(i) {
65 if (get_specialist_output(pcity, i, O_LUXURY) >= game.info.happy_cost) {
66 providers += pcity->specialists[i];
67 }
68 } specialist_type_iterate_end;
69
70 return providers;
71}
72
73/**********************************************************************/
77 adv_want dai_content_effect_value(const struct player *pplayer,
78 const struct city *pcity,
79 int amount,
80 int num_cities,
81 int happiness_step)
82{
83 adv_want v = 0;
84
85 if (get_city_bonus(pcity, EFT_NO_UNHAPPY) <= 0) {
86 int i;
87 int max_converted = pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL];
88
89 /* See if some step of happiness calculation gets capped */
90 for (i = happiness_step; i < FEELING_FINAL; i++) {
91 max_converted = MIN(max_converted, pcity->feel[CITIZEN_UNHAPPY][i]);
92 }
93
94 v = MIN(amount, max_converted + get_entertainers(pcity)) * 35;
95 }
96
97 if (num_cities > 1) {
98 int factor = 2;
99
100 /* Try to build wonders to offset empire size unhappiness */
101 if (city_list_size(pplayer->cities)
102 > get_player_bonus(pplayer, EFT_EMPIRE_SIZE_BASE)) {
103 if (get_player_bonus(pplayer, EFT_EMPIRE_SIZE_BASE) > 0) {
104 int step_bonus = get_player_bonus(pplayer, EFT_EMPIRE_SIZE_STEP);
105
106 factor += city_list_size(pplayer->cities)
107 / MAX(step_bonus, 1);
108 }
109 factor += 2;
110 }
111 v += factor * num_cities * amount;
112 }
113
114 return v;
115}
116
117/**********************************************************************/
120 static int num_affected_units(const struct effect *peffect,
121 const struct adv_data *ai)
122{
123 int unit_count = 0;
124
125 unit_class_iterate(pclass) {
126 if (requirement_fulfilled_by_unit_class(pclass, &peffect->reqs)) {
127 unit_count += ai->stats.units.byclass[uclass_index(pclass)];
128 }
129 } unit_class_iterate_end;
130
131 return unit_count;
132}
133
134/**********************************************************************/
138 adv_want dai_effect_value(struct player *pplayer,
139 const struct adv_data *adv, const struct city *pcity,
140 const bool capital, int turns,
141 const struct effect *peffect, const int c,
142 const int nplayers)
143{
144 int amount = peffect->value;
145 bool affects_sea_capable_units = FALSE;
146 bool affects_land_capable_units = FALSE;
147 int num;
148 int trait;
149 adv_want v = 0;
150 enum effect_type value_as;
151
152 if (peffect->multiplier) {
153 if (pplayer) {
154 amount = (player_multiplier_effect_value(pplayer, peffect->multiplier)
155 * amount) / 100;
156 } else {
157 amount = 0;
158 }
159 }
160
161 if (amount == 0) {
162 /* We could prune such effects in ruleset loading already,
163 * but we allow people tuning their rulesets to temporarily disable
164 * the effect by setting value to 0 without need to completely
165 * remove the effect.
166 * Shortcutting these effects here is not only for performance,
167 * more importantly it makes sure code below assuming amount to
168 * be positive does not assign positive value. */
169 return 0;
170 }
171
172 value_as = user_effect_ai_valued_as(peffect->type);
173
174 switch (value_as) {
175 /* These effects have already been evaluated in base_want() */
176 case EFT_CAPITAL_CITY:
177 case EFT_GOV_CENTER:
178 case EFT_UPKEEP_FREE:
179 case EFT_IMPR_UPKEEP_REDUCTION:
180 case EFT_TECH_UPKEEP_FREE:
181 case EFT_POLLU_POP_PCT:
182 case EFT_POLLU_POP_PCT_2:
183 case EFT_POLLU_PROD_PCT:
184 case EFT_OUTPUT_BONUS:
185 case EFT_OUTPUT_BONUS_ABSOLUTE:
186 case EFT_OUTPUT_BONUS_2:
187 case EFT_OUTPUT_ADD_TILE:
188 case EFT_OUTPUT_INC_TILE:
189 case EFT_OUTPUT_PER_TILE:
190 case EFT_OUTPUT_WASTE:
191 case EFT_OUTPUT_WASTE_BY_DISTANCE:
192 case EFT_OUTPUT_WASTE_BY_REL_DISTANCE:
193 case EFT_OUTPUT_WASTE_PCT:
194 case EFT_SURPLUS_WASTE_PCT:
195 case EFT_SURPLUS_WASTE_PCT_BY_REL_DISTANCE:
196 case EFT_SPECIALIST_OUTPUT:
197 case EFT_ENEMY_CITIZEN_UNHAPPY_PCT:
198 case EFT_IRRIGATION_PCT:
199 case EFT_MINING_PCT:
200 case EFT_OUTPUT_TILE_PUNISH_PCT:
201 break;
202
203 case EFT_CITY_VISION_RADIUS_SQ:
204 case EFT_UNIT_VISION_RADIUS_SQ:
205 /* Wild guess. "Amount" is the number of tiles (on average) that
206 * will be revealed by the effect. Note that with an omniscient
207 * AI this effect is actually not useful at all. */
208 v += c * amount;
209 break;
210
211 case EFT_TURN_YEARS:
212 case EFT_TURN_FRAGMENTS:
213 case EFT_SLOW_DOWN_TIMELINE:
214 /* AI doesn't care about these. */
215 break;
216
217 /* WAG evaluated effects */
218 case EFT_INCITE_COST_PCT:
219 v += c * amount / 100;
220 break;
221 case EFT_MAKE_HAPPY:
222 v += (get_entertainers(pcity) + pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]) * 5 * amount;
223 if (city_list_size(pplayer->cities)
224 > get_player_bonus(pplayer, EFT_EMPIRE_SIZE_BASE)) {
225 v += c * amount; /* Offset large empire size */
226 }
227 v += c * amount;
228 break;
229 case EFT_UNIT_RECOVER:
230 /* TODO */
231 break;
232 case EFT_NO_UNHAPPY:
233 v += (get_entertainers(pcity) + pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]) * 30;
234 break;
235 case EFT_FORCE_CONTENT:
236 v += dai_content_effect_value(pplayer, pcity, amount, c, FEELING_FINAL);
237 break;
238 case EFT_MAKE_CONTENT:
239 v += dai_content_effect_value(pplayer, pcity, amount, c, FEELING_EFFECT);
240 break;
241 case EFT_MAKE_CONTENT_MIL_PER:
242 if (get_city_bonus(pcity, EFT_NO_UNHAPPY) <= 0) {
243 v += MIN(pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL] + get_entertainers(pcity),
244 amount) * 25;
245 v += MIN(amount, 5) * c;
246 }
247 break;
248 case EFT_MAKE_CONTENT_MIL:
249 if (get_city_bonus(pcity, EFT_NO_UNHAPPY) <= 0) {
250 v += pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL] * amount
251 * MAX(unit_list_size(pcity->units_supported), 0) * 2;
252 v += c * MAX(amount + 2, 1);
253 }
254 break;
255 case EFT_TECH_PARASITE_PCT_MAX:
256 amount = (amount * research_count()) / 100;
257 fc__fallthrough;
258 case EFT_TECH_PARASITE:
259 {
260 int bulbs;
261 int value;
262
263 if (nplayers <= amount) {
264 break;
265 }
266
267 bulbs = 0;
268 players_iterate_alive(aplayer) {
269 if (aplayer != pplayer
270 && (!game.info.team_pooled_research
271 || !players_on_same_team(aplayer, pplayer))) {
272 bulbs += (aplayer->server.bulbs_last_turn
273 + city_list_size(aplayer->cities) + 1);
274 }
275 } players_iterate_alive_end;
276
277 /* For some number of turns we will be receiving bulbs for free
278 * Bulbs should be amortized properly for each turn.
279 * We use formula for the sum of geometric series:
280 */
281 value = bulbs * (1.0 - pow(1.0 - (1.0 / MORT), turns)) * MORT;
282
283 value = value * (100 - game.server.freecost)
284 * (nplayers - amount) / (nplayers * amount * 100);
285
286 /* WAG */
287 value /= 3;
288
289 v += value;
290 break;
291 }
292 case EFT_CONQUEST_TECH_PCT:
293 /* Compare to EFT_GIVE_IMM_TECH which gives game.info.sciencebox * num_techs */
294 v += game.info.sciencebox * (100 - game.server.conquercost) / 200
295 * amount / 100;
296 break;
297 case EFT_GROWTH_FOOD:
298 /* FIXME: As total value is clipped 0 ... 100, single
299 * effect should have no value at all in some cases. */
300 v += c * 4 + (amount / 10) * MAX(pcity->surplus[O_FOOD], 0);
301 break;
302 case EFT_SHRINK_FOOD:
303 v += c * 4 + (amount / 15) * MAX(-pcity->surplus[O_FOOD], 1);
304 break;
305 case EFT_POPCOST_FREE:
306 v += amount * city_granary_size(pcity->size) / 10;
307 break;
308 case EFT_HEALTH_PCT:
309 /* Is plague possible */
310 if (game.info.illness_on) {
311 v += c * 5 + (amount / 5) * pcity->server.illness;
312 }
313 break;
314 case EFT_AIRLIFT:
315 /* FIXME: We need some smart algorithm here. The below is
316 * totally braindead. */
317 v += c + MIN(adv->stats.units.airliftable, 13);
318 break;
319 case EFT_ANY_GOVERNMENT:
320 if (!can_change_to_government(pplayer, adv->goal.govt.gov)) {
321 v += MIN(MIN(adv->goal.govt.val, 65),
322 research_goal_unknown_techs(research_get(pplayer),
323 adv->goal.govt.req) * 10);
324 }
325 break;
326 case EFT_ENABLE_NUKE:
327 /* Treat nuke as a Cruise Missile upgrade */
328 v += 20 + adv->stats.units.suicide_attackers * 5;
329 break;
330 case EFT_ENABLE_SPACE:
331 if (victory_enabled(VC_SPACERACE)) {
332 v += 10;
333 if (adv->dipl.production_leader == pplayer
334 || adv->dipl.tech_leader == pplayer) {
335 v += 150;
336 }
337 }
338 break;
339 case EFT_VICTORY:
340 v += 250;
341 break;
342 case EFT_GIVE_IMM_TECH:
343 if (adv_wants_science(pplayer)) {
344 v += amount * (game.info.sciencebox + 1);
345 }
346 break;
347 case EFT_HAVE_CONTACTS:
348 {
349 int new_contacts = 0;
350
351 players_iterate_alive(theother) {
352 if (player_diplstate_get(pplayer, theother)->contact_turns_left <= 0) {
353 new_contacts++;
354 }
355 } players_iterate_alive_end;
356
357 v += 30 * new_contacts;
358 }
359 break;
360 case EFT_HAVE_EMBASSIES:
361 v += 2 * nplayers;
362 break;
363 case EFT_REVEAL_CITIES:
364 case EFT_NO_ANARCHY:
365 break; /* Useless for AI */
366 case EFT_NUKE_PROOF:
367 if (adv->threats.nuclear) {
368 v += city_size_get(pcity) * unit_list_size(pcity->tile->units)
369 * (capital + 1) * amount / 100;
370 }
371 break;
372 case EFT_REVEAL_MAP:
373 if (!adv->explore.land_done || !adv->explore.sea_done) {
374 v += 10;
375 }
376 break;
377 case EFT_UNIT_SLOTS:
378 v += 8 * c;
379 break;
380 case EFT_SIZE_UNLIMIT:
381 /* Note we look up the SIZE_UNLIMIT again right below. This could
382 * be avoided... */
383 if (amount > 0) {
384 if (get_city_bonus(pcity, EFT_SIZE_UNLIMIT) <= 0) {
385 amount = 20; /* really big city */
386 }
387 } else {
388 /* Effect trying to remove unlimit. */
389 v -= 30 * c * adv->food_priority;
390 break;
391 }
392 fc__fallthrough; /* there not being a break here is deliberate, mind you */
393 case EFT_SIZE_ADJ:
394 if (get_city_bonus(pcity, EFT_SIZE_UNLIMIT) <= 0) {
395 const int aqueduct_size = get_city_bonus(pcity, EFT_SIZE_ADJ);
396 int extra_food = pcity->surplus[O_FOOD];
397
398 if (city_granary_size(city_size_get(pcity)) == pcity->food_stock) {
399 /* The idea being that if we have a full granary, we have an
400 * automatic surplus of our granary excess in addition to anything
401 * collected by city workers. */
402 extra_food += pcity->food_stock -
403 city_granary_size(city_size_get(pcity) - 1);
404 }
405
406 if (amount > 0 && !city_can_grow_to(pcity, city_size_get(pcity) + 1)) {
407 v += extra_food * adv->food_priority * amount;
408 if (city_size_get(pcity) == aqueduct_size) {
409 v += 30 * extra_food;
410 }
411 }
412 v += c * amount * 4 / aqueduct_size;
413 }
414 break;
415 case EFT_SS_STRUCTURAL:
416 case EFT_SS_COMPONENT:
417 case EFT_SS_MODULE:
418 if (victory_enabled(VC_SPACERACE)
419 /* If someone has started building spaceship already or
420 * we have chance to win a spacerace */
421 && (adv->dipl.spacerace_leader
422 || adv->dipl.production_leader == pplayer
423 || adv->dipl.tech_leader == pplayer)) {
424 int space_want;
425
426 if (pcity->id == adv->wonder_city) {
427 /* adjust_improvement_wants_by_effects() lowers want for any non-wonder
428 * target on wonder city. We want space part want reduced even more than
429 * regular buildings, as buildings are at least helping the specific city
430 * when finished. */
431 space_want = 120;
432 } else {
433 space_want = 210;
434 }
435
436 if (pplayer->spaceship.state == SSHIP_STARTED) {
437 /* We are already running. Let's not make it a half-hearted attempt. */
438 space_want *= 3;
439 }
440
441 v += space_want;
442 }
443 break;
444 case EFT_SPY_RESISTANT:
445 case EFT_SABOTEUR_RESISTANT:
446 /* Uhm, problem: City Wall has -50% here!! */
447 break;
448 case EFT_MOVE_BONUS:
449 num = num_affected_units(peffect, adv);
450 v += (8 * v * amount + num);
451 break;
452 case EFT_ACTIVITY_TIME:
453 /* TODO: As an override, this can be either good or bad,
454 * depending on the value being overridden. */
455 break;
456 case EFT_UNIT_NO_LOSE_POP:
457 v += unit_list_size(pcity->tile->units) * 2;
458 break;
459 case EFT_HP_REGEN:
460 case EFT_HP_REGEN_2:
461 num = num_affected_units(peffect, adv);
462 v += (5 * c + num);
463 break;
464 case EFT_MIN_HP_PCT:
465 num = num_affected_units(peffect, adv);
466 /* Lesser value than EFT_HP_REGEN as this does not add health
467 * with full effect value, but only up to the effect value.
468 * Only badly wounded units affected at all. */
469 v += (3 * c + num);
470 break;
471 case EFT_VETERAN_COMBAT:
472 num = num_affected_units(peffect, adv);
473 v += (2 * c + num);
474 break;
475 case EFT_VETERAN_BUILD:
476 /* FIXME: check other reqs (e.g., unitflag) */
477 num = num_affected_units(peffect, adv);
478 v += amount * (3 * c + num);
479 break;
480 case EFT_UPGRADE_UNIT:
481 if (amount == 1) {
482 v += adv->stats.units.upgradeable * 2;
483 } else if (amount == 2) {
484 v += adv->stats.units.upgradeable * 3;
485 } else {
486 v += adv->stats.units.upgradeable * 4;
487 }
488 break;
489 case EFT_UNIT_BRIBE_COST_PCT:
490 num = num_affected_units(peffect, adv);
491 v += ((2 * c + num) * amount) / 400;
492 break;
493 case EFT_ATTACK_BONUS:
494 num = num_affected_units(peffect, adv);
495 v += (num + 4) * amount / 200;
496 break;
497 case EFT_DEFEND_BONUS:
498 if (has_handicap(pplayer, H_DEFENSIVE)) {
499 v += amount / 10; /* make AI slow */
500 }
501
502 /* TODO: Really should consider how many affected enemy units there is. */
503 unit_class_iterate(pclass) {
504 if (requirement_fulfilled_by_unit_class(pclass, &peffect->reqs)) {
505 if (pclass->adv.sea_move != MOVE_NONE) {
506 affects_sea_capable_units = TRUE;
507 }
508 if (pclass->adv.land_move != MOVE_NONE) {
509 affects_land_capable_units = TRUE;
510 }
511 }
512 if (affects_sea_capable_units && affects_land_capable_units) {
513 /* Don't bother searching more if we already know enough. */
514 break;
515 }
516 } unit_class_iterate_end;
517
518 if (affects_sea_capable_units) {
519 if (is_ocean_tile(pcity->tile)) {
520 v += adv->oceans[-tile_continent(pcity->tile)].threat
521 ? amount / 6 : amount / 25;
522 } else {
523 adjc_iterate(&(wld.map), pcity->tile, tile2) {
524 if (is_ocean_tile(tile2)) {
525 if (adv->oceans[-tile_continent(tile2)].threat) {
526 v += amount / 6;
527 break;
528 }
529 }
530 } adjc_iterate_end;
531 }
532 }
533 v += (amount / 25 + adv->threats.invasions - 1) * c; /* For wonder */
534 if (capital || affects_land_capable_units) {
535 Continent_id place = tile_continent(pcity->tile);
536
537 if ((place > 0 && adv->continents[place].threat)
538 || capital
539 || (adv->threats.invasions
540 /* FIXME: This ignores riverboats on some rulesets.
541 We should analyze rulesets when game starts
542 and have relevant checks here. */
543 && is_terrain_class_near_tile(&(wld.map), pcity->tile, TC_OCEAN))) {
544 if (place > 0 && adv->continents[place].threat) {
545 v += amount * 4 / 5;
546 } else {
547 v += amount / (!adv->threats.igwall ? (18 - capital * 6) : 18);
548 }
549 }
550 }
551 break;
552 case EFT_FORTIFY_DEFENSE_BONUS:
553 num = num_affected_units(peffect, adv);
554 v += (num + 4) * amount / 250; /* Divisor 250 is a bit bigger than one for
555 * EFT_ATTACK_BONUS that is always active.
556 * Fortify bonus applies only in special case that
557 * unit is fortified. */
558 break;
559 case EFT_GAIN_AI_LOVE:
560 players_iterate(aplayer) {
561 if (is_ai(aplayer)) {
562 if (has_handicap(pplayer, H_DEFENSIVE)) {
563 v += amount / 10;
564 } else {
565 v += amount / 20;
566 }
567 }
568 } players_iterate_end;
569 break;
570 case EFT_UPGRADE_PRICE_PCT:
571 /* This is based on average base upgrade price of 50. */
572 v -= adv->stats.units.upgradeable * amount / 2;
573 break;
574 case EFT_BORDER_STRENGTH_PCT:
575 v += amount / 4;
576 break;
577
578 /* Currently not supported for building AI - wait for modpack users */
579 case EFT_CITY_UNHAPPY_SIZE:
580 case EFT_UNHAPPY_FACTOR:
581 case EFT_UPKEEP_FACTOR:
582 case EFT_UNIT_UPKEEP_FREE_PER_CITY:
583 case EFT_CIVIL_WAR_CHANCE:
584 case EFT_EMPIRE_SIZE_BASE:
585 case EFT_EMPIRE_SIZE_STEP:
586 case EFT_MAX_RATES:
587 case EFT_MARTIAL_LAW_EACH:
588 case EFT_MARTIAL_LAW_MAX:
589 case EFT_RAPTURE_GROW:
590 case EFT_REVOLUTION_UNHAPPINESS:
591 case EFT_HAS_SENATE:
592 case EFT_INSPIRE_PARTISANS:
593 case EFT_HAPPINESS_TO_GOLD:
594 case EFT_FANATICS:
595 case EFT_NO_DIPLOMACY:
596 case EFT_NOT_TECH_SOURCE:
597 case EFT_OUTPUT_PENALTY_TILE:
598 case EFT_OUTPUT_INC_TILE_CELEBRATE:
599 case EFT_TRADE_REVENUE_BONUS:
600 case EFT_TILE_WORKABLE:
601 case EFT_COMBAT_ROUNDS:
602 case EFT_ILLEGAL_ACTION_MOVE_COST:
603 case EFT_ILLEGAL_ACTION_HP_COST:
604 case EFT_CASUS_BELLI_CAUGHT:
605 case EFT_CASUS_BELLI_SUCCESS:
606 case EFT_CASUS_BELLI_COMPLETE:
607 case EFT_ACTION_ODDS_PCT:
608 case EFT_ACTION_RESIST_PCT:
609 case EFT_BORDER_VISION:
610 case EFT_STEALINGS_IGNORE:
611 case EFT_MAPS_STOLEN_PCT:
612 case EFT_UNIT_SHIELD_VALUE_PCT:
613 case EFT_NUKE_BLAST_RADIUS_1_SQ:
614 case EFT_HEAL_UNIT_PCT:
615 break;
616 /* This has no effect for AI */
617 case EFT_VISIBLE_WALLS:
618 case EFT_CITY_IMAGE:
619 case EFT_SHIELD2GOLD_FACTOR:
620 break;
621 case EFT_PERFORMANCE:
622 case EFT_NATION_PERFORMANCE:
623 /* Consider each culture point worth 1/10 point, minimum of 1 point... */
624 v += amount / 10 + 1;
625 break;
626 case EFT_HISTORY:
627 case EFT_NATION_HISTORY:
628 /* ...and history effect to accumulate those points for 50 turns. */
629 v += amount * 5;
630 break;
631 case EFT_TECH_COST_FACTOR:
632 v -= amount * 50;
633 break;
634 case EFT_IMPR_BUILD_COST_PCT:
635 case EFT_UNIT_BUILD_COST_PCT:
636 v -= amount * 30;
637 break;
638 case EFT_IMPR_BUY_COST_PCT:
639 case EFT_UNIT_BUY_COST_PCT:
640 v -= amount * 25;
641 break;
642 case EFT_CITY_RADIUS_SQ:
643 v += amount * 10; /* AI wants bigger city radii */
644 break;
645 case EFT_CITY_BUILD_SLOTS:
646 v += amount * 10;
647 break;
648 case EFT_MIGRATION_PCT:
649 /* Consider all foreign cities within set distance */
650 iterate_outward(&(wld.map), city_tile(pcity),
651 game.server.mgr_distance + (int)sqrt(MAX(city_map_radius_sq_get(pcity), 0)),
652 ptile) {
653 struct city *acity = tile_city(ptile);
654
655 if (!acity || acity == pcity || city_owner(acity) == pplayer) {
656 /* No city, the city in the center, or our own city */
657 continue;
658 }
659
660 v += amount; /* AI wants migration into its cities! */
661 } iterate_outward_end;
662 break;
663 case EFT_MAX_TRADE_ROUTES:
664 {
665 /* We may know no caravans yet, then consider primary one
666 * (Supposed that if this effect is defined then some unit
667 * can establish trade routes) */
668 int trr = action_id_get_role(ACTION_TRADE_ROUTE);
669 const struct unit_type *van = best_role_unit(pcity, trr);
670 int bonus;
671
672 if (NULL == van){
673 if (0 < num_role_units(trr)) {
674 van = get_role_unit(trr, 0);
675 }
676 }
677 /* NOTE: if you have "DiplRel" in reqs, becomes 0 */
678 bonus =
679 get_target_bonus_effects(NULL,
680 &(const struct req_context) {
681 .player = city_owner(pcity),
682 .city = pcity,
683 .tile = city_tile(pcity),
684 .unittype = van
685 }, NULL, EFT_TRADE_REVENUE_BONUS);
686
687 trait = ai_trait_get_value(TRAIT_TRADER, pplayer);
688 v += amount
689 * (pow(2.0,
690 (double) bonus / 1000.0)
691 + c)
692 * trait
693 / TRAIT_DEFAULT_VALUE;
694 if (city_num_trade_routes(pcity) >= max_trade_routes(pcity)
695 && amount > 0) {
696 /* Has no free trade routes before this */
697 v += trait;
698 }
699 }
700 break;
701 case EFT_TRADE_ROUTE_PCT:
702 {
703 int trade = 0;
704
705 trait = ai_trait_get_value(TRAIT_TRADER, pplayer);
706
707 trade_partners_iterate(pcity, tgt) {
708 trade += trade_base_between_cities(pcity, tgt);
709 } trade_partners_iterate_end;
710
711 v += trade * amount * trait / 100 / TRAIT_DEFAULT_VALUE;
712
713 if (city_num_trade_routes(pcity) < max_trade_routes(pcity)
714 && amount > 0) {
715 /* Space for future routes */
716 v += trait * 5 / TRAIT_DEFAULT_VALUE;
717 }
718 }
719 break;
720 case EFT_MAX_STOLEN_GOLD_PM:
721 v -= amount / 40;
722 break;
723 case EFT_THIEFS_SHARE_PM:
724 v -= amount / 80;
725 break;
726 case EFT_RETIRE_PCT:
727 num = num_affected_units(peffect, adv);
728 v -= amount * num / 20;
729 break;
730 case EFT_ACTION_SUCCESS_MOVE_COST:
731 case EFT_ACTION_SUCCESS_TARGET_MOVE_COST:
732 {
733 /* Taking MAX_MOVE_FRAGS takes all the move fragments. */
734 adv_want move_fragment_cost = MIN(MAX_MOVE_FRAGS, amount);
735
736 /* Lose all movement => 1. */
737 v -= move_fragment_cost / (adv_want)MAX_MOVE_FRAGS;
738 }
739 break;
740 case EFT_INFRA_POINTS:
741 v += amount * adv->infra_priority;
742 break;
743 case EFT_USER_EFFECT_1:
744 case EFT_USER_EFFECT_2:
745 case EFT_USER_EFFECT_3:
746 case EFT_USER_EFFECT_4:
747 /* The AI has no idea what this does. */
748 break;
749 case EFT_COUNT:
750 log_error("Bad effect type.");
751 break;
752 }
753
754 return v;
755}
756
757/**********************************************************************/
760 static bool have_better_government(const struct player *pplayer,
761 const struct government *pgov)
762{
763 if (pgov->ai.better) {
764 if (pplayer->government == pgov->ai.better) {
765 return TRUE;
766 } else {
767 return have_better_government(pplayer, pgov->ai.better);
768 }
769 }
770 return FALSE;
771}
772/**********************************************************************/
782 bool dai_can_requirement_be_met_in_city(const struct requirement *preq,
783 const struct player *pplayer,
784 const struct city *pcity)
785{
786 switch (preq->source.kind) {
787 case VUT_GOVERNMENT:
788 /* We can't meet a government requirement if we have a better one. */
789 return !have_better_government(pplayer, preq->source.value.govern);
790
791 case VUT_IMPROVEMENT: {
792 const struct impr_type *pimprove = preq->source.value.building;
793
794 if (preq->present && improvement_obsolete(pplayer, pimprove, pcity)) {
795 /* Would need to unobsolete a building, which is too hard. */
796 return FALSE;
797 } else if (!preq->present && pcity != NULL
798 && I_NEVER < pcity->built[improvement_index(pimprove)].turn
799 && !can_improvement_go_obsolete(pimprove)) {
800 /* Would need to unbuild an unobsoleteable building, which is too hard. */
801 return FALSE;
802 } else if (preq->present) {
803 requirement_vector_iterate(&pimprove->reqs, ireq) {
804 if (!dai_can_requirement_be_met_in_city(ireq, pplayer, pcity)) {
805 return FALSE;
806 }
807 } requirement_vector_iterate_end;
808 }
809 break;
810 } /* VUT_IMPROVEMENT inline block */
811
812 case VUT_SPECIALIST:
813 if (preq->present) {
814 requirement_vector_iterate(&(preq->source.value.specialist)->reqs,
815 sreq) {
816 if (!dai_can_requirement_be_met_in_city(sreq, pplayer, pcity)) {
817 return FALSE;
818 }
819 } requirement_vector_iterate_end;
820 } /* It is always possible to remove a specialist. */
821 break;
822
823 case VUT_NATIONALITY:
824 /* Crude, but the right answer needs to consider civil wars. */
825 return nation_is_in_current_set(preq->source.value.nation);
826
827 case VUT_ORIGINAL_OWNER:
828 return FALSE;
829
830 case VUT_CITYSTATUS:
831 if (pcity != NULL) {
832 if (preq->source.value.citystatus == CITYS_OWNED_BY_ORIGINAL
833 && pcity->original != NULL) {
834 if (preq->present) {
835 return city_owner(pcity) == pcity->original;
836 } else {
837 return city_owner(pcity) != pcity->original;
838 }
839 } else if (preq->source.value.citystatus == CITYS_TRANSFERRED) {
840 if ((preq->present && pcity->acquire_t == CACQ_FOUNDED)
841 || (!preq->present && pcity->acquire_t != CACQ_FOUNDED)) {
842 /* Would change only when the AI loses the city */
843 return FALSE;
844 }
845 }
846 }
847 break;
848 case VUT_TERRAIN:
849 case VUT_TERRAINCLASS:
850 case VUT_TERRAINALTER:
851 case VUT_TERRFLAG:
852 case VUT_ROADFLAG:
853 case VUT_EXTRAFLAG:
854 case VUT_EXTRA:
855 /* TODO: These could be determined by building a map of all
856 * possible futures (e.g. terrain transformations, etc.),
857 * and traversing it for all tiles in largest possible range
858 * of city, and using that to check requirements. */
859 break;
860
861 case VUT_ADVANCE:
862 case VUT_MINSIZE:
863 case VUT_MINYEAR:
864 case VUT_TOPO:
865 case VUT_WRAP:
866 case VUT_AGE:
867 case VUT_TECHFLAG:
868 case VUT_ACHIEVEMENT:
869 case VUT_MINCULTURE:
870 case VUT_MINTECHS:
871 /* No way to remove once present. */
872 return preq->present;
873
874 case VUT_FORM_AGE:
875 /* FIXME: Sometimes it would be possible to convert back and forth */
876 return preq->present;
877
878 case VUT_MINFOREIGNPCT:
879 /* No way to add once lost. */
880 return !preq->present;
881
882 case VUT_NATION:
883 case VUT_NATIONGROUP:
884 case VUT_AI_LEVEL:
885 case VUT_SERVERSETTING:
886 case VUT_MINLATITUDE:
887 case VUT_MAXLATITUDE:
888 case VUT_PLAYER_FLAG:
889 case VUT_PLAYER_STATE:
890 /* Beyond player control. */
891 return FALSE;
892
893 case VUT_OTYPE:
894 case VUT_IMPR_GENUS:
895 /* Can always be achieved. */
896 return TRUE;
897
898 case VUT_IMPR_FLAG:
899 /* TODO: Have at least some checks for this. */
900 break;
901
902 case VUT_NONE:
903 case VUT_COUNTER:
904 case VUT_UTYPE:
905 case VUT_UTFLAG:
906 case VUT_UCLASS:
907 case VUT_UCFLAG:
908 case VUT_DIPLREL:
909 case VUT_DIPLREL_TILE:
910 case VUT_DIPLREL_TILE_O:
911 case VUT_DIPLREL_UNITANY:
912 case VUT_DIPLREL_UNITANY_O:
913 case VUT_MAXTILEUNITS:
914 case VUT_STYLE:
915 case VUT_UNITSTATE:
916 case VUT_ACTIVITY:
917 case VUT_CITYTILE:
918 case VUT_MINMOVES:
919 case VUT_MINVETERAN:
920 case VUT_MINHP:
921 case VUT_ACTION:
922 case VUT_GOOD:
923 case VUT_MINCALFRAG:
924 case VUT_COUNT:
925 /* No sensible implementation possible with data available. */
926 break;
927 }
928
929 return TRUE;
930}
action_id_get_role
#define action_id_get_role(act_id)
Definition actions.h:694
adv_wants_science
bool adv_wants_science(struct player *pplayer)
Definition advdata.c:1096
advdata.h
advtools.h
MORT
#define MORT
Definition advtools.h:19
ai_trait_get_value
int ai_trait_get_value(enum trait tr, struct player *pplayer)
Definition aitraits.c:69
aitraits.h
city_granary_size
int city_granary_size(int city_size)
Definition city.c:2123
city_can_grow_to
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2004
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:136
city.h
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
CITIZEN_UNHAPPY
@ CITIZEN_UNHAPPY
Definition city.h:270
city_owner
#define city_owner(_pcity_)
Definition city.h:563
FEELING_EFFECT
@ FEELING_EFFECT
Definition city.h:281
FEELING_FINAL
@ FEELING_FINAL
Definition city.h:284
incite_cost
char * incite_cost
Definition comments.c:74
dai_can_requirement_be_met_in_city
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Definition daieffects.c:782
dai_effect_value
adv_want dai_effect_value(struct player *pplayer, const struct adv_data *adv, const struct city *pcity, const bool capital, int turns, const struct effect *peffect, const int c, const int nplayers)
Definition daieffects.c:138
dai_content_effect_value
adv_want dai_content_effect_value(const struct player *pplayer, const struct city *pcity, int amount, int num_cities, int happiness_step)
Definition daieffects.c:77
num_affected_units
static int num_affected_units(const struct effect *peffect, const struct adv_data *ai)
Definition daieffects.c:120
have_better_government
static bool have_better_government(const struct player *pplayer, const struct government *pgov)
Definition daieffects.c:760
get_entertainers
static int get_entertainers(const struct city *pcity)
Definition daieffects.c:60
daieffects.h
get_target_bonus_effects
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct player *other_player, enum effect_type effect_type)
Definition effects.c:748
get_city_bonus
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:846
user_effect_ai_valued_as
enum effect_type user_effect_ai_valued_as(enum effect_type real)
Definition effects.c:1359
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
effects.h
adv_want
float adv_want
Definition fc_types.h:1355
VC_SPACERACE
@ VC_SPACERACE
Definition fc_types.h:1272
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_LUXURY
@ O_LUXURY
Definition fc_types.h:101
Continent_id
signed short Continent_id
Definition fc_types.h:375
game
struct civ_game game
Definition game.c:62
wld
struct world wld
Definition game.c:63
game.h
can_change_to_government
bool can_change_to_government(struct player *pplayer, const struct government *gov)
Definition government.c:166
government.h
has_handicap
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
handicaps.h
H_DEFENSIVE
@ H_DEFENSIVE
Definition handicaps.h:21
can_improvement_go_obsolete
bool can_improvement_go_obsolete(const struct impr_type *pimprove)
Definition improvement.c:403
improvement_index
Impr_type_id improvement_index(const struct impr_type *pimprove)
Definition improvement.c:175
improvement_obsolete
bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity)
Definition improvement.c:411
log_error
#define log_error(message,...)
Definition log.h:103
map.h
iterate_outward
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:367
iterate_outward_end
#define iterate_outward_end
Definition map.h:371
adjc_iterate_end
#define adjc_iterate_end
Definition map.h:433
adjc_iterate
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
movement.h
MAX_MOVE_FRAGS
#define MAX_MOVE_FRAGS
Definition movement.h:29
multipliers.h
player_multiplier_effect_value
int player_multiplier_effect_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1969
players_on_same_team
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1476
player_diplstate_get
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
player.h
players_iterate_end
#define players_iterate_end
Definition player.h:537
players_iterate
#define players_iterate(_pplayer)
Definition player.h:532
is_ai
#define is_ai(plr)
Definition player.h:230
players_iterate_alive_end
#define players_iterate_alive_end
Definition player.h:547
players_iterate_alive
#define players_iterate_alive(_pplayer)
Definition player.h:542
nation_is_in_current_set
bool nation_is_in_current_set(const struct nation_type *pnation)
Definition plrhand.c:2585
plrhand.h
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
requirement_fulfilled_by_unit_class
#define requirement_fulfilled_by_unit_class(_uc_, _rqs_)
Definition requirements.h:423
research_goal_unknown_techs
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:750
research_count
int research_count(void)
Definition research.c:1328
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:128
research.h
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
SSHIP_STARTED
@ SSHIP_STARTED
Definition spaceship.h:84
get_specialist_output
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
Definition specialist.c:217
specialist.h
specialist_type_iterate_end
#define specialist_type_iterate_end
Definition specialist.h:79
specialist_type_iterate
#define specialist_type_iterate(sp)
Definition specialist.h:73
adv_area_info::threat
bool threat
Definition advdata.h:47
adv_data
Definition advdata.h:50
adv_data::req
int req
Definition advdata.h:133
adv_data::val
adv_want val
Definition advdata.h:132
adv_data::threats
struct adv_data::@89 threats
adv_data::invasions
bool invasions
Definition advdata.h:66
adv_data::igwall
bool igwall
Definition advdata.h:69
adv_data::dipl
struct adv_data::@92 dipl
adv_data::units
struct adv_data::@91::@94 units
adv_data::byclass
int byclass[UCL_LAST]
Definition advdata.h:91
adv_data::nuclear
int nuclear
Definition advdata.h:68
adv_data::upgradeable
int upgradeable
Definition advdata.h:94
adv_data::food_priority
int food_priority
Definition advdata.h:114
adv_data::oceans
struct adv_area_info * oceans
Definition advdata.h:62
adv_data::production_leader
struct player * production_leader
Definition advdata.h:106
adv_data::gov
struct government * gov
Definition advdata.h:131
adv_data::goal
struct adv_data::@93 goal
adv_data::continents
struct adv_area_info * continents
Definition advdata.h:61
adv_data::airliftable
int airliftable
Definition advdata.h:89
adv_data::stats
struct adv_data::@91 stats
adv_data::govt
struct adv_data::@93::@95 govt
adv_data::sea_done
bool sea_done
Definition advdata.h:77
adv_data::suicide_attackers
int suicide_attackers
Definition advdata.h:89
adv_data::wonder_city
int wonder_city
Definition advdata.h:55
adv_data::explore
struct adv_data::@90 explore
adv_data::land_done
bool land_done
Definition advdata.h:76
adv_data::tech_leader
struct player * tech_leader
Definition advdata.h:105
adv_data::spacerace_leader
struct player * spacerace_leader
Definition advdata.h:104
city
Definition city.h:320
city::surplus
int surplus[O_LAST]
Definition city.h:355
city::food_stock
int food_stock
Definition city.h:367
city::original
struct player * original
Definition city.h:324
city::id
int id
Definition city.h:326
city::acquire_t
enum city_acquire_type acquire_t
Definition city.h:329
city::size
citizens size
Definition city.h:332
city::illness
int illness
Definition city.h:434
city::feel
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:333
city::specialists
citizens specialists[SP_MAX]
Definition city.h:336
city::tile
struct tile * tile
Definition city.h:322
city::server
struct city::@17::@19 server
city::units_supported
struct unit_list * units_supported
Definition city.h:406
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::conquercost
int conquercost
Definition game.h:136
civ_game::freecost
int freecost
Definition game.h:148
civ_game::server
struct civ_game::@31::@35 server
civ_game::mgr_distance
int mgr_distance
Definition game.h:158
effect
Definition effects.h:365
government
Definition government.h:52
government::better
struct government * better
Definition government.h:65
government::ai
struct government::@41 ai
impr_type
Definition improvement.h:50
impr_type::reqs
struct requirement_vector reqs
Definition improvement.h:58
packet_game_info::team_pooled_research
bool team_pooled_research
Definition packets_gen.h:224
packet_game_info::happy_cost
int happy_cost
Definition packets_gen.h:176
packet_game_info::illness_on
bool illness_on
Definition packets_gen.h:181
packet_game_info::sciencebox
int sciencebox
Definition packets_gen.h:220
player_spaceship::state
enum spaceship_state state
Definition spaceship.h:108
player
Definition player.h:247
player::cities
struct city_list * cities
Definition player.h:279
player::government
struct government * government
Definition player.h:256
player::ai
const struct ai_type * ai
Definition player.h:287
player::spaceship
struct player_spaceship spaceship
Definition player.h:284
req_context
Definition requirements.h:100
requirement
Definition requirements.h:81
tile::units
struct unit_list * units
Definition tile.h:58
unit_type
Definition unittype.h:500
unit_type::adv
struct unit_type::@87 adv
world::map
struct civ_map map
Definition world_object.h:38
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc__fallthrough
#define fc__fallthrough
Definition support.h:119
is_terrain_class_near_tile
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:612
is_ocean_tile
#define is_ocean_tile(ptile)
Definition terrain.h:303
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_continent
#define tile_continent(_tile)
Definition tile.h:92
trade_base_between_cities
int trade_base_between_cities(const struct city *pc1, const struct city *pc2)
Definition traderoutes.c:322
city_num_trade_routes
int city_num_trade_routes(const struct city *pcity)
Definition traderoutes.c:383
max_trade_routes
unsigned max_trade_routes(const struct city *pcity)
Definition traderoutes.c:48
traderoutes.h
trade_partners_iterate_end
#define trade_partners_iterate_end
Definition traderoutes.h:166
trade_partners_iterate
#define trade_partners_iterate(c, p)
Definition traderoutes.h:161
TRAIT_DEFAULT_VALUE
#define TRAIT_DEFAULT_VALUE
Definition traits.h:32
best_role_unit
struct unit_type * best_role_unit(const struct city *pcity, int role)
Definition unittype.c:2271
get_role_unit
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2253
num_role_units
int num_role_units(int role)
Definition unittype.c:2203
unit_class_iterate
#define unit_class_iterate(_p)
Definition unittype.h:905
MOVE_NONE
@ MOVE_NONE
Definition unittype.h:144
uclass_index
#define uclass_index(_c_)
Definition unittype.h:742
unit_class_iterate_end
#define unit_class_iterate_end
Definition unittype.h:912
victory_enabled
bool victory_enabled(enum victory_condition_type victory)
Definition victory.c:26
victory.h