Freeciv-3.1
Loading...
Searching...
No Matches
autosettlers.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 <math.h>
19#include <stdio.h>
20#include <string.h>
21
22/* utility */
23#include "log.h"
24#include "mem.h"
25#include "support.h"
26#include "timing.h"
27
28/* common */
29#include "ai.h"
30#include "city.h"
31#include "game.h"
32#include "government.h"
33#include "map.h"
34#include "movement.h"
35#include "packets.h"
36#include "unitlist.h"
37
38/* common/aicore */
39#include "citymap.h"
40#include "path_finding.h"
41#include "pf_tools.h"
42
43/* server */
44#include "citytools.h"
45#include "maphand.h"
46#include "plrhand.h"
47#include "srv_log.h"
48#include "unithand.h"
49#include "unittools.h"
50
51/* server/advisors */
52#include "advbuilding.h"
53#include "advdata.h"
54#include "advgoto.h"
55#include "advtools.h"
56#include "infracache.h"
57
58/* ai */
59#include "handicaps.h"
60
61#include "autosettlers.h"
62
63/* This factor is multiplied on when calculating the want. This is done
64 * to avoid rounding errors in comparisons when looking for the best
65 * possible work. However before returning the final want we have to
66 * divide by it again. This loses accuracy but is needed since the want
67 * values are used for comparison by the AI in trying to calculate the
68 * goodness of building worker units. */
69#define WORKER_FACTOR 1024
70
71struct settlermap {
72 int enroute; /* unit ID of settler en route to this tile */
73 int eta; /* estimated number of turns until enroute arrives */
74};
75
79
80static struct timer *as_timer = NULL;
81
82/**********************************************************************/
86{
88 as_timer = NULL;
89}
90
91/**********************************************************************/
95{
96 int i;
97
98 i = 0;
100 ACTRES_CULTIVATE);
102 ACTRES_PLANT);
104 ACTRES_TRANSFORM_TERRAIN);
106
107 i = 0;
109 ACTRES_IRRIGATE);
111 ACTRES_MINE);
113 ACTRES_ROAD);
115 ACTRES_BASE);
117
118 i = 0;
120 ACTRES_CLEAN_POLLUTION);
122 ACTRES_CLEAN_FALLOUT);
123 /* We could have ACTRES_PILLAGE here, but currently we don't */
125}
126
127/**********************************************************************/
134 struct tile *ptile, struct road_type *proad)
135{
136#define MAX_DEP_ROADS 5
137
138 int bonus = 0, i;
139 bool potential_road[12], real_road[12], is_slow[12];
140 int dx[12] = {-1, 0, 1, -1, 1, -1, 0, 1, 0, -2, 2, 0};
141 int dy[12] = {-1, -1, -1, 0, 0, 1, 1, 1, -2, 0, 0, 2};
142 int x, y;
143 int rnbr;
144 struct road_type *pdep_roads[MAX_DEP_ROADS];
145 int dep_rnbr[MAX_DEP_ROADS];
146 int dep_count = 0;
147 struct extra_type *pextra;
148
149 if (proad == NULL) {
150 return 0;
151 }
152
153 rnbr = road_number(proad);
154 pextra = road_extra_get(proad);
155
156 road_deps_iterate(&(pextra->reqs), pdep) {
157 if (dep_count < MAX_DEP_ROADS) {
158 pdep_roads[dep_count] = pdep;
159 dep_rnbr[dep_count++] = road_number(pdep);
160 }
162
163 index_to_map_pos(&x, &y, tile_index(ptile));
164 for (i = 0; i < 12; i++) {
165 struct tile *tile1 = map_pos_to_tile(nmap, x + dx[i], y + dy[i]);
166
167 if (!tile1) {
168 real_road[i] = FALSE;
169 potential_road[i] = FALSE;
170 is_slow[i] = FALSE; /* FIXME: should be TRUE? */
171 } else {
172 int build_time = terrain_extra_build_time(tile_terrain(tile1), ACTIVITY_GEN_ROAD, pextra);
173 int j;
174
175 real_road[i] = tile_has_road(tile1, proad);
176 potential_road[i] = real_road[i];
177 for (j = 0 ; !potential_road[i] && j < dep_count ; j++) {
178 potential_road[i] = tile_has_road(tile1, pdep_roads[j]);
179 }
180
181 /* If TRUE, this value indicates that this tile does not need
182 * a road connector. This is set for terrains which cannot have
183 * road or where road takes "too long" to build. */
184 is_slow[i] = (build_time == 0 || build_time > 5);
185
186 if (!real_road[i]) {
187 unit_list_iterate(tile1->units, punit) {
188 if (punit->activity == ACTIVITY_GEN_ROAD) {
189 /* If a road, or its dependency is being built here, consider as if it's already
190 * built. */
191 int build_rnbr;
192
194
196
197 if (build_rnbr == rnbr) {
198 real_road[i] = TRUE;
199 potential_road[i] = TRUE;
200 }
201 for (j = 0 ; !potential_road[i] && j < dep_count ; j++) {
202 if (build_rnbr == dep_rnbr[j]) {
203 potential_road[i] = TRUE;
204 }
205 }
206 }
208 }
209 }
210 }
211
212 if (current_topo_has_flag(TF_HEX)) {
213 /* On hex map, road is always a benefit */
214 bonus += 20; /* Later divided by 20 */
215
216 /* Road is more valuable when even longer road around does not exist. */
217 for (i = 0; i < 12; i++) {
218 if (!real_road[i]) {
219 bonus += 3;
220 }
221 }
222
223 /* Scale down the bonus. */
224 bonus /= 20;
225 } else {
226 /*
227 * Consider the following tile arrangement (numbered in hex):
228 *
229 * 8
230 * 012
231 * 93 4A
232 * 567
233 * B
234 *
235 * these are the tiles defined by the (dx,dy) arrays above.
236 *
237 * Then the following algorithm is supposed to determine if it's a good
238 * idea to build a road here. Note this won't work well for hex maps
239 * since the (dx,dy) arrays will not cover the same tiles.
240 *
241 * FIXME: if you can understand the algorithm below please rewrite this
242 * explanation!
243 */
244 if (potential_road[0]
245 && !real_road[1] && !real_road[3]
246 && (!real_road[2] || !real_road[8])
247 && (!is_slow[2] || !is_slow[4] || !is_slow[7]
248 || !is_slow[6] || !is_slow[5])) {
249 bonus++;
250 }
251 if (potential_road[2]
252 && !real_road[1] && !real_road[4]
253 && (!real_road[7] || !real_road[10])
254 && (!is_slow[0] || !is_slow[3] || !is_slow[7]
255 || !is_slow[6] || !is_slow[5])) {
256 bonus++;
257 }
258 if (potential_road[5]
259 && !real_road[6] && !real_road[3]
260 && (!real_road[5] || !real_road[11])
261 && (!is_slow[2] || !is_slow[4] || !is_slow[7]
262 || !is_slow[1] || !is_slow[0])) {
263 bonus++;
264 }
265 if (potential_road[7]
266 && !real_road[6] && !real_road[4]
267 && (!real_road[0] || !real_road[9])
268 && (!is_slow[2] || !is_slow[3] || !is_slow[0]
269 || !is_slow[1] || !is_slow[5])) {
270 bonus++;
271 }
272
273 /* A
274 * B*B
275 * CCC
276 *
277 * We are at tile *. If tile A has a road, and neither B tile does, and
278 * one C tile is a valid destination, then we might want a road here.
279 *
280 * Of course the same logic applies if you rotate the diagram.
281 */
282 if (potential_road[1] && !real_road[4] && !real_road[3]
283 && (!is_slow[5] || !is_slow[6] || !is_slow[7])) {
284 bonus++;
285 }
286 if (potential_road[3] && !real_road[1] && !real_road[6]
287 && (!is_slow[2] || !is_slow[4] || !is_slow[7])) {
288 bonus++;
289 }
290 if (potential_road[4] && !real_road[1] && !real_road[6]
291 && (!is_slow[0] || !is_slow[3] || !is_slow[5])) {
292 bonus++;
293 }
294 if (potential_road[6] && !real_road[4] && !real_road[3]
295 && (!is_slow[0] || !is_slow[1] || !is_slow[2])) {
296 bonus++;
297 }
298 }
299
300 return bonus;
301}
302
303/**********************************************************************/
309static void consider_settler_action(const struct player *pplayer,
310 enum unit_activity act,
311 struct extra_type *target,
312 adv_want extra,
313 adv_want new_tile_value,
314 adv_want old_tile_value,
315 bool in_use, int delay,
317 adv_want *best_old_tile_value,
318 int *best_extra,
319 bool *improve_worked,
320 int *best_delay,
321 enum unit_activity *best_act,
322 struct extra_type **best_target,
323 struct tile **best_tile,
324 struct tile *ptile)
325{
326 bool improves;
327 adv_want total_value = 0;
328 adv_want base_value = 0;
329 int old_improvement_value;
330
331 fc_assert(act != ACTIVITY_LAST);
332
333 if (extra < 0) {
334 extra = 0;
335 }
336
337 if (new_tile_value > old_tile_value) {
338 improves = TRUE;
339 } else if (ADV_WANTS_EQ(new_tile_value, old_tile_value) && extra > 0) {
340 improves = TRUE;
341 } else {
342 improves = FALSE;
343 }
344
345 /* find the present value of the future benefit of this action */
346 if (improves || extra > 0) {
347 if (!(*improve_worked) && !in_use) {
348 /* Going to improve tile that is not yet in use.
349 * Getting the best possible total for next citizen to work on is more
350 * important than amount tile gets improved. */
351 if (improves && (new_tile_value > *best_value
352 || (ADV_WANTS_EQ(new_tile_value, *best_value)
353 && old_tile_value < *best_old_tile_value))) {
354 *best_value = new_tile_value;
355 *best_old_tile_value = old_tile_value;
356 *best_extra = extra;
357 *best_act = act;
358 *best_target = target;
359 *best_tile = ptile;
360 *best_delay = delay;
361 }
362
363 return;
364 }
365
366 /* At least one of the previous best or current tile is in use
367 * Prefer the tile that gets improved more, regardless of
368 * the resulting total */
369
370 base_value = new_tile_value - old_tile_value;
371 total_value = base_value * WORKER_FACTOR;
372 if (!in_use) {
373 total_value /= 2;
374 }
375 total_value += extra * WORKER_FACTOR;
376
377 /* Use factor to prevent rounding errors */
378 total_value = amortize(total_value, delay);
379
380 if (*improve_worked) {
381 old_improvement_value = *best_value;
382 } else {
383 /* Convert old best_value to improvement value compatible with in_use
384 * tile value */
385 old_improvement_value = amortize((*best_value - *best_old_tile_value) * WORKER_FACTOR / 2,
386 *best_delay);
387 }
388
389 if (total_value > old_improvement_value
390 || (ADV_WANTS_EQ(total_value, old_improvement_value)
391 && old_tile_value > *best_old_tile_value)) {
392 if (in_use) {
393 *best_value = total_value;
394 *improve_worked = TRUE;
395 } else {
396 *best_value = new_tile_value;
397 *improve_worked = FALSE;
398 }
399 *best_old_tile_value = old_tile_value;
400 *best_extra = extra;
401 *best_act = act;
402 *best_target = target;
403 *best_tile = ptile;
404 *best_delay = delay;
405 }
406 }
407}
408
409/**********************************************************************/
412static enum tile_behavior
413autosettler_tile_behavior(const struct tile *ptile,
414 enum known_type known,
415 const struct pf_parameter *param)
416{
417 const struct player *owner = tile_owner(ptile);
418
419 if (NULL != owner && !pplayers_allied(owner, param->owner)) {
420 return TB_IGNORE;
421 }
422 return TB_NORMAL;
423}
424
425/**********************************************************************/
443 struct unit *punit,
444 enum unit_activity *best_act,
445 struct extra_type **best_target,
446 struct tile **best_tile,
447 struct pf_path **path,
448 struct settlermap *state)
449{
450 const struct player *pplayer = unit_owner(punit);
451 struct pf_parameter parameter;
452 struct pf_map *pfm;
453 struct pf_position pos;
454 adv_want oldv; /* Current value of consideration tile. */
455 adv_want best_oldv = 9999; /* oldv of best target so far; compared if
456 * newv == best_newv; not initialized to zero,
457 * so that newv = 0 activities are not chosen. */
458 adv_want best_newv = 0;
459 bool improve_worked = FALSE;
460 int best_extra = 0;
461 int best_delay = 0;
462
463 /* Closest worker, if any, headed towards target tile */
464 struct unit *enroute = NULL;
465
466 pft_fill_unit_parameter(&parameter, nmap, punit);
467 parameter.omniscience = !has_handicap(pplayer, H_MAP);
469 pfm = pf_map_new(&parameter);
470
471 city_list_iterate(pplayer->cities, pcity) {
472 struct tile *pcenter = city_tile(pcity);
473
474 /* Try to work near the city */
475 city_tile_iterate_index(nmap, city_map_radius_sq_get(pcity), pcenter, ptile,
476 cindex) {
477 bool consider = TRUE;
478 bool in_use = (tile_worked(ptile) == pcity);
479
480 if (!in_use && !city_can_work_tile(pcity, ptile)) {
481 /* Don't risk bothering with this tile. */
482 continue;
483 }
484
485 if (!adv_settler_safe_tile(nmap, pplayer, punit, ptile)) {
486 /* Too dangerous place */
487 continue;
488 }
489
490 /* Do not go to tiles that already have workers there. */
491 unit_list_iterate(ptile->units, aunit) {
492 if (unit_owner(aunit) == pplayer
493 && aunit->id != punit->id
494 && unit_has_type_flag(aunit, UTYF_SETTLERS)) {
495 consider = FALSE;
496 }
498
499 if (!consider) {
500 continue;
501 }
502
503 if (state) {
504 enroute = player_unit_by_number(pplayer,
505 state[tile_index(ptile)].enroute);
506 }
507
508 if (pf_map_position(pfm, ptile, &pos)) {
509 int eta = FC_INFINITY, inbound_distance = FC_INFINITY, turns;
510
511 if (enroute) {
512 eta = state[tile_index(ptile)].eta;
513 inbound_distance = real_map_distance(ptile, unit_tile(enroute));
514 }
515
516 /* Only consider this tile if we are closer in time and space to
517 * it than our other worker (if any) travelling to the site. */
518 if ((enroute && enroute->id == punit->id)
519 || pos.turn < eta
520 || (pos.turn == eta
522 < inbound_distance))) {
523
524 if (enroute) {
526 "Considering (%d, %d) because we're closer "
527 "(%d, %d) than %d (%d, %d)",
528 TILE_XY(ptile), pos.turn,
530 enroute->id, eta, inbound_distance);
531 }
532
533 oldv = city_tile_value(pcity, ptile, 0, 0);
534
535 /* Now, consider various activities... */
537 struct extra_type *target = NULL;
538 enum extra_cause cause =
540 enum extra_rmcause rmcause =
542
543 if (cause != EC_NONE) {
544 target = next_extra_for_tile(ptile, cause, pplayer,
545 punit);
546 } else if (rmcause != ERM_NONE) {
547 target = prev_extra_in_tile(ptile, rmcause, pplayer,
548 punit);
549 }
550
551 if (adv_city_worker_act_get(pcity, cindex,
552 action_id_get_activity(act)) >= 0
556 ptile,
557 parameter.omniscience,
558 ptile, target))) {
559 adv_want base_value
560 = adv_city_worker_act_get(pcity, cindex,
562
563 turns = pos.turn
566 ptile, target);
567 if (pos.moves_left == 0) {
568 /* We need moves left to begin activity immediately. */
569 turns++;
570 }
571
574 target, 0.0, base_value,
575 oldv, in_use, turns,
576 &best_newv, &best_oldv, &best_extra,
577 &improve_worked,
578 &best_delay, best_act, best_target,
579 best_tile, ptile);
580
581 } /* endif: can the worker perform this action */
583
584 extra_type_iterate(pextra) {
585 enum unit_activity act = ACTIVITY_LAST;
586 enum unit_activity eval_act = ACTIVITY_LAST;
587 adv_want base_value;
588 bool removing = tile_has_extra(ptile, pextra);
589
590 if (removing) {
592 struct action *taction = action_by_number(try_act);
593 if (is_extra_removed_by_action(pextra, taction)) {
594 /* We do not even evaluate actions we can't do.
595 * Removal is not considered prerequisite for anything */
598 punit,
600 ptile,
601 parameter.omniscience,
602 ptile, pextra))) {
603 act = actres_get_activity(taction->result);
604 eval_act = actres_get_activity(taction->result);
605 break;
606 }
607 }
609 } else {
610 as_extra_action_iterate(try_act) {
611 struct action *taction = action_by_number(try_act);
612 if (is_extra_caused_by_action(pextra, taction)) {
613 eval_act = action_id_get_activity(try_act);
616 punit,
618 ptile,
619 parameter.omniscience,
620 ptile, pextra))) {
621 act = actres_get_activity(taction->result);
622 break;
623 }
624 }
626 }
627
628 if (eval_act == ACTIVITY_LAST) {
629 /* No activity can provide (or remove) the extra */
630 continue;
631 }
632
633 if (removing) {
634 base_value = adv_city_worker_rmextra_get(pcity, cindex, pextra);
635 } else {
636 base_value = adv_city_worker_extra_get(pcity, cindex, pextra);
637 }
638
639 if (base_value >= 0) {
640 adv_want extra;
641 struct road_type *proad;
642
643 turns = pos.turn + get_turns_for_activity_at(punit, eval_act,
644 ptile, pextra);
645 if (pos.moves_left == 0) {
646 /* We need moves left to begin activity immediately. */
647 turns++;
648 }
649
650 proad = extra_road_get(pextra);
651
652 if (proad != NULL && road_provides_move_bonus(proad)) {
653 int mc_multiplier = 1;
654 int mc_divisor = 1;
655 int old_move_cost = tile_terrain(ptile)->movement_cost * SINGLE_MOVE;
656
657 /* Here 'old' means actually 'without the evaluated': In case of
658 * removal activity it's the value after the removal. */
659
660 extra_type_by_cause_iterate(EC_ROAD, pold) {
661 if (tile_has_extra(ptile, pold) && pold != pextra) {
662 struct road_type *po_road = extra_road_get(pold);
663
664 /* This ignores the fact that new road may be native to units that
665 * old road is not. */
666 if (po_road->move_cost < old_move_cost) {
667 old_move_cost = po_road->move_cost;
668 }
669 }
671
672 if (proad->move_cost < old_move_cost) {
673 if (proad->move_cost >= terrain_control.move_fragments) {
674 mc_divisor = proad->move_cost / terrain_control.move_fragments;
675 } else {
676 if (proad->move_cost == 0) {
677 mc_multiplier = 2;
678 } else {
679 mc_multiplier = 1 - proad->move_cost;
680 }
681 mc_multiplier += old_move_cost;
682 }
683 }
684
685 extra = adv_settlers_road_bonus(nmap, ptile, proad)
686 * mc_multiplier / mc_divisor;
687
688 } else {
689 extra = 0;
690 }
691
692 if (extra_has_flag(pextra, EF_GLOBAL_WARMING)) {
693 extra -= pplayer->ai_common.warmth;
694 }
695 if (extra_has_flag(pextra, EF_NUCLEAR_WINTER)) {
696 extra -= pplayer->ai_common.frost;
697 }
698
699 if (removing) {
700 extra = -extra;
701 }
702
703 if (act != ACTIVITY_LAST) {
704 consider_settler_action(pplayer, act, pextra, extra, base_value,
705 oldv, in_use, turns,
706 &best_newv, &best_oldv, &best_extra,
707 &improve_worked,
708 &best_delay, best_act, best_target,
709 best_tile, ptile);
710 } else {
711 fc_assert(!removing);
712
713 road_deps_iterate(&(pextra->reqs), pdep) {
714 struct extra_type *dep_tgt;
715
716 dep_tgt = road_extra_get(pdep);
717
720 punit, unit_home(punit), ptile,
721 parameter.omniscience,
722 ptile, dep_tgt))) {
723 /* Consider building dependency road for later upgrade to target extra.
724 * Here we set value to be sum of dependency
725 * road and target extra values, which increases want, and turns is sum
726 * of dependency and target build turns, which decreases want. This can
727 * result in either bigger or lesser want than when checking dependency
728 * road for the sake of itself when its turn in extra_type_iterate() is. */
729 int dep_turns = turns + get_turns_for_activity_at(punit,
730 ACTIVITY_GEN_ROAD,
731 ptile,
732 dep_tgt);
733 adv_want dep_value
734 = base_value + adv_city_worker_extra_get(pcity, cindex, dep_tgt);
735
736 consider_settler_action(pplayer, ACTIVITY_GEN_ROAD, dep_tgt, extra,
737 dep_value,
738 oldv, in_use, dep_turns,
739 &best_newv, &best_oldv, &best_extra,
740 &improve_worked,
741 &best_delay, best_act, best_target,
742 best_tile, ptile);
743 }
745
746 extra_deps_iterate(&(pextra->reqs), pdep) {
747 /* Roads handled above already */
748 if (!is_extra_caused_by(pdep, EC_ROAD)) {
749 enum unit_activity eval_dep_act = ACTIVITY_LAST;
750 action_id eval_dep_action;
751
752 as_extra_action_iterate(try_act) {
753 struct action *taction = action_by_number(try_act);
754
755 if (is_extra_caused_by_action(pdep, taction)) {
756 eval_dep_action = try_act;
757 eval_dep_act = action_id_get_activity(try_act);
758 break;
759 }
761
762 if (eval_dep_act != ACTIVITY_LAST) {
764 action_speculate_unit_on_tile(eval_dep_action,
765 punit, unit_home(punit), ptile,
766 parameter.omniscience,
767 ptile, pdep))) {
768 /* Consider building dependency extra for later upgrade to
769 * target extra. See similar road implementation above for
770 * extended commentary. */
771 int dep_turns = turns + get_turns_for_activity_at(punit,
772 eval_dep_act,
773 ptile,
774 pdep);
775 adv_want dep_value
776 = base_value + adv_city_worker_extra_get(pcity, cindex,
777 pdep);
778
779 consider_settler_action(pplayer, eval_dep_act, pdep,
780 0.0, dep_value, oldv, in_use,
781 dep_turns, &best_newv, &best_oldv,
782 &best_extra, &improve_worked,
783 &best_delay,
784 best_act, best_target,
785 best_tile, ptile);
786 }
787 }
788 }
790 }
791 }
793 } /* endif: can we arrive sooner than current worker, if any? */
794 } /* endif: are we travelling to a legal destination? */
797
798 if (!improve_worked) {
799 /* best_newv contains total value of improved tile. Check amount of improvement
800 * instead. */
801 best_newv = amortize((best_newv - best_oldv + best_extra) * WORKER_FACTOR, best_delay);
802 }
803 best_newv /= WORKER_FACTOR;
804
805 best_newv = MAX(best_newv, 0); /* sanity */
806
807 if (best_newv > 0) {
808 log_debug("Settler %d@(%d,%d) wants to %s at (%d,%d) with desire " ADV_WANT_PRINTF,
810 get_activity_text(*best_act), TILE_XY(*best_tile), best_newv);
811 } else {
812 /* Fill in dummy values. The callers should check if the return value
813 * is > 0 but this will avoid confusing them. */
814 *best_act = ACTIVITY_IDLE;
815 *best_tile = NULL;
816 }
817
818 if (path) {
819 *path = *best_tile ? pf_map_path(pfm, *best_tile) : NULL;
820 }
821
822 pf_map_destroy(pfm);
823
824 return best_newv;
825}
826
827/**********************************************************************/
831 struct worker_task **best_task,
832 struct pf_path **path,
833 struct settlermap *state)
834{
835 const struct player *pplayer = unit_owner(punit);
836 struct pf_parameter parameter;
837 struct pf_map *pfm;
838 struct pf_position pos;
839 int best_value = -1;
840 struct worker_task *best = NULL;
841 struct city *taskcity = NULL;
842 int dist = FC_INFINITY;
843 const struct civ_map *nmap = &(wld.map);
844
845 pft_fill_unit_parameter(&parameter, nmap, punit);
846 parameter.omniscience = !has_handicap(pplayer, H_MAP);
848 pfm = pf_map_new(&parameter);
849
850 /* Have nearby cities requests? */
851 city_list_iterate(pplayer->cities, pcity) {
852 worker_task_list_iterate(pcity->task_reqs, ptask) {
853 bool consider = TRUE;
854
855 /* Do not go to tiles that already have workers there. */
856 unit_list_iterate(ptask->ptile->units, aunit) {
857 if (unit_owner(aunit) == pplayer
858 && aunit->id != punit->id
859 && unit_has_type_flag(aunit, UTYF_SETTLERS)) {
860 consider = FALSE;
861 }
863
864 if (consider
866 parameter.omniscience,
867 ptask->tgt, ptask->ptile)) {
868 /* closest worker, if any, headed towards target tile */
869 struct unit *enroute = NULL;
870
871 if (state) {
872 enroute = player_unit_by_number(pplayer,
873 state[tile_index(ptask->ptile)].enroute);
874 }
875
876 if (pf_map_position(pfm, ptask->ptile, &pos)) {
877 int value = (ptask->want + 1) * 10 / (pos.turn + 1);
878
879 if (value > best_value) {
880 int eta = FC_INFINITY, inbound_distance = FC_INFINITY;
881
882 if (enroute) {
883 eta = state[tile_index(ptask->ptile)].eta;
884 inbound_distance = real_map_distance(ptask->ptile, unit_tile(enroute));
885 }
886
887 /* Only consider this tile if we are closer in time and space to
888 * it than our other worker (if any) travelling to the site. */
889 if (pos.turn < dist
890 && ((enroute && enroute->id == punit->id)
891 || pos.turn < eta
892 || (pos.turn == eta
893 && (real_map_distance(ptask->ptile, unit_tile(punit))
894 < inbound_distance)))) {
895 dist = pos.turn;
896 best = ptask;
897 best_value = value;
898 taskcity = pcity;
899 }
900 }
901 }
902 }
905
906 *best_task = best;
907
908 if (path != NULL) {
909 *path = best ? pf_map_path(pfm, best->ptile) : NULL;
910 }
911
912 pf_map_destroy(pfm);
913
914 return taskcity;
915}
916
917/**********************************************************************/
920#define LOG_SETTLER LOG_DEBUG
921void auto_settler_findwork(const struct civ_map *nmap,
922 struct player *pplayer,
923 struct unit *punit,
924 struct settlermap *state,
925 int recursion)
926{
927 struct worker_task *best_task;
928 enum unit_activity best_act;
929 struct tile *best_tile = NULL;
930 struct extra_type *best_target;
931 struct pf_path *path = NULL;
932 struct city *taskcity;
933
934 /* Time it will take worker to complete its given task */
935 int completion_time = 0;
936
937 /* Terminate what might be an inifite recursion of two units
938 * displacing each other, but leave enough space for
939 * finite recursion. */
940 if (recursion > 5
941 && recursion > unit_list_size(pplayer->units) * 1.5) {
942 log_warn("Workers displacing each other recursing too much.");
943
945 set_unit_activity(punit, ACTIVITY_IDLE);
946 send_unit_info(NULL, punit);
947
948 return; /* Avoid further recursion. */
949 }
950
952
953 fc_assert_ret(pplayer && punit);
955 || unit_has_type_flag(punit, UTYF_SETTLERS));
956
957 /* Have nearby cities requests? */
958
959 taskcity = settler_evaluate_city_requests(punit, &best_task, &path, state);
960
961 if (taskcity != NULL) {
962 if (path != NULL) {
963 completion_time = pf_path_last_position(path)->turn;
964 }
965
967
968 best_target = best_task->tgt;
969
970 if (auto_settler_setup_work(nmap, pplayer, punit, state, recursion,
971 path, best_task->ptile, best_task->act,
972 &best_target, completion_time)) {
973 clear_worker_task(taskcity, best_task);
974 }
975
976 if (path != NULL) {
977 pf_path_destroy(path);
978 }
979
980 return;
981 }
982
983 /*** Try find some work ***/
984
985 if (unit_has_type_flag(punit, UTYF_SETTLERS)) {
987 settler_evaluate_improvements(nmap, punit, &best_act, &best_target,
988 &best_tile, &path, state);
989 if (path) {
990 completion_time = pf_path_last_position(path)->turn;
991 }
993
995
996 auto_settler_setup_work(nmap, pplayer, punit, state, recursion, path,
997 best_tile, best_act, &best_target,
998 completion_time);
999
1000 if (NULL != path) {
1001 pf_path_destroy(path);
1002 }
1003 }
1004}
1005
1006/**********************************************************************/
1010bool auto_settler_setup_work(const struct civ_map *nmap,
1011 struct player *pplayer, struct unit *punit,
1012 struct settlermap *state, int recursion,
1013 struct pf_path *path,
1014 struct tile *best_tile,
1015 enum unit_activity best_act,
1016 struct extra_type **best_target,
1017 int completion_time)
1018{
1019 /* Run the "autosettler" program */
1021 struct pf_map *pfm = NULL;
1022 struct pf_parameter parameter;
1023 bool working = FALSE;
1024 struct unit *displaced;
1025
1026 if (!best_tile) {
1027 UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
1028 return FALSE; /* We cannot do anything */
1029 }
1030
1031 /* Mark the square as taken. */
1032 displaced = player_unit_by_number(pplayer,
1033 state[tile_index(best_tile)].enroute);
1034
1035 if (displaced) {
1036 fc_assert(state[tile_index(best_tile)].enroute == displaced->id);
1037 fc_assert(state[tile_index(best_tile)].eta > completion_time
1038 || (state[tile_index(best_tile)].eta == completion_time
1039 && (real_map_distance(best_tile, unit_tile(punit))
1040 < real_map_distance(best_tile,
1041 unit_tile(displaced)))));
1043 "%d (%d,%d) has displaced %d (%d,%d) for worksite %d,%d",
1044 punit->id, completion_time,
1045 real_map_distance(best_tile, unit_tile(punit)),
1046 displaced->id, state[tile_index(best_tile)].eta,
1047 real_map_distance(best_tile, unit_tile(displaced)),
1048 TILE_XY(best_tile));
1049 }
1050
1051 state[tile_index(best_tile)].enroute = punit->id;
1052 state[tile_index(best_tile)].eta = completion_time;
1053
1054 if (displaced) {
1055 struct tile *goto_tile = punit->goto_tile;
1056 int saved_id = punit->id;
1057 struct tile *old_pos = unit_tile(punit);
1058
1059 displaced->goto_tile = NULL;
1060 auto_settler_findwork(nmap, pplayer, displaced, state, recursion + 1);
1061 if (NULL == player_unit_by_number(pplayer, saved_id)) {
1062 /* Actions of the displaced settler somehow caused this settler
1063 * to die. (maybe by recursively giving control back to this unit)
1064 */
1065 return FALSE;
1066 }
1067 if (goto_tile != punit->goto_tile || old_pos != unit_tile(punit)
1068 || punit->activity != ACTIVITY_IDLE) {
1069 /* Actions of the displaced settler somehow caused this settler
1070 * to get a new job, or to already move toward current job.
1071 * (A displaced B, B displaced C, C displaced A)
1072 */
1074 "%d itself acted due to displacement recursion. "
1075 "Was going from (%d, %d) to (%d, %d). "
1076 "Now heading from (%d, %d) to (%d, %d).",
1077 punit->id,
1078 TILE_XY(old_pos), TILE_XY(goto_tile),
1080 return FALSE;
1081 }
1082 }
1083
1085 "is heading to do %s(%s) at (%d, %d)",
1086 unit_activity_name(best_act),
1087 best_target && *best_target ? extra_rule_name(*best_target) : "-",
1088 TILE_XY(best_tile));
1089
1090 if (!path) {
1091 pft_fill_unit_parameter(&parameter, nmap, punit);
1092 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1094 pfm = pf_map_new(&parameter);
1095 path = pf_map_path(pfm, best_tile);
1096 }
1097
1098 if (path) {
1099 bool alive;
1100
1101 alive = adv_follow_path(punit, path, best_tile);
1102
1103 if (alive && same_pos(unit_tile(punit), best_tile)
1104 && punit->moves_left > 0) {
1105 /* Reached destination and can start working immediately */
1106 if (activity_requires_target(best_act)) {
1107 unit_activity_handling_targeted(punit, best_act, best_target);
1108 } else {
1109 unit_activity_handling(punit, best_act);
1110 }
1111 send_unit_info(NULL, punit); /* FIXME: probably duplicate */
1112
1114 "reached its worksite and started work");
1115 working = TRUE;
1116 } else if (alive) {
1118 "didn't start work yet; got to (%d, %d) with "
1119 "%d move frags left", TILE_XY(unit_tile(punit)),
1120 punit->moves_left);
1121 }
1122 } else {
1124 "does not find path (%d, %d) -> (%d, %d)",
1125 TILE_XY(unit_tile(punit)), TILE_XY(best_tile));
1126 }
1127
1128 if (pfm) {
1129 pf_map_destroy(pfm);
1130 }
1131
1132 return working;
1133 }
1134
1135 return FALSE;
1136}
1137#undef LOG_SETTLER
1138
1139/**********************************************************************/
1142bool adv_settler_safe_tile(const struct civ_map *nmap,
1143 const struct player *pplayer, struct unit *punit,
1144 struct tile *ptile)
1145{
1146 unit_list_iterate(ptile->units, defender) {
1147 if (is_military_unit(defender)) {
1148 return TRUE;
1149 }
1151
1152 if (is_square_threatened(nmap, pplayer, ptile,
1153 !has_handicap(pplayer, H_FOG))) {
1154 return FALSE;
1155 }
1156
1157 return TRUE;
1158}
1159
1160/**********************************************************************/
1164void auto_settlers_player(struct player *pplayer)
1165{
1166 struct settlermap *state;
1167 const struct civ_map *nmap = &(wld.map);
1168
1169 state = fc_calloc(MAP_INDEX_SIZE, sizeof(*state));
1170
1173
1174 if (is_ai(pplayer)) {
1175 /* Set up our city map. */
1176 citymap_turn_init(pplayer);
1177 }
1178
1179 whole_map_iterate(nmap, ptile) {
1180 state[tile_index(ptile)].enroute = -1;
1181 state[tile_index(ptile)].eta = FC_INFINITY;
1183
1184 /* Initialize the infrastructure cache, which is used shortly. */
1186
1187 /* An extra consideration for the benefit of cleaning up pollution/fallout.
1188 * This depends heavily on the calculations in update_environmental_upset.
1189 * Aside from that it's more or less a WAG that simply grows incredibly
1190 * large as an environmental disaster approaches. */
1191 pplayer->ai_common.warmth
1194 pplayer->ai_common.frost
1197
1198 log_debug("Warmth = %d, game.globalwarming=%d",
1200 log_debug("Frost = %d, game.nuclearwinter=%d",
1202
1203 /* Auto-settle with a settler unit if it's under AI control (e.g. human
1204 * player auto-settler mode) or if the player is an AI. But don't
1205 * auto-settle with a unit under orders even for an AI player - these come
1206 * from the human player and take precedence. */
1208 if ((punit->ssa_controller == SSA_AUTOSETTLER || is_ai(pplayer))
1209 && (unit_type_get(punit)->adv.worker
1212 && punit->moves_left > 0) {
1213 log_debug("%s %s at (%d, %d) is controlled by server side agent %s.",
1217 server_side_agent_name(SSA_AUTOSETTLER));
1218 if (punit->activity == ACTIVITY_SENTRY) {
1219 unit_activity_handling(punit, ACTIVITY_IDLE);
1220 }
1221 if (punit->activity == ACTIVITY_GOTO && punit->moves_left > 0) {
1222 unit_activity_handling(punit, ACTIVITY_IDLE);
1223 }
1224 if (punit->activity != ACTIVITY_IDLE) {
1225 if (!is_ai(pplayer)) {
1226 if (!adv_settler_safe_tile(nmap, pplayer, punit,
1227 unit_tile(punit))) {
1228 unit_activity_handling(punit, ACTIVITY_IDLE);
1229 }
1230 } else {
1231 CALL_PLR_AI_FUNC(settler_cont, pplayer, pplayer, punit, state);
1232 }
1233 }
1234 if (punit->activity == ACTIVITY_IDLE) {
1235 if (!is_ai(pplayer)) {
1236 auto_settler_findwork(nmap, pplayer, punit, state, 0);
1237 } else {
1238 CALL_PLR_AI_FUNC(settler_run, pplayer, pplayer, punit, state);
1239 }
1240 }
1241 }
1243 /* Reset auto settler state for the next run. */
1244 if (is_ai(pplayer)) {
1245 CALL_PLR_AI_FUNC(settler_reset, pplayer, pplayer);
1246 }
1247
1248 if (timer_in_use(as_timer)) {
1249
1250#ifdef LOG_TIMERS
1251 log_verbose("%s autosettlers consumed %g milliseconds.",
1253 1000.0 * timer_read_seconds(as_timer));
1254#else
1255 log_verbose("%s autosettlers finished",
1257#endif
1258
1259 }
1260
1261 FC_FREE(state);
1262}
1263
1264/**********************************************************************/
1268 struct tile *ptile)
1269{
1270 if (punit->server.adv->task == task) {
1271 /* Already that task */
1272 return;
1273 }
1274
1275 punit->server.adv->task = task;
1276
1277 CALL_PLR_AI_FUNC(unit_task, unit_owner(punit), punit, task, ptile);
1278}
1279
1280/**********************************************************************/
1285 enum unit_activity activity,
1286 bool omniscient_cheat,
1287 struct extra_type *target,
1288 const struct tile *ptile)
1289{
1290 action_by_activity_iterate(paction, activity) {
1291 if (action_get_actor_kind(paction) != AAK_UNIT) {
1292 /* Not relevant. */
1293 continue;
1294 }
1295
1296 switch (action_get_target_kind(paction)) {
1297 case ATK_CITY:
1299 paction->id,
1300 punit, unit_home(punit), ptile,
1301 omniscient_cheat,
1302 tile_city(ptile)));
1303 case ATK_UNIT:
1304 fc_assert_ret_val(action_get_target_kind(paction) != ATK_UNIT,
1305 FALSE);
1306 break;
1307 case ATK_UNITS:
1309 paction->id,
1310 punit, unit_home(punit), ptile,
1311 omniscient_cheat,
1312 ptile));
1313 case ATK_TILE:
1315 paction->id,
1316 punit, unit_home(punit), ptile,
1317 omniscient_cheat,
1318 ptile, target));
1319 case ATK_EXTRAS:
1321 paction->id,
1322 punit, unit_home(punit), ptile,
1323 omniscient_cheat,
1324 ptile, target));
1325 case ATK_SELF:
1327 paction->id,
1328 punit, unit_home(punit), ptile,
1329 omniscient_cheat));
1330 case ATK_COUNT:
1331 fc_assert_ret_val(action_get_target_kind(paction) != ATK_COUNT,
1332 FALSE);
1333 break;
1334 }
1336
1337 log_debug("No action found for activity %d", activity);
1338
1339 return FALSE;
1340}
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1730
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:6707
void action_list_end(action_id *act_list, int size)
Definition actions.c:7401
struct act_prob action_speculate_unit_on_self(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat)
Definition actions.c:6628
enum unit_activity actres_get_activity(enum action_result result)
Definition actions.c:2136
struct act_prob action_speculate_unit_on_extras(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6594
void action_list_add_all_by_result(action_id *act_list, int *position, enum action_result result)
Definition actions.c:7418
struct act_prob action_speculate_unit_on_units(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target)
Definition actions.c:6527
struct act_prob action_speculate_unit_on_city(const action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, const bool omniscient_cheat, const struct city *target)
Definition actions.c:6459
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1740
struct act_prob action_speculate_unit_on_tile(action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, bool omniscient_cheat, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:6560
#define action_by_activity_iterate(_paction_, _activity_)
Definition actions.h:496
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define action_by_activity_iterate_end
Definition actions.h:500
#define MAX_NUM_ACTIONS
Definition actions.h:296
#define action_id_get_activity(act_id)
Definition actions.h:712
#define COOLING_FACTOR
Definition advbuilding.h:31
#define WARMING_FACTOR
Definition advbuilding.h:30
bool adv_follow_path(struct unit *punit, struct pf_path *path, struct tile *ptile)
Definition advgoto.c:47
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
#define ADV_WANTS_EQ(_w1, _w2)
Definition advtools.h:23
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:374
static void consider_settler_action(const struct player *pplayer, enum unit_activity act, struct extra_type *target, adv_want extra, adv_want new_tile_value, adv_want old_tile_value, bool in_use, int delay, adv_want *best_value, adv_want *best_old_tile_value, int *best_extra, bool *improve_worked, int *best_delay, enum unit_activity *best_act, struct extra_type **best_target, struct tile **best_tile, struct tile *ptile)
action_id as_actions_rmextra[MAX_NUM_ACTIONS]
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
action_id as_actions_transform[MAX_NUM_ACTIONS]
bool auto_settler_setup_work(const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion, struct pf_path *path, struct tile *best_tile, enum unit_activity best_act, struct extra_type **best_target, int completion_time)
void auto_settlers_ruleset_init(void)
static enum tile_behavior autosettler_tile_behavior(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
struct city * settler_evaluate_city_requests(struct unit *punit, struct worker_task **best_task, struct pf_path **path, struct settlermap *state)
adv_want settler_evaluate_improvements(const struct civ_map *nmap, struct unit *punit, enum unit_activity *best_act, struct extra_type **best_target, struct tile **best_tile, struct pf_path **path, struct settlermap *state)
void auto_settlers_player(struct player *pplayer)
action_id as_actions_extra[MAX_NUM_ACTIONS]
adv_want adv_settlers_road_bonus(const struct civ_map *nmap, struct tile *ptile, struct road_type *proad)
bool adv_settler_safe_tile(const struct civ_map *nmap, const struct player *pplayer, struct unit *punit, struct tile *ptile)
void adv_settlers_free(void)
static struct timer * as_timer
bool auto_settlers_speculate_can_act_at(const struct unit *punit, enum unit_activity activity, bool omniscient_cheat, struct extra_type *target, const struct tile *ptile)
#define WORKER_FACTOR
#define MAX_DEP_ROADS
void auto_settler_findwork(const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion)
#define as_transform_action_iterate_end
#define as_rmextra_action_iterate(_act_)
#define as_rmextra_action_iterate_end
#define as_extra_action_iterate_end
#define as_extra_action_iterate(_act_)
#define as_transform_action_iterate(_act_)
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1425
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
#define city_tile_iterate_index(_nmap, _radius_sq, _city_tile, _tile, _index)
Definition city.h:193
#define city_tile_iterate_index_end
Definition city.h:201
#define city_list_iterate_end
Definition city.h:490
void citymap_turn_init(struct player *pplayer)
Definition citymap.c:61
void clear_worker_task(struct city *pcity, struct worker_task *ptask)
Definition citytools.c:3469
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 extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:740
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:810
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:765
enum extra_cause activity_to_extra_cause(enum unit_activity act)
Definition extras.c:1028
bool is_extra_caused_by_action(const struct extra_type *pextra, const struct action *paction)
Definition extras.c:1006
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:195
bool is_extra_removed_by_action(const struct extra_type *pextra, const struct action *paction)
Definition extras.c:1017
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
Definition extras.c:1049
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:338
#define extra_type_iterate_end
Definition extras.h:297
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_deps_iterate_end
Definition extras.h:346
#define extra_road_get(_e_)
Definition extras.h:185
#define extra_type_by_cause_iterate_end
Definition extras.h:315
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:309
float adv_want
Definition fc_types.h:1206
adv_unit_task
Definition fc_types.h:340
@ AUT_NONE
Definition fc_types.h:340
@ AUT_AUTO_SETTLER
Definition fc_types.h:340
int action_id
Definition fc_types.h:359
#define EC_NONE
Definition fc_types.h:967
#define ERM_NONE
Definition fc_types.h:992
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct city * owner
Definition citydlg.c:219
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_FOG
Definition handicaps.h:26
adv_want adv_city_worker_act_get(const struct city *pcity, int city_tile_index, enum unit_activity act_id)
Definition infracache.c:359
int adv_city_worker_extra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Definition infracache.c:429
void initialize_infrastructure_cache(struct player *pplayer)
Definition infracache.c:250
int adv_city_worker_rmextra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Definition infracache.c:446
adv_want city_tile_value(const struct city *pcity, const struct tile *ptile, int foodneed, int prodneed)
Definition infracache.c:302
#define fc_assert_ret(condition)
Definition log.h:191
#define log_warn(message,...)
Definition log.h:105
#define log_verbose(message,...)
Definition log.h:109
#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
struct tile * map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
Definition map.c:417
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
struct terrain_misc terrain_control
Definition map.c:69
#define current_topo_has_flag(flag)
Definition map.h:45
#define MAP_INDEX_SIZE
Definition map.h:131
#define whole_map_iterate(_map, _tile)
Definition map.h:539
#define whole_map_iterate_end
Definition map.h:548
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:227
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define SINGLE_MOVE
Definition movement.h:24
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:137
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
const struct pf_position * pf_path_last_position(const struct pf_path *path)
void pf_path_destroy(struct pf_path *path)
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
struct pf_path * pf_map_path(struct pf_map *pfm, struct tile *ptile)
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
void pf_map_destroy(struct pf_map *pfm)
tile_behavior
@ TB_NORMAL
@ TB_IGNORE
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:840
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
#define is_ai(plr)
Definition player.h:234
struct extra_type * road_extra_get(const struct road_type *proad)
Definition road.c:42
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:499
#define road_deps_iterate(_reqs, _dep)
Definition road.h:159
#define road_deps_iterate_end
Definition road.h:168
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
static int recursion[AIT_LAST]
Definition srv_log.c:44
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
#define LOG_AI_TEST
Definition srv_log.h:38
@ AIT_WORKERS
Definition srv_log.h:45
@ 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 action_result result
Definition actions.h:382
Definition city.h:309
struct packet_game_info info
Definition game.h:89
struct requirement_vector reqs
Definition extras.h:102
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
const struct player * owner
int warmth
Definition player.h:127
int frost
Definition player.h:127
struct city_list * cities
Definition player.h:281
struct player_ai ai_common
Definition player.h:288
struct unit_list * units
Definition player.h:282
int move_cost
Definition road.h:78
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
Definition timing.c:81
enum adv_unit_task task
Definition unit.h:89
bool worker
Definition unittype.h:556
Definition unit.h:138
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
bool debug
Definition unit.h:231
struct extra_type * activity_target
Definition unit.h:164
struct unit_adv * adv
Definition unit.h:233
struct unit::@80::@83 server
struct tile * goto_tile
Definition unit.h:155
enum server_side_agent ssa_controller
Definition unit.h:172
enum unit_activity act
Definition workertask.h:23
struct tile * ptile
Definition workertask.h:22
struct extra_type * tgt
Definition workertask.h:24
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
int terrain_extra_build_time(const struct terrain *pterrain, enum unit_activity activity, const struct extra_type *tgt)
Definition terrain.c:682
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:829
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:87
#define tile_worked(_tile)
Definition tile.h:113
known_type
Definition tile.h:34
#define tile_terrain(_tile)
Definition tile.h:109
#define TILE_XY(ptile)
Definition tile.h:42
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
#define tile_owner(_tile)
Definition tile.h:95
bool timer_in_use(struct timer *t)
Definition timing.c:202
void timer_destroy(struct timer *t)
Definition timing.c:191
void timer_start(struct timer *t)
Definition timing.c:224
double timer_read_seconds(struct timer *t)
Definition timing.c:344
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use)
Definition timing.c:176
#define TIMER_DEBUG
Definition timing.h:59
@ TIMER_CPU
Definition timing.h:40
static int best_value(const void *a, const void *b)
int get_turns_for_activity_at(const struct unit *punit, enum unit_activity activity, const struct tile *ptile, struct extra_type *tgt)
Definition unit.c:521
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1108
bool is_military_unit(const struct unit *punit)
Definition unit.c:322
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2625
const char * get_activity_text(enum unit_activity activity)
Definition unit.c:625
bool is_square_threatened(const struct civ_map *nmap, const struct player *pplayer, const struct tile *ptile, bool omniscient)
Definition unit.c:360
bool unit_has_orders(const struct unit *punit)
Definition unit.c:207
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:541
#define unit_tile(_pu)
Definition unit.h:388
#define CHECK_UNIT(punit)
Definition unit.h:268
#define unit_owner(_pu)
Definition unit.h:387
#define unit_home(_pu_)
Definition unit.h:386
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6176
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Definition unithand.c:6243
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2798
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35