Freeciv-3.2
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 "aidiplomat.h"
59#include "aiferry.h"
60#include "aihand.h"
61#include "aihunt.h"
62#include "aiparatrooper.h"
63#include "aitech.h"
64#include "aitools.h"
65#include "daicity.h"
66#include "daidata.h"
67#include "daieffects.h"
68#include "dailog.h"
69#include "daiplayer.h"
70
71#include "daimilitary.h"
72
73/* Size 1 city gets destroyed when conquered. It's still a good thing
74 * stop enemy from having it. */
75#define CITY_CONQUEST_WORTH(_city_, _data_) \
76 (_data_->worth * 0.9 + (city_size_get(_city_) - 0.5) * 10)
77
78static unsigned int assess_danger(struct ai_type *ait,
79 const struct civ_map *nmap,
80 struct city *pcity,
82
84 const struct unit_type *punittype);
86 const struct unit_type *punittype);
87
88/**********************************************************************/
92 struct unit *attacker)
93{
94 struct unit_type *bestunit = NULL;
95 double best = 0;
97 struct player *pplayer = city_owner(pcity);
98 struct civ_map *nmap = &(wld.map);
99
102 int fpatt, fpdef, defense, attack;
103 double want, loss, cost = utype_build_shield_cost(pcity, NULL, punittype);
104 struct unit *defender;
105 int veteran = get_unittype_bonus(city_owner(pcity), pcity->tile,
108
109 defender = unit_virtual_create(pplayer, pcity, punittype, veteran);
110 defense = get_total_defense_power(attacker, defender);
111 attack = get_total_attack_power(attacker, defender, NULL);
112 get_modified_firepower(nmap, attacker, defender, &fpatt, &fpdef);
113
114 /* Greg's algorithm. loss is the average number of health lost by
115 * defender. If loss > attacker's hp then we should win the fight,
116 * which is always a good thing, since we avoid shield loss. */
117 loss = (double) defense * punittype->hp * fpdef / (attack * fpatt);
118 want = (loss + MAX(0, loss - attacker->hp)) / cost;
119
120#ifdef NEVER
121 CITY_LOG(LOG_DEBUG, pcity, "desire for %s against %s(%d,%d) is %.2f",
123 unit_name_orig(unit_type_get(attacker)),
124 TILE_XY(attacker->tile), want);
125#endif /* NEVER */
126
127 if (want > best || (ADV_WANTS_EQ(want, best)
128 && cost <= best_cost)) {
129 best = want;
131 best_cost = cost;
132 }
133 unit_virtual_destroy(defender);
134 }
136
137 return bestunit;
138}
139
140/**********************************************************************/
145static struct unit_type *dai_choose_attacker(struct ai_type *ait,
146 struct city *pcity,
147 enum terrain_class tc,
149{
150 struct unit_type *bestid = NULL;
151 adv_want best = -1;
153 struct player *pplayer = city_owner(pcity);
154 const struct civ_map *nmap = &(wld.map);
155
157 if (!allow_gold_upkeep && utype_upkeep_cost(putype, pplayer, O_GOLD) > 0) {
158 continue;
159 }
160
162 if ((tc == TC_LAND && utype_class(putype)->adv.land_move != MOVE_NONE)
163 || (tc == TC_OCEAN
164 && utype_class(putype)->adv.sea_move != MOVE_NONE)) {
166 && (cur > best
167 || (ADV_WANTS_EQ(cur, best)
169 <= utype_build_shield_cost(pcity, NULL, bestid)))) {
170 best = cur;
171 bestid = putype;
172 }
173 }
175
176 return bestid;
177}
178
179/**********************************************************************/
187static struct unit_type *dai_choose_bodyguard(struct ai_type *ait,
188 const struct civ_map *nmap,
189 struct city *pcity,
190 enum terrain_class tc,
191 enum unit_role_id role,
193{
194 struct unit_type *bestid = NULL;
195 adv_want best = 0;
196 struct player *pplayer = city_owner(pcity);
197
199 /* Only consider units of given role, or any if invalid given */
201 if (!utype_has_role(putype, role)) {
202 continue;
203 }
204 }
205
206 if (!allow_gold_upkeep && utype_upkeep_cost(putype, pplayer, O_GOLD) > 0) {
207 continue;
208 }
209
210 /* Only consider units of same move type */
211 if ((tc == TC_LAND && utype_class(putype)->adv.land_move == MOVE_NONE)
212 || (tc == TC_OCEAN
213 && utype_class(putype)->adv.sea_move == MOVE_NONE)) {
214 continue;
215 }
216
217 /* Now find best */
218 if (can_city_build_unit_now(nmap, pcity, putype)) {
220
221 if (desire > best
222 || (ADV_WANTS_EQ(desire, best) && utype_build_shield_cost(pcity, NULL, putype) <=
224 best = desire;
225 bestid = putype;
226 }
227 }
229
230 return bestid;
231}
232
233/**********************************************************************/
236static int base_assess_defense_unit(struct city *pcity, struct unit *punit,
237 bool igwall, bool quadratic,
238 int wall_value)
239{
240 int defense;
241 int fp;
242
243 if (is_special_unit(punit)) {
244 return 0;
245 }
246
250 /* Attacker firepower doubled, defender firepower set to
251 * game.info.low_firepower_pearl_harbour at max. */
253 defense /= 2;
254 } else {
255 defense *= fp;
256 }
257
258 defense /= POWER_DIVIDER;
259
260 if (quadratic) {
261 defense *= defense;
262 }
263
264 if (pcity != NULL && !igwall && city_got_defense_effect(pcity, NULL)) {
265 /* FIXME: We checked if city got defense effect against *some*
266 * unit type. Sea unit danger might cause us to build defenses
267 * against air units... */
268
269 /* TODO: What about wall_value < 10? Do we really want walls to
270 * result in decrease in the returned value? */
271 defense *= wall_value;
272 defense /= 10;
273 }
274
275 return defense;
276}
277
278/**********************************************************************/
281int assess_defense_quadratic(struct ai_type *ait, struct city *pcity)
282{
283 int defense = 0, walls = 0;
284 /* This can be an arg if needed, but we don't need to change it now. */
285 const bool igwall = FALSE;
286 struct ai_city *city_data = def_ai_city_data(pcity, ait);
287
288 /* wallvalue = 10, walls = 10,
289 * wallvalue = 40, walls = 20,
290 * wallvalue = 90, walls = 30 */
291
292 while (walls * walls < city_data->wallvalue * 10) {
293 walls++;
294 }
295
297 defense += base_assess_defense_unit(pcity, punit, igwall, FALSE,
298 walls);
300
301 if (defense > 1<<12) {
302 CITY_LOG(LOG_VERBOSE, pcity, "Overflow danger in assess_defense_quadratic:"
303 " %d", defense);
304 if (defense > 1<<15) {
305 defense = 1<<15; /* more defense than we know what to do with! */
306 }
307 }
308
309 return defense * defense;
310}
311
312/**********************************************************************/
315int assess_defense_unit(struct ai_type *ait, struct city *pcity,
316 struct unit *punit, bool igwall)
317{
318 return base_assess_defense_unit(pcity, punit, igwall, TRUE,
319 def_ai_city_data(pcity, ait)->wallvalue);
320}
321
322/**********************************************************************/
329static int assess_defense_backend(struct ai_type *ait, struct city *pcity,
330 bool igwall)
331{
332 /* Estimate of our total city defensive might */
333 int defense = 0;
334
336 defense += assess_defense_unit(ait, pcity, punit, igwall);
338
339 return defense;
340}
341
342/**********************************************************************/
345int assess_defense(struct ai_type *ait, struct city *pcity)
346{
347 return assess_defense_backend(ait, pcity, FALSE);
348}
349
350/**********************************************************************/
354static int assess_defense_igwall(struct ai_type *ait, struct city *pcity)
355{
356 return assess_defense_backend(ait, pcity, TRUE);
357}
358
359/**********************************************************************/
365static enum fc_tristate
367 const struct player *other_player,
368 const struct requirement *req,
369 void *data, int n_data)
370{
371 switch (req->source.kind) {
372 case VUT_IMPROVEMENT:
373 case VUT_SITE:
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 case VUT_COUNTER:
392 /* Can be changed back or forth quickly */
393 return TRI_MAYBE;
394 case VUT_MINVETERAN:
395 /* Can be changed forth but not back */
396 return is_req_preventing(context, other_player, req, RPT_POSSIBLE)
399 case VUT_NATIONALITY:
400 /* Can be changed back but hardly forth (foreign citizens reduced first) */
401 switch (tri_req_active(context, other_player, req)) {
402 case TRI_NO:
403 return req->present ? TRI_NO : TRI_MAYBE;
404 case TRI_YES:
405 return req->present ? TRI_MAYBE : TRI_YES;
406 default:
407 return TRI_MAYBE;
408 }
409 case VUT_DIPLREL:
410 case VUT_DIPLREL_TILE:
414 /* If the attack happens, there is a diplrel that allows it */
415 return TRI_YES;
416 case VUT_AGE:
417 case VUT_FORM_AGE:
418 case VUT_MINCALFRAG:
419 case VUT_MINYEAR:
420 /* If it is not near, won't change */
421 return tri_req_active_turns(n_data, 5 /* WAG */,
422 context, other_player, req);
423 case VUT_CITYSTATUS:
426 return TRI_MAYBE;
427 }
429 case VUT_UTYPE:
430 case VUT_UTFLAG:
431 case VUT_UCLASS:
432 case VUT_UCFLAG:
433 /* FIXME: support converting siege machines (needs hard reqs checked) */
434 case VUT_ACTION:
435 case VUT_OTYPE:
436 case VUT_SPECIALIST:
437 case VUT_EXTRAFLAG:
438 case VUT_MINLATITUDE:
439 case VUT_MAXLATITUDE:
440 case VUT_AI_LEVEL:
441 case VUT_CITYTILE:
442 case VUT_STYLE:
443 case VUT_TOPO:
444 case VUT_WRAP:
446 case VUT_NATION:
447 case VUT_NATIONGROUP:
448 case VUT_ADVANCE:
449 case VUT_TECHFLAG:
450 case VUT_GOVERNMENT:
451 case VUT_ACHIEVEMENT:
452 case VUT_IMPR_GENUS:
453 case VUT_IMPR_FLAG:
454 case VUT_PLAYER_FLAG:
455 case VUT_PLAYER_STATE:
456 case VUT_MINCULTURE:
457 case VUT_MINTECHS:
459 case VUT_ROADFLAG:
460 case VUT_TERRAIN:
461 case VUT_EXTRA:
462 case VUT_GOOD:
463 case VUT_TERRAINCLASS:
464 case VUT_TERRFLAG:
465 case VUT_TERRAINALTER:
466 case VUT_NONE:
467 return tri_req_active(context, other_player, req);
468 case VUT_COUNT:
469 /* Not implemented. */
470 break;
471 }
473
474 return TRI_NO;
475}
476
477/**********************************************************************/
484static bool
486 const struct unit *actor,
487 const struct city *pcity,
488 int turns)
489{
490 const struct player *target_player = city_owner(pcity),
492 const struct unit_type *utype = unit_type_get(actor);
493 const struct req_context target_ctx = {
495 .city = pcity,
496 .tile = city_tile(pcity)
497 }, actor_ctx = {
498 .player = actor_player,
499 .unit = actor,
500 .unittype = utype
501 };
502
503 if (!utype_can_do_action(utype, wanted_action)) {
504 return FALSE;
505 }
507 enabler) {
508 /* We assume that we could build or move units into the city
509 * that are not present there yet */
511 &enabler->actor_reqs, NULL,
512 tactical_req_cb, NULL, turns)
513 &&
515 &enabler->target_reqs, NULL,
516 tactical_req_cb, NULL, turns)) {
517 return TRUE;
518 }
520
521 return FALSE;
522}
523
524/**********************************************************************/
527static unsigned int assess_danger_unit(const struct civ_map *nmap,
528 const struct city *pcity,
530 const struct unit *punit,
531 int *move_time)
532{
533 struct pf_position pos;
534 const struct unit_type *punittype = unit_type_get(punit);
535 const struct tile *ptile = city_tile(pcity);
536 const struct player *uowner = unit_owner(punit);
537 const struct unit *ferry;
538 unsigned int danger;
539 int amod = -99, dmod;
540 bool attack_danger = FALSE;
541
543
546 && 0 < punittype->paratroopers_range) {
548 / punittype->paratroopers_range);
549 }
550
553 || *move_time > pos.turn)) {
554 *move_time = pos.turn;
555 }
556
558 && (ferry = unit_transport_get(punit))
561 || *move_time > pos.turn)) {
562 *move_time = pos.turn;
564 (*move_time)++;
565 }
566 }
567 }
568
569 if (PF_IMPOSSIBLE_MC == *move_time) {
570 return 0;
571 }
572 if (!is_native_tile(punittype, ptile)
574 return 0;
575 }
577 return 0;
578 }
579
580 /* Find the worst attack action to expect */
582 /* Is it possible that punit will do action id to the city? */
583 /* FIXME: some unit parameters (notably, veterancy) may meddle in */
584
586 int b;
587
589
591 if (b > amod) {
592 amod = b;
593 }
594 }
596
597 /* FIXME: it's a dummy support for anti-bombard defense just to do something against
598 * approaching bombarders. Some better logic is needed, see OSDN#41778 */
599 if (!attack_danger) {
601 /* FIXME: some unit parameters (notably, veterancy) may meddle in */
602
604 *move_time)) {
605 int b;
606
608
610 if (b > amod) {
611 amod = b;
612 }
613 }
615 /* Here something should be done cuz the modifier affects
616 * more than one unit but not their full hp, but is not done yet...*/
617 }
618 if (!attack_danger) {
619 /* If the unit is dangerous, it's not about its combat strength */
620 return 0;
621 }
622
623 danger = adv_unit_att_rating(punit);
624 dmod = 100 + get_unittype_bonus(city_owner(pcity), ptile,
626 return danger * (amod + 100) / MAX(dmod, 1);
627}
628
629/**********************************************************************/
635 const struct civ_map *nmap,
636 struct player *pplayer)
637{
638 /* Do nothing if game is not running */
639 if (S_S_RUNNING == server_state()) {
640 city_list_iterate(pplayer->cities, pcity) {
641 (void) assess_danger(ait, nmap, pcity, NULL);
643 }
644}
645
646/**********************************************************************/
665static void dai_reevaluate_building(struct city *pcity, adv_want *value,
666 unsigned int urgency, unsigned int danger,
667 int defense)
668{
669 if (*value == 0 || danger <= 0) {
670 return;
671 }
672
673 *value = MAX(*value, 100 + urgency); /* default */
674
675 if (urgency > 0 && danger > defense * 2) {
676 *value += 100;
677 } else if (defense != 0 && danger > defense) {
678 *value = MAX(danger * 100 / defense, *value);
679 }
680}
681
682/**********************************************************************/
700static unsigned int assess_danger(struct ai_type *ait,
701 const struct civ_map *nmap,
702 struct city *pcity,
704{
705 struct player *pplayer = city_owner(pcity);
706 struct tile *ptile = city_tile(pcity);
707 struct ai_city *city_data = def_ai_city_data(pcity, ait);
708 /* How much such danger there is that building would help against. */
709 unsigned int danger_reduced[B_LAST];
710 int i;
711 int defender;
712 unsigned int urgency = 0;
713 int defense;
714 int total_danger = 0;
715
716 /* TODO: Presumably most, or even all, of these arrays
717 * could be of size game.control.num_unit_types instead
718 * of full U_LAST */
724 int assess_turns;
725 bool omnimap;
726
728
729 /* Initialize data. */
731 if (has_handicap(pplayer, H_DANGER)) {
732 /* Always thinks that city is in grave danger */
733 city_data->grave_danger = 1;
734 } else {
735 city_data->grave_danger = 0;
736 }
737 city_data->diplomat_threat = FALSE;
738 city_data->has_diplomat = FALSE;
739
740 unit_type_iterate(utype) {
741 int idx = utype_index(utype);
742
743 defense_bonuses_pct[idx] = 0;
745 best_non_scramble[idx] = -1;
746 /* FIXME: cache it somewhere? */
748 = 100 + get_unittype_bonus(pplayer, ptile, utype, NULL,
750 city_def_against[idx] = MAX(city_def_against[idx], 1);
752
753 /* What flag-specific bonuses do our units have. */
754 /* We value them less than general defense increment */
755 unit_list_iterate(ptile->units, punit) {
756 const struct unit_type *def = unit_type_get(punit);
757
759 city_data->has_diplomat = TRUE;
760 }
762 /* This is first defender of this type. Check defender type
763 * specific bonuses. */
764
765 /* Skip defenders that have no bonuses at all. Acceptable
766 * side-effect is that we can't consider negative bonuses at
767 * all ("No bonuses" should be better than "negative bonus") */
768 if (def->cache.max_defense_mp_bonus_pct > 0) {
769 unit_type_iterate(utype) {
770 int idx = utype_index(utype);
771 int coeff = def->cache.scramble_coeff[idx];
772 int bonus;
773
774 /* FIXME: consider EFT_FORTIFY_DEFENSE_BONUS */
775 if (coeff) {
776 bonus = coeff / city_def_against[idx] - 100;
777 } else {
778 bonus = def->cache.defense_mp_bonuses_pct[idx];
779 }
780
781 if (bonus > defense_bonuses_pct[idx]) {
782 if (!coeff) {
783 best_non_scramble[idx] = bonus;
784 }
785 defense_bonuses_pct[idx] = bonus;
786 } else if (!coeff) {
787 best_non_scramble[idx] = MAX(best_non_scramble[idx], bonus);
788 }
790 } else {
791 /* Just remember that such a unit exists and hope its bonuses are just 0 */
793 }
794
796 }
798 if (sth_does_not_scramble || unit_list_size(ptile->units) <= 0) {
799 /* Scrambling units tend to be expensive. If we have a barenaked city, we'll
800 * need at least a cheap unit. If we have only scramblers,
801 * maybe it's OK. */
804
807 }
808
809 if (player_is_cpuhog(pplayer)) {
810 assess_turns = 6;
811 } else {
813 }
814
815 omnimap = !has_handicap(pplayer, H_MAP);
816
817 /* Check. */
820 struct unit_list *units;
821
822 if (!adv_is_player_dangerous(pplayer, aplayer)) {
823 continue;
824 }
825 /* Note that we still consider the units of players we are not (yet)
826 * at war with. */
827
829 omnimap);
830
831 if (ul_cb != NULL) {
832 units = ul_cb(aplayer);
833 } else {
834 units = aplayer->units;
835 }
836 unit_list_iterate(units, punit) {
837 int move_time;
838 unsigned int vulnerability;
839 int defbonus_pct;
840 const struct unit_type *utype = unit_type_get(punit);
841 struct unit_type_ai *utai = utype_ai_data(utype, ait);
842
843#ifdef FREECIV_WEB
844 /* freeciv-web ignores danger that is far in distance,
845 * no matter how quickly it would reach us; even if
846 * that's *immediately* over a road type that allows
847 * unlimited movement. */
849
853 /* Too far away. */
854 continue;
855 }
856#endif /* FREECIV_WEB */
857
858 if (!utai->carries_occupiers
859 && !utype_acts_hostile(utype)) {
860 /* Harmless unit. */
861 continue;
862 }
863
864 /* Defender unspecific vulnerability and potential move time */
866 punit, &move_time);
867
869 continue;
870 }
871
872 if (unit_can_take_over(punit) || utai->carries_occupiers) {
873 /* Even if there is no attack strength,
874 * we need ANY protector for the city */
876 if (3 >= move_time) {
877 urgency++;
878 if (1 >= move_time) {
879 city_data->grave_danger++;
880 }
881 }
882 }
883
885 if (defbonus_pct > 100) {
886 defbonus_pct = (defbonus_pct + 100) / 2;
887 }
888 /* Reduce vulnerability for specific bonuses we do have */
889 vulnerability = vulnerability * 100 / (defbonus_pct + 100);
890 /* Pass the order for a new defender type against it
891 * to the scientific advisor, urgency considered */
892 (void) dai_wants_defender_against(ait, nmap, pplayer, pcity, utype,
894
896 city_data->diplomat_threat = TRUE;
897 }
898
899 vulnerability *= vulnerability; /* positive feedback */
900 if (1 < move_time) {
902 }
903
907 defender = dai_find_source_building(pcity, EFT_NUKE_PROOF, utype);
908 if (defender != B_LAST) {
909 danger_reduced[defender] += vulnerability / MAX(move_time, 1);
910 }
911 } else if (best_non_scramble[utype_index(utype)] >= 0) {
912 /* To consider building a defensive building,
913 * build first a defender that gets any profit of it */
914 defender = dai_find_source_building(pcity, EFT_DEFEND_BONUS, utype);
915 if (defender != B_LAST) {
916 int danred = vulnerability / MAX(move_time, 1);
917 /* Maybe we can build an improvement
918 * that gets normal defender over scrambling one?
919 * Effectively a sqrt-scale because we don't test how high
920 * the effect is. */
923 danred = danred * (100 + best_non_scramble[utype_index(utype)])
924 / (100 + defense_bonuses_pct[utype_index(utype)]);
925 }
926 danger_reduced[defender] += danred;
927 }
928 }
929
932
934
936
937 if (total_danger) {
938 /* If any hostile player has any dangerous unit that can in any time
939 * reach the city, we consider building walls here, if none yet.
940 * FIXME: this value assumes that walls give x3 defense. */
941 city_data->wallvalue = 90;
942 } else {
943 /* No danger.
944 * This is half of the wallvalue of what danger 1 would produce. */
945 city_data->wallvalue = 5;
946 }
947
948 if (0 < city_data->grave_danger) {
949 /* really, REALLY urgent to defend */
950 urgency += 10 * city_data->grave_danger;
951 }
952
953 /* HACK: This needs changing if multiple improvements provide
954 * this effect. */
955 /* FIXME: Accept only buildings helping unit classes we actually use.
956 * Now we consider any land mover helper suitable. */
957 /* Sum of squared defense ratings */
958 defense = assess_defense_igwall(ait, pcity);
959
960 for (i = 0; i < B_LAST; i++) {
961 if (0 < danger_reduced[i]) {
963 urgency, danger_reduced[i], defense);
964 }
965 }
966
967 if (has_handicap(pplayer, H_DANGER) && 0 == total_danger) {
968 /* Has to have some danger
969 * Otherwise grave_danger will be ignored. */
970 city_data->danger = 1;
971 } else {
972 city_data->danger = total_danger;
973 }
974 city_data->urgency = urgency;
975
977
978 return urgency;
979}
980
981/**********************************************************************/
986 const struct unit_type *punittype)
987{
989 int attack = punittype->attack_strength;
990 int defense = punittype->defense_strength;
991 int maxbonus_pct = 0;
992 int fp = punittype->firepower;
993
994 /* Sea and helicopters often have their firepower set to low firepower when
995 * defending. We can't have such units as defenders. */
998 }
999 if (((struct unit_type_ai *)utype_ai_data(punittype, ait))->low_firepower) {
1001 }
1002 desire *= fp;
1003 desire *= defense;
1004 desire += punittype->move_rate / SINGLE_MOVE;
1005 desire += attack;
1006
1007 maxbonus_pct = punittype->cache.max_defense_mp_bonus_pct;
1008 if (maxbonus_pct > 100) {
1009 maxbonus_pct = (maxbonus_pct + 100) / 2;
1010 }
1011 desire += desire * maxbonus_pct / 100;
1013 desire /= 10; /* But might actually be worth it */
1014 }
1015
1016 return desire;
1017}
1018
1019/**********************************************************************/
1023 const struct unit_type *punittype)
1024{
1026 int attack = punittype->attack_strength;
1027 int defense = punittype->defense_strength;
1028
1029 desire *= punittype->move_rate;
1030 desire *= punittype->firepower;
1031 desire *= attack;
1032 desire += defense;
1034 desire += desire / 2;
1035 }
1037 desire /= 10; /* But might actually be worth it */
1038 }
1040 desire += desire / 2;
1041 }
1043 desire += desire / 4;
1044 }
1045 if (punittype->adv.igwall) {
1046 desire += desire / 4;
1047 }
1048
1049 return desire;
1050}
1051
1052/**********************************************************************/
1057bool dai_process_defender_want(struct ai_type *ait, const struct civ_map *nmap,
1058 struct player *pplayer,
1059 struct city *pcity, unsigned int danger,
1060 struct adv_choice *choice, adv_want extra_want)
1061{
1062 const struct research *presearch = research_get(pplayer);
1063 /* FIXME: We check if the city has *some* defensive structure,
1064 * but not whether the city has a defensive structure against
1065 * any specific attacker. The actual danger may not be mitigated
1066 * by the defense selected... */
1067 bool walls = city_got_defense_effect(pcity, NULL);
1068 /* Technologies we would like to have. */
1070 /* Our favourite unit. */
1071 adv_want best = -1;
1072 struct unit_type *best_unit_type = NULL;
1073 int best_unit_cost = 1;
1074 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1075 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
1076 adv_want total_want = danger + extra_want;
1077
1078 memset(tech_desire, 0, sizeof(tech_desire));
1079
1081 adv_want desire; /* How much we want the unit? */
1082
1083 /* Only consider proper defenders - otherwise waste CPU and
1084 * bump tech want needlessly. */
1087 continue;
1088 }
1089
1091
1093 desire /= 2; /* Not good, just ok */
1094 }
1095
1097 /* Causes unhappiness even when in defense, so not a good
1098 * idea for a defender, unless it is _really_ good.
1099 * Downright counter productive, if we want unit just for
1100 * maintaining peace. */
1101 if (danger == 0) {
1102 desire = -50;
1103 } else {
1104 desire /= 2;
1105 }
1106 }
1107
1108 if (desire > 0) {
1109 desire /= POWER_DIVIDER / 2; /* Good enough, no rounding errors. */
1110 desire *= desire;
1111
1112 if (can_city_build_unit_now(nmap, pcity, punittype)) {
1113 /* We can build the unit now... */
1114
1115 int build_cost = utype_build_shield_cost(pcity, NULL, punittype);
1116 int limit_cost = pcity->shield_stock + 40;
1117
1119 desire *= city_data->wallvalue;
1120 /* TODO: More use of POWER_FACTOR ! */
1122 }
1123
1125 && build_cost < best_unit_cost)
1126 || ((desire > best
1127 || (ADV_WANTS_EQ(desire, best)
1128 && build_cost <= best_unit_cost))
1129 && (best_unit_type == NULL
1130 /* In case all units are more expensive than limit_cost */
1131 || limit_cost <= pcity->shield_stock + 40))) {
1132 best = desire;
1134 best_unit_cost = build_cost;
1135 }
1136 } else if (can_city_build_unit_later(nmap, pcity, punittype)) {
1137 /* We first need to develop the tech required by the unit... */
1138
1139 /* Cost (shield equivalent) of gaining these techs. */
1140 /* FIXME? Katvrr advises that this should be weighted more heavily in
1141 * big danger. */
1142 int tech_cost = 0;
1143
1148
1149 tech_cost = tech_cost / 4 / city_list_size(pplayer->cities);
1150
1151 /* Contrary to the above, we don't care if walls are actually built
1152 * - we're looking into the future now. */
1154 desire *= city_data->wallvalue;
1156 }
1157
1158 /* Yes, there's some similarity with kill_desire(). */
1159 /* TODO: Explain what shield cost has to do with tech want. */
1163 }
1164 }
1166
1167 if (best == -1) {
1168 CITY_LOG(LOG_DEBUG, pcity, "Ooops - we cannot build any defender!");
1169 }
1170
1171 if (best_unit_type != NULL) {
1173 best *= city_data->wallvalue;
1174 best /= POWER_FACTOR;
1175 }
1176 } else {
1177 best_unit_cost = 100; /* Building impossible is considered costly.
1178 * This should increase want for tech providing
1179 * first defender type. */
1180 }
1181
1182 if (best <= 0) {
1183 best = 1; /* Avoid division by zero below. */
1184 }
1185
1186 /* Update tech_want for appropriate techs for units we want to build. */
1188 if (tech_desire[utype_index(punittype)] > 0) {
1189 /* TODO: Document or fix the algorithm below. I have no idea why
1190 * it is written this way, and the results seem strange to me. - Per */
1192
1194 plr_data->tech_want[advance_index(padv)]
1195 += desire;
1196 TECH_LOG(ait, LOG_DEBUG, pplayer, padv,
1197 "+ " ADV_WANT_PRINTF " for %s to defend %s",
1198 desire,
1200 city_name_get(pcity));
1202 }
1204
1205 if (!best_unit_type) {
1206 return FALSE;
1207 }
1208
1209 choice->value.utype = best_unit_type;
1210 choice->want = danger; /* FIXME: Not 'total_want' because of the way callers
1211 * are constructed. They may overwrite this value,
1212 * and then the value will NOT contain 'extra_want'.
1213 * Later we may add 'extra_want', and don't want it
1214 * already included in case this was NOT overwritten. */
1215 choice->type = CT_DEFENDER;
1216
1217 return TRUE;
1218}
1219
1220/**********************************************************************/
1237static void process_attacker_want(struct ai_type *ait,
1238 struct city *pcity,
1239 adv_want value,
1240 const struct unit_type *victim_unit_type,
1241 struct player *victim_player,
1242 int veteran, struct tile *ptile,
1243 struct adv_choice *best_choice,
1244 struct pf_map *ferry_map,
1245 struct unit *boat,
1246 const struct unit_type *boattype)
1247{
1248 struct player *pplayer = city_owner(pcity);
1249 const struct research *presearch = research_get(pplayer);
1250 /* The enemy city. acity == NULL means stray enemy unit */
1251 struct city *acity = tile_city(ptile);
1252 struct pf_parameter parameter;
1253 struct pf_map *pfm;
1254 struct pf_position pos;
1255 const struct unit_type *orig_utype = best_choice->value.utype;
1256 int victim_count = 1;
1257 int needferry = 0;
1258 bool unhap;
1259 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
1260 const struct civ_map *nmap = &(wld.map);
1261
1262 /* Has to be initialized to make gcc happy */
1263 struct ai_city *acity_data = NULL;
1264
1266
1267 if (acity != NULL) {
1269 }
1270
1271 if (utype_class(orig_utype)->adv.sea_move == MOVE_NONE
1272 && !boat && boattype) {
1273 /* Cost of ferry */
1275 }
1276
1277 if (!is_stack_vulnerable(ptile)) {
1278 /* If it is a city, a fortress or an air base,
1279 * we may have to whack it many times */
1281 }
1282
1286 && (U_NOT_OBSOLETED == punittype->obsoleted_by
1287 || !can_city_build_unit_direct(nmap, pcity, punittype->obsoleted_by))
1288 && punittype->attack_strength > 0 /* Or we'll get SIGFPE */) {
1289 /* Values to be computed */
1291 adv_want want;
1292 int move_time;
1293 int vuln;
1294 int veteran_level
1296 &(const struct req_context) {
1297 .player = pplayer,
1298 .city = pcity,
1299 .tile = city_tile(pcity),
1300 .unittype = punittype,
1301 },
1302 NULL,
1304 /* Cost (shield equivalent) of gaining these techs. */
1305 /* FIXME? Katvrr advises that this should be weighted more heavily in big
1306 * danger. */
1307 int tech_cost = 0;
1309 /* See description of kill_desire() for info about this variables. */
1313 punittype->hp);
1314 int tech_dist = 0;
1315
1318
1320 if (tech_dist == 0) {
1322 }
1324
1325 tech_cost = tech_cost / 4 / city_list_size(pplayer->cities);
1326
1327 /* Take into account reinforcements strength */
1328 if (acity) {
1329 attack += acity_data->attack;
1330 }
1331
1332 if (attack == 0) {
1333 /* Yes, it can happen that a military unit has attack = 1,
1334 * for example militia with HP = 1 (in civ1 ruleset). */
1335 continue;
1336 }
1337
1338 attack *= attack;
1339
1340 pft_fill_utype_parameter(&parameter, nmap, punittype, city_tile(pcity),
1341 pplayer);
1342 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1343 pfm = pf_map_new(&parameter);
1344
1345 /* Set the move_time appropriately. */
1346 move_time = -1;
1347 if (NULL != ferry_map) {
1348 struct tile *dest_tile;
1349
1350 if (find_beachhead(pplayer, ferry_map, ptile, punittype,
1351 &dest_tile, NULL)
1352 && pf_map_position(ferry_map, dest_tile, &pos)) {
1353 move_time = pos.turn;
1356 if (atile == dest_tile) {
1358 move_time += pos.turn;
1359 break;
1360 } else if (atile == ptile) {
1361 /* Reaching directly seems better. */
1363 move_time = pos.turn;
1364 break;
1365 }
1367 }
1368 }
1369
1370 if (-1 == move_time) {
1371 if (pf_map_position(pfm, ptile, &pos)) {
1372 move_time = pos.turn;
1373 } else {
1375 continue;
1376 }
1377 }
1379
1380 /* Estimate strength of the enemy. */
1381
1382 if (victim_unit_type) {
1385 ptile, FALSE, veteran);
1386 } else {
1387 vuln = 0;
1388 }
1389
1390 /* Not bothering to s/!vuln/!pdef/ here for the time being. -- Syela
1391 * (this is noted elsewhere as terrible bug making warships yoyoing)
1392 * as the warships will go to enemy cities hoping that the enemy builds
1393 * something for them to kill. */
1394 if (vuln == 0
1395 && (utype_class(punittype)->adv.land_move == MOVE_NONE
1396 || 0 < utype_fuel(punittype))) {
1397 desire = 0;
1398
1399 } else {
1400 if (acity
1402 && acity_data->invasion.attack > 0
1403 && acity_data->invasion.occupy == 0) {
1405 float finishing_factor = 1;
1406
1409 }
1411 } else {
1412 desire = 0;
1413 }
1414
1415 if (!acity) {
1416 desire = kill_desire(value, attack, bcost, vuln, victim_count);
1417 } else {
1418 adv_want kd;
1419 int city_attack = acity_data->attack * acity_data->attack;
1420
1421 /* See aiunit.c:find_something_to_kill() for comments. */
1422 kd = kill_desire(value, attack,
1423 (bcost + acity_data->bcost), vuln,
1424 victim_count);
1425
1426 if (value * city_attack > acity_data->bcost * vuln) {
1427 kd -= kill_desire(value, city_attack,
1428 acity_data->bcost, vuln,
1429 victim_count);
1430 }
1431
1432 desire = MAX(desire, kd);
1433 }
1434 }
1435
1437 /* We can be possibly making some people of our homecity unhappy - then
1438 * we don't want to travel too far away to our victims. */
1439 /* TODO: Unify the 'unhap' dependency to some common function. */
1442
1443 want = military_amortize(pplayer, pcity, desire, MAX(1, move_time),
1445
1446 if (want > 0) {
1447 if (tech_dist > 0) {
1448 /* This is a future unit, tell the scientist how much we need it */
1450 plr_data->tech_want[advance_index(padv)]
1451 += want;
1452 TECH_LOG(ait, LOG_DEBUG, pplayer, padv,
1453 "+ " ADV_WANT_PRINTF " for %s vs %s(%d,%d)",
1454 want,
1457 TILE_XY(ptile));
1459 } else if (want > best_choice->want) {
1460 const struct impr_type *impr_req;
1461
1462 if (can_city_build_unit_now(nmap, pcity, punittype)) {
1463 /* This is a real unit and we really want it */
1464
1465 CITY_LOG(LOG_DEBUG, pcity, "overriding %s(" ADV_WANT_PRINTF
1466 ") with %s(" ADV_WANT_PRINTF ")"
1467 " [attack=%d,value=" ADV_WANT_PRINTF
1468 ",move_time=%d,vuln=%d,bcost=%d]",
1469 utype_rule_name(best_choice->value.utype),
1470 best_choice->want,
1472 want,
1473 attack, value, move_time, vuln, bcost);
1474
1475 best_choice->value.utype = punittype;
1476 best_choice->want = want;
1477 best_choice->type = CT_ATTACKER;
1479 pcity)))) {
1480 CITY_LOG(LOG_DEBUG, pcity, "cannot build unit %s",
1482 } else if (can_city_build_improvement_now(pcity, impr_req)) {
1483 /* Building this unit requires a specific type of improvement.
1484 * So we build this improvement instead. This may not be the
1485 * best behavior. */
1486 CITY_LOG(LOG_DEBUG, pcity, "building %s to build unit %s",
1489 best_choice->value.building = impr_req;
1490 best_choice->want = want;
1491 best_choice->type = CT_BUILDING;
1492 } else {
1493 /* This should never happen? */
1494 CITY_LOG(LOG_DEBUG, pcity, "cannot build %s or unit %s",
1497 }
1498 }
1499 }
1500 }
1502}
1503
1504/**********************************************************************/
1515static struct adv_choice *kill_something_with(struct ai_type *ait,
1516 struct player *pplayer,
1517 struct city *pcity, struct unit *myunit,
1518 struct adv_choice *choice)
1519{
1520 /* Our attack rating (with reinforcements) */
1521 int attack;
1522 /* Benefit from fighting the target */
1524 /* Defender of the target city/tile */
1525 struct unit *pdef;
1526 const struct unit_type *def_type;
1527 struct player *def_owner;
1528 int def_vet; /* Is the defender veteran? */
1529 /* Target coordinates */
1530 struct tile *ptile;
1531 /* Our transport */
1532 struct unit *ferryboat;
1533 /* Our target */
1534 struct city *acity;
1535 /* Type of the boat (real or a future one) */
1536 const struct unit_type *boattype;
1537 struct pf_map *ferry_map = NULL;
1538 int move_time;
1539 struct adv_choice *best_choice;
1540 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1541 struct ai_city *acity_data;
1542 struct civ_map *nmap = &(wld.map);
1543
1545 best_choice->value.utype = unit_type_get(myunit);
1546 best_choice->type = CT_ATTACKER;
1547 adv_choice_set_use(best_choice, "attacker");
1548
1550 && !utype_fuel(unit_type_get(myunit)), choice);
1551
1552 if (city_data->danger != 0 && assess_defense(ait, pcity) == 0) {
1553 /* Defense comes first! */
1554 goto cleanup;
1555 }
1556
1557 best_choice->want = find_something_to_kill(ait, pplayer, myunit, &ptile, NULL,
1558 &ferry_map, &ferryboat,
1559 &boattype, &move_time);
1560 if (NULL == ptile
1561 || ptile == unit_tile(myunit)
1562 || !can_unit_attack_tile(myunit, NULL, ptile)) {
1563 goto cleanup;
1564 }
1565
1566 acity = tile_city(ptile);
1567
1568 if (myunit->id != 0) {
1569 log_error("%s(): non-virtual unit!", __FUNCTION__);
1570 goto cleanup;
1571 }
1572
1574 if (acity) {
1576 attack += acity_data->attack;
1577 }
1578 attack *= attack;
1579
1580 if (NULL != acity) {
1581 /* Rating of enemy defender */
1582 int vulnerability;
1583
1584 if (!POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(acity))) {
1585 /* Not a valid target */
1586 goto cleanup;
1587 }
1588
1591 if (1 < move_time && def_type) {
1594 city_owner(acity), ptile,
1595 FALSE, def_vet);
1597 } else {
1598 vulnerability = 0;
1599 benefit = 0;
1600 def_vet = 0;
1601 }
1602
1603 pdef = get_defender(nmap, myunit, ptile, NULL);
1604 if (pdef) {
1606 city_owner(acity), ptile, FALSE,
1607 pdef->veteran);
1608 if (vulnerability < m) {
1610 def_vet = pdef->veteran;
1613 }
1614 }
1615 if (unit_can_take_over(myunit) || acity_data->invasion.occupy > 0) {
1616 /* Bonus for getting the city */
1618 float finishing_factor = 1;
1619
1622 }
1624 }
1625
1626 /* end dealing with cities */
1627 } else {
1628
1629 if (NULL != ferry_map) {
1631 ferry_map = NULL;
1632 }
1633
1634 pdef = get_defender(nmap, myunit, ptile, NULL);
1635 if (!pdef) {
1636 /* Nobody to attack! */
1637 goto cleanup;
1638 }
1639
1641
1643 def_vet = pdef->veteran;
1645 /* end dealing with units */
1646 }
1647
1648 if (NULL == ferry_map) {
1650 def_vet, ptile,
1652 } else {
1653 /* Attract a boat to our city or retain the one that's already here */
1655 best_choice->need_boat = TRUE;
1657 def_vet, ptile,
1658 best_choice, ferry_map, ferryboat, boattype);
1659 }
1660
1661 if (best_choice->want > choice->want) {
1662 /* We want attacker more than what we have selected before */
1663 adv_free_choice(choice);
1664 choice = best_choice;
1665 CITY_LOG(LOG_DEBUG, pcity, "kill_something_with()"
1666 " %s has chosen attacker, %s, want=" ADV_WANT_PRINTF,
1667 city_name_get(pcity),
1668 utype_rule_name(best_choice->value.utype),
1669 best_choice->want);
1670
1671 if (NULL != ferry_map && !ferryboat) { /* need a new ferry */
1672 /* We might need a new boat even if there are boats free,
1673 * if they are blockaded or in inland seas*/
1675 if (dai_choose_role_unit(ait, pplayer, pcity, choice, CT_ATTACKER,
1676 L_FERRYBOAT, choice->want, TRUE)
1677 && dai_is_ferry_type(choice->value.utype, ait)) {
1678#ifdef FREECIV_DEBUG
1679 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, NULL);
1680
1681 log_debug("kill_something_with() %s has chosen attacker ferry, "
1682 "%s, want=" ADV_WANT_PRINTF ", %d of %d free",
1683 city_name_get(pcity),
1684 utype_rule_name(choice->value.utype),
1685 choice->want,
1686 ai->stats.available_boats, ai->stats.boats);
1687#endif /* FREECIV_DEBUG */
1688
1689 adv_choice_set_use(choice, "attacker ferry");
1690 } /* else can not build ferries yet */
1691 }
1692 }
1693
1694cleanup:
1695 if (best_choice != choice) {
1696 /* It was not taken to use.
1697 * This hackery needed since 'goto cleanup:' might skip
1698 * sensible points to do adv_free_choice(). */
1700 }
1701 if (NULL != ferry_map) {
1703 }
1704
1705 return choice;
1706}
1707
1708/**********************************************************************/
1714static void dai_unit_consider_bodyguard(struct ai_type *ait,
1715 struct city *pcity,
1716 struct unit_type *punittype,
1717 struct adv_choice *choice)
1718{
1719 if (choice->want < DAI_WANT_MILITARY_EMERGENCY) {
1720 struct player *pplayer = city_owner(pcity);
1721 struct unit *aunit = NULL;
1722 struct city *acity = NULL;
1723 struct unit *virtualunit
1724 = unit_virtual_create(pplayer, pcity, punittype,
1726 punittype));
1727 const adv_want want = look_for_charge(ait, pplayer, virtualunit,
1728 &aunit, &acity);
1729
1730 if (want > choice->want) {
1731 choice->want = want;
1732 choice->value.utype = punittype;
1733 choice->type = CT_DEFENDER;
1734 adv_choice_set_use(choice, "bodyguard");
1735 }
1736
1738 }
1739}
1740
1741/**********************************************************************/
1749static void adjust_ai_unit_choice(struct city *pcity,
1750 struct adv_choice *choice)
1751{
1753
1754 /* Sanity */
1755 if (!is_unit_choice_type(choice->type)
1757 || city_production_unit_veteran_level(pcity, choice->value.utype)) {
1758 return;
1759 }
1760
1761 /* N.B.: have to check that we haven't already built the building --mck */
1763 choice->value.utype)) != B_LAST
1764 && !city_has_building(pcity, improvement_by_number(id))) {
1765 choice->value.building = improvement_by_number(id);
1766 choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER,
1767 city_owner(pcity))
1768 / TRAIT_DEFAULT_VALUE / 2));
1769 choice->type = CT_BUILDING;
1770 adv_choice_set_use(choice, "veterancy building");
1771 }
1772}
1773
1774/**********************************************************************/
1780 const struct civ_map *nmap,
1781 struct player *pplayer,
1782 struct city *pcity,
1784{
1785 struct adv_data *ai = adv_data_get(pplayer, NULL);
1786 struct unit_type *punittype;
1787 unsigned int our_def, urgency;
1788 struct tile *ptile = pcity->tile;
1789 struct unit *virtualunit;
1790 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1792 bool martial_need = FALSE;
1793 struct adv_choice *choice = adv_new_choice();
1794 bool allow_gold_upkeep;
1795
1796 urgency = assess_danger(ait, nmap, pcity, ul_cb);
1797 /* Changing to quadratic to stop AI from building piles
1798 * of small units -- Syela */
1799 /* It has to be AFTER assess_danger() thanks to wallvalue. */
1800 our_def = assess_defense_quadratic(ait, pcity);
1801
1802 dai_choose_diplomat_defensive(ait, pplayer, pcity, choice, our_def);
1803
1805 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY] > 0) {
1807 }
1808
1809 if (!martial_need) {
1811 if (pcity->specialists[sp] > 0
1812 && get_specialist_output(pcity, sp, O_LUXURY) > 0) {
1814 break;
1815 }
1817 }
1818
1819 if (martial_need
1821 martial_value = dai_content_effect_value(pplayer, pcity,
1823 1, FEELING_FINAL);
1824 }
1825
1826 /* Otherwise no need to defend yet */
1827 if (city_data->danger != 0 || martial_value > 0) {
1828 struct impr_type *pimprove;
1829 int num_defenders = unit_list_size(ptile->units);
1830 int wall_id, danger;
1831 bool build_walls = TRUE;
1832 bool def_unit_selected = FALSE;
1833 int qdanger = city_data->danger * city_data->danger;
1834
1835 if (qdanger <= 0) {
1836 /* We only need these defenders because of Martial Law value */
1837 danger = 0;
1838 build_walls = FALSE; /* Walls don't provide Martial Law */
1839 } else {
1840 /* First determine the danger. It is measured in percents of our
1841 * defensive strength, capped at 200 + urgency */
1842 if (qdanger >= our_def) {
1843 if (urgency == 0) {
1844 /* Don't waste money */
1845 danger = 100;
1846 } else if (our_def == 0) {
1847 danger = 200 + urgency;
1848 } else {
1849 danger = MIN(200, 100 * qdanger / our_def) + urgency;
1850 }
1851 } else {
1852 danger = 100 * qdanger / our_def;
1853 }
1854
1855 if (pcity->surplus[O_SHIELD] <= 0 && our_def != 0) {
1856 /* Won't be able to support anything */
1857 danger = 0;
1858 }
1859 }
1860
1861 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d urgency=%d danger=%d num_def=%d "
1862 "our_def=%d", urgency, danger, num_defenders, our_def);
1863
1864 if (our_def == 0 && danger > 0) {
1865 /* Build defensive unit first! Walls will help nothing if there's
1866 * nobody behind them. */
1867 if (dai_process_defender_want(ait, nmap, pplayer, pcity, danger, choice,
1868 martial_value)) {
1869 choice->want = DAI_WANT_BELOW_MIL_EMERGENCY + danger;
1870 adv_choice_set_use(choice, "first defender");
1873
1874 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants first defender with " ADV_WANT_PRINTF,
1875 choice->want);
1876 }
1877 }
1878 if (build_walls) {
1879 /* FIXME: 1. Does not consider what kind of future danger is likely, so
1880 * may build SAM batteries when enemy has only land units. */
1881 /* We will build walls if we can and want and (have "enough" defenders or
1882 * can just buy the walls straight away) */
1883
1884 /* HACK: This needs changing if multiple improvements provide
1885 * this effect. */
1887 pimprove = improvement_by_number(wall_id);
1888
1889 if (wall_id != B_LAST
1890 && pcity->server.adv->building_want[wall_id] != 0 && our_def != 0
1891 && can_city_build_improvement_now(pcity, pimprove)
1893 || (city_data->grave_danger == 0
1894 && pplayer->economic.gold
1895 > impr_buy_gold_cost(pcity, pimprove, pcity->shield_stock)))
1896 && ai_fuzzy(pplayer, TRUE)) {
1897 if (pcity->server.adv->building_want[wall_id] > 0) {
1898 /* NB: great wall is under domestic */
1899 choice->value.building = pimprove;
1900 /* building_want is hacked by assess_danger() */
1901 choice->want = pcity->server.adv->building_want[wall_id];
1902 choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER, pplayer)
1903 / TRAIT_DEFAULT_VALUE / 2));
1904 if (urgency == 0 && choice->want > DAI_WANT_BELOW_MIL_EMERGENCY) {
1906 }
1907 choice->type = CT_BUILDING;
1908 adv_choice_set_use(choice, "defense building");
1909 CITY_LOG(LOG_DEBUG, pcity,
1910 "m_a_c_d wants defense building with " ADV_WANT_PRINTF,
1911 choice->want);
1912 } else {
1914 }
1915 } else {
1917 }
1918 }
1919
1920 /* If our choice isn't defender unit already, consider one */
1921 if (!def_unit_selected) {
1922 if ((danger > 0 && num_defenders <= urgency) || martial_value > 0) {
1923 struct adv_choice uchoice;
1924
1926
1927 /* Consider building defensive units */
1928 if (dai_process_defender_want(ait, nmap, pplayer, pcity, danger,
1930 /* Potential defender found */
1931 if (urgency == 0
1932 && uchoice.value.utype->defense_strength == 1) {
1933 /* FIXME: check other reqs (unit class?) */
1934 if (get_city_bonus(pcity, EFT_HP_REGEN) > 0) {
1935 /* Unlikely */
1936 uchoice.want = MIN(49, danger);
1937 } else {
1938 uchoice.want = MIN(25, danger);
1939 }
1940 } else {
1941 uchoice.want = danger;
1942 }
1943
1944 uchoice.want += martial_value;
1945 if (danger > 0) {
1946 adv_choice_set_use(&uchoice, "defender");
1947 } else {
1948 adv_choice_set_use(&uchoice, "police");
1949 }
1950
1951 if (!build_walls || uchoice.want > choice->want) {
1952 adv_choice_copy(choice, &uchoice);
1953 }
1955
1956 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants %s with desire " ADV_WANT_PRINTF,
1957 utype_rule_name(choice->value.utype),
1958 choice->want);
1959 } else {
1960 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d cannot select defender");
1961 }
1962 } else {
1963 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d does not want defenders");
1964 }
1965 }
1966 } /* Ok, don't need to defend */
1967
1968 if (pcity->surplus[O_SHIELD] <= 0
1970 || pcity->id == ai->wonder_city) {
1971 /* Things we consider below are not life-saving so we don't want to
1972 * build them if our populace doesn't feel like it */
1973 return choice;
1974 }
1975
1976 if (pplayer->economic.tax <= 50 || city_total_unit_gold_upkeep(pcity) <= 0) {
1977 /* Always allow one unit with real gold upkeep (after EFT_UNIT_UPKEEP_FREE_PER_CITY)
1978 * Allow more if economics is so strong that we have not increased taxes. */
1980 } else {
1982 }
1983
1984 /* Consider making a land bodyguard */
1987 if (punittype) {
1988 dai_unit_consider_bodyguard(ait, pcity, punittype, choice);
1989 }
1990
1991 /* If we are in severe danger, don't consider attackers. This is probably
1992 too general. In many cases we will want to buy attackers to counterattack.
1993 -- Per */
1995 && city_data->grave_danger > 0) {
1996 CITY_LOG(LOGLEVEL_BUILD, pcity,
1997 "severe danger (want " ADV_WANT_PRINTF "), force defender",
1998 choice->want);
1999 return choice;
2000 }
2001
2002 /* Consider making an offensive diplomat */
2003 dai_choose_diplomat_offensive(ait, pplayer, pcity, choice);
2004
2005 /* Consider making a sea bodyguard */
2008 if (punittype) {
2009 dai_unit_consider_bodyguard(ait, pcity, punittype, choice);
2010 }
2011
2012 /* Consider making an airplane */
2013 (void) dai_choose_attacker_air(ait, pplayer, pcity, choice, allow_gold_upkeep);
2014
2015 /* Consider making a paratrooper */
2016 dai_choose_paratrooper(ait, pplayer, pcity, choice, allow_gold_upkeep);
2017
2018 /* Check if we want a sailing attacker. Have to put sailing first
2019 before we mung the seamap */
2021 if (punittype) {
2023 pplayer, pcity, punittype,
2025 choice = kill_something_with(ait, pplayer, pcity, virtualunit, choice);
2027 }
2028
2029 /* Consider a land attacker or a ferried land attacker
2030 * (in which case, we might want a ferry before an attacker)
2031 */
2033 if (punittype) {
2034 virtualunit = unit_virtual_create(pplayer, pcity, punittype, 1);
2035 choice = kill_something_with(ait, pplayer, pcity, virtualunit, choice);
2037 }
2038
2039 /* Consider a hunter */
2040 dai_hunter_choice(ait, pplayer, pcity, choice, allow_gold_upkeep);
2041
2042 /* Consider veteran level enhancing buildings before non-urgent units */
2043 adjust_ai_unit_choice(pcity, choice);
2044
2045 if (choice->want <= 0) {
2046 CITY_LOG(LOGLEVEL_BUILD, pcity, "military advisor has no advice");
2047 } else {
2048 CITY_LOG(LOGLEVEL_BUILD, pcity,
2049 "military advisor choice: %s (want " ADV_WANT_PRINTF ")",
2050 adv_choice_rule_name(choice),
2051 choice->want);
2052 }
2053
2054 return choice;
2055}
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:2315
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:481
#define action_enabler_list_iterate_end
Definition actions.h:441
#define action_by_result_iterate_end
Definition actions.h:485
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:439
#define action_id(_act_)
Definition actions.h:661
#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:605
bool adv_is_player_dangerous(struct player *pplayer, struct player *aplayer)
Definition advdata.c:1107
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:380
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:391
#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:582
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:166
bool dai_is_ferry_type(const struct unit_type *pferry, struct ai_type *ait)
Definition aiferry.c:149
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:254
void dai_choose_paratrooper(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
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:390
bool dai_assess_military_unhappiness(const struct civ_map *nmap, struct city *pcity)
Definition aitools.c:1417
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:1346
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:69
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:804
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:854
bool city_got_defense_effect(const struct city *pcity, const struct unit_type *attacker)
Definition city.c:1596
bool can_city_build_unit_direct(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:903
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:947
bool can_city_build_unit_later(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:970
int city_total_unit_gold_upkeep(const struct city *pcity)
Definition city.c:1222
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:564
@ CITIZEN_ANGRY
Definition city.h:271
@ CITIZEN_UNHAPPY
Definition city.h:270
#define city_owner(_pcity_)
Definition city.h:563
#define city_list_iterate_end
Definition city.h:510
@ FEELING_EFFECT
Definition city.h:281
@ FEELING_FINAL
Definition city.h:284
@ FEELING_NATIONALITY
Definition city.h:282
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:989
int get_fortified_defense_power(const struct unit *attacker, struct unit *defender)
Definition combat.c:781
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:767
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:610
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:836
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:311
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:409
#define POWER_FACTOR
Definition combat.h:32
char * incite_cost
Definition comments.c:75
Impr_type_id dai_find_source_building(struct city *pcity, enum effect_type effect_type, const struct unit_type *utype)
Definition daicity.c:2156
struct ai_plr * dai_plr_data_get(struct ai_type *ait, struct player *pplayer, bool *caller_closes)
Definition daidata.c:308
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
#define TECH_LOG(ait, loglevel, pplayer, padvance, msg,...)
Definition dailog.h:36
struct unit_type * dai_choose_defender_versus(struct city *pcity, struct unit *attacker)
Definition daimilitary.c:91
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 void dai_unit_consider_bodyguard(struct ai_type *ait, struct city *pcity, struct unit_type *punittype, struct adv_choice *choice)
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:75
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)
struct unit_list *() player_unit_list_getter(struct player *pplayer)
Definition daimilitary.h:34
#define FINISH_HIM_CITY_COUNT
Definition daimilitary.h:32
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition daiplayer.h:54
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition daiplayer.h:42
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition daiunit.c:342
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 daiunit.c:304
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition daiunit.c:2896
int build_cost_balanced(const struct unit_type *punittype)
Definition daiunit.c:250
adv_want look_for_charge(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct unit **aunit, struct city **acity)
Definition daiunit.c:715
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 daiunit.c:1136
bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower, const struct unit_type *followee, struct ai_type *ait)
Definition daiunit.c:835
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 daiunit.c:1061
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition daiunit.h:72
#define simple_ai_unit_type_iterate_end
Definition daiunit.h:151
#define simple_ai_unit_type_iterate(_ut)
Definition daiunit.h:145
static void attack(QVariant data1, QVariant data2)
Definition dialogs.cpp:3009
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: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 * punit
Definition dialogs_g.h:74
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:74
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:748
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:846
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:1035
float adv_want
Definition fc_types.h:1354
int Tech_type_id
Definition fc_types.h:377
int Impr_type_id
Definition fc_types.h:376
@ RPT_POSSIBLE
Definition fc_types.h:700
int action_id
Definition fc_types.h:389
#define ADV_WANT_PRINTF
Definition fc_types.h:1355
int Unit_type_id
Definition fc_types.h:382
@ O_SHIELD
Definition fc_types.h:101
@ O_LUXURY
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
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:630
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:331
bool can_attack_from_non_native(const struct unit_type *utype)
Definition movement.c:227
bool is_native_near_tile(const struct civ_map *nmap, const struct unit_class *uclass, const struct tile *ptile)
Definition movement.c:465
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:214
#define SINGLE_MOVE
Definition movement.h:26
struct city_list * cities
Definition packhand.c:119
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:537
#define players_iterate(_pplayer)
Definition player.h:532
static bool player_is_cpuhog(const struct player *pplayer)
Definition player.h:575
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:750
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:772
struct research * research_get(const struct player *pplayer)
Definition research.c:128
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:333
enum choice_type type
Definition advchoice.h:46
adv_want want
Definition advchoice.h:48
universals_u value
Definition advchoice.h:47
adv_want building_want[B_LAST]
Definition infracache.h:32
int wonder_city
Definition advdata.h:55
int bcost
Definition daicity.h:44
unsigned int urgency
Definition daicity.h:49
int wallvalue
Definition daicity.h:51
struct ai_plr::@253 stats
int boats
Definition daidata.h:79
int available_boats
Definition daidata.h:80
Definition ai.h:50
Definition city.h:320
int surplus[O_LAST]
Definition city.h:355
int id
Definition city.h:326
struct adv_city * adv
Definition city.h:452
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:333
citizens specialists[SP_MAX]
Definition city.h:336
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
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:279
struct player_economic economic
Definition player.h:282
struct adv_data * adv
Definition player.h:332
const struct player * player
struct universal source
Definition tile.h:50
struct unit_list * units
Definition tile.h:58
enum move_level sea_move
Definition unittype.h:163
bool low_firepower
Definition daiunit.h:51
int max_defense_mp_bonus_pct
Definition unittype.h:579
int firepower
Definition unittype.h:525
int scramble_coeff[U_LAST]
Definition unittype.h:583
struct unit_type::@88 cache
int defense_mp_bonuses_pct[U_LAST]
Definition unittype.h:582
Definition unit.h:138
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:902
universals_u value
Definition fc_types.h:901
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define fc__fallthrough
Definition support.h:119
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:43
#define TRAIT_DEFAULT_VALUE
Definition traits.h:32
const struct unit_type * utype
Definition fc_types.h:721
enum citystatus_type citystatus
Definition fc_types.h:731
const struct impr_type * building
Definition fc_types.h:714
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2441
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:359
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1624
bool is_special_unit(const struct unit *punit)
Definition unit.c:350
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1729
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2425
#define unit_tile(_pu)
Definition unit.h:397
#define unit_owner(_pu)
Definition unit.h:396
#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:199
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1468
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1484
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2499
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:387
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:264
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2739
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:276
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1438
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:443
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
#define utype_class(_t_)
Definition unittype.h:749
#define utype_fuel(ptype)
Definition unittype.h:839
#define unit_tech_reqs_iterate_end
Definition unittype.h:881
#define unit_tech_reqs_iterate(_utype_, _p)
Definition unittype.h:875
@ MOVE_FULL
Definition unittype.h:144
@ MOVE_NONE
Definition unittype.h:144
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_type_iterate(_p)
Definition unittype.h:855
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:862
#define U_NOT_OBSOLETED
Definition unittype.h:528