Freeciv-3.1
Loading...
Searching...
No Matches
daimilitary.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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#include <string.h>
19
20/* utility */
21#include "log.h"
22
23/* common */
24#include "combat.h"
25#include "game.h"
26#include "government.h"
27#include "map.h"
28#include "movement.h"
29#include "research.h"
30#include "specialist.h"
31#include "unitlist.h"
32
33/* common/aicore */
34#include "pf_tools.h"
35
36/* server */
37#include "citytools.h"
38#include "cityturn.h"
39#include "srv_log.h"
40#include "srv_main.h"
41
42/* server/advisors */
43#include "advbuilding.h"
44#include "advchoice.h"
45#include "advdata.h"
46#include "advgoto.h"
47#include "advtools.h"
48#include "autosettlers.h"
49#include "infracache.h" /* adv_city */
50
51/* ai */
52#include "aitraits.h"
53#include "difficulty.h"
54#include "handicaps.h"
55
56/* ai/default */
57#include "aiair.h"
58#include "aidata.h"
59#include "aidiplomat.h"
60#include "aiferry.h"
61#include "aihand.h"
62#include "aihunt.h"
63#include "ailog.h"
64#include "aiparatrooper.h"
65#include "aiplayer.h"
66#include "aitech.h"
67#include "aitools.h"
68#include "aiunit.h"
69#include "daicity.h"
70#include "daieffects.h"
71
72#include "daimilitary.h"
73
74/* Size 1 city gets destroyed when conquered. It's still a good thing
75 * stop enemy from having it. */
76#define CITY_CONQUEST_WORTH(_city_, _data_) \
77 (_data_->worth * 0.9 + (city_size_get(_city_) - 0.5) * 10)
78
79static unsigned int assess_danger(struct ai_type *ait,
80 const struct civ_map *nmap,
81 struct city *pcity,
83
85 const struct unit_type *punittype);
87 const struct unit_type *punittype);
88
89/**********************************************************************/
93 struct unit *attacker)
94{
95 struct unit_type *bestunit = NULL;
96 double best = 0;
97 int best_cost = FC_INFINITY;
98 struct player *pplayer = city_owner(pcity);
99 struct civ_map *nmap = &(wld.map);
100
101 simple_ai_unit_type_iterate(punittype) {
102 if (can_city_build_unit_now(nmap, pcity, punittype)) {
103 int fpatt, fpdef, defense, attack;
104 double want, loss, cost = utype_build_shield_cost(pcity, NULL, punittype);
105 struct unit *defender;
106 int veteran = get_unittype_bonus(city_owner(pcity), pcity->tile,
107 punittype, NULL,
108 EFT_VETERAN_BUILD);
109
110 defender = unit_virtual_create(pplayer, pcity, punittype, veteran);
111 defense = get_total_defense_power(attacker, defender);
112 attack = get_total_attack_power(attacker, defender);
113 get_modified_firepower(nmap, attacker, defender, &fpatt, &fpdef);
114
115 /* Greg's algorithm. loss is the average number of health lost by
116 * defender. If loss > attacker's hp then we should win the fight,
117 * which is always a good thing, since we avoid shield loss. */
118 loss = (double) defense * punittype->hp * fpdef / (attack * fpatt);
119 want = (loss + MAX(0, loss - attacker->hp)) / cost;
120
121#ifdef NEVER
122 CITY_LOG(LOG_DEBUG, pcity, "desire for %s against %s(%d,%d) is %.2f",
123 unit_name_orig(punittype),
124 unit_name_orig(unit_type_get(attacker)),
125 TILE_XY(attacker->tile), want);
126#endif /* NEVER */
127
128 if (want > best || (ADV_WANTS_EQ(want, best)
129 && cost <= best_cost)) {
130 best = want;
131 bestunit = punittype;
132 best_cost = cost;
133 }
134 unit_virtual_destroy(defender);
135 }
137
138 return bestunit;
139}
140
141/**********************************************************************/
146static struct unit_type *dai_choose_attacker(struct ai_type *ait,
147 struct city *pcity,
148 enum terrain_class tc,
149 bool allow_gold_upkeep)
150{
151 struct unit_type *bestid = NULL;
152 adv_want best = -1;
153 adv_want cur;
154 struct player *pplayer = city_owner(pcity);
155 const struct civ_map *nmap = &(wld.map);
156
158 if (!allow_gold_upkeep && utype_upkeep_cost(putype, pplayer, O_GOLD) > 0) {
159 continue;
160 }
161
162 cur = dai_unit_attack_desirability(ait, putype);
163 if ((tc == TC_LAND && utype_class(putype)->adv.land_move != MOVE_NONE)
164 || (tc == TC_OCEAN
165 && utype_class(putype)->adv.sea_move != MOVE_NONE)) {
166 if (can_city_build_unit_now(nmap, pcity, putype)
167 && (cur > best
168 || (ADV_WANTS_EQ(cur, best)
169 && utype_build_shield_cost(pcity, NULL, putype)
170 <= utype_build_shield_cost(pcity, NULL, bestid)))) {
171 best = cur;
172 bestid = putype;
173 }
174 }
176
177 return bestid;
178}
179
180/**********************************************************************/
188static struct unit_type *dai_choose_bodyguard(struct ai_type *ait,
189 const struct civ_map *nmap,
190 struct city *pcity,
191 enum terrain_class tc,
192 enum unit_role_id role,
193 bool allow_gold_upkeep)
194{
195 struct unit_type *bestid = NULL;
196 adv_want best = 0;
197 struct player *pplayer = city_owner(pcity);
198
200 /* Only consider units of given role, or any if invalid given */
201 if (unit_role_id_is_valid(role)) {
202 if (!utype_has_role(putype, role)) {
203 continue;
204 }
205 }
206
207 if (!allow_gold_upkeep && utype_upkeep_cost(putype, pplayer, O_GOLD) > 0) {
208 continue;
209 }
210
211 /* Only consider units of same move type */
212 if ((tc == TC_LAND && utype_class(putype)->adv.land_move == MOVE_NONE)
213 || (tc == TC_OCEAN
214 && utype_class(putype)->adv.sea_move == MOVE_NONE)) {
215 continue;
216 }
217
218 /* Now find best */
219 if (can_city_build_unit_now(nmap, pcity, putype)) {
220 const adv_want desire = dai_unit_defense_desirability(ait, putype);
221
222 if (desire > best
223 || (ADV_WANTS_EQ(desire, best) && utype_build_shield_cost(pcity, NULL, putype) <=
224 utype_build_shield_cost(pcity, NULL, bestid))) {
225 best = desire;
226 bestid = putype;
227 }
228 }
230
231 return bestid;
232}
233
234/**********************************************************************/
237static int base_assess_defense_unit(struct city *pcity, struct unit *punit,
238 bool igwall, bool quadratic,
239 int wall_value)
240{
241 int defense;
242 int fp;
243
244 if (!is_military_unit(punit)) {
245 return 0;
246 }
247
248 defense = get_fortified_defense_power(NULL, punit) * punit->hp;
250 if (unit_has_type_flag(punit, UTYF_BADCITYDEFENDER)) {
251 /* Attacker firepower doubled, defender firepower set to
252 * game.info.low_firepower_pearl_harbour at max. */
254 defense /= 2;
255 } else {
256 defense *= fp;
257 }
258
259 defense /= POWER_DIVIDER;
260
261 if (quadratic) {
262 defense *= defense;
263 }
264
265 if (pcity != NULL && !igwall && city_got_defense_effect(pcity, NULL)) {
266 /* FIXME: We checked if city got defense effect against *some*
267 * unit type. Sea unit danger might cause us to build defenses
268 * against air units... */
269
270 /* TODO: What about wall_value < 10? Do we really want walls to
271 * result in decrease in the returned value? */
272 defense *= wall_value;
273 defense /= 10;
274 }
275
276 return defense;
277}
278
279/**********************************************************************/
282int assess_defense_quadratic(struct ai_type *ait, struct city *pcity)
283{
284 int defense = 0, walls = 0;
285 /* This can be an arg if needed, but we don't need to change it now. */
286 const bool igwall = FALSE;
287 struct ai_city *city_data = def_ai_city_data(pcity, ait);
288
289 /* wallvalue = 10, walls = 10,
290 * wallvalue = 40, walls = 20,
291 * wallvalue = 90, walls = 30 */
292
293 while (walls * walls < city_data->wallvalue * 10) {
294 walls++;
295 }
296
298 defense += base_assess_defense_unit(pcity, punit, igwall, FALSE,
299 walls);
301
302 if (defense > 1<<12) {
303 CITY_LOG(LOG_VERBOSE, pcity, "Overflow danger in assess_defense_quadratic:"
304 " %d", defense);
305 if (defense > 1<<15) {
306 defense = 1<<15; /* more defense than we know what to do with! */
307 }
308 }
309
310 return defense * defense;
311}
312
313/**********************************************************************/
316int assess_defense_unit(struct ai_type *ait, struct city *pcity,
317 struct unit *punit, bool igwall)
318{
319 return base_assess_defense_unit(pcity, punit, igwall, TRUE,
320 def_ai_city_data(pcity, ait)->wallvalue);
321}
322
323/**********************************************************************/
330static int assess_defense_backend(struct ai_type *ait, struct city *pcity,
331 bool igwall)
332{
333 /* Estimate of our total city defensive might */
334 int defense = 0;
335
337 defense += assess_defense_unit(ait, pcity, punit, igwall);
339
340 return defense;
341}
342
343/**********************************************************************/
346int assess_defense(struct ai_type *ait, struct city *pcity)
347{
348 return assess_defense_backend(ait, pcity, FALSE);
349}
350
351/**********************************************************************/
355static int assess_defense_igwall(struct ai_type *ait, struct city *pcity)
356{
357 return assess_defense_backend(ait, pcity, TRUE);
358}
359
360/**********************************************************************/
366static enum fc_tristate
367tactical_req_cb(const struct req_context *context,
368 const struct player *other_player,
369 const struct requirement *req,
370 void *data, int n_data)
371{
372 switch (req->source.kind) {
373 case VUT_IMPROVEMENT:
374 {
375 const struct impr_type *b = req->source.value.building;
376
377 /* FIXME: in actor_reqs, may allow attack _from_ a city with... */
378 if (req->survives || NULL == context->city || is_great_wonder(b)
379 || !city_has_building(context->city, b) || b->sabotage <= 0) {
380 return tri_req_active(context, other_player, req);
381 }
382 /* Else may be sabotaged */
383 }
385 case VUT_UNITSTATE:
386 case VUT_ACTIVITY:
387 case VUT_MINSIZE:
388 case VUT_MAXTILEUNITS:
389 case VUT_MINHP:
390 case VUT_MINMOVES:
391 /* Can be changed back or forth quickly */
392 return TRI_MAYBE;
393 case VUT_MINVETERAN:
394 /* Can be changed forth but not back */
395 return is_req_preventing(context, other_player, req, RPT_POSSIBLE)
397 case VUT_MINFOREIGNPCT:
398 case VUT_NATIONALITY:
399 /* Can be changed back but hardly forth (foreign citizens reduced first) */
400 switch (tri_req_active(context, other_player, req)) {
401 case TRI_NO:
402 return req->present ? TRI_NO : TRI_MAYBE;
403 case TRI_YES:
404 return req->present ? TRI_MAYBE : TRI_YES;
405 default:
406 return TRI_MAYBE;
407 }
408 case VUT_DIPLREL:
409 case VUT_DIPLREL_TILE:
410 case VUT_DIPLREL_TILE_O:
411 case VUT_DIPLREL_UNITANY:
412 case VUT_DIPLREL_UNITANY_O:
413 /* If the attack happens, there is a diplrel that allows it */
414 return TRI_YES;
415 case VUT_AGE:
416 case VUT_MINCALFRAG:
417 case VUT_MINYEAR:
418 /* If it is not near, won't change */
419 return tri_req_active_turns(n_data, 5 /* WAG */,
420 context, other_player, req);
421 case VUT_UTYPE:
422 case VUT_UTFLAG:
423 case VUT_UCLASS:
424 case VUT_UCFLAG:
425 /* FIXME: support converting siege machines (needs hard reqs checked) */
426 case VUT_CITYSTATUS:
427 case VUT_ACTION:
428 case VUT_OTYPE:
429 case VUT_SPECIALIST:
430 case VUT_EXTRAFLAG:
431 case VUT_AI_LEVEL:
432 case VUT_CITYTILE:
433 case VUT_STYLE:
434 case VUT_TOPO:
435 case VUT_SERVERSETTING:
436 case VUT_NATION:
437 case VUT_NATIONGROUP:
438 case VUT_ADVANCE:
439 case VUT_TECHFLAG:
440 case VUT_GOVERNMENT:
441 case VUT_ACHIEVEMENT:
442 case VUT_IMPR_GENUS:
443 case VUT_MINCULTURE:
444 case VUT_MINTECHS:
445 case VUT_ROADFLAG:
446 case VUT_TERRAIN:
447 case VUT_EXTRA:
448 case VUT_GOOD:
449 case VUT_TERRAINCLASS:
450 case VUT_TERRFLAG:
451 case VUT_TERRAINALTER:
452 case VUT_NONE:
453 return tri_req_active(context, other_player, req);
454 case VUT_COUNT:
455 /* Not implemented. */
456 break;
457 }
459
460 return TRI_NO;
461}
462
463/**********************************************************************/
470static bool
472 const struct unit *actor,
473 const struct city *pcity,
474 int turns)
475{
476 const struct player *target_player = city_owner(pcity),
477 *actor_player = unit_owner(actor);
478 const struct unit_type *utype = unit_type_get(actor);
479 const struct req_context target_ctx = {
480 .player = target_player,
481 .city = pcity,
482 .tile = city_tile(pcity)
483 }, actor_ctx = {
484 .player = actor_player,
485 .unit = actor,
486 .unittype = utype
487 };
488
489 if (!utype_can_do_action(utype, wanted_action)) {
490 return FALSE;
491 }
493 enabler) {
494 /* We assume that we could build or move units into the city
495 * that are not present there yet */
496 if (TRI_NO != tri_reqs_cb_active(&actor_ctx, target_player,
497 &enabler->actor_reqs, NULL,
498 tactical_req_cb, NULL, turns)
499 &&
500 TRI_NO != tri_reqs_cb_active(&target_ctx, actor_player,
501 &enabler->target_reqs, NULL,
502 tactical_req_cb, NULL, turns)) {
503 return TRUE;
504 }
506
507 return FALSE;
508}
509
510/**********************************************************************/
513static unsigned int assess_danger_unit(const struct civ_map *nmap,
514 const struct city *pcity,
515 struct pf_reverse_map *pcity_map,
516 const struct unit *punit,
517 int *move_time)
518{
519 struct pf_position pos;
520 const struct unit_type *punittype = unit_type_get(punit);
521 const struct tile *ptile = city_tile(pcity);
522 const struct player *uowner = unit_owner(punit);
523 const struct unit *ferry;
524 unsigned int danger;
525 int amod = -99, dmod;
526 bool attack_danger = FALSE;
527
528 *move_time = PF_IMPOSSIBLE_MC;
529
530 if ((utype_can_do_action_result(punittype, ACTRES_PARADROP)
531 || utype_can_do_action_result(punittype, ACTRES_PARADROP_CONQUER))
532 && 0 < punittype->paratroopers_range) {
533 *move_time = (real_map_distance(ptile, unit_tile(punit))
534 / punittype->paratroopers_range);
535 }
536
537 if (pf_reverse_map_unit_position(pcity_map, punit, &pos)
538 && (PF_IMPOSSIBLE_MC == *move_time
539 || *move_time > pos.turn)) {
540 *move_time = pos.turn;
541 }
542
544 && (ferry = unit_transport_get(punit))
545 && pf_reverse_map_unit_position(pcity_map, ferry, &pos)) {
546 if ((PF_IMPOSSIBLE_MC == *move_time
547 || *move_time > pos.turn)) {
548 *move_time = pos.turn;
549 if (!can_attack_from_non_native(punittype)) {
550 (*move_time)++;
551 }
552 }
553 }
554
555 if (PF_IMPOSSIBLE_MC == *move_time) {
556 return 0;
557 }
558 if (!is_native_tile(punittype, ptile)
559 && !can_attack_non_native(punittype)) {
560 return 0;
561 }
562 if (!is_native_near_tile(nmap, unit_class_get(punit), ptile)) {
563 return 0;
564 }
565
566 /* Find the worst attack action to expect */
567 action_by_result_iterate(paction, ACTRES_ATTACK) {
568 /* Is it possible that punit will do action id to the city? */
569
570 if (action_may_happen_unit_on_city(paction->id, punit, pcity, *move_time)) {
571 int b;
572
573 attack_danger = TRUE;
574
575 b = get_unittype_bonus(uowner, ptile, punittype, paction, EFT_ATTACK_BONUS);
576 if (b > amod) {
577 amod = b;
578 }
579 }
581
582 /* FIXME: it's a dummy support for anti-bombard defense just to do something against
583 * approaching bombarders. Some better logic is needed, see OSDN#41778 */
584 if (!attack_danger) {
585 action_by_result_iterate(paction, ACTRES_BOMBARD) {
586 if (action_may_happen_unit_on_city(paction->id, punit, pcity, *move_time)) {
587 int b;
588
589 attack_danger = TRUE;
590
591 b = get_unittype_bonus(uowner, ptile, punittype, paction, EFT_ATTACK_BONUS);
592 if (b > amod) {
593 amod = b;
594 }
595 }
597 /* Here something should be done cuz the modifier affects
598 * more than one unit but not their full hp, but is not done yet...*/
599 }
600 if (!attack_danger) {
601 /* If the unit is dangerous, it's not about its combat strength */
602 return 0;
603 }
604
605 danger = adv_unit_att_rating(punit);
606 dmod = 100 + get_unittype_bonus(city_owner(pcity), ptile,
607 punittype, NULL, EFT_DEFEND_BONUS);
608 return danger * (amod + 100) / MAX(dmod, 1);
609}
610
611/**********************************************************************/
617 const struct civ_map *nmap,
618 struct player *pplayer)
619{
620 /* Do nothing if game is not running */
621 if (S_S_RUNNING == server_state()) {
622 city_list_iterate(pplayer->cities, pcity) {
623 (void) assess_danger(ait, nmap, pcity, NULL);
625 }
626}
627
628/**********************************************************************/
647static void dai_reevaluate_building(struct city *pcity, adv_want *value,
648 unsigned int urgency, unsigned int danger,
649 int defense)
650{
651 if (*value == 0 || danger <= 0) {
652 return;
653 }
654
655 *value = MAX(*value, 100 + urgency); /* default */
656
657 if (urgency > 0 && danger > defense * 2) {
658 *value += 100;
659 } else if (defense != 0 && danger > defense) {
660 *value = MAX(danger * 100 / defense, *value);
661 }
662}
663
664/**********************************************************************/
682static unsigned int assess_danger(struct ai_type *ait,
683 const struct civ_map *nmap,
684 struct city *pcity,
686{
687 struct player *pplayer = city_owner(pcity);
688 struct tile *ptile = city_tile(pcity);
689 struct ai_city *city_data = def_ai_city_data(pcity, ait);
690 /* How much such danger there is that building would help against. */
691 unsigned int danger_reduced[B_LAST];
692 int i;
693 int defender;
694 unsigned int urgency = 0;
695 int defense;
696 int total_danger = 0;
697
698 /* TODO: Presumably most, or even all, of these arrays
699 * could be of size game.control.num_unit_types instead
700 * of full U_LAST */
701 int defense_bonuses_pct[U_LAST];
702 bool defender_type_handled[U_LAST];
703 int best_non_scramble[U_LAST];
704 bool sth_does_not_scramble = FALSE;
705 int city_def_against[U_LAST];
706 int assess_turns;
707 bool omnimap;
708
710
711 /* Initialize data. */
712 memset(&danger_reduced, 0, sizeof(danger_reduced));
713 if (has_handicap(pplayer, H_DANGER)) {
714 /* Always thinks that city is in grave danger */
715 city_data->grave_danger = 1;
716 } else {
717 city_data->grave_danger = 0;
718 }
719 city_data->diplomat_threat = FALSE;
720 city_data->has_diplomat = FALSE;
721
722 unit_type_iterate(utype) {
723 int idx = utype_index(utype);
724
725 defense_bonuses_pct[idx] = 0;
726 defender_type_handled[idx] = FALSE;
727 best_non_scramble[idx] = -1;
728 /* FIXME: cache it somewhere? */
729 city_def_against[idx]
730 = 100 + get_unittype_bonus(pplayer, ptile, utype, NULL,
731 EFT_DEFEND_BONUS);
732 city_def_against[idx] = MAX(city_def_against[idx], 1);
734
735 /* What flag-specific bonuses do our units have. */
736 /* We value them less than general defense increment */
737 unit_list_iterate(ptile->units, punit) {
738 const struct unit_type *def = unit_type_get(punit);
739
740 if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
741 city_data->has_diplomat = TRUE;
742 }
743 if (!defender_type_handled[utype_index(def)]) {
744 /* This is first defender of this type. Check defender type
745 * specific bonuses. */
746
747 /* Skip defenders that have no bonuses at all. Acceptable
748 * side-effect is that we can't consider negative bonuses at
749 * all ("No bonuses" should be better than "negative bonus") */
750 if (def->cache.max_defense_mp_bonus_pct > 0) {
751 unit_type_iterate(utype) {
752 int idx = utype_index(utype);
753 int coeff = def->cache.scramble_coeff[idx];
754 int bonus;
755
756 /* FIXME: consider EFT_FORTIFY_DEFENSE_BONUS */
757 if (coeff) {
758 bonus = coeff / city_def_against[idx] - 100;
759 } else {
760 bonus = def->cache.defense_mp_bonuses_pct[idx];
761 }
762
763 if (bonus > defense_bonuses_pct[idx]) {
764 if (!coeff) {
765 best_non_scramble[idx] = bonus;
766 }
767 defense_bonuses_pct[idx] = bonus;
768 } else if (!coeff) {
769 best_non_scramble[idx] = MAX(best_non_scramble[idx], bonus);
770 }
772 } else {
773 /* Just remember that such a unit exists and hope its bonuses are just 0 */
774 sth_does_not_scramble = TRUE;
775 }
776
777 defender_type_handled[utype_index(def)] = TRUE;
778 }
780 if (sth_does_not_scramble || unit_list_size(ptile->units) <= 0) {
781 /* Scrambling units tend to be expensive. If we have a barenaked city, we'll
782 * need at least a cheap unit. If we have only scramblers,
783 * maybe it's OK. */
784 unit_type_iterate(scrambler_type) {
785 Unit_type_id id = utype_index(scrambler_type);
786
787 best_non_scramble[id] = MAX(best_non_scramble[id], 0);
789 }
790
791 if (player_is_cpuhog(pplayer)) {
792 assess_turns = 6;
793 } else {
794 assess_turns = has_handicap(pplayer, H_ASSESS_DANGER_LIMITED) ? 2 : 3;
795 }
796
797 omnimap = !has_handicap(pplayer, H_MAP);
798
799 /* Check. */
800 players_iterate(aplayer) {
801 struct pf_reverse_map *pcity_map;
802 struct unit_list *units;
803
804 if (!adv_is_player_dangerous(pplayer, aplayer)) {
805 continue;
806 }
807 /* Note that we still consider the units of players we are not (yet)
808 * at war with. */
809
810 pcity_map = pf_reverse_map_new_for_city(nmap, pcity, aplayer, assess_turns,
811 omnimap);
812
813 if (ul_cb != NULL) {
814 units = ul_cb(aplayer);
815 } else {
816 units = aplayer->units;
817 }
818 unit_list_iterate(units, punit) {
819 int move_time;
820 unsigned int vulnerability;
821 int defbonus_pct;
822 const struct unit_type *utype = unit_type_get(punit);
823 struct unit_type_ai *utai = utype_ai_data(utype, ait);
824
825#ifdef FREECIV_WEB
826 /* freeciv-web ignores danger that is far in distance,
827 * no matter how quickly it would reach us; even if
828 * that's *immediately* over a road type that allows
829 * unlimited movement. */
830 int unit_distance = real_map_distance(ptile, unit_tile(punit));
831
832 if (unit_distance > ASSESS_DANGER_MAX_DISTANCE
834 && unit_distance > AI_HANDICAP_DISTANCE_LIMIT)) {
835 /* Too far away. */
836 continue;
837 }
838#endif /* FREECIV_WEB */
839
840 if (!utai->carries_occupiers
841 && !utype_acts_hostile(utype)) {
842 /* Harmless unit. */
843 continue;
844 }
845
846 /* Defender unspecific vulnerability and potential move time */
847 vulnerability = assess_danger_unit(nmap, pcity, pcity_map,
848 punit, &move_time);
849
850 if (PF_IMPOSSIBLE_MC == move_time) {
851 continue;
852 }
853
855 /* Even if there is no attack strength,
856 * we need ANY protector for the city */
857 vulnerability = MAX(vulnerability, 1);
858 if (3 >= move_time) {
859 urgency++;
860 if (1 >= move_time) {
861 city_data->grave_danger++;
862 }
863 }
864 }
865
866 defbonus_pct = defense_bonuses_pct[utype_index(utype)];
867 if (defbonus_pct > 100) {
868 defbonus_pct = (defbonus_pct + 100) / 2;
869 }
870 /* Reduce vulnerability for specific bonuses we do have */
871 vulnerability = vulnerability * 100 / (defbonus_pct + 100);
872 /* Pass the order for a new defender type against it
873 * to the scientific advisor, urgency considered */
874 (void) dai_wants_defender_against(ait, nmap, pplayer, pcity, utype,
875 vulnerability / MAX(move_time, 1));
876
877 if (utype_acts_hostile(unit_type_get(punit)) && 2 >= move_time) {
878 city_data->diplomat_threat = TRUE;
879 }
880
881 vulnerability *= vulnerability; /* positive feedback */
882 if (1 < move_time) {
883 vulnerability /= move_time;
884 }
885
886 if (unit_can_do_action(punit, ACTION_NUKE)
887 || unit_can_do_action(punit, ACTION_NUKE_CITY)
888 || unit_can_do_action(punit, ACTION_NUKE_UNITS)) {
889 defender = dai_find_source_building(pcity, EFT_NUKE_PROOF, utype);
890 if (defender != B_LAST) {
891 danger_reduced[defender] += vulnerability / MAX(move_time, 1);
892 }
893 } else if (best_non_scramble[utype_index(utype)] >= 0) {
894 /* To consider building a defensive building,
895 * build first a defender that gets any profit of it */
896 defender = dai_find_source_building(pcity, EFT_DEFEND_BONUS, utype);
897 if (defender != B_LAST) {
898 int danred = vulnerability / MAX(move_time, 1);
899 /* Maybe we can build an improvement
900 * that gets normal defender over scrambling one?
901 * Effectively a sqrt-scale because we don't test how high
902 * the effect is. */
903 if (best_non_scramble[utype_index(utype)]
904 < defense_bonuses_pct[utype_index(utype)]) {
905 danred = danred * (100 + best_non_scramble[utype_index(utype)])
906 / (100 + defense_bonuses_pct[utype_index(utype)]);
907 }
908 danger_reduced[defender] += danred;
909 }
910 }
911
912 total_danger += vulnerability;
914
915 pf_reverse_map_destroy(pcity_map);
916
918
919 if (total_danger) {
920 /* If any hostile player has any dangerous unit that can in any time
921 * reach the city, we consider building walls here, if none yet.
922 * FIXME: this value assumes that walls give x3 defense. */
923 city_data->wallvalue = 90;
924 } else {
925 /* No danger.
926 * This is half of the wallvalue of what danger 1 would produce. */
927 city_data->wallvalue = 5;
928 }
929
930 if (0 < city_data->grave_danger) {
931 /* really, REALLY urgent to defend */
932 urgency += 10 * city_data->grave_danger;
933 }
934
935 /* HACK: This needs changing if multiple improvements provide
936 * this effect. */
937 /* FIXME: Accept only buildings helping unit classes we actually use.
938 * Now we consider any land mover helper suitable. */
939 /* Sum of squared defense ratings */
940 defense = assess_defense_igwall(ait, pcity);
941
942 for (i = 0; i < B_LAST; i++) {
943 if (0 < danger_reduced[i]) {
945 urgency, danger_reduced[i], defense);
946 }
947 }
948
949 if (has_handicap(pplayer, H_DANGER) && 0 == total_danger) {
950 /* Has to have some danger
951 * Otherwise grave_danger will be ignored. */
952 city_data->danger = 1;
953 } else {
954 city_data->danger = total_danger;
955 }
956 city_data->urgency = urgency;
957
959
960 return urgency;
961}
962
963/**********************************************************************/
968 const struct unit_type *punittype)
969{
970 adv_want desire = punittype->hp;
971 int attack = punittype->attack_strength;
972 int defense = punittype->defense_strength;
973 int maxbonus_pct = 0;
974 int fp = punittype->firepower;
975
976 /* Sea and helicopters often have their firepower set to low firepower when
977 * defending. We can't have such units as defenders. */
978 if (utype_has_flag(punittype, UTYF_BADCITYDEFENDER)) {
980 }
981 if (((struct unit_type_ai *)utype_ai_data(punittype, ait))->low_firepower) {
983 }
984 desire *= fp;
985 desire *= defense;
986 desire += punittype->move_rate / SINGLE_MOVE;
987 desire += attack;
988
989 maxbonus_pct = punittype->cache.max_defense_mp_bonus_pct;
990 if (maxbonus_pct > 100) {
991 maxbonus_pct = (maxbonus_pct + 100) / 2;
992 }
993 desire += desire * maxbonus_pct / 100;
994 if (utype_has_flag(punittype, UTYF_GAMELOSS)) {
995 desire /= 10; /* But might actually be worth it */
996 }
997
998 return desire;
999}
1000
1001/**********************************************************************/
1005 const struct unit_type *punittype)
1006{
1007 adv_want desire = punittype->hp;
1008 int attack = punittype->attack_strength;
1009 int defense = punittype->defense_strength;
1010
1011 desire *= punittype->move_rate;
1012 desire *= punittype->firepower;
1013 desire *= attack;
1014 desire += defense;
1015 if (utype_has_flag(punittype, UTYF_IGTER)) {
1016 desire += desire / 2;
1017 }
1018 if (utype_has_flag(punittype, UTYF_GAMELOSS)) {
1019 desire /= 10; /* But might actually be worth it */
1020 }
1021 if (utype_has_flag(punittype, UTYF_CITYBUSTER)) {
1022 desire += desire / 2;
1023 }
1024 if (can_attack_from_non_native(punittype)) {
1025 desire += desire / 4;
1026 }
1027 if (punittype->adv.igwall) {
1028 desire += desire / 4;
1029 }
1030
1031 return desire;
1032}
1033
1034/**********************************************************************/
1039bool dai_process_defender_want(struct ai_type *ait, const struct civ_map *nmap,
1040 struct player *pplayer,
1041 struct city *pcity, unsigned int danger,
1042 struct adv_choice *choice, adv_want extra_want)
1043{
1044 const struct research *presearch = research_get(pplayer);
1045 /* FIXME: We check if the city has *some* defensive structure,
1046 * but not whether the city has a defensive structure against
1047 * any specific attacker. The actual danger may not be mitigated
1048 * by the defense selected... */
1049 bool walls = city_got_defense_effect(pcity, NULL);
1050 /* Technologies we would like to have. */
1051 adv_want tech_desire[U_LAST];
1052 /* Our favourite unit. */
1053 adv_want best = -1;
1054 struct unit_type *best_unit_type = NULL;
1055 int best_unit_cost = 1;
1056 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1057 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
1058 adv_want total_want = danger + extra_want;
1059
1060 memset(tech_desire, 0, sizeof(tech_desire));
1061
1062 simple_ai_unit_type_iterate(punittype) {
1063 adv_want desire; /* How much we want the unit? */
1064
1065 /* Only consider proper defenders - otherwise waste CPU and
1066 * bump tech want needlessly. */
1067 if (!utype_has_role(punittype, L_DEFEND_GOOD)
1068 && !utype_has_role(punittype, L_DEFEND_OK)) {
1069 continue;
1070 }
1071
1072 desire = dai_unit_defense_desirability(ait, punittype);
1073
1074 if (!utype_has_role(punittype, L_DEFEND_GOOD)) {
1075 desire /= 2; /* Not good, just ok */
1076 }
1077
1078 if (utype_has_flag(punittype, UTYF_FIELDUNIT)) {
1079 /* Causes unhappiness even when in defense, so not a good
1080 * idea for a defender, unless it is _really_ good.
1081 * Downright counter productive, if we want unit just for
1082 * maintaining peace. */
1083 if (danger == 0) {
1084 desire = -50;
1085 } else {
1086 desire /= 2;
1087 }
1088 }
1089
1090 if (desire > 0) {
1091 desire /= POWER_DIVIDER / 2; /* Good enough, no rounding errors. */
1092 desire *= desire;
1093
1094 if (can_city_build_unit_now(nmap, pcity, punittype)) {
1095 /* We can build the unit now... */
1096
1097 int build_cost = utype_build_shield_cost(pcity, NULL, punittype);
1098 int limit_cost = pcity->shield_stock + 40;
1099
1100 if (walls && !utype_has_flag(punittype, UTYF_BADCITYDEFENDER)) {
1101 desire *= city_data->wallvalue;
1102 /* TODO: More use of POWER_FACTOR ! */
1103 desire /= POWER_FACTOR;
1104 }
1105
1106 if ((best_unit_cost > limit_cost
1107 && build_cost < best_unit_cost)
1108 || ((desire > best
1109 || (ADV_WANTS_EQ(desire, best)
1110 && build_cost <= best_unit_cost))
1111 && (best_unit_type == NULL
1112 /* In case all units are more expensive than limit_cost */
1113 || limit_cost <= pcity->shield_stock + 40))) {
1114 best = desire;
1115 best_unit_type = punittype;
1116 best_unit_cost = build_cost;
1117 }
1118 } else if (can_city_build_unit_later(nmap, pcity, punittype)) {
1119 /* We first need to develop the tech required by the unit... */
1120
1121 /* Cost (shield equivalent) of gaining these techs. */
1122 /* FIXME? Katvrr advises that this should be weighted more heavily in
1123 * big danger. */
1124 int tech_cost = research_goal_bulbs_required(presearch,
1125 advance_number(punittype->require_advance)) / 4
1126 / city_list_size(pplayer->cities);
1127
1128 /* Contrary to the above, we don't care if walls are actually built
1129 * - we're looking into the future now. */
1130 if (!utype_has_flag(punittype, UTYF_BADCITYDEFENDER)) {
1131 desire *= city_data->wallvalue;
1132 desire /= POWER_FACTOR;
1133 }
1134
1135 /* Yes, there's some similarity with kill_desire(). */
1136 /* TODO: Explain what shield cost has to do with tech want. */
1137 tech_desire[utype_index(punittype)] =
1138 (desire * total_want
1139 / (utype_build_shield_cost(pcity, NULL, punittype) + tech_cost));
1140 }
1141 }
1143
1144 if (best == -1) {
1145 CITY_LOG(LOG_DEBUG, pcity, "Ooops - we cannot build any defender!");
1146 }
1147
1148 if (best_unit_type != NULL) {
1149 if (!walls && !utype_has_flag(best_unit_type, UTYF_BADCITYDEFENDER)) {
1150 best *= city_data->wallvalue;
1151 best /= POWER_FACTOR;
1152 }
1153 } else {
1154 best_unit_cost = 100; /* Building impossible is considered costly.
1155 * This should increase want for tech providing
1156 * first defender type. */
1157 }
1158
1159 if (best <= 0) {
1160 best = 1; /* Avoid division by zero below. */
1161 }
1162
1163 /* Update tech_want for appropriate techs for units we want to build. */
1164 simple_ai_unit_type_iterate(punittype) {
1165 if (tech_desire[utype_index(punittype)] > 0) {
1166 /* TODO: Document or fix the algorithm below. I have no idea why
1167 * it is written this way, and the results seem strange to me. - Per */
1168 adv_want desire = tech_desire[utype_index(punittype)] * best_unit_cost / best;
1169
1170 plr_data->tech_want[advance_index(punittype->require_advance)]
1171 += desire;
1172 TECH_LOG(ait, LOG_DEBUG, pplayer, punittype->require_advance,
1173 "+ " ADV_WANT_PRINTF " for %s to defend %s",
1174 desire,
1175 utype_rule_name(punittype),
1176 city_name_get(pcity));
1177 }
1179
1180 if (!best_unit_type) {
1181 return FALSE;
1182 }
1183
1184 choice->value.utype = best_unit_type;
1185 choice->want = danger; /* FIXME: Not 'total_want' because of the way callers
1186 * are constructed. They may overwrite this value,
1187 * and then the value will NOT contain 'extra_want'.
1188 * Later we may add 'extra_want', and don't want it
1189 * already included in case this was NOT overwritten. */
1190 choice->type = CT_DEFENDER;
1191
1192 return TRUE;
1193}
1194
1195/**********************************************************************/
1212static void process_attacker_want(struct ai_type *ait,
1213 struct city *pcity,
1214 adv_want value,
1215 const struct unit_type *victim_unit_type,
1216 struct player *victim_player,
1217 int veteran, struct tile *ptile,
1218 struct adv_choice *best_choice,
1219 struct pf_map *ferry_map,
1220 struct unit *boat,
1221 const struct unit_type *boattype)
1222{
1223 struct player *pplayer = city_owner(pcity);
1224 const struct research *presearch = research_get(pplayer);
1225 /* The enemy city. acity == NULL means stray enemy unit */
1226 struct city *acity = tile_city(ptile);
1227 struct pf_parameter parameter;
1228 struct pf_map *pfm;
1229 struct pf_position pos;
1230 const struct unit_type *orig_utype = best_choice->value.utype;
1231 int victim_count = 1;
1232 int needferry = 0;
1233 bool unhap;
1234 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
1235 const struct civ_map *nmap = &(wld.map);
1236
1237 /* Has to be initialized to make gcc happy */
1238 struct ai_city *acity_data = NULL;
1239
1240 unhap = dai_assess_military_unhappiness(nmap, pcity);
1241
1242 if (acity != NULL) {
1243 acity_data = def_ai_city_data(acity, ait);
1244 }
1245
1246 if (utype_class(orig_utype)->adv.sea_move == MOVE_NONE
1247 && !boat && boattype) {
1248 /* Cost of ferry */
1249 needferry = utype_build_shield_cost(pcity, NULL, boattype);
1250 }
1251
1252 if (!is_stack_vulnerable(ptile)) {
1253 /* If it is a city, a fortress or an air base,
1254 * we may have to whack it many times */
1255 victim_count += unit_list_size(ptile->units);
1256 }
1257
1258 simple_ai_unit_type_iterate(punittype) {
1259 Tech_type_id tech_req = advance_number(punittype->require_advance);
1260 int tech_dist = research_goal_unknown_techs(presearch, tech_req);
1261
1262 if (dai_can_unit_type_follow_unit_type(punittype, orig_utype, ait)
1263 && is_native_near_tile(&(wld.map), utype_class(punittype), ptile)
1264 && (U_NOT_OBSOLETED == punittype->obsoleted_by
1265 || !can_city_build_unit_direct(nmap, pcity, punittype->obsoleted_by))
1266 && punittype->attack_strength > 0 /* Or we'll get SIGFPE */) {
1267 /* Values to be computed */
1268 adv_want desire;
1269 adv_want want;
1270 int move_time;
1271 int vuln;
1272 int veteran_level
1274 &(const struct req_context) {
1275 .player = pplayer,
1276 .city = pcity,
1277 .tile = city_tile(pcity),
1278 .unittype = punittype,
1279 },
1280 NULL,
1281 EFT_VETERAN_BUILD);
1282 /* Cost (shield equivalent) of gaining these techs. */
1283 /* FIXME? Katvrr advises that this should be weighted more heavily in big
1284 * danger. */
1285 int tech_cost = research_goal_bulbs_required(presearch, tech_req) / 4
1286 / city_list_size(pplayer->cities);
1287 int bcost_balanced = build_cost_balanced(punittype);
1288 /* See description of kill_desire() for info about this variables. */
1289 int bcost = utype_build_shield_cost(pcity, NULL, punittype);
1292 punittype->hp);
1293
1294 /* Take into account reinforcements strength */
1295 if (acity) {
1296 attack += acity_data->attack;
1297 }
1298
1299 if (attack == 0) {
1300 /* Yes, it can happen that a military unit has attack = 1,
1301 * for example militia with HP = 1 (in civ1 ruleset). */
1302 continue;
1303 }
1304
1305 attack *= attack;
1306
1307 pft_fill_utype_parameter(&parameter, nmap, punittype, city_tile(pcity),
1308 pplayer);
1309 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1310 pfm = pf_map_new(&parameter);
1311
1312 /* Set the move_time appropriately. */
1313 move_time = -1;
1314 if (NULL != ferry_map) {
1315 struct tile *dest_tile;
1316
1317 if (find_beachhead(pplayer, ferry_map, ptile, punittype,
1318 &dest_tile, NULL)
1319 && pf_map_position(ferry_map, dest_tile, &pos)) {
1320 move_time = pos.turn;
1321 dest_tile = pf_map_parameter(ferry_map)->start_tile;
1322 pf_map_tiles_iterate(pfm, atile, FALSE) {
1323 if (atile == dest_tile) {
1325 move_time += pos.turn;
1326 break;
1327 } else if (atile == ptile) {
1328 /* Reaching directly seems better. */
1330 move_time = pos.turn;
1331 break;
1332 }
1334 }
1335 }
1336
1337 if (-1 == move_time) {
1338 if (pf_map_position(pfm, ptile, &pos)) {
1339 move_time = pos.turn;
1340 } else {
1341 pf_map_destroy(pfm);
1342 continue;
1343 }
1344 }
1345 pf_map_destroy(pfm);
1346
1347 /* Estimate strength of the enemy. */
1348
1349 if (victim_unit_type) {
1350 vuln = unittype_def_rating_squared(punittype, victim_unit_type,
1351 victim_player,
1352 ptile, FALSE, veteran);
1353 } else {
1354 vuln = 0;
1355 }
1356
1357 /* Not bothering to s/!vuln/!pdef/ here for the time being. -- Syela
1358 * (this is noted elsewhere as terrible bug making warships yoyoing)
1359 * as the warships will go to enemy cities hoping that the enemy builds
1360 * something for them to kill. */
1361 if (vuln == 0
1362 && (utype_class(punittype)->adv.land_move == MOVE_NONE
1363 || 0 < utype_fuel(punittype))) {
1364 desire = 0;
1365
1366 } else {
1367 if (acity
1368 && utype_can_take_over(punittype)
1369 && acity_data->invasion.attack > 0
1370 && acity_data->invasion.occupy == 0) {
1371 int owner_size = city_list_size(city_owner(acity)->cities);
1372 float finishing_factor = 1;
1373
1374 if (owner_size <= FINISH_HIM_CITY_COUNT) {
1375 finishing_factor = (2 - (float)owner_size / FINISH_HIM_CITY_COUNT);
1376 }
1377 desire = CITY_CONQUEST_WORTH(acity, acity_data) * 10 * finishing_factor;
1378 } else {
1379 desire = 0;
1380 }
1381
1382 if (!acity) {
1383 desire = kill_desire(value, attack, bcost, vuln, victim_count);
1384 } else {
1385 adv_want kd;
1386 int city_attack = acity_data->attack * acity_data->attack;
1387
1388 /* See aiunit.c:find_something_to_kill() for comments. */
1389 kd = kill_desire(value, attack,
1390 (bcost + acity_data->bcost), vuln,
1391 victim_count);
1392
1393 if (value * city_attack > acity_data->bcost * vuln) {
1394 kd -= kill_desire(value, city_attack,
1395 acity_data->bcost, vuln,
1396 victim_count);
1397 }
1398
1399 desire = MAX(desire, kd);
1400 }
1401 }
1402
1403 desire -= tech_cost * SHIELD_WEIGHTING;
1404 /* We can be possibly making some people of our homecity unhappy - then
1405 * we don't want to travel too far away to our victims. */
1406 /* TODO: Unify the 'unhap' dependency to some common function. */
1407 desire -= move_time * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING
1409
1410 want = military_amortize(pplayer, pcity, desire, MAX(1, move_time),
1411 bcost_balanced + needferry);
1412
1413 if (want > 0) {
1414 if (tech_dist > 0) {
1415 /* This is a future unit, tell the scientist how much we need it */
1416 plr_data->tech_want[advance_index(punittype->require_advance)]
1417 += want;
1418 TECH_LOG(ait, LOG_DEBUG, pplayer, punittype->require_advance,
1419 "+ " ADV_WANT_PRINTF " for %s vs %s(%d,%d)",
1420 want,
1421 utype_rule_name(punittype),
1422 (acity ? city_name_get(acity) : utype_rule_name(victim_unit_type)),
1423 TILE_XY(ptile));
1424 } else if (want > best_choice->want) {
1425 const struct impr_type *impr_req;
1426
1427 if (can_city_build_unit_now(nmap, pcity, punittype)) {
1428 /* This is a real unit and we really want it */
1429
1430 CITY_LOG(LOG_DEBUG, pcity, "overriding %s(" ADV_WANT_PRINTF
1431 ") with %s(" ADV_WANT_PRINTF ")"
1432 " [attack=%d,value=" ADV_WANT_PRINTF
1433 ",move_time=%d,vuln=%d,bcost=%d]",
1434 utype_rule_name(best_choice->value.utype),
1435 best_choice->want,
1436 utype_rule_name(punittype),
1437 want,
1438 attack, value, move_time, vuln, bcost);
1439
1440 best_choice->value.utype = punittype;
1441 best_choice->want = want;
1442 best_choice->type = CT_ATTACKER;
1443 } else if (!((impr_req = utype_needs_improvement(punittype,
1444 pcity)))) {
1445 CITY_LOG(LOG_DEBUG, pcity, "cannot build unit %s",
1446 utype_rule_name(punittype));
1447 } else if (can_city_build_improvement_now(pcity, impr_req)) {
1448 /* Building this unit requires a specific type of improvement.
1449 * So we build this improvement instead. This may not be the
1450 * best behavior. */
1451 CITY_LOG(LOG_DEBUG, pcity, "building %s to build unit %s",
1452 improvement_rule_name(impr_req),
1453 utype_rule_name(punittype));
1454 best_choice->value.building = impr_req;
1455 best_choice->want = want;
1456 best_choice->type = CT_BUILDING;
1457 } else {
1458 /* This should never happen? */
1459 CITY_LOG(LOG_DEBUG, pcity, "cannot build %s or unit %s",
1460 improvement_rule_name(impr_req),
1461 utype_rule_name(punittype));
1462 }
1463 }
1464 }
1465 }
1467}
1468
1469/**********************************************************************/
1480static struct adv_choice *kill_something_with(struct ai_type *ait,
1481 struct player *pplayer,
1482 struct city *pcity, struct unit *myunit,
1483 struct adv_choice *choice)
1484{
1485 /* Our attack rating (with reinforcements) */
1486 int attack;
1487 /* Benefit from fighting the target */
1488 adv_want benefit;
1489 /* Defender of the target city/tile */
1490 struct unit *pdef;
1491 const struct unit_type *def_type;
1492 struct player *def_owner;
1493 int def_vet; /* Is the defender veteran? */
1494 /* Target coordinates */
1495 struct tile *ptile;
1496 /* Our transport */
1497 struct unit *ferryboat;
1498 /* Our target */
1499 struct city *acity;
1500 /* Type of the boat (real or a future one) */
1501 const struct unit_type *boattype;
1502 struct pf_map *ferry_map = NULL;
1503 int move_time;
1504 struct adv_choice *best_choice;
1505 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1506 struct ai_city *acity_data;
1507 struct civ_map *nmap = &(wld.map);
1508
1509 best_choice = adv_new_choice();
1510 best_choice->value.utype = unit_type_get(myunit);
1511 best_choice->type = CT_ATTACKER;
1512 adv_choice_set_use(best_choice, "attacker");
1513
1514 fc_assert_ret_val(is_military_unit(myunit) && !utype_fuel(unit_type_get(myunit)), choice);
1515
1516 if (city_data->danger != 0 && assess_defense(ait, pcity) == 0) {
1517 /* Defense comes first! */
1518 goto cleanup;
1519 }
1520
1521 best_choice->want = find_something_to_kill(ait, pplayer, myunit, &ptile, NULL,
1522 &ferry_map, &ferryboat,
1523 &boattype, &move_time);
1524 if (NULL == ptile
1525 || ptile == unit_tile(myunit)
1526 || !can_unit_attack_tile(myunit, NULL, ptile)) {
1527 goto cleanup;
1528 }
1529
1530 acity = tile_city(ptile);
1531
1532 if (myunit->id != 0) {
1533 log_error("%s(): non-virtual unit!", __FUNCTION__);
1534 goto cleanup;
1535 }
1536
1537 attack = adv_unit_att_rating(myunit);
1538 if (acity) {
1539 acity_data = def_ai_city_data(acity, ait);
1540 attack += acity_data->attack;
1541 }
1542 attack *= attack;
1543
1544 if (NULL != acity) {
1545 /* Rating of enemy defender */
1546 int vulnerability;
1547
1548 if (!POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(acity))) {
1549 /* Not a valid target */
1550 goto cleanup;
1551 }
1552
1553 def_type = dai_choose_defender_versus(acity, myunit);
1554 def_owner = city_owner(acity);
1555 if (1 < move_time && def_type) {
1556 def_vet = city_production_unit_veteran_level(acity, def_type);
1557 vulnerability = unittype_def_rating_squared(unit_type_get(myunit), def_type,
1558 city_owner(acity), ptile,
1559 FALSE, def_vet);
1560 benefit = utype_build_shield_cost_base(def_type);
1561 } else {
1562 vulnerability = 0;
1563 benefit = 0;
1564 def_vet = 0;
1565 }
1566
1567 pdef = get_defender(nmap, myunit, ptile);
1568 if (pdef) {
1570 city_owner(acity), ptile, FALSE,
1571 pdef->veteran);
1572 if (vulnerability < m) {
1573 benefit = unit_build_shield_cost_base(pdef);
1574 def_vet = pdef->veteran;
1575 def_type = unit_type_get(pdef);
1576 def_owner = unit_owner(pdef);
1577 }
1578 }
1579 if (unit_can_take_over(myunit) || acity_data->invasion.occupy > 0) {
1580 /* Bonus for getting the city */
1581 int owner_size = city_list_size(city_owner(acity)->cities);
1582 float finishing_factor = 1;
1583
1584 if (owner_size <= FINISH_HIM_CITY_COUNT) {
1585 finishing_factor = (2 - (float)owner_size / FINISH_HIM_CITY_COUNT);
1586 }
1587 benefit += CITY_CONQUEST_WORTH(acity, acity_data) * finishing_factor / 3;
1588 }
1589
1590 /* end dealing with cities */
1591 } else {
1592
1593 if (NULL != ferry_map) {
1594 pf_map_destroy(ferry_map);
1595 ferry_map = NULL;
1596 }
1597
1598 pdef = get_defender(nmap, myunit, ptile);
1599 if (!pdef) {
1600 /* Nobody to attack! */
1601 goto cleanup;
1602 }
1603
1604 benefit = unit_build_shield_cost_base(pdef);
1605
1606 def_type = unit_type_get(pdef);
1607 def_vet = pdef->veteran;
1608 def_owner = unit_owner(pdef);
1609 /* end dealing with units */
1610 }
1611
1612 if (NULL == ferry_map) {
1613 process_attacker_want(ait, pcity, benefit, def_type, def_owner,
1614 def_vet, ptile,
1615 best_choice, NULL, NULL, NULL);
1616 } else {
1617 /* Attract a boat to our city or retain the one that's already here */
1618 fc_assert_ret_val(unit_class_get(myunit)->adv.sea_move != MOVE_FULL, choice);
1619 best_choice->need_boat = TRUE;
1620 process_attacker_want(ait, pcity, benefit, def_type, def_owner,
1621 def_vet, ptile,
1622 best_choice, ferry_map, ferryboat, boattype);
1623 }
1624
1625 if (best_choice->want > choice->want) {
1626 /* We want attacker more than what we have selected before */
1627 adv_free_choice(choice);
1628 choice = best_choice;
1629 CITY_LOG(LOG_DEBUG, pcity, "kill_something_with()"
1630 " %s has chosen attacker, %s, want=" ADV_WANT_PRINTF,
1631 city_name_get(pcity),
1632 utype_rule_name(best_choice->value.utype),
1633 best_choice->want);
1634
1635 if (NULL != ferry_map && !ferryboat) { /* need a new ferry */
1636 /* We might need a new boat even if there are boats free,
1637 * if they are blockaded or in inland seas*/
1638 fc_assert_ret_val(unit_class_get(myunit)->adv.sea_move != MOVE_FULL, choice);
1639 if (dai_choose_role_unit(ait, pplayer, pcity, choice, CT_ATTACKER,
1640 L_FERRYBOAT, choice->want, TRUE)
1641 && dai_is_ferry_type(choice->value.utype, ait)) {
1642#ifdef FREECIV_DEBUG
1643 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
1644
1645 log_debug("kill_something_with() %s has chosen attacker ferry, "
1646 "%s, want=" ADV_WANT_PRINTF ", %d of %d free",
1647 city_name_get(pcity),
1648 utype_rule_name(choice->value.utype),
1649 choice->want,
1650 ai->stats.available_boats, ai->stats.boats);
1651#endif /* FREECIV_DEBUG */
1652
1653 adv_choice_set_use(choice, "attacker ferry");
1654 } /* else can not build ferries yet */
1655 }
1656 }
1657
1658cleanup:
1659 if (best_choice != choice) {
1660 /* It was not taken to use.
1661 * This hackery needed since 'goto cleanup:' might skip
1662 * sensible points to do adv_free_choice(). */
1663 adv_free_choice(best_choice);
1664 }
1665 if (NULL != ferry_map) {
1666 pf_map_destroy(ferry_map);
1667 }
1668
1669 return choice;
1670}
1671
1672/**********************************************************************/
1678static void dai_unit_consider_bodyguard(struct ai_type *ait,
1679 const struct civ_map *nmap,
1680 struct city *pcity,
1681 struct unit_type *punittype,
1682 struct adv_choice *choice)
1683{
1684 if (choice->want < DAI_WANT_MILITARY_EMERGENCY) {
1685 struct player *pplayer = city_owner(pcity);
1686 struct unit *aunit = NULL;
1687 struct city *acity = NULL;
1688 struct unit *virtualunit
1689 = unit_virtual_create(pplayer, pcity, punittype,
1691 punittype));
1692 const adv_want want = look_for_charge(ait, nmap, pplayer, virtualunit,
1693 &aunit, &acity);
1694
1695 if (want > choice->want) {
1696 choice->want = want;
1697 choice->value.utype = punittype;
1698 choice->type = CT_DEFENDER;
1699 adv_choice_set_use(choice, "bodyguard");
1700 }
1701
1702 unit_virtual_destroy(virtualunit);
1703 }
1704}
1705
1706/**********************************************************************/
1714static void adjust_ai_unit_choice(struct city *pcity,
1715 struct adv_choice *choice)
1716{
1718
1719 /* Sanity */
1720 if (!is_unit_choice_type(choice->type)
1721 || utype_has_flag(choice->value.utype, UTYF_CIVILIAN)
1722 || city_production_unit_veteran_level(pcity, choice->value.utype)) {
1723 return;
1724 }
1725
1726 /* N.B.: have to check that we haven't already built the building --mck */
1727 if ((id = dai_find_source_building(pcity, EFT_VETERAN_BUILD,
1728 choice->value.utype)) != B_LAST
1729 && !city_has_building(pcity, improvement_by_number(id))) {
1730 choice->value.building = improvement_by_number(id);
1731 choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER,
1732 city_owner(pcity))
1733 / TRAIT_DEFAULT_VALUE / 2));
1734 choice->type = CT_BUILDING;
1735 adv_choice_set_use(choice, "veterancy building");
1736 }
1737}
1738
1739/**********************************************************************/
1745 const struct civ_map *nmap,
1746 struct player *pplayer,
1747 struct city *pcity,
1749{
1750 struct adv_data *ai = adv_data_get(pplayer, NULL);
1751 struct unit_type *punittype;
1752 unsigned int our_def, urgency;
1753 struct tile *ptile = pcity->tile;
1754 struct unit *virtualunit;
1755 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1756 adv_want martial_value = 0;
1757 bool martial_need = FALSE;
1758 struct adv_choice *choice = adv_new_choice();
1759 bool allow_gold_upkeep;
1760
1761 urgency = assess_danger(ait, nmap, pcity, ul_cb);
1762 /* Changing to quadratic to stop AI from building piles
1763 * of small units -- Syela */
1764 /* It has to be AFTER assess_danger() thanks to wallvalue. */
1765 our_def = assess_defense_quadratic(ait, pcity);
1766
1767 dai_choose_diplomat_defensive(ait, pplayer, pcity, choice, our_def);
1768
1770 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY] > 0) {
1771 martial_need = TRUE;
1772 }
1773
1774 if (!martial_need) {
1776 if (pcity->specialists[sp] > 0
1777 && get_specialist_output(pcity, sp, O_LUXURY) > 0) {
1778 martial_need = TRUE;
1779 break;
1780 }
1782 }
1783
1784 if (martial_need
1785 && unit_list_size(pcity->tile->units) < get_city_bonus(pcity, EFT_MARTIAL_LAW_MAX)) {
1786 martial_value = dai_content_effect_value(pplayer, pcity,
1787 get_city_bonus(pcity, EFT_MARTIAL_LAW_EACH),
1788 1, FEELING_FINAL);
1789 }
1790
1791 /* Otherwise no need to defend yet */
1792 if (city_data->danger != 0 || martial_value > 0) {
1793 struct impr_type *pimprove;
1794 int num_defenders = unit_list_size(ptile->units);
1795 int wall_id, danger;
1796 bool build_walls = TRUE;
1797 bool def_unit_selected = FALSE;
1798 int qdanger = city_data->danger * city_data->danger;
1799
1800 if (qdanger <= 0) {
1801 /* We only need these defenders because of Martial Law value */
1802 danger = 0;
1803 build_walls = FALSE; /* Walls don't provide Martial Law */
1804 } else {
1805 /* First determine the danger. It is measured in percents of our
1806 * defensive strength, capped at 200 + urgency */
1807 if (qdanger >= our_def) {
1808 if (urgency == 0) {
1809 /* Don't waste money */
1810 danger = 100;
1811 } else if (our_def == 0) {
1812 danger = 200 + urgency;
1813 } else {
1814 danger = MIN(200, 100 * qdanger / our_def) + urgency;
1815 }
1816 } else {
1817 danger = 100 * qdanger / our_def;
1818 }
1819
1820 if (pcity->surplus[O_SHIELD] <= 0 && our_def != 0) {
1821 /* Won't be able to support anything */
1822 danger = 0;
1823 }
1824 }
1825
1826 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d urgency=%d danger=%d num_def=%d "
1827 "our_def=%d", urgency, danger, num_defenders, our_def);
1828
1829 if (our_def == 0 && danger > 0) {
1830 /* Build defensive unit first! Walls will help nothing if there's
1831 * nobody behind them. */
1832 if (dai_process_defender_want(ait, nmap, pplayer, pcity, danger, choice,
1833 martial_value)) {
1834 choice->want = DAI_WANT_BELOW_MIL_EMERGENCY + danger;
1835 adv_choice_set_use(choice, "first defender");
1836 build_walls = FALSE;
1837 def_unit_selected = TRUE;
1838
1839 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants first defender with " ADV_WANT_PRINTF,
1840 choice->want);
1841 }
1842 }
1843 if (build_walls) {
1844 /* FIXME: 1. Does not consider what kind of future danger is likely, so
1845 * may build SAM batteries when enemy has only land units. */
1846 /* We will build walls if we can and want and (have "enough" defenders or
1847 * can just buy the walls straight away) */
1848
1849 /* HACK: This needs changing if multiple improvements provide
1850 * this effect. */
1851 wall_id = dai_find_source_building(pcity, EFT_DEFEND_BONUS, NULL);
1852 pimprove = improvement_by_number(wall_id);
1853
1854 if (wall_id != B_LAST
1855 && pcity->server.adv->building_want[wall_id] != 0 && our_def != 0
1856 && can_city_build_improvement_now(pcity, pimprove)
1857 && (danger < 101 || num_defenders > 1
1858 || (city_data->grave_danger == 0
1859 && pplayer->economic.gold
1860 > impr_buy_gold_cost(pcity, pimprove, pcity->shield_stock)))
1861 && ai_fuzzy(pplayer, TRUE)) {
1862 if (pcity->server.adv->building_want[wall_id] > 0) {
1863 /* NB: great wall is under domestic */
1864 choice->value.building = pimprove;
1865 /* building_want is hacked by assess_danger() */
1866 choice->want = pcity->server.adv->building_want[wall_id];
1867 choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER, pplayer)
1868 / TRAIT_DEFAULT_VALUE / 2));
1869 if (urgency == 0 && choice->want > DAI_WANT_BELOW_MIL_EMERGENCY) {
1871 }
1872 choice->type = CT_BUILDING;
1873 adv_choice_set_use(choice, "defense building");
1874 CITY_LOG(LOG_DEBUG, pcity,
1875 "m_a_c_d wants defense building with " ADV_WANT_PRINTF,
1876 choice->want);
1877 } else {
1878 build_walls = FALSE;
1879 }
1880 } else {
1881 build_walls = FALSE;
1882 }
1883 }
1884
1885 /* If our choice isn't defender unit already, consider one */
1886 if (!def_unit_selected) {
1887 if ((danger > 0 && num_defenders <= urgency) || martial_value > 0) {
1888 struct adv_choice uchoice;
1889
1890 adv_init_choice(&uchoice);
1891
1892 /* Consider building defensive units */
1893 if (dai_process_defender_want(ait, nmap, pplayer, pcity, danger,
1894 &uchoice, martial_value)) {
1895 /* Potential defender found */
1896 if (urgency == 0
1897 && uchoice.value.utype->defense_strength == 1) {
1898 /* FIXME: check other reqs (unit class?) */
1899 if (get_city_bonus(pcity, EFT_HP_REGEN) > 0) {
1900 /* Unlikely */
1901 uchoice.want = MIN(49, danger);
1902 } else {
1903 uchoice.want = MIN(25, danger);
1904 }
1905 } else {
1906 uchoice.want = danger;
1907 }
1908
1909 uchoice.want += martial_value;
1910 if (danger > 0) {
1911 adv_choice_set_use(&uchoice, "defender");
1912 } else {
1913 adv_choice_set_use(&uchoice, "police");
1914 }
1915
1916 if (!build_walls || uchoice.want > choice->want) {
1917 adv_choice_copy(choice, &uchoice);
1918 }
1919 adv_deinit_choice(&uchoice);
1920
1921 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants %s with desire " ADV_WANT_PRINTF,
1922 utype_rule_name(choice->value.utype),
1923 choice->want);
1924 } else {
1925 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d cannot select defender");
1926 }
1927 } else {
1928 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d does not want defenders");
1929 }
1930 }
1931 } /* ok, don't need to defend */
1932
1933 if (pcity->surplus[O_SHIELD] <= 0
1935 || pcity->id == ai->wonder_city) {
1936 /* Things we consider below are not life-saving so we don't want to
1937 * build them if our populace doesn't feel like it */
1938 return choice;
1939 }
1940
1941 if (pplayer->economic.tax <= 50 || city_total_unit_gold_upkeep(pcity) <= 0) {
1942 /* Always allow one unit with real gold upkeep (after EFT_UNIT_UPKEEP_FREE_PER_CITY)
1943 * Allow more if economics is so strong that we have not increased taxes. */
1944 allow_gold_upkeep = TRUE;
1945 } else {
1946 allow_gold_upkeep = FALSE;
1947 }
1948
1949 /* Consider making a land bodyguard */
1950 punittype = dai_choose_bodyguard(ait, nmap, pcity, TC_LAND, L_DEFEND_GOOD,
1951 allow_gold_upkeep);
1952 if (punittype) {
1953 dai_unit_consider_bodyguard(ait, nmap, pcity, punittype, choice);
1954 }
1955
1956 /* If we are in severe danger, don't consider attackers. This is probably
1957 too general. In many cases we will want to buy attackers to counterattack.
1958 -- Per */
1959 if (choice->want - martial_value >= DAI_WANT_MILITARY_EMERGENCY
1960 && city_data->grave_danger > 0) {
1961 CITY_LOG(LOGLEVEL_BUILD, pcity,
1962 "severe danger (want " ADV_WANT_PRINTF "), force defender",
1963 choice->want);
1964 return choice;
1965 }
1966
1967 /* Consider making an offensive diplomat */
1968 dai_choose_diplomat_offensive(ait, pplayer, pcity, choice);
1969
1970 /* Consider making a sea bodyguard */
1971 punittype = dai_choose_bodyguard(ait, nmap, pcity, TC_OCEAN, L_DEFEND_GOOD,
1972 allow_gold_upkeep);
1973 if (punittype) {
1974 dai_unit_consider_bodyguard(ait, nmap, pcity, punittype, choice);
1975 }
1976
1977 /* Consider making an airplane */
1978 (void) dai_choose_attacker_air(ait, pplayer, pcity, choice, allow_gold_upkeep);
1979
1980 /* Consider making a paratrooper */
1981 dai_choose_paratrooper(ait, pplayer, pcity, choice, allow_gold_upkeep);
1982
1983 /* Check if we want a sailing attacker. Have to put sailing first
1984 before we mung the seamap */
1985 punittype = dai_choose_attacker(ait, pcity, TC_OCEAN, allow_gold_upkeep);
1986 if (punittype) {
1987 virtualunit = unit_virtual_create(
1988 pplayer, pcity, punittype,
1989 city_production_unit_veteran_level(pcity, punittype));
1990 choice = kill_something_with(ait, pplayer, pcity, virtualunit, choice);
1991 unit_virtual_destroy(virtualunit);
1992 }
1993
1994 /* Consider a land attacker or a ferried land attacker
1995 * (in which case, we might want a ferry before an attacker)
1996 */
1997 punittype = dai_choose_attacker(ait, pcity, TC_LAND, allow_gold_upkeep);
1998 if (punittype) {
1999 virtualunit = unit_virtual_create(pplayer, pcity, punittype, 1);
2000 choice = kill_something_with(ait, pplayer, pcity, virtualunit, choice);
2001 unit_virtual_destroy(virtualunit);
2002 }
2003
2004 /* Consider a hunter */
2005 dai_hunter_choice(ait, pplayer, pcity, choice, allow_gold_upkeep);
2006
2007 /* Consider veteran level enhancing buildings before non-urgent units */
2008 adjust_ai_unit_choice(pcity, choice);
2009
2010 if (choice->want <= 0) {
2011 CITY_LOG(LOGLEVEL_BUILD, pcity, "military advisor has no advice");
2012 } else {
2013 CITY_LOG(LOGLEVEL_BUILD, pcity,
2014 "military advisor choice: %s (want " ADV_WANT_PRINTF ")",
2015 adv_choice_rule_name(choice),
2016 choice->want);
2017 }
2018
2019 return choice;
2020}
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2475
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:488
#define action_enabler_list_iterate_end
Definition actions.h:457
#define action_by_result_iterate_end
Definition actions.h:492
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:455
#define TRADE_WEIGHTING
Definition advbuilding.h:21
#define SHIELD_WEIGHTING
Definition advbuilding.h:20
void adv_deinit_choice(struct adv_choice *choice)
Definition advchoice.c:46
void adv_init_choice(struct adv_choice *choice)
Definition advchoice.c:31
void adv_free_choice(struct adv_choice *choice)
Definition advchoice.c:71
struct adv_choice * adv_new_choice(void)
Definition advchoice.c:59
bool is_unit_choice_type(enum choice_type type)
Definition advchoice.c:115
const char * adv_choice_rule_name(const struct adv_choice *choice)
Definition advchoice.c:124
#define adv_choice_set_use(_choice, _use)
Definition advchoice.h:85
static void adv_choice_copy(struct adv_choice *dest, struct adv_choice *src)
Definition advchoice.h:79
@ CT_DEFENDER
Definition advchoice.h:41
@ CT_ATTACKER
Definition advchoice.h:40
@ CT_BUILDING
Definition advchoice.h:38
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:593
bool adv_is_player_dangerous(struct player *pplayer, struct player *aplayer)
Definition advdata.c:1087
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:374
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:385
#define POWER_DIVIDER
Definition advtools.h:32
#define ADV_WANTS_EQ(_w1, _w2)
Definition advtools.h:23
bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Definition aiair.c:584
struct ai_plr * dai_plr_data_get(struct ai_type *ait, struct player *pplayer, bool *caller_closes)
Definition aidata.c:308
void dai_choose_diplomat_defensive(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, int def)
Definition aidiplomat.c:115
void dai_choose_diplomat_offensive(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice)
Definition aidiplomat.c:164
bool dai_is_ferry_type(const struct unit_type *pferry, struct ai_type *ait)
Definition aiferry.c:151
void dai_hunter_choice(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Definition aihunt.c:255
#define TECH_LOG(ait, loglevel, pplayer, padvance, msg,...)
Definition ailog.h:36
void dai_choose_paratrooper(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition aiplayer.h:54
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition aiplayer.h:42
struct unit_type * dai_wants_defender_against(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, const struct unit_type *att, int want)
Definition aitech.c:388
bool dai_assess_military_unhappiness(const struct civ_map *nmap, struct city *pcity)
Definition aitools.c:1399
bool dai_choose_role_unit(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, enum choice_type type, int role, int want, bool need_boat)
Definition aitools.c:1328
adv_want military_amortize(struct player *pplayer, struct city *pcity, adv_want value, int delay, int build_cost)
Definition aitools.c:118
#define DAI_WANT_BELOW_MIL_EMERGENCY
Definition aitools.h:31
#define DAI_WANT_MILITARY_EMERGENCY
Definition aitools.h:32
int ai_trait_get_value(enum trait tr, struct player *pplayer)
Definition aitraits.c:68
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition aiunit.c:341
int unittype_def_rating_squared(const struct unit_type *att_type, const struct unit_type *def_type, struct player *def_player, struct tile *ptile, bool fortified, int veteran)
Definition aiunit.c:303
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition aiunit.c:2894
int build_cost_balanced(const struct unit_type *punittype)
Definition aiunit.c:249
adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile **pdest_tile, struct pf_path **ppath, struct pf_map **pferrymap, struct unit **pferryboat, const struct unit_type **pboattype, int *pmove_time)
Definition aiunit.c:1133
adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct unit **aunit, struct city **acity)
Definition aiunit.c:714
bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower, const struct unit_type *followee, struct ai_type *ait)
Definition aiunit.c:833
bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile *dest_tile, const struct unit_type *cargo_type, struct tile **ferry_dest, struct tile **beachhead_tile)
Definition aiunit.c:1058
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition aiunit.h:72
#define simple_ai_unit_type_iterate_end
Definition aiunit.h:151
#define simple_ai_unit_type_iterate(_ut)
Definition aiunit.h:145
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1216
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:789
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:839
bool city_got_defense_effect(const struct city *pcity, const struct unit_type *attacker)
Definition city.c:1569
bool can_city_build_unit_direct(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:888
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:927
bool can_city_build_unit_later(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:948
int city_total_unit_gold_upkeep(const struct city *pcity)
Definition city.c:1198
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
@ CITIZEN_ANGRY
Definition city.h:263
@ CITIZEN_UNHAPPY
Definition city.h:262
#define city_owner(_pcity_)
Definition city.h:543
#define city_list_iterate_end
Definition city.h:490
@ FEELING_EFFECT
Definition city.h:273
@ FEELING_FINAL
Definition city.h:276
@ FEELING_NATIONALITY
Definition city.h:274
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:930
int get_fortified_defense_power(const struct unit *attacker, struct unit *defender)
Definition combat.c:728
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:714
int get_total_attack_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:569
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:271
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile)
Definition combat.c:783
void get_modified_firepower(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, int *att_fp, int *def_fp)
Definition combat.c:369
#define POWER_FACTOR
Definition combat.h:32
Impr_type_id dai_find_source_building(struct city *pcity, enum effect_type effect_type, const struct unit_type *utype)
Definition daicity.c:2152
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
struct unit_type * dai_choose_defender_versus(struct city *pcity, struct unit *attacker)
Definition daimilitary.c:92
int assess_defense(struct ai_type *ait, struct city *pcity)
static adv_want dai_unit_attack_desirability(struct ai_type *ait, const struct unit_type *punittype)
struct adv_choice * military_advisor_choose_build(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, player_unit_list_getter ul_cb)
static unsigned int assess_danger(struct ai_type *ait, const struct civ_map *nmap, struct city *pcity, player_unit_list_getter ul_cb)
static bool action_may_happen_unit_on_city(const action_id wanted_action, const struct unit *actor, const struct city *pcity, int turns)
static void dai_reevaluate_building(struct city *pcity, adv_want *value, unsigned int urgency, unsigned int danger, int defense)
static void process_attacker_want(struct ai_type *ait, struct city *pcity, adv_want value, const struct unit_type *victim_unit_type, struct player *victim_player, int veteran, struct tile *ptile, struct adv_choice *best_choice, struct pf_map *ferry_map, struct unit *boat, const struct unit_type *boattype)
static struct adv_choice * kill_something_with(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct unit *myunit, struct adv_choice *choice)
bool dai_process_defender_want(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, unsigned int danger, struct adv_choice *choice, adv_want extra_want)
static void adjust_ai_unit_choice(struct city *pcity, struct adv_choice *choice)
static adv_want dai_unit_defense_desirability(struct ai_type *ait, const struct unit_type *punittype)
#define CITY_CONQUEST_WORTH(_city_, _data_)
Definition daimilitary.c:76
static enum fc_tristate tactical_req_cb(const struct req_context *context, const struct player *other_player, const struct requirement *req, void *data, int n_data)
int assess_defense_quadratic(struct ai_type *ait, struct city *pcity)
static struct unit_type * dai_choose_bodyguard(struct ai_type *ait, const struct civ_map *nmap, struct city *pcity, enum terrain_class tc, enum unit_role_id role, bool allow_gold_upkeep)
static int base_assess_defense_unit(struct city *pcity, struct unit *punit, bool igwall, bool quadratic, int wall_value)
static unsigned int assess_danger_unit(const struct civ_map *nmap, const struct city *pcity, struct pf_reverse_map *pcity_map, const struct unit *punit, int *move_time)
static int assess_defense_backend(struct ai_type *ait, struct city *pcity, bool igwall)
static struct unit_type * dai_choose_attacker(struct ai_type *ait, struct city *pcity, enum terrain_class tc, bool allow_gold_upkeep)
void dai_assess_danger_player(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer)
int assess_defense_unit(struct ai_type *ait, struct city *pcity, struct unit *punit, bool igwall)
static int assess_defense_igwall(struct ai_type *ait, struct city *pcity)
static void dai_unit_consider_bodyguard(struct ai_type *ait, const struct civ_map *nmap, struct city *pcity, struct unit_type *punittype, struct adv_choice *choice)
struct unit_list *() player_unit_list_getter(struct player *pplayer)
Definition daimilitary.h:34
#define FINISH_HIM_CITY_COUNT
Definition daimilitary.h:32
static void attack(QVariant data1, QVariant data2)
Definition dialogs.cpp:2918
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:72
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
Definition difficulty.c:339
int int id
Definition editgui_g.h:28
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:691
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:957
float adv_want
Definition fc_types.h:1206
int Tech_type_id
Definition fc_types.h:347
int Impr_type_id
Definition fc_types.h:346
@ RPT_POSSIBLE
Definition fc_types.h:585
int action_id
Definition fc_types.h:359
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
int Unit_type_id
Definition fc_types.h:352
@ O_SHIELD
Definition fc_types.h:91
@ O_LUXURY
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
static struct tile * pos
Definition finddlg.c:53
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_MAP
Definition handicaps.h:28
@ H_DANGER
Definition handicaps.h:32
@ H_ASSESS_DANGER_LIMITED
Definition handicaps.h:36
struct impr_type * improvement_by_number(const Impr_type_id id)
const char * improvement_rule_name(const struct impr_type *pimprove)
int impr_buy_gold_cost(const struct city *pcity, const struct impr_type *pimprove, int shields_in_stock)
bool is_great_wonder(const struct impr_type *pimprove)
#define B_LAST
Definition improvement.h:42
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
@ LOG_DEBUG
Definition log.h:34
@ LOG_VERBOSE
Definition log.h:33
#define log_error(message,...)
Definition log.h:103
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:316
bool can_attack_from_non_native(const struct unit_type *utype)
Definition movement.c:215
bool is_native_near_tile(const struct civ_map *nmap, const struct unit_class *uclass, const struct tile *ptile)
Definition movement.c:450
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:202
#define SINGLE_MOVE
Definition movement.h:24
struct city_list * cities
Definition packhand.c:117
bool pf_reverse_map_unit_position(struct pf_reverse_map *pfrm, const struct unit *punit, struct pf_position *pos)
const struct pf_parameter * pf_map_parameter(const struct pf_map *pfm)
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
void pf_map_iter_position(struct pf_map *pfm, struct pf_position *pos)
struct pf_reverse_map * pf_reverse_map_new_for_city(const struct civ_map *nmap, const struct city *pcity, const struct player *attacker, int max_turns, bool omniscient)
void pf_reverse_map_destroy(struct pf_reverse_map *pfrm)
void pf_map_destroy(struct pf_map *pfm)
#define PF_IMPOSSIBLE_MC
#define pf_map_tiles_iterate(ARG_pfm, NAME_tile, COND_from_start)
#define pf_map_tiles_iterate_end
void pft_fill_utype_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit_type *punittype, struct tile *pstart_tile, struct player *pplayer)
Definition pf_tools.c:826
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
static bool player_is_cpuhog(const struct player *pplayer)
Definition player.h:573
enum fc_tristate tri_req_active_turns(int pass, int period, const struct req_context *context, const struct player *other_player, const struct requirement *req)
enum fc_tristate tri_reqs_cb_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, struct requirement_vector *maybe_reqs, req_tester_cb tester, void *data, int n_data)
enum fc_tristate tri_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req)
enum req_unchanging_status is_req_preventing(const struct req_context *context, const struct player *other_player, const struct requirement *req, enum req_problem_type prob_type)
@ REQUCH_CTRL
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:747
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:769
struct research * research_get(const struct player *pplayer)
Definition research.c:126
fc_tristate
Definition shared.h:46
@ TRI_YES
Definition shared.h:46
@ TRI_NO
Definition shared.h:46
@ TRI_MAYBE
Definition shared.h:46
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
Definition specialist.c:217
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#define CITY_LOG(loglevel, pcity, msg,...)
Definition srv_log.h:83
@ AIT_DANGER
Definition srv_log.h:52
#define LOGLEVEL_BUILD
Definition srv_log.h:34
@ TIMER_STOP
Definition srv_log.h:76
@ TIMER_START
Definition srv_log.h:76
#define TIMING_LOG(timer, activity)
Definition srv_log.h:125
enum server_states server_state(void)
Definition srv_main.c:323
enum choice_type type
Definition advchoice.h:46
adv_want want
Definition advchoice.h:48
universals_u value
Definition advchoice.h:47
bool need_boat
Definition advchoice.h:49
adv_want building_want[B_LAST]
Definition infracache.h:32
int wonder_city
Definition advdata.h:50
bool has_diplomat
Definition daicity.h:59
unsigned int danger
Definition daicity.h:47
int bcost
Definition daicity.h:44
unsigned int urgency
Definition daicity.h:49
bool diplomat_threat
Definition daicity.h:58
int wallvalue
Definition daicity.h:51
int attack
Definition daicity.h:44
struct ai_invasion invasion
Definition daicity.h:43
unsigned int grave_danger
Definition daicity.h:48
int attack
Definition daicity.h:30
int occupy
Definition daicity.h:31
struct ai_plr::@267 stats
int boats
Definition aidata.h:79
adv_want tech_want[A_LAST+1]
Definition aidata.h:103
int available_boats
Definition aidata.h:80
Definition ai.h:50
Definition city.h:309
int surplus[O_LAST]
Definition city.h:343
int id
Definition city.h:315
struct adv_city * adv
Definition city.h:435
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:321
citizens specialists[SP_MAX]
Definition city.h:324
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
struct city::@17::@19 server
struct packet_game_info info
Definition game.h:89
int low_firepower_pearl_harbour
int low_firepower_combat_bonus
struct tile * start_tile
struct city_list * cities
Definition player.h:281
struct player_economic economic
Definition player.h:284
struct adv_data * adv
Definition player.h:334
const struct player * player
const struct city * city
struct universal source
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
enum move_level sea_move
Definition unittype.h:150
bool carries_occupiers
Definition aiunit.h:54
bool low_firepower
Definition aiunit.h:51
int max_defense_mp_bonus_pct
Definition unittype.h:560
struct unit_type::@87 adv
int defense_strength
Definition unittype.h:496
int firepower
Definition unittype.h:506
int paratroopers_range
Definition unittype.h:522
int move_rate
Definition unittype.h:497
int scramble_coeff[U_LAST]
Definition unittype.h:564
struct unit_type::@88 cache
bool igwall
Definition unittype.h:555
int attack_strength
Definition unittype.h:495
int defense_mp_bonuses_pct[U_LAST]
Definition unittype.h:563
Definition unit.h:138
int id
Definition unit.h:145
int hp
Definition unit.h:151
struct tile * tile
Definition unit.h:140
int veteran
Definition unit.h:152
enum universals_n kind
Definition fc_types.h:758
universals_u value
Definition fc_types.h:757
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define fc__fallthrough
Definition support.h:109
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
tech_req
Definition tech.h:110
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define TILE_XY(ptile)
Definition tile.h:42
#define TRAIT_DEFAULT_VALUE
Definition traits.h:32
const struct unit_type * utype
Definition fc_types.h:604
const struct impr_type * building
Definition fc_types.h:598
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2425
bool is_military_unit(const struct unit *punit)
Definition unit.c:319
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:328
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1617
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1713
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
#define unit_tile(_pu)
Definition unit.h:395
#define unit_owner(_pu)
Definition unit.h:394
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:193
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1520
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2547
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:459
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:258
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2755
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:270
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:515
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
#define utype_class(_t_)
Definition unittype.h:736
#define utype_fuel(ptype)
Definition unittype.h:825
@ MOVE_FULL
Definition unittype.h:131
@ MOVE_NONE
Definition unittype.h:131
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define unit_type_iterate(_p)
Definition unittype.h:841
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:848
#define U_NOT_OBSOLETED
Definition unittype.h:509