Freeciv-3.2: /fast/freeciv/nightly/S3_2/server/advisors/autosettlers.c Source File

Freeciv-3.2

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