Freeciv-3.4
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 "infracache.h"
49
50/* ai */
51#include "aitraits.h"
52#include "difficulty.h"
53#include "handicaps.h"
54
55/* ai/default */
56#include "daiair.h"
57#include "daicity.h"
58#include "daidata.h"
59#include "daidiplomat.h"
60#include "daieffects.h"
61#include "daiferry.h"
62#include "daihunter.h"
63#include "dailog.h"
64#include "daiparadrop.h"
65#include "daiplayer.h"
66#include "daitech.h"
67#include "daitools.h"
68
69#include "daimilitary.h"
70
71/* Size 1 city gets destroyed when conquered. It's still a good thing
72 * stop enemy from having it. */
73#define CITY_CONQUEST_WORTH(_city_, _data_) \
74 (_data_->worth * 0.9 + (city_size_get(_city_) - 0.5) * 10)
75
76static unsigned int assess_danger(struct ai_type *ait,
77 const struct civ_map *nmap,
78 struct city *pcity,
80
82 const struct unit_type *punittype);
84 const struct unit_type *punittype);
85
86/**********************************************************************/
90 struct unit *attacker)
91{
92 struct unit_type *bestunit = nullptr;
93 double best = 0;
95 struct player *pplayer = city_owner(pcity);
96 struct civ_map *nmap = &(wld.map);
97
100 int fpatt, fpdef, defense, attack;
101 double want, loss, cost = utype_build_shield_cost(pcity, nullptr, punittype);
102 struct unit *defender;
104 punittype, nullptr,
106
107 defender = unit_virtual_create(pplayer, pcity, punittype, veteran);
108 defense = get_total_defense_power(attacker, defender);
109 attack = get_total_attack_power(attacker, defender, nullptr);
110 get_modified_firepower(nmap, attacker, defender, &fpatt, &fpdef);
111
112 /* Greg's algorithm. loss is the average number of health lost by
113 * defender. If loss > attacker's hp then we should win the fight,
114 * which is always a good thing, since we avoid shield loss. */
115 loss = (double) defense * punittype->hp * fpdef / (attack * fpatt);
116 want = (loss + MAX(0, loss - attacker->hp)) / cost;
117
118#ifdef NEVER
119 CITY_LOG(LOG_DEBUG, pcity, "desire for %s against %s(%d,%d) is %.2f",
121 unit_rule_name(attacker),
122 TILE_XY(attacker->tile), want);
123#endif /* NEVER */
124
125 if (want > best || (ADV_WANTS_EQ(want, best)
126 && cost <= best_cost)) {
127 best = want;
129 best_cost = cost;
130 }
131 unit_virtual_destroy(defender);
132 }
134
135 return bestunit;
136}
137
138/**********************************************************************/
143static struct unit_type *dai_choose_attacker(struct ai_type *ait,
144 const struct civ_map *nmap,
145 struct city *pcity,
146 enum terrain_class tc,
148{
149 struct unit_type *bestid = nullptr;
150 adv_want best = -1;
152 struct player *pplayer = city_owner(pcity);
153
156 && utype_upkeep_cost(putype, nullptr, pplayer, O_GOLD) > 0) {
157 continue;
158 }
159
161 if ((tc == TC_LAND && utype_class(putype)->adv.land_move != MOVE_NONE)
162 || (tc == TC_OCEAN
163 && utype_class(putype)->adv.sea_move != MOVE_NONE)) {
165 && (cur > best
166 || (ADV_WANTS_EQ(cur, best)
168 <= utype_build_shield_cost(pcity, nullptr, bestid)))) {
169 best = cur;
170 bestid = putype;
171 }
172 }
174
175 return bestid;
176}
177
178/**********************************************************************/
186static struct unit_type *dai_choose_bodyguard(struct ai_type *ait,
187 const struct civ_map *nmap,
188 struct city *pcity,
189 enum terrain_class tc,
190 enum unit_role_id role,
192{
193 struct unit_type *bestid = nullptr;
194 adv_want best = 0;
195 struct player *pplayer = city_owner(pcity);
196
198 /* Only consider units of given role, or any if invalid given */
200 if (!utype_has_role(putype, role)) {
201 continue;
202 }
203 }
204
206 && utype_upkeep_cost(putype, nullptr, 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 */
220
221 if (desire > best
222 || (ADV_WANTS_EQ(desire, best)
223 && utype_build_shield_cost(pcity, nullptr, putype) <=
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_special_unit(punit)) {
245 return 0;
246 }
247
248 defense = get_fortified_defense_power(nullptr, punit) * punit->hp;
251 /* Attacker firepower doubled, defender firepower set to
252 * game.info.low_firepower_pearl_harbor at max. */
253 defense *= MIN(fp, game.info.low_firepower_pearl_harbor);
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 != nullptr && !igwall && city_got_defense_effect(pcity, nullptr)) {
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/**********************************************************************/
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,
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
368 const struct req_context *other_context,
369 const struct requirement *req,
370 void *data, int n_data)
371{
372 switch (req->source.kind) {
373 case VUT_IMPROVEMENT:
374 case VUT_SITE:
375 {
376 const struct impr_type *b = req->source.value.building;
377
378 /* FIXME: In actor_reqs, may allow attack _from_ a city with... */
379 if (req->survives || context->city == nullptr || is_great_wonder(b)
380 || !city_has_building(context->city, b) || b->sabotage <= 0) {
382 }
383 /* Else may be sabotaged */
384 }
386 case VUT_UNITSTATE:
387 case VUT_ACTIVITY:
388 case VUT_MINSIZE:
391 case VUT_MINHP:
392 case VUT_MINMOVES:
393 case VUT_COUNTER:
394 /* Can be changed back or forth quickly */
395 return TRI_MAYBE;
396 case VUT_MINVETERAN:
397 /* Can be changed forth but not back */
401 case VUT_NATIONALITY:
402 /* Can be changed back but hardly forth (foreign citizens reduced first) */
403 switch (tri_req_active(context, other_context, req)) {
404 case TRI_NO:
405 return req->present ? TRI_NO : TRI_MAYBE;
406 case TRI_YES:
407 return req->present ? TRI_MAYBE : TRI_YES;
408 default:
409 return TRI_MAYBE;
410 }
411 case VUT_DIPLREL:
412 case VUT_DIPLREL_TILE:
416 /* If the attack happens, there is a diplrel that allows it */
417 return TRI_YES;
418 case VUT_AGE:
419 case VUT_FORM_AGE:
420 case VUT_MINCALFRAG:
421 case VUT_MINYEAR:
422 /* If it is not near, won't change */
423 return tri_req_active_turns(n_data, 5 /* WAG */,
424 context, other_context, req);
425 case VUT_CITYSTATUS:
428 return TRI_MAYBE;
429 }
431 case VUT_UTYPE:
432 case VUT_UTFLAG:
433 case VUT_UCLASS:
434 case VUT_UCFLAG:
435 /* FIXME: Support converting siege machines (needs hard reqs checked) */
436 case VUT_ACTION:
437 case VUT_OTYPE:
438 case VUT_SPECIALIST:
439 case VUT_EXTRAFLAG:
440 case VUT_MINLATITUDE:
441 case VUT_MAXLATITUDE:
442 case VUT_AI_LEVEL:
443 case VUT_CITYTILE:
444 case VUT_STYLE:
445 case VUT_TOPO:
446 case VUT_WRAP:
448 case VUT_NATION:
449 case VUT_NATIONGROUP:
450 case VUT_ADVANCE:
451 case VUT_TECHFLAG:
452 case VUT_GOVERNMENT:
453 case VUT_GOVFLAG:
454 case VUT_ACHIEVEMENT:
455 case VUT_IMPR_GENUS:
456 case VUT_IMPR_FLAG:
457 case VUT_PLAYER_FLAG:
458 case VUT_PLAYER_STATE:
459 case VUT_MINCULTURE:
460 case VUT_MINTECHS:
461 case VUT_FUTURETECHS:
462 case VUT_MINCITIES:
464 case VUT_ROADFLAG:
465 case VUT_TERRAIN:
466 case VUT_EXTRA:
467 case VUT_TILEDEF:
469 case VUT_GOOD:
470 case VUT_TERRAINCLASS:
471 case VUT_TERRFLAG:
472 case VUT_TERRAINALTER:
475 case VUT_TILE_REL:
476 case VUT_NONE:
478 case VUT_COUNT:
479 /* Not implemented. */
480 break;
481 }
483
484 return TRI_NO;
485}
486
487/**********************************************************************/
494static bool
496 const struct unit *actor,
497 const struct city *pcity,
498 int turns)
499{
500 const struct player *target_player = city_owner(pcity),
502 const struct unit_type *utype = unit_type_get(actor);
503 const struct req_context target_ctx = {
505 .city = pcity,
507 }, actor_ctx = {
508 .player = actor_player,
509 .unit = actor,
510 .unittype = utype
511 };
512
513 if (!utype_can_do_action(utype, wanted_action)) {
514 return FALSE;
515 }
517 enabler) {
518 /* We assume that we could build or move units into the city
519 * that are not present there yet */
521 &enabler->actor_reqs, nullptr,
522 tactical_req_cb, nullptr, turns)
523 &&
525 &enabler->target_reqs, nullptr,
526 tactical_req_cb, nullptr, turns)) {
527 return TRUE;
528 }
530
531 return FALSE;
532}
533
534/**********************************************************************/
537static unsigned int assess_danger_unit(const struct civ_map *nmap,
538 const struct city *pcity,
540 const struct unit *punit,
541 int *move_time)
542{
543 struct pf_position pos;
544 const struct unit_type *punittype = unit_type_get(punit);
545 const struct tile *ptile = city_tile(pcity);
546 const struct player *uowner = unit_owner(punit);
547 const struct unit *ferry;
548 unsigned int danger;
549 int amod = -99, dmod;
550 bool attack_danger = FALSE;
551
553
556 && 0 < punittype->paratroopers_range) {
558 / punittype->paratroopers_range);
559 }
560
563 || *move_time > pos.turn)) {
564 *move_time = pos.turn;
565 }
566
568 && (ferry = unit_transport_get(punit))
571 || *move_time > pos.turn)) {
572 *move_time = pos.turn;
574 (*move_time)++;
575 }
576 }
577 }
578
579 if (PF_IMPOSSIBLE_MC == *move_time) {
580 return 0;
581 }
582 if (!is_native_tile(punittype, ptile)
584 return 0;
585 }
587 return 0;
588 }
589
590 /* Find the worst attack action to expect */
592 /* Is it possible that punit will do action id to the city? */
593 /* FIXME: some unit parameters (notably, veterancy) may meddle in */
594
596 int b;
597
599
601 if (b > amod) {
602 amod = b;
603 }
604 }
606
607 /* FIXME: it's a dummy support for anti-bombard defense just to do something against
608 * approaching bombarders. Some better logic is needed, see OSDN#41778 */
609 if (!attack_danger) {
611 /* FIXME: some unit parameters (notably, veterancy) may meddle in */
612
614 *move_time)) {
615 int b;
616
618
620 if (b > amod) {
621 amod = b;
622 }
623 }
625 /* Here something should be done cuz the modifier affects
626 * more than one unit but not their full hp, but is not done yet...*/
627 }
628 if (!attack_danger) {
629 /* If the unit is dangerous, it's not about its combat strength */
630 return 0;
631 }
632
633 danger = adv_unit_att_rating(punit);
634 dmod = 100 + get_unittype_bonus(city_owner(pcity), ptile,
635 punittype, nullptr, EFT_DEFEND_BONUS);
636 return danger * (amod + 100) / MAX(dmod, 1);
637}
638
639/**********************************************************************/
645 const struct civ_map *nmap,
646 struct player *pplayer)
647{
648 /* Do nothing if game is not running */
649 if (S_S_RUNNING == server_state()) {
650 city_list_iterate(pplayer->cities, pcity) {
651 (void) assess_danger(ait, nmap, pcity, nullptr);
653 }
654}
655
656/**********************************************************************/
675static void dai_reevaluate_building(struct city *pcity, adv_want *value,
676 unsigned int urgency, unsigned int danger,
677 int defense)
678{
679 if (*value == 0 || danger <= 0) {
680 return;
681 }
682
683 *value = MAX(*value, 100 + urgency); /* default */
684
685 if (urgency > 0 && danger > defense * 2) {
686 *value += 100;
687 } else if (defense != 0 && danger > defense) {
688 *value = MAX(danger * 100 / defense, *value);
689 }
690}
691
692/**********************************************************************/
710static unsigned int assess_danger(struct ai_type *ait,
711 const struct civ_map *nmap,
712 struct city *pcity,
714{
715 struct player *pplayer = city_owner(pcity);
716 struct tile *ptile = city_tile(pcity);
717 struct ai_city *city_data = def_ai_city_data(pcity, ait);
718 /* How much such danger there is that building would help against. */
719 unsigned int danger_reduced[B_LAST];
720 int i;
721 int defender;
722 unsigned int urgency = 0;
723 int defense;
724 int total_danger = 0;
725
726 /* TODO: Presumably most, or even all, of these arrays
727 * could be of size game.control.num_unit_types instead
728 * of full U_LAST */
734 int assess_turns;
735 bool omnimap;
736
738
739 /* Initialize data. */
741 if (has_handicap(pplayer, H_DANGER)) {
742 /* Always thinks that city is in grave danger */
743 city_data->grave_danger = 1;
744 } else {
745 city_data->grave_danger = 0;
746 }
747 city_data->diplomat_threat = FALSE;
748 city_data->has_diplomat = FALSE;
749
750 unit_type_iterate(utype) {
751 int idx = utype_index(utype);
752
753 defense_bonuses_pct[idx] = 0;
755 best_non_scramble[idx] = -1;
756 /* FIXME: Cache it somewhere? */
758 = 100 + get_unittype_bonus(pplayer, ptile, utype, nullptr,
760 city_def_against[idx] = MAX(city_def_against[idx], 1);
762
763 /* What flag-specific bonuses do our units have. */
764 /* We value them less than general defense increment */
765 unit_list_iterate(ptile->units, punit) {
766 const struct unit_type *def = unit_type_get(punit);
767
769 city_data->has_diplomat = TRUE;
770 }
772 /* This is first defender of this type. Check defender type
773 * specific bonuses. */
774
775 /* Skip defenders that have no bonuses at all. Acceptable
776 * side-effect is that we can't consider negative bonuses at
777 * all ("No bonuses" should be better than "negative bonus") */
778 if (def->cache.max_defense_mp_bonus_pct > 0) {
779 unit_type_iterate(utype) {
780 int idx = utype_index(utype);
781 int coeff = def->cache.scramble_coeff[idx];
782 int bonus;
783
784 /* FIXME: consider EFT_FORTIFY_DEFENSE_BONUS */
785 if (coeff) {
786 bonus = coeff / city_def_against[idx] - 100;
787 } else {
788 bonus = def->cache.defense_mp_bonuses_pct[idx];
789 }
790
791 if (bonus > defense_bonuses_pct[idx]) {
792 if (!coeff) {
793 best_non_scramble[idx] = bonus;
794 }
795 defense_bonuses_pct[idx] = bonus;
796 } else if (!coeff) {
797 best_non_scramble[idx] = MAX(best_non_scramble[idx], bonus);
798 }
800 } else {
801 /* Just remember that such a unit exists and hope its bonuses are just 0 */
803 }
804
806 }
808 if (sth_does_not_scramble || unit_list_size(ptile->units) <= 0) {
809 /* Scrambling units tend to be expensive. If we have a barenaked city, we'll
810 * need at least a cheap unit. If we have only scramblers,
811 * maybe it's OK. */
814
817 }
818
819 if (player_is_cpuhog(pplayer)) {
820 assess_turns = 6;
821 } else {
823 }
824
825 omnimap = !has_handicap(pplayer, H_MAP);
826
827 /* Check. */
830 struct unit_list *units;
831
832 if (!adv_is_player_dangerous(pplayer, aplayer)) {
833 continue;
834 }
835 /* Note that we still consider the units of players we are not (yet)
836 * at war with. */
837
839 omnimap);
840
841 if (ul_cb != nullptr) {
842 units = ul_cb(aplayer);
843 } else {
844 units = aplayer->units;
845 }
846 unit_list_iterate(units, punit) {
847 int move_time;
848 unsigned int vulnerability;
849 int defbonus_pct;
850 const struct unit_type *utype = unit_type_get(punit);
851 struct unit_type_ai *utai = utype_ai_data(utype, ait);
852
853#ifdef FREECIV_WEB
854 /* freeciv-web ignores danger that is far in distance,
855 * no matter how quickly it would reach us; even if
856 * that's *immediately* over a road type that allows
857 * unlimited movement. */
859
863 /* Too far away. */
864 continue;
865 }
866#endif /* FREECIV_WEB */
867
868 if (!utai->carries_occupiers
869 && !utype_acts_hostile(utype)) {
870 /* Harmless unit. */
871 continue;
872 }
873
874 /* Defender unspecific vulnerability and potential move time */
876 punit, &move_time);
877
879 continue;
880 }
881
882 if (unit_can_take_over(punit) || utai->carries_occupiers) {
883 /* Even if there is no attack strength,
884 * we need ANY protector for the city */
886 if (3 >= move_time) {
887 urgency++;
888 if (1 >= move_time) {
889 city_data->grave_danger++;
890 }
891 }
892 }
893
895 if (defbonus_pct > 100) {
896 defbonus_pct = (defbonus_pct + 100) / 2;
897 }
898 /* Reduce vulnerability for specific bonuses we do have */
899 vulnerability = vulnerability * 100 / (defbonus_pct + 100);
900 /* Pass the order for a new defender type against it
901 * to the scientific advisor, urgency considered */
902 (void) dai_wants_defender_against(ait, nmap, pplayer, pcity, utype,
904
906 city_data->diplomat_threat = TRUE;
907 }
908
909 vulnerability *= vulnerability; /* positive feedback */
910 if (1 < move_time) {
912 }
913
918 if (defender != B_LAST) {
919 danger_reduced[defender] += vulnerability / MAX(move_time, 1);
920 }
921 } else if (best_non_scramble[utype_index(utype)] >= 0) {
922 /* To consider building a defensive building,
923 * build first a defender that gets any profit of it */
925 if (defender != B_LAST) {
926 int danred = vulnerability / MAX(move_time, 1);
927 /* Maybe we can build an improvement
928 * that gets normal defender over scrambling one?
929 * Effectively a sqrt-scale because we don't test how high
930 * the effect is. */
933 danred = danred * (100 + best_non_scramble[utype_index(utype)])
934 / (100 + defense_bonuses_pct[utype_index(utype)]);
935 }
936 danger_reduced[defender] += danred;
937 }
938 }
939
942
944
946
947 if (total_danger) {
948 /* If any hostile player has any dangerous unit that can in any time
949 * reach the city, we consider building walls here, if none yet.
950 * FIXME: this value assumes that walls give x3 defense. */
951 city_data->wallvalue = 90;
952 } else {
953 /* No danger.
954 * This is half of the wallvalue of what danger 1 would produce. */
955 city_data->wallvalue = 5;
956 }
957
958 if (0 < city_data->grave_danger) {
959 /* really, REALLY urgent to defend */
960 urgency += 10 * city_data->grave_danger;
961 }
962
963 /* HACK: This needs changing if multiple improvements provide
964 * this effect. */
965 /* FIXME: Accept only buildings helping unit classes we actually use.
966 * Now we consider any land mover helper suitable. */
967 /* Sum of squared defense ratings */
968 defense = assess_defense_igwall(ait, pcity);
969
970 for (i = 0; i < B_LAST; i++) {
971 if (0 < danger_reduced[i]) {
972 dai_reevaluate_building(pcity, &pcity->server.adv->building_want[i],
973 urgency, danger_reduced[i], defense);
974 }
975 }
976
977 if (has_handicap(pplayer, H_DANGER) && 0 == total_danger) {
978 /* Has to have some danger
979 * Otherwise grave_danger will be ignored. */
980 city_data->danger = 1;
981 } else {
982 city_data->danger = total_danger;
983 }
984 city_data->urgency = urgency;
985
987
988 return urgency;
989}
990
991/**********************************************************************/
996 const struct unit_type *punittype)
997{
999 int attack = punittype->attack_strength;
1000 int defense = punittype->defense_strength;
1001 int maxbonus_pct = 0;
1002 int fp = punittype->firepower;
1003
1004 /* Sea and helicopters often have their firepower set to low firepower when
1005 * defending. We can't have such units as defenders. */
1008 }
1009 if (((struct unit_type_ai *)utype_ai_data(punittype, ait))->low_firepower) {
1011 }
1012 desire *= fp;
1013 desire *= defense;
1014 desire += punittype->move_rate / SINGLE_MOVE;
1015 desire += attack;
1016
1017 maxbonus_pct = punittype->cache.max_defense_mp_bonus_pct;
1018 if (maxbonus_pct > 100) {
1019 maxbonus_pct = (maxbonus_pct + 100) / 2;
1020 }
1021 desire += desire * maxbonus_pct / 100;
1023 desire /= 10; /* But might actually be worth it */
1024 }
1025
1026 return desire;
1027}
1028
1029/**********************************************************************/
1033 const struct unit_type *punittype)
1034{
1036 int attack = punittype->attack_strength;
1037 int defense = punittype->defense_strength;
1038
1039 desire *= punittype->move_rate;
1040 desire *= punittype->firepower;
1041 desire *= attack;
1042 desire += defense;
1044 desire += desire / 2;
1045 }
1047 desire /= 10; /* But might actually be worth it */
1048 }
1050 desire += desire / 2;
1051 }
1053 desire += desire / 4;
1054 }
1055 if (punittype->adv.igwall) {
1056 desire += desire / 4;
1057 }
1058
1059 return desire;
1060}
1061
1062/**********************************************************************/
1067bool dai_process_defender_want(struct ai_type *ait, const struct civ_map *nmap,
1068 struct player *pplayer,
1069 struct city *pcity, unsigned int danger,
1070 struct adv_choice *choice, adv_want extra_want)
1071{
1072 const struct research *presearch = research_get(pplayer);
1073 /* FIXME: We check if the city has *some* defensive structure,
1074 * but not whether the city has a defensive structure against
1075 * any specific attacker. The actual danger may not be mitigated
1076 * by the defense selected... */
1077 bool walls = city_got_defense_effect(pcity, nullptr);
1078 /* Technologies we would like to have. */
1080 /* Our favourite unit. */
1081 adv_want best = -1;
1082 struct unit_type *best_unit_type = nullptr;
1083 int best_unit_cost = 1;
1084 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1085 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
1086 adv_want total_want = danger + extra_want;
1087
1088 memset(tech_desire, 0, sizeof(tech_desire));
1089
1091 adv_want desire; /* How much we want the unit? */
1092
1093 /* Only consider proper defenders - otherwise waste CPU and
1094 * bump tech want needlessly. */
1097 continue;
1098 }
1099
1101
1103 desire /= 2; /* Not good, just ok */
1104 }
1105
1107 /* Causes unhappiness even when in defense, so not a good
1108 * idea for a defender, unless it is _really_ good.
1109 * Downright counter productive, if we want unit just for
1110 * maintaining peace. */
1111 if (danger == 0) {
1112 desire = -50;
1113 } else {
1114 desire /= 2;
1115 }
1116 }
1117
1118 if (desire > 0) {
1119 desire /= POWER_DIVIDER / 2; /* Good enough, no rounding errors. */
1120 desire *= desire;
1121
1123 /* We can build the unit now... */
1124
1125 int build_cost = utype_build_shield_cost(pcity, nullptr, punittype);
1126 int limit_cost = pcity->shield_stock + 40;
1127
1129 desire *= city_data->wallvalue;
1130 /* TODO: More use of POWER_FACTOR ! */
1132 }
1133
1135 && build_cost < best_unit_cost)
1136 || ((desire > best
1137 || (ADV_WANTS_EQ(desire, best)
1138 && build_cost <= best_unit_cost))
1139 && (best_unit_type == nullptr
1140 /* In case all units are more expensive than limit_cost */
1141 || limit_cost <= pcity->shield_stock + 40))) {
1142 best = desire;
1144 best_unit_cost = build_cost;
1145 }
1147 /* We first need to develop the tech required by the unit... */
1148
1149 /* Cost (shield equivalent) of gaining these techs. */
1150 /* FIXME? Katvrr advises that this should be weighted more heavily in
1151 * big danger. */
1152 int tech_cost = 0;
1153
1158
1159 tech_cost = tech_cost / 4 / city_list_size(pplayer->cities);
1160
1161 /* Contrary to the above, we don't care if walls are actually built
1162 * - we're looking into the future now. */
1164 desire *= city_data->wallvalue;
1166 }
1167
1168 /* Yes, there's some similarity with kill_desire(). */
1169 /* TODO: Explain what shield cost has to do with tech want. */
1171 = (desire * total_want
1173 }
1174 }
1176
1177 if (best == -1) {
1178 CITY_LOG(LOG_DEBUG, pcity, "Ooops - we cannot build any defender!");
1179 }
1180
1181 if (best_unit_type != nullptr) {
1183 best *= city_data->wallvalue;
1184 best /= POWER_FACTOR;
1185 }
1186 } else {
1187 best_unit_cost = 100; /* Building impossible is considered costly.
1188 * This should increase want for tech providing
1189 * first defender type. */
1190 }
1191
1192 if (best <= 0) {
1193 best = 1; /* Avoid division by zero below. */
1194 }
1195
1196 /* Update tech_want for appropriate techs for units we want to build. */
1198 if (tech_desire[utype_index(punittype)] > 0) {
1199 /* TODO: Document or fix the algorithm below. I have no idea why
1200 * it is written this way, and the results seem strange to me. - Per */
1202
1204 plr_data->tech_want[advance_index(padv)]
1205 += desire;
1206 TECH_LOG(ait, LOG_DEBUG, pplayer, padv,
1207 "+ " ADV_WANT_PRINTF " for %s to defend %s",
1208 desire,
1212 }
1214
1215 if (!best_unit_type) {
1216 return FALSE;
1217 }
1218
1219 choice->value.utype = best_unit_type;
1220 choice->want = danger; /* FIXME: Not 'total_want' because of the way callers
1221 * are constructed. They may overwrite this value,
1222 * and then the value will NOT contain 'extra_want'.
1223 * Later we may add 'extra_want', and don't want it
1224 * already included in case this was NOT overwritten. */
1225 choice->type = CT_DEFENDER;
1226
1227 return TRUE;
1228}
1229
1230/**********************************************************************/
1247static void process_attacker_want(struct ai_type *ait,
1248 struct city *pcity,
1249 adv_want value,
1250 const struct unit_type *victim_unit_type,
1251 struct player *victim_player,
1252 int veteran, struct tile *ptile,
1253 struct adv_choice *best_choice,
1254 struct pf_map *ferry_map,
1255 struct unit *boat,
1256 const struct unit_type *boattype)
1257{
1258 struct player *pplayer = city_owner(pcity);
1259 const struct research *presearch = research_get(pplayer);
1260 /* The enemy city. acity == nullptr means stray enemy unit */
1261 struct city *acity = tile_city(ptile);
1262 struct pf_parameter parameter;
1263 struct pf_map *pfm;
1264 struct pf_position pos;
1265 const struct unit_type *orig_utype = best_choice->value.utype;
1266 int victim_count = 1;
1267 int needferry = 0;
1268 bool unhap;
1269 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
1270 const struct civ_map *nmap = &(wld.map);
1271
1272 /* Has to be initialized to make gcc happy */
1273 struct ai_city *acity_data = nullptr;
1274
1276
1277 if (acity != nullptr) {
1279 }
1280
1281 if (utype_class(orig_utype)->adv.sea_move == MOVE_NONE
1282 && !boat && boattype != nullptr) {
1283 /* Cost of ferry */
1285 }
1286
1287 if (!is_stack_vulnerable(ptile)) {
1288 /* If it is a city, a fortress or an air base,
1289 * we may have to whack it many times */
1291 }
1292
1296 && (U_NOT_OBSOLETED == punittype->obsoleted_by
1297 || !can_city_build_unit_direct(nmap, pcity, punittype->obsoleted_by,
1298 RPT_CERTAIN))
1299 && punittype->attack_strength > 0 /* Or we'll get SIGFPE */) {
1300 /* Values to be computed */
1302 adv_want want;
1303 int move_time;
1304 int vuln;
1305 int veteran_level
1306 = get_target_bonus_effects(nullptr,
1307 &(const struct req_context) {
1308 .player = pplayer,
1309 .city = pcity,
1310 .tile = city_tile(pcity),
1311 .unittype = punittype,
1312 },
1313 nullptr,
1315 /* Levels start from zero, so max level is 'number of levels - 1' */
1317 /* Cost (shield equivalent) of gaining these techs. */
1318 /* FIXME? Katvrr advises that this should be weighted more heavily in big
1319 * danger. */
1320 int tech_cost = 0;
1322 /* See description of kill_desire() for info about this variables. */
1324 int attack;
1325 int tech_dist = 0;
1326
1329 SINGLE_MOVE, punittype->hp);
1330
1333
1335 if (tech_dist == 0) {
1337 }
1339
1340 tech_cost = tech_cost / 4 / city_list_size(pplayer->cities);
1341
1342 /* Take into account reinforcements strength */
1343 if (acity) {
1344 attack += acity_data->attack;
1345 }
1346
1347 if (attack == 0) {
1348 /* Yes, it can happen that a military unit has attack = 1,
1349 * for example militia with HP = 1 (in civ1 ruleset). */
1350 continue;
1351 }
1352
1353 attack *= attack;
1354
1356 pplayer);
1357 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1358 pfm = pf_map_new(&parameter);
1359
1360 /* Set the move_time appropriately. */
1361 move_time = -1;
1362 if (ferry_map != nullptr) {
1363 struct tile *dest_tile;
1364
1365 if (find_beachhead(pplayer, ferry_map, ptile, punittype,
1366 boattype, &dest_tile, nullptr)
1367 && pf_map_position(ferry_map, dest_tile, &pos)) {
1368 move_time = pos.turn;
1371 if (atile == dest_tile) {
1373 move_time += pos.turn;
1374 break;
1375 } else if (atile == ptile) {
1376 /* Reaching directly seems better. */
1378 move_time = pos.turn;
1379 break;
1380 }
1382 }
1383 }
1384
1385 if (-1 == move_time) {
1386 if (pf_map_position(pfm, ptile, &pos)) {
1387 move_time = pos.turn;
1388 } else {
1390 continue;
1391 }
1392 }
1394
1395 /* Estimate strength of the enemy. */
1396
1397 if (victim_unit_type) {
1400 ptile, FALSE, veteran);
1401 } else {
1402 vuln = 0;
1403 }
1404
1405 /* Not bothering to s/!vuln/!pdef/ here for the time being. -- Syela
1406 * (this is noted elsewhere as terrible bug making warships yoyoing)
1407 * as the warships will go to enemy cities hoping that the enemy builds
1408 * something for them to kill. */
1409 if (vuln == 0
1410 && (utype_class(punittype)->adv.land_move == MOVE_NONE
1411 || 0 < utype_fuel(punittype))) {
1412 desire = 0;
1413
1414 } else {
1415 if (acity
1417 && acity_data->invasion.attack > 0
1418 && acity_data->invasion.occupy == 0) {
1420 float finishing_factor = 1;
1421
1424 }
1426 } else {
1427 desire = 0;
1428 }
1429
1430 if (!acity) {
1431 desire = kill_desire(value, attack, bcost, vuln, victim_count);
1432 } else {
1433 adv_want kd;
1434 int city_attack = acity_data->attack * acity_data->attack;
1435
1436 /* See daiunit.c:find_something_to_kill() for comments. */
1437 kd = kill_desire(value, attack,
1438 (bcost + acity_data->bcost), vuln,
1439 victim_count);
1440
1441 if (value * city_attack > acity_data->bcost * vuln) {
1442 kd -= kill_desire(value, city_attack,
1443 acity_data->bcost, vuln,
1444 victim_count);
1445 }
1446
1447 desire = MAX(desire, kd);
1448 }
1449 }
1450
1452 /* We can be possibly making some people of our homecity unhappy - then
1453 * we don't want to travel too far away to our victims. */
1454 /* TODO: Unify the 'unhap' dependency to some common function. */
1457
1458 want = military_amortize(pplayer, pcity, desire, MAX(1, move_time),
1460
1461 if (want > 0) {
1462 if (tech_dist > 0) {
1463 /* This is a future unit, tell the scientist how much we need it */
1465 plr_data->tech_want[advance_index(padv)]
1466 += want;
1467 TECH_LOG(ait, LOG_DEBUG, pplayer, padv,
1468 "+ " ADV_WANT_PRINTF " for %s vs %s(%d,%d)",
1469 want,
1472 TILE_XY(ptile));
1474 } else if (want > best_choice->want) {
1475 const struct impr_type *impr_req;
1476
1478 /* This is a real unit and we really want it */
1479
1480 CITY_LOG(LOG_DEBUG, pcity, "overriding %s(" ADV_WANT_PRINTF
1481 ") with %s(" ADV_WANT_PRINTF ")"
1482 " [attack=%d,value=" ADV_WANT_PRINTF
1483 ",move_time=%d,vuln=%d,bcost=%d]",
1484 utype_rule_name(best_choice->value.utype),
1485 best_choice->want,
1487 want,
1488 attack, value, move_time, vuln, bcost);
1489
1490 best_choice->value.utype = punittype;
1491 best_choice->want = want;
1492 best_choice->type = CT_ATTACKER;
1494 pcity)))) {
1495 CITY_LOG(LOG_DEBUG, pcity, "cannot build unit %s",
1498 RPT_CERTAIN)) {
1499 /* Building this unit requires a specific type of improvement.
1500 * So we build this improvement instead. This may not be the
1501 * best behavior. */
1502 CITY_LOG(LOG_DEBUG, pcity, "building %s to build unit %s",
1505 best_choice->value.building = impr_req;
1506 best_choice->want = want;
1507 best_choice->type = CT_BUILDING;
1508 } else {
1509 /* This should never happen? */
1510 CITY_LOG(LOG_DEBUG, pcity, "cannot build %s or unit %s",
1513 }
1514 }
1515 }
1516 }
1518}
1519
1520/**********************************************************************/
1531static struct adv_choice *kill_something_with(struct ai_type *ait,
1532 const struct civ_map *nmap,
1533 struct player *pplayer,
1534 struct city *pcity, struct unit *myunit,
1535 struct adv_choice *choice)
1536{
1537 /* Our attack rating (with reinforcements) */
1538 int attack;
1539 /* Benefit from fighting the target */
1541 /* Defender of the target city/tile */
1542 struct unit *pdef;
1543 const struct unit_type *def_type;
1544 struct player *def_owner;
1545 int def_vet; /* Is the defender veteran? */
1546 /* Target coordinates */
1547 struct tile *ptile;
1548 /* Our transport */
1549 struct unit *ferryboat;
1550 /* Our target */
1551 struct city *acity;
1552 /* Type of the boat (real or a future one) */
1553 const struct unit_type *boattype;
1554 struct pf_map *ferry_map = nullptr;
1555 int move_time;
1556 struct adv_choice *best_choice;
1557 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1558 struct ai_city *acity_data;
1559
1561 best_choice->value.utype = unit_type_get(myunit);
1562 best_choice->type = CT_ATTACKER;
1563 adv_choice_set_use(best_choice, "attacker");
1564
1567
1568 if (city_data->danger != 0 && assess_defense(ait, pcity) == 0) {
1569 /* Defense comes first! */
1570 goto cleanup;
1571 }
1572
1573 best_choice->want = find_something_to_kill(ait, pplayer, myunit, &ptile, nullptr,
1574 &ferry_map, &ferryboat,
1575 &boattype, &move_time);
1576
1577 if (ptile == nullptr
1578 || ptile == unit_tile(myunit)
1579 || !can_unit_attack_tile(myunit, nullptr, ptile)) {
1580 goto cleanup;
1581 }
1582
1583 acity = tile_city(ptile);
1584
1585 if (myunit->id != 0) {
1586 log_error("%s(): non-virtual unit!", __FUNCTION__);
1587 goto cleanup;
1588 }
1589
1591 if (acity) {
1593 attack += acity_data->attack;
1594 }
1595 attack *= attack;
1596
1597 if (acity != nullptr) {
1598 /* Rating of enemy defender */
1599 int vulnerability;
1600
1601 if (!POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(acity))) {
1602 /* Not a valid target */
1603 goto cleanup;
1604 }
1605
1608 if (1 < move_time && def_type) {
1611 city_owner(acity), ptile,
1612 FALSE, def_vet);
1614 } else {
1615 vulnerability = 0;
1616 benefit = 0;
1617 def_vet = 0;
1618 }
1619
1620 pdef = get_defender(nmap, myunit, ptile, nullptr);
1621 if (pdef) {
1623 city_owner(acity), ptile, FALSE,
1624 pdef->veteran);
1625 if (vulnerability < m) {
1627 def_vet = pdef->veteran;
1630 }
1631 }
1632 if (unit_can_take_over(myunit) || acity_data->invasion.occupy > 0) {
1633 /* Bonus for getting the city */
1635 float finishing_factor = 1;
1636
1639 }
1641 }
1642
1643 /* end dealing with cities */
1644 } else {
1645
1646 if (ferry_map != nullptr) {
1648 ferry_map = nullptr;
1649 }
1650
1651 pdef = get_defender(nmap, myunit, ptile, nullptr);
1652 if (!pdef) {
1653 /* Nobody to attack! */
1654 goto cleanup;
1655 }
1656
1658
1660 def_vet = pdef->veteran;
1662 /* End dealing with units */
1663 }
1664
1665 if (ferry_map == nullptr) {
1667 def_vet, ptile,
1668 best_choice, nullptr, nullptr, nullptr);
1669 } else {
1670 /* Attract a boat to our city or retain the one that's already here */
1672 best_choice->need_boat = TRUE;
1674 def_vet, ptile,
1675 best_choice, ferry_map, ferryboat, boattype);
1676 }
1677
1678 if (best_choice->want > choice->want) {
1679 /* We want attacker more than what we have selected before */
1682 CITY_LOG(LOG_DEBUG, pcity, "kill_something_with()"
1683 " %s has chosen attacker, %s, want=" ADV_WANT_PRINTF,
1685 utype_rule_name(best_choice->value.utype),
1686 best_choice->want);
1687
1688 if (ferry_map != nullptr && !ferryboat) { /* Need a new ferry */
1689 /* We might need a new boat even if there are boats free,
1690 * if they are blockaded or in inland seas. */
1692 if (dai_choose_role_unit(ait, pplayer, pcity, choice, CT_ATTACKER,
1694 && dai_is_ferry_type(choice->value.utype, ait)) {
1695#ifdef FREECIV_DEBUG
1696 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, nullptr);
1697
1698 log_debug("kill_something_with() %s has chosen attacker ferry, "
1699 "%s, want=" ADV_WANT_PRINTF ", %d of %d free",
1701 utype_rule_name(choice->value.utype),
1702 choice->want,
1703 ai->stats.available_boats, ai->stats.boats);
1704#endif /* FREECIV_DEBUG */
1705
1706 adv_choice_set_use(choice, "attacker ferry");
1707 } /* else can not build ferries yet */
1708 }
1709 }
1710
1711cleanup:
1712 if (best_choice != choice) {
1713 /* It was not taken to use.
1714 * This hackery needed since 'goto cleanup:' might skip
1715 * sensible points to do adv_free_choice(). */
1717 }
1718 if (ferry_map != nullptr) {
1720 }
1721
1722 return choice;
1723}
1724
1725/**********************************************************************/
1731static void dai_unit_consider_bodyguard(struct ai_type *ait,
1732 const struct civ_map *nmap,
1733 struct city *pcity,
1734 struct unit_type *punittype,
1735 struct adv_choice *choice)
1736{
1737 if (choice->want < DAI_WANT_MILITARY_EMERGENCY) {
1738 struct player *pplayer = city_owner(pcity);
1739 struct unit *aunit = nullptr;
1740 struct city *acity = nullptr;
1741 struct unit *virtualunit
1744 punittype));
1745 const adv_want want = look_for_charge(ait, nmap, pplayer, virtualunit,
1746 &aunit, &acity);
1747
1748 if (want > choice->want) {
1749 choice->want = want;
1750 choice->value.utype = punittype;
1751 choice->type = CT_DEFENDER;
1752 adv_choice_set_use(choice, "bodyguard");
1753 }
1754
1756 }
1757}
1758
1759/**********************************************************************/
1768 struct adv_choice *choice)
1769{
1771
1772 /* Sanity */
1773 if (!is_unit_choice_type(choice->type)
1776 return;
1777 }
1778
1779 /* N.B.: have to check that we haven't already built the building --mck */
1781 choice->value.utype)) != B_LAST
1783 choice->value.building = improvement_by_number(id);
1784 choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER,
1786 / TRAIT_DEFAULT_VALUE / 2));
1787 choice->type = CT_BUILDING;
1788 adv_choice_set_use(choice, "veterancy building");
1789 }
1790}
1791
1792/**********************************************************************/
1798 const struct civ_map *nmap,
1799 struct player *pplayer,
1800 struct city *pcity,
1802{
1803 struct adv_data *ai = adv_data_get(pplayer, nullptr);
1804 struct unit_type *punittype;
1805 unsigned int our_def, urgency;
1806 struct tile *ptile = pcity->tile;
1807 struct unit *virtualunit;
1808 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1810 bool martial_need = FALSE;
1811 struct adv_choice *choice = adv_new_choice();
1812 bool allow_gold_upkeep;
1813
1814 urgency = assess_danger(ait, nmap, pcity, ul_cb);
1815 /* Changing to quadratic to stop AI from building piles
1816 * of small units -- Syela */
1817 /* It has to be AFTER assess_danger() thanks to wallvalue. */
1819
1820 dai_choose_diplomat_defensive(ait, pplayer, pcity, choice, our_def);
1821
1823 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY] > 0) {
1825 }
1826
1827 if (!martial_need) {
1829 if (pcity->specialists[sp] > 0
1832 break;
1833 }
1835 }
1836
1837 if (martial_need
1841 1, FEELING_FINAL);
1842 }
1843
1844 /* Otherwise no need to defend yet */
1845 if (city_data->danger != 0 || martial_value > 0) {
1846 struct impr_type *pimprove;
1847 int num_defenders = unit_list_size(ptile->units);
1848 int wall_id, danger;
1849 bool build_walls = TRUE;
1850 bool def_unit_selected = FALSE;
1851 int qdanger = city_data->danger * city_data->danger;
1852
1853 if (qdanger <= 0) {
1854 /* We only need these defenders because of Martial Law value */
1855 danger = 0;
1856 build_walls = FALSE; /* Walls don't provide Martial Law */
1857 } else {
1858 /* First determine the danger. It is measured in percents of our
1859 * defensive strength, capped at 200 + urgency */
1860 if (qdanger >= our_def) {
1861 if (urgency == 0) {
1862 /* Don't waste money */
1863 danger = 100;
1864 } else if (our_def == 0) {
1865 danger = 200 + urgency;
1866 } else {
1867 danger = MIN(200, 100 * qdanger / our_def) + urgency;
1868 }
1869 } else {
1870 danger = 100 * qdanger / our_def;
1871 }
1872
1873 if (pcity->surplus[O_SHIELD] <= 0 && our_def != 0) {
1874 /* Won't be able to support anything */
1875 danger = 0;
1876 }
1877 }
1878
1879 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d urgency=%d danger=%d num_def=%d "
1880 "our_def=%d", urgency, danger, num_defenders, our_def);
1881
1882 if (our_def == 0 && danger > 0) {
1883 /* Build defensive unit first! Walls will help nothing if there's
1884 * nobody behind them. */
1885 if (dai_process_defender_want(ait, nmap, pplayer, pcity, danger, choice,
1886 martial_value)) {
1887 choice->want = DAI_WANT_BELOW_MIL_EMERGENCY + danger;
1888 adv_choice_set_use(choice, "first defender");
1891
1892 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants first defender with " ADV_WANT_PRINTF,
1893 choice->want);
1894 }
1895 }
1896 if (build_walls) {
1897 /* FIXME: 1. Does not consider what kind of future danger is likely, so
1898 * may build SAM batteries when enemy has only land units. */
1899 /* We will build walls if we can and want and (have "enough" defenders or
1900 * can just buy the walls straight away) */
1901
1902 /* HACK: This needs changing if multiple improvements provide
1903 * this effect. */
1905 pimprove = improvement_by_number(wall_id);
1906
1907 if (wall_id != B_LAST
1908 && pcity->server.adv->building_want[wall_id] != 0 && our_def != 0
1911 || (city_data->grave_danger == 0
1912 && pplayer->economic.gold
1913 > impr_buy_gold_cost(pcity, pimprove, pcity->shield_stock)))
1914 && ai_fuzzy(pplayer, TRUE)) {
1915 if (pcity->server.adv->building_want[wall_id] > 0) {
1916 /* NB: great wall is under domestic */
1917 choice->value.building = pimprove;
1918 /* building_want is hacked by assess_danger() */
1919 choice->want = pcity->server.adv->building_want[wall_id];
1920 choice->want = choice->want * (0.5 + (ai_trait_get_value(TRAIT_BUILDER, pplayer)
1921 / TRAIT_DEFAULT_VALUE / 2));
1922 if (urgency == 0 && choice->want > DAI_WANT_BELOW_MIL_EMERGENCY) {
1924 }
1925 choice->type = CT_BUILDING;
1926 adv_choice_set_use(choice, "defense building");
1928 "m_a_c_d wants defense building with " ADV_WANT_PRINTF,
1929 choice->want);
1930 } else {
1932 }
1933 } else {
1935 }
1936 }
1937
1938 /* If our choice isn't defender unit already, consider one */
1939 if (!def_unit_selected) {
1940 if ((danger > 0 && num_defenders <= urgency) || martial_value > 0) {
1941 struct adv_choice uchoice;
1942
1944
1945 /* Consider building defensive units */
1946 if (dai_process_defender_want(ait, nmap, pplayer, pcity, danger,
1948 /* Potential defender found */
1949 if (urgency == 0
1950 && uchoice.value.utype->defense_strength == 1) {
1951 /* FIXME: check other reqs (unit class?) */
1952 if (get_city_bonus(pcity, EFT_HP_REGEN) > 0) {
1953 /* Unlikely */
1954 uchoice.want = MIN(49, danger);
1955 } else {
1956 uchoice.want = MIN(25, danger);
1957 }
1958 } else {
1959 uchoice.want = danger;
1960 }
1961
1962 uchoice.want += martial_value;
1963 if (danger > 0) {
1964 adv_choice_set_use(&uchoice, "defender");
1965 } else {
1966 adv_choice_set_use(&uchoice, "police");
1967 }
1968
1969 if (!build_walls || uchoice.want > choice->want) {
1970 adv_choice_copy(choice, &uchoice);
1971 }
1973
1974 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d wants %s with desire " ADV_WANT_PRINTF,
1975 utype_rule_name(choice->value.utype),
1976 choice->want);
1977 } else {
1978 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d cannot select defender");
1979 }
1980 } else {
1981 CITY_LOG(LOG_DEBUG, pcity, "m_a_c_d does not want defenders");
1982 }
1983 }
1984 } /* Ok, don't need to defend */
1985
1986 if (pcity->surplus[O_SHIELD] <= 0
1988 || pcity->id == ai->wonder_city) {
1989 /* Things we consider below are not life-saving so we don't want to
1990 * build them if our populace doesn't feel like it */
1991 return choice;
1992 }
1993
1994 if (pplayer->economic.tax <= 50 || city_total_unit_gold_upkeep(pcity) <= 0) {
1995 /* Always allow one unit with real gold upkeep (after EFT_UNIT_UPKEEP_FREE_PER_CITY)
1996 * Allow more if economics is so strong that we have not increased taxes. */
1998 } else {
2000 }
2001
2002 /* Consider making a land bodyguard */
2005 if (punittype) {
2007 }
2008
2009 /* If we are in severe danger, don't consider attackers. This is probably
2010 too general. In many cases we will want to buy attackers to counterattack.
2011 -- Per */
2013 && city_data->grave_danger > 0) {
2015 "severe danger (want " ADV_WANT_PRINTF "), force defender",
2016 choice->want);
2017 return choice;
2018 }
2019
2020 /* Consider making an offensive diplomat */
2021 dai_choose_diplomat_offensive(ait, nmap, pplayer, pcity, choice);
2022
2023 /* Consider making a sea bodyguard */
2026 if (punittype) {
2028 }
2029
2030 /* Consider making an airplane */
2031 (void) dai_choose_attacker_air(ait, nmap, pplayer, pcity, choice,
2033
2034 /* Consider making a paratrooper */
2035 dai_choose_paratrooper(ait, nmap, pplayer, pcity, choice, allow_gold_upkeep);
2036
2037 /* Check if we want a sailing attacker. Have to put sailing first
2038 before we mung the seamap */
2040 if (punittype) {
2042 pplayer, pcity, punittype,
2044 choice = kill_something_with(ait, nmap, pplayer, pcity, virtualunit, choice);
2046 }
2047
2048 /* Consider a land attacker or a ferried land attacker
2049 * (in which case, we might want a ferry before an attacker)
2050 */
2052 if (punittype) {
2054 choice = kill_something_with(ait, nmap, pplayer, pcity, virtualunit, choice);
2056 }
2057
2058 /* Consider a hunter */
2059 dai_hunter_choice(ait, pplayer, pcity, choice, allow_gold_upkeep);
2060
2061 /* Consider veteran level enhancing buildings before non-urgent units */
2063
2064 if (choice->want <= 0) {
2065 CITY_LOG(LOGLEVEL_BUILD, pcity, "military advisor has no advice");
2066 } else {
2068 "military advisor choice: %s (want " ADV_WANT_PRINTF ")",
2069 adv_choice_rule_name(choice),
2070 choice->want);
2071 }
2072
2073 return choice;
2074}
struct action_enabler_list * action_enablers_for_action(action_id action)
Definition actions.c:1585
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:245
#define action_enabler_list_iterate_end
Definition actions.h:194
#define action_by_result_iterate_end
Definition actions.h:249
#define action_enabler_list_iterate(action_enabler_list, aenabler)
Definition actions.h:192
#define action_id(_act_)
Definition actions.h:426
#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:48
void adv_init_choice(struct adv_choice *choice)
Definition advchoice.c:31
void adv_free_choice(struct adv_choice *choice)
Definition advchoice.c:73
struct adv_choice * adv_new_choice(void)
Definition advchoice.c:61
bool is_unit_choice_type(enum choice_type type)
Definition advchoice.c:118
const char * adv_choice_rule_name(const struct adv_choice *choice)
Definition advchoice.c:127
#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:614
bool adv_is_player_dangerous(struct player *pplayer, struct player *aplayer)
Definition advdata.c:1122
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:387
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:398
#define POWER_DIVIDER
Definition advtools.h:32
#define ADV_WANTS_EQ(_w1, _w2)
Definition advtools.h:23
int ai_trait_get_value(enum trait tr, struct player *pplayer)
Definition aitraits.c:68
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1292
const char * city_name_get(const struct city *pcity)
Definition city.c:1157
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:808
bool city_got_defense_effect(const struct city *pcity, const struct unit_type *attacker)
Definition city.c:1649
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
Definition city.c:860
bool can_city_build_unit_direct(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype, const enum req_problem_type prob_type)
Definition city.c:911
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype, const enum req_problem_type prob_type)
Definition city.c:957
bool can_city_build_unit_later(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:982
int city_total_unit_gold_upkeep(const struct city *pcity)
Definition city.c:1274
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:565
@ CITIZEN_ANGRY
Definition city.h:269
@ CITIZEN_UNHAPPY
Definition city.h:268
#define city_owner(_pcity_)
Definition city.h:564
#define city_list_iterate_end
Definition city.h:510
@ FEELING_EFFECT
Definition city.h:279
@ FEELING_FINAL
Definition city.h:282
@ FEELING_NATIONALITY
Definition city.h:280
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:994
int get_fortified_defense_power(const struct unit *attacker, struct unit *defender)
Definition combat.c:786
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:772
int get_total_attack_power(const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:615
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:312
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:411
#define POWER_FACTOR
Definition combat.h:32
char * incite_cost
Definition comments.c:77
bool dai_choose_attacker_air(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Definition daiair.c:590
Impr_type_id dai_find_source_building(struct city *pcity, enum effect_type effect_type, const struct unit_type *utype)
Definition daicity.c:2198
struct ai_plr * dai_plr_data_get(struct ai_type *ait, struct player *pplayer, bool *caller_closes)
Definition daidata.c:310
void dai_choose_diplomat_defensive(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, int def)
void dai_choose_diplomat_offensive(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, struct adv_choice *choice)
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
bool dai_is_ferry_type(const struct unit_type *pferry, struct ai_type *ait)
Definition daiferry.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 daihunter.c:252
#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:89
static enum fc_tristate tactical_req_cb(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, void *data, int n_data)
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)
static struct unit_type * dai_choose_attacker(struct ai_type *ait, const struct civ_map *nmap, struct city *pcity, enum terrain_class tc, bool allow_gold_upkeep)
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)
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:73
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)
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 struct adv_choice * kill_something_with(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, struct unit *myunit, struct adv_choice *choice)
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
void dai_choose_paratrooper(struct ai_type *ait, const struct civ_map *nmap, 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 daiplayer.h:54
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition daiplayer.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 daitech.c:390
bool dai_assess_military_unhappiness(const struct civ_map *nmap, struct city *pcity)
Definition daitools.c:1444
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 daitools.c:1373
adv_want military_amortize(struct player *pplayer, struct city *pcity, adv_want value, int delay, int build_cost)
Definition daitools.c:117
#define DAI_WANT_BELOW_MIL_EMERGENCY
Definition daitools.h:31
#define DAI_WANT_MILITARY_EMERGENCY
Definition daitools.h:32
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition daiunit.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 daiunit.c:303
bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile *dest_tile, const struct unit_type *cargo_type, const struct unit_type *ferry_type, struct tile **ferry_dest, struct tile **beachhead_tile)
Definition daiunit.c:1135
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition daiunit.c:2997
int build_cost_balanced(const struct unit_type *punittype)
Definition daiunit.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 daiunit.c:1214
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 daiunit.c:784
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:903
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition daiunit.h:72
#define simple_ai_unit_type_iterate_end
Definition daiunit.h:153
#define simple_ai_unit_type_iterate(_ut)
Definition daiunit.h:147
static void attack(QVariant data1, QVariant data2)
Definition dialogs.cpp:3497
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 const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:77
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_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
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:1036
float adv_want
Definition fc_types.h:1050
int Tech_type_id
Definition fc_types.h:238
int Impr_type_id
Definition fc_types.h:237
@ RPT_CERTAIN
Definition fc_types.h:516
@ RPT_POSSIBLE
Definition fc_types.h:515
int action_id
Definition fc_types.h:250
#define ADV_WANT_PRINTF
Definition fc_types.h:1051
int Unit_type_id
Definition fc_types.h:243
@ O_SHIELD
Definition fc_types.h:103
@ O_LUXURY
Definition fc_types.h:103
@ O_GOLD
Definition fc_types.h:103
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
static enum log_level max_level
Definition log.c:49
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
@ LOG_DEBUG
Definition log.h:35
@ LOG_VERBOSE
Definition log.h:34
#define log_error(message,...)
Definition log.h:104
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:675
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:362
bool can_attack_from_non_native(const struct unit_type *utype)
Definition movement.c:226
bool is_native_near_tile(const struct civ_map *nmap, const struct unit_class *uclass, const struct tile *ptile)
Definition movement.c:496
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:213
#define SINGLE_MOVE
Definition movement.h:26
struct city_list * cities
Definition packhand.c:121
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:828
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
static bool player_is_cpuhog(const struct player *pplayer)
Definition player.h:590
enum fc_tristate tri_req_active(const struct req_context *context, const struct req_context *other_context, const struct requirement *req)
enum fc_tristate tri_reqs_cb_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, struct requirement_vector *maybe_reqs, req_tester_cb tester, void *data, int n_data)
enum req_unchanging_status is_req_preventing(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, enum req_problem_type prob_type)
enum fc_tristate tri_req_active_turns(int pass, int period, const struct req_context *context, const struct req_context *other_context, const struct requirement *req)
@ REQUCH_CTRL
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:753
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:775
struct research * research_get(const struct player *pplayer)
Definition research.c:130
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 CLIP(lower, current, upper)
Definition shared.h:57
#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:280
#define normal_specialist_type_iterate(sp)
Definition specialist.h:89
#define normal_specialist_type_iterate_end
Definition specialist.h:95
#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:341
enum choice_type type
Definition advchoice.h:46
adv_want want
Definition advchoice.h:48
universals_u value
Definition advchoice.h:47
int wonder_city
Definition advdata.h:55
struct adv_choice choice
Definition daicity.h:41
int bcost
Definition daicity.h:44
unsigned int urgency
Definition daicity.h:49
int wallvalue
Definition daicity.h:51
int boats
Definition daidata.h:79
struct ai_plr::@279 stats
int available_boats
Definition daidata.h:80
Definition ai.h:50
Definition city.h:318
struct packet_game_info info
Definition game.h:89
int low_firepower_pearl_harbor
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
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:586
int firepower
Definition unittype.h:532
struct unit_type::@91 cache
int scramble_coeff[U_LAST]
Definition unittype.h:590
int defense_mp_bonuses_pct[U_LAST]
Definition unittype.h:589
Definition unit.h:139
int id
Definition unit.h:146
int hp
Definition unit.h:152
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:141
struct unit_adv * adv
Definition unit.h:238
int veteran
Definition unit.h:153
enum universals_n kind
Definition fc_types.h:595
universals_u value
Definition fc_types.h:594
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:90
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:100
tech_req
Definition tech.h:107
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:536
enum citystatus_type citystatus
Definition fc_types.h:547
const struct impr_type * building
Definition fc_types.h:529
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2526
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:402
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1682
bool is_special_unit(const struct unit *punit)
Definition unit.c:369
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1787
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2512
#define unit_tile(_pu)
Definition unit.h:408
#define unit_owner(_pu)
Definition unit.h:407
#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:126
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1613
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:224
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1493
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1509
int utype_upkeep_cost(const struct unit_type *ut, const struct unit *punit, struct player *pplayer, Output_type_id otype)
Definition unittype.c:136
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2662
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1604
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2535
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:412
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:215
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:289
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2776
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:93
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:301
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1463
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:468
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:396
#define utype_class(_t_)
Definition unittype.h:756
#define utype_fuel(ptype)
Definition unittype.h:849
#define unit_tech_reqs_iterate_end
Definition unittype.h:891
#define unit_tech_reqs_iterate(_utype_, _p)
Definition unittype.h:885
@ 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:624
#define unit_type_iterate(_p)
Definition unittype.h:865
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:872
#define U_NOT_OBSOLETED
Definition unittype.h:535