Freeciv21
Develop your civilization from humble roots to a global empire
autosettlers.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // utility
15 #include "log.h"
16 #include "support.h"
17 #include "timing.h"
18 
19 // common
20 #include "ai.h"
21 #include "city.h"
22 #include "game.h"
23 #include "government.h"
24 #include "map.h"
25 #include "movement.h"
26 #include "nation.h"
27 #include "packets.h"
28 #include "unitlist.h"
29 #include "workertask.h"
30 
31 /* common/aicore */
32 #include "citymap.h"
33 #include "path_finding.h"
34 #include "pf_tools.h"
35 
36 // server
37 #include "citytools.h"
38 #include "maphand.h"
39 #include "srv_log.h"
40 #include "unithand.h"
41 #include "unittools.h"
42 
43 /* server/advisors */
44 #include "advbuilding.h"
45 #include "advdata.h"
46 #include "advgoto.h"
47 #include "advtools.h"
48 #include "infracache.h"
49 
50 // ai
51 #include "handicaps.h"
52 
53 #include "autosettlers.h"
54 
55 /* This factor is multiplied on when calculating the want. This is done
56  * to avoid rounding errors in comparisons when looking for the best
57  * possible work. However before returning the final want we have to
58  * divide by it again. This loses accuracy but is needed since the want
59  * values are used for comparison by the AI in trying to calculate the
60  * goodness of building worker units. */
61 #define WORKER_FACTOR 1024
62 
63 struct settlermap {
64  int enroute; // unit ID of settler en route to this tile
65  int eta; // estimated number of turns until enroute arrives
66 };
67 
71 
72 static civtimer *as_timer = nullptr;
73 
78 {
80  as_timer = nullptr;
81 }
82 
87 {
88  int i;
89 
90  i = 0;
94  ACTRES_TRANSFORM_TERRAIN);
96 
97  i = 0;
98  action_list_add_all_by_result(as_actions_extra, &i, ACTRES_IRRIGATE);
103 
104  i = 0;
106  ACTRES_CLEAN_POLLUTION);
108  ACTRES_CLEAN_FALLOUT);
109  // We could have ACTRES_PILLAGE here, but currently we don't
111 }
112 
119 adv_want adv_settlers_road_bonus(struct tile *ptile, struct road_type *proad)
120 {
121 #define MAX_DEP_ROADS 5
122 
123  int bonus = 0, i;
124  bool potential_road[12], real_road[12], is_slow[12];
125  int dx[12] = {-1, 0, 1, -1, 1, -1, 0, 1, 0, -2, 2, 0};
126  int dy[12] = {-1, -1, -1, 0, 0, 1, 1, 1, -2, 0, 0, 2};
127  int x, y;
128  int rnbr;
129  struct road_type *pdep_roads[MAX_DEP_ROADS];
130  int dep_rnbr[MAX_DEP_ROADS];
131  int dep_count = 0;
132  struct extra_type *pextra;
133 
134  if (proad == nullptr) {
135  return 0;
136  }
137 
138  rnbr = road_number(proad);
139  pextra = road_extra_get(proad);
140 
141  road_deps_iterate(&(pextra->reqs), pdep)
142  {
143  if (dep_count < MAX_DEP_ROADS) {
144  pdep_roads[dep_count] = pdep;
145  dep_rnbr[dep_count++] = road_number(pdep);
146  }
147  }
149 
150  index_to_map_pos(&x, &y, tile_index(ptile));
151  for (i = 0; i < 12; i++) {
152  struct tile *tile1 = map_pos_to_tile(&(wld.map), x + dx[i], y + dy[i]);
153 
154  if (!tile1) {
155  real_road[i] = false;
156  potential_road[i] = false;
157  is_slow[i] = false; // FIXME: should be TRUE?
158  } else {
159  int build_time = terrain_extra_build_time(tile_terrain(tile1),
160  ACTIVITY_GEN_ROAD, pextra);
161  int j;
162 
163  real_road[i] = tile_has_road(tile1, proad);
164  potential_road[i] = real_road[i];
165  for (j = 0; !potential_road[i] && j < dep_count; j++) {
166  potential_road[i] = tile_has_road(tile1, pdep_roads[j]);
167  }
168 
169  /* If TRUE, this value indicates that this tile does not need
170  * a road connector. This is set for terrains which cannot have
171  * road or where road takes "too long" to build. */
172  is_slow[i] = (build_time == 0 || build_time > 5);
173 
174  if (!real_road[i]) {
175  unit_list_iterate(tile1->units, punit)
176  {
177  if (punit->activity == ACTIVITY_GEN_ROAD) {
178  /* If a road, or its dependency is being built here, consider as
179  * if it's already built. */
180  int build_rnbr;
181 
182  fc_assert(punit->activity_target != nullptr);
183 
184  build_rnbr = road_number(extra_road_get(punit->activity_target));
185 
186  if (build_rnbr == rnbr) {
187  real_road[i] = true;
188  potential_road[i] = true;
189  }
190  for (j = 0; !potential_road[i] && j < dep_count; j++) {
191  if (build_rnbr == dep_rnbr[j]) {
192  potential_road[i] = true;
193  }
194  }
195  }
196  }
198  }
199  }
200  }
201 
202  if (current_topo_has_flag(TF_HEX)) {
203  // On hex map, road is always a benefit
204  bonus += 20; // Later divided by 20
205 
206  // Road is more valuable when even longer road around does not exist.
207  for (i = 0; i < 12; i++) {
208  if (!real_road[i]) {
209  bonus += 3;
210  }
211  }
212 
213  // Scale down the bonus.
214  bonus /= 20;
215  } else {
216  /*
217  * Consider the following tile arrangement (numbered in hex):
218  *
219  * 8
220  * 012
221  * 93 4A
222  * 567
223  * B
224  *
225  * these are the tiles defined by the (dx,dy) arrays above.
226  *
227  * Then the following algorithm is supposed to determine if it's a good
228  * idea to build a road here. Note this won't work well for hex maps
229  * since the (dx,dy) arrays will not cover the same tiles.
230  *
231  * FIXME: if you can understand the algorithm below please rewrite this
232  * explanation!
233  */
234  if (potential_road[0] && !real_road[1] && !real_road[3]
235  && (!real_road[2] || !real_road[8])
236  && (!is_slow[2] || !is_slow[4] || !is_slow[7] || !is_slow[6]
237  || !is_slow[5])) {
238  bonus++;
239  }
240  if (potential_road[2] && !real_road[1] && !real_road[4]
241  && (!real_road[7] || !real_road[10])
242  && (!is_slow[0] || !is_slow[3] || !is_slow[7] || !is_slow[6]
243  || !is_slow[5])) {
244  bonus++;
245  }
246  if (potential_road[5] && !real_road[6] && !real_road[3]
247  && (!real_road[5] || !real_road[11])
248  && (!is_slow[2] || !is_slow[4] || !is_slow[7] || !is_slow[1]
249  || !is_slow[0])) {
250  bonus++;
251  }
252  if (potential_road[7] && !real_road[6] && !real_road[4]
253  && (!real_road[0] || !real_road[9])
254  && (!is_slow[2] || !is_slow[3] || !is_slow[0] || !is_slow[1]
255  || !is_slow[5])) {
256  bonus++;
257  }
258 
259  /* A
260  * B*B
261  * CCC
262  *
263  * We are at tile *. If tile A has a road, and neither B tile does, and
264  * one C tile is a valid destination, then we might want a road here.
265  *
266  * Of course the same logic applies if you rotate the diagram.
267  */
268  if (potential_road[1] && !real_road[4] && !real_road[3]
269  && (!is_slow[5] || !is_slow[6] || !is_slow[7])) {
270  bonus++;
271  }
272  if (potential_road[3] && !real_road[1] && !real_road[6]
273  && (!is_slow[2] || !is_slow[4] || !is_slow[7])) {
274  bonus++;
275  }
276  if (potential_road[4] && !real_road[1] && !real_road[6]
277  && (!is_slow[0] || !is_slow[3] || !is_slow[5])) {
278  bonus++;
279  }
280  if (potential_road[6] && !real_road[4] && !real_road[3]
281  && (!is_slow[0] || !is_slow[1] || !is_slow[2])) {
282  bonus++;
283  }
284  }
285 
286  return bonus;
287 }
288 
296  const struct player *pplayer, enum unit_activity act,
297  struct extra_type *target, adv_want extra, int new_tile_value,
298  int old_tile_value, bool in_use, int delay, adv_want *best_value,
299  int *best_old_tile_value, int *best_extra, bool *improve_worked,
300  int *best_delay, enum unit_activity *best_act,
301  struct extra_type **best_target, struct tile **best_tile,
302  struct tile *ptile)
303 {
304  bool improves;
305  int total_value = 0, base_value = 0;
306  int old_improvement_value;
307 
308  fc_assert(act != ACTIVITY_LAST);
309 
310  if (extra < 0) {
311  extra = 0;
312  }
313 
314  if (new_tile_value > old_tile_value) {
315  improves = true;
316  } else if (new_tile_value == old_tile_value && extra > 0) {
317  improves = true;
318  } else {
319  improves = false;
320  }
321 
322  // find the present value of the future benefit of this action
323  if (improves || extra > 0) {
324  if (!(*improve_worked) && !in_use) {
325  /* Going to improve tile that is not yet in use.
326  * Getting the best possible total for next citizen to work on is more
327  * important than amount tile gets improved. */
328  if (improves
329  && (new_tile_value > *best_value
330  || (new_tile_value == *best_value
331  && old_tile_value < *best_old_tile_value))) {
332  *best_value = new_tile_value;
333  *best_old_tile_value = old_tile_value;
334  *best_extra = extra;
335  *best_act = act;
336  *best_target = target;
337  *best_tile = ptile;
338  *best_delay = delay;
339  }
340 
341  return;
342  }
343 
344  /* At least one of the previous best or current tile is in use
345  * Prefer the tile that gets improved more, regarless of the resulting
346  * total */
347 
348  base_value = new_tile_value - old_tile_value;
349  total_value = base_value * WORKER_FACTOR;
350  if (!in_use) {
351  total_value /= 2;
352  }
353  total_value += extra * WORKER_FACTOR;
354 
355  // use factor to prevent rounding errors
356  total_value = amortize(total_value, delay);
357 
358  if (*improve_worked) {
359  old_improvement_value = *best_value;
360  } else {
361  /* Convert old best_value to improvement value compatible with in_use
362  * tile value */
363  old_improvement_value =
364  amortize((*best_value - *best_old_tile_value) * WORKER_FACTOR / 2,
365  *best_delay);
366  }
367 
368  if (total_value > old_improvement_value
369  || (total_value == old_improvement_value
370  && old_tile_value > *best_old_tile_value)) {
371  if (in_use) {
372  *best_value = total_value;
373  *improve_worked = true;
374  } else {
375  *best_value = new_tile_value;
376  *improve_worked = false;
377  }
378  *best_old_tile_value = old_tile_value;
379  *best_extra = extra;
380  *best_act = act;
381  *best_target = target;
382  *best_tile = ptile;
383  *best_delay = delay;
384  }
385  }
386 }
387 
391 static enum tile_behavior
392 autosettler_tile_behavior(const struct tile *ptile, enum known_type known,
393  const struct pf_parameter *param)
394 {
395  const struct player *owner = tile_owner(ptile);
396 
397  if (nullptr != owner && !pplayers_allied(owner, param->owner)) {
398  return TB_IGNORE;
399  }
400  return TB_NORMAL;
401 }
402 
421  enum unit_activity *best_act,
422  struct extra_type **best_target,
423  struct tile **best_tile, PFPath *path,
424  struct settlermap *state)
425 {
426  const struct player *pplayer = unit_owner(punit);
427  struct pf_parameter parameter;
428  struct pf_map *pfm;
429  struct pf_position pos;
430  int oldv; // Current value of consideration tile.
431  int best_oldv = 9999; /* oldv of best target so far; compared if
432  * newv == best_newv; not initialized to zero,
433  * so that newv = 0 activities are not chosen. */
434  adv_want best_newv = 0;
435  bool improve_worked = false;
436  int best_extra = 0;
437  int best_delay = 0;
438 
439  // closest worker, if any, headed towards target tile
440  struct unit *enroute = nullptr;
441 
442  pft_fill_unit_parameter(&parameter, punit);
443  parameter.omniscience = !has_handicap(pplayer, H_MAP);
444  parameter.get_TB = autosettler_tile_behavior;
445  pfm = pf_map_new(&parameter);
446 
447  city_list_iterate(pplayer->cities, pcity)
448  {
449  struct tile *pcenter = city_tile(pcity);
450 
451  // try to work near the city
452  city_tile_iterate_index(city_map_radius_sq_get(pcity), pcenter, ptile,
453  cindex)
454  {
455  bool consider = true;
456  bool in_use = (tile_worked(ptile) == pcity);
457 
458  if (!in_use && !city_can_work_tile(pcity, ptile)) {
459  // Don't risk bothering with this tile.
460  continue;
461  }
462 
463  if (!adv_settler_safe_tile(pplayer, punit, ptile)) {
464  // Too dangerous place
465  continue;
466  }
467 
468  // Do not go to tiles that already have workers there.
469  unit_list_iterate(ptile->units, aunit)
470  {
471  if (unit_owner(aunit) == pplayer && aunit->id != punit->id
472  && unit_has_type_flag(aunit, UTYF_SETTLERS)) {
473  consider = false;
474  }
475  }
477 
478  if (!consider) {
479  continue;
480  }
481 
482  if (state) {
483  enroute =
484  player_unit_by_number(pplayer, state[tile_index(ptile)].enroute);
485  }
486 
487  if (pf_map_position(pfm, ptile, &pos)) {
488  int eta = FC_INFINITY, inbound_distance = FC_INFINITY, turns;
489 
490  if (enroute) {
491  eta = state[tile_index(ptile)].eta;
492  inbound_distance = real_map_distance(ptile, unit_tile(enroute));
493  }
494 
495  /* Only consider this tile if we are closer in time and space to
496  * it than our other worker (if any) travelling to the site. */
497  if ((enroute && enroute->id == punit->id) || pos.turn < eta
498  || (pos.turn == eta
499  && (real_map_distance(ptile, unit_tile(punit))
500  < inbound_distance))) {
501  if (enroute) {
502  UNIT_LOG(LOG_DEBUG, punit,
503  "Considering (%d, %d) because we're closer "
504  "(%d, %d) than %d (%d, %d)",
505  TILE_XY(ptile), pos.turn,
506  real_map_distance(ptile, unit_tile(punit)), enroute->id,
507  eta, inbound_distance);
508  }
509 
510  oldv = city_tile_value(pcity, ptile, 0, 0);
511 
512  // Now, consider various activities...
514  {
515  struct extra_type *target = nullptr;
516  enum extra_cause cause =
518  enum extra_rmcause rmcause =
520 
521  if (cause != EC_NONE) {
522  target = next_extra_for_tile(ptile, cause, pplayer, punit);
523  } else if (rmcause != ERM_NONE) {
524  target = prev_extra_in_tile(ptile, rmcause, pplayer, punit);
525  }
526 
527  if (adv_city_worker_act_get(pcity, cindex,
529  >= 0
531  act, punit, unit_home(punit), ptile,
532  parameter.omniscience, ptile, target))) {
533  int base_value = adv_city_worker_act_get(
534  pcity, cindex, action_id_get_activity(act));
535 
536  turns = pos.turn
538  punit, action_id_get_activity(act), ptile, target);
539  if (pos.moves_left == 0) {
540  // We need moves left to begin activity immediately.
541  turns++;
542  }
543 
545  pplayer, action_id_get_activity(act), target, 0.0,
546  base_value, oldv, in_use, turns, &best_newv, &best_oldv,
547  &best_extra, &improve_worked, &best_delay, best_act,
548  best_target, best_tile, ptile);
549  } // endif: can the worker perform this action
550  }
552 
553  extra_type_iterate(pextra)
554  {
555  enum unit_activity act = ACTIVITY_LAST;
556  enum unit_activity eval_act = ACTIVITY_LAST;
557  int base_value;
558  bool removing = tile_has_extra(ptile, pextra);
559 
560  if (removing) {
562  {
563  struct action *taction = action_by_number(try_act);
564  if (is_extra_removed_by_action(pextra, taction)) {
565  /* We do not even evaluate actions we can't do.
566  * Removal is not considered prerequisite for anything */
568  try_act, punit, unit_home(punit), ptile,
569  parameter.omniscience, ptile, pextra))) {
570  act = action_get_activity(taction);
571  eval_act = action_get_activity(taction);
572  break;
573  }
574  }
575  }
577  } else {
578  as_extra_action_iterate(try_act)
579  {
580  struct action *taction = action_by_number(try_act);
581  if (is_extra_caused_by_action(pextra, taction)) {
582  eval_act = action_id_get_activity(try_act);
584  try_act, punit, unit_home(punit), ptile,
585  parameter.omniscience, ptile, pextra))) {
586  act = action_get_activity(taction);
587  break;
588  }
589  }
590  }
592  }
593 
594  if (eval_act == ACTIVITY_LAST) {
595  // No activity can provide (or remove) the extra
596  continue;
597  }
598 
599  if (removing) {
600  base_value =
601  adv_city_worker_rmextra_get(pcity, cindex, pextra);
602  } else {
603  base_value = adv_city_worker_extra_get(pcity, cindex, pextra);
604  }
605 
606  if (base_value >= 0) {
607  adv_want extra;
608  struct road_type *proad;
609 
610  turns = pos.turn
611  + get_turns_for_activity_at(punit, eval_act, ptile,
612  pextra);
613  if (pos.moves_left == 0) {
614  // We need moves left to begin activity immediately.
615  turns++;
616  }
617 
618  proad = extra_road_get(pextra);
619 
620  if (proad != nullptr && road_provides_move_bonus(proad)) {
621  int mc_multiplier = 1;
622  int mc_divisor = 1;
623  int old_move_cost =
624  tile_terrain(ptile)->movement_cost * SINGLE_MOVE;
625 
626  /* Here 'old' means actually 'without the evaluated': In case
627  * of removal activity it's the value after the removal. */
628 
629  extra_type_by_cause_iterate(EC_ROAD, pold)
630  {
631  if (tile_has_extra(ptile, pold) && pold != pextra) {
632  struct road_type *po_road = extra_road_get(pold);
633 
634  /* This ignores the fact that new road may be native to
635  * units that old road is not. */
636  if (po_road->move_cost < old_move_cost) {
637  old_move_cost = po_road->move_cost;
638  }
639  }
640  }
642 
643  if (proad->move_cost < old_move_cost) {
644  if (proad->move_cost >= terrain_control.move_fragments) {
645  mc_divisor =
646  proad->move_cost / terrain_control.move_fragments;
647  } else {
648  if (proad->move_cost == 0) {
649  mc_multiplier = 2;
650  } else {
651  mc_multiplier = 1 - proad->move_cost;
652  }
653  mc_multiplier += old_move_cost;
654  }
655  }
656 
657  extra = adv_settlers_road_bonus(ptile, proad) * mc_multiplier
658  / mc_divisor;
659 
660  } else {
661  extra = 0;
662  }
663 
664  if (extra_has_flag(pextra, EF_GLOBAL_WARMING)) {
665  extra -= pplayer->ai_common.warmth;
666  }
667  if (extra_has_flag(pextra, EF_NUCLEAR_WINTER)) {
668  extra -= pplayer->ai_common.frost;
669  }
670 
671  if (removing) {
672  extra = -extra;
673  }
674 
675  if (act != ACTIVITY_LAST) {
677  pplayer, act, pextra, extra, base_value, oldv, in_use,
678  turns, &best_newv, &best_oldv, &best_extra,
679  &improve_worked, &best_delay, best_act, best_target,
680  best_tile, ptile);
681  } else {
682  fc_assert(!removing);
683 
684  road_deps_iterate(&(pextra->reqs), pdep)
685  {
686  struct extra_type *dep_tgt;
687 
688  dep_tgt = road_extra_get(pdep);
689 
691  ACTION_ROAD, punit, unit_home(punit), ptile,
692  parameter.omniscience, ptile, dep_tgt))) {
693  /* Consider building dependency road for later upgrade to
694  * target extra. Here we set value to be sum of
695  * dependency road and target extra values, which
696  * increases want, and turns is sum of dependency and
697  * target build turns, which decreases want. This can
698  * result in either bigger or lesser want than when
699  * checkin dependency road for the sake of itself when
700  * its turn in extra_type_iterate() is. */
701  int dep_turns =
702  turns
703  + get_turns_for_activity_at(punit, ACTIVITY_GEN_ROAD,
704  ptile, dep_tgt);
705  int dep_value =
706  base_value
707  + adv_city_worker_extra_get(pcity, cindex, dep_tgt);
708 
710  pplayer, ACTIVITY_GEN_ROAD, dep_tgt, extra,
711  dep_value, oldv, in_use, dep_turns, &best_newv,
712  &best_oldv, &best_extra, &improve_worked,
713  &best_delay, best_act, best_target, best_tile,
714  ptile);
715  }
716  }
718 
719  base_deps_iterate(&(pextra->reqs), pdep)
720  {
721  struct extra_type *dep_tgt;
722 
723  dep_tgt = base_extra_get(pdep);
725  ACTION_BASE, punit, unit_home(punit), ptile,
726  parameter.omniscience, ptile, dep_tgt))) {
727  /* Consider building dependency base for later upgrade to
728  * target extra. See similar road implementation above
729  * for extended commentary. */
730  int dep_turns =
731  turns
732  + get_turns_for_activity_at(punit, ACTIVITY_BASE,
733  ptile, dep_tgt);
734  int dep_value =
735  base_value
736  + adv_city_worker_extra_get(pcity, cindex, dep_tgt);
737 
739  pplayer, ACTIVITY_BASE, dep_tgt, 0.0, dep_value,
740  oldv, in_use, dep_turns, &best_newv, &best_oldv,
741  &best_extra, &improve_worked, &best_delay, best_act,
742  best_target, best_tile, ptile);
743  }
744  }
746  }
747  }
748  }
750  } // endif: can we arrive sooner than current worker, if any?
751  } // endif: are we travelling to a legal destination?
752  }
754  }
756 
757  if (!improve_worked) {
758  /* best_newv contains total value of improved tile. Check amount of
759  * improvement instead. */
760  best_newv = amortize(
761  (best_newv - best_oldv + best_extra) * WORKER_FACTOR, best_delay);
762  }
763  best_newv /= WORKER_FACTOR;
764 
765  best_newv = MAX(best_newv, 0); // sanity
766 
767  if (best_newv > 0) {
768  log_debug("Settler %d@(%d,%d) wants to %s at (%d,%d) with "
769  "desire " ADV_WANT_PRINTF,
770  punit->id, TILE_XY(unit_tile(punit)),
771  get_activity_text(*best_act), TILE_XY(*best_tile), best_newv);
772  } else {
773  /* Fill in dummy values. The callers should check if the return value
774  * is > 0 but this will avoid confusing them. */
775  *best_act = ACTIVITY_IDLE;
776  *best_tile = nullptr;
777  }
778 
779  if (path) {
780  *path = *best_tile ? pf_map_path(pfm, *best_tile) : PFPath();
781  }
782 
783  pf_map_destroy(pfm);
784 
785  return best_newv;
786 }
787 
792  struct worker_task **best_task,
793  PFPath *path,
794  struct settlermap *state)
795 {
796  const struct player *pplayer = unit_owner(punit);
797  struct pf_parameter parameter;
798  struct pf_map *pfm;
799  struct pf_position pos;
800  int best_value = -1;
801  struct worker_task *best = nullptr;
802  struct city *taskcity = nullptr;
803  int dist = FC_INFINITY;
804 
805  pft_fill_unit_parameter(&parameter, punit);
806  parameter.omniscience = !has_handicap(pplayer, H_MAP);
807  parameter.get_TB = autosettler_tile_behavior;
808  pfm = pf_map_new(&parameter);
809 
810  // Have nearby cities requests?
811  city_list_iterate(pplayer->cities, pcity)
812  {
813  worker_task_list_iterate(pcity->task_reqs, ptask)
814  {
815  bool consider = true;
816 
817  // Do not go to tiles that already have workers there.
818  unit_list_iterate(ptask->ptile->units, aunit)
819  {
820  if (unit_owner(aunit) == pplayer && aunit->id != punit->id
821  && unit_has_type_flag(aunit, UTYF_SETTLERS)) {
822  consider = false;
823  }
824  }
826 
827  if (consider
828  && auto_settlers_speculate_can_act_at(punit, ptask->act,
829  parameter.omniscience,
830  ptask->tgt, ptask->ptile)) {
831  // closest worker, if any, headed towards target tile
832  struct unit *enroute = nullptr;
833 
834  if (state) {
835  enroute = player_unit_by_number(
836  pplayer, state[tile_index(ptask->ptile)].enroute);
837  }
838 
839  if (pf_map_position(pfm, ptask->ptile, &pos)) {
840  int value = (ptask->want + 1) * 10 / (pos.turn + 1);
841 
842  if (value > best_value) {
843  int eta = FC_INFINITY, inbound_distance = FC_INFINITY;
844 
845  if (enroute) {
846  eta = state[tile_index(ptask->ptile)].eta;
847  inbound_distance =
848  real_map_distance(ptask->ptile, unit_tile(enroute));
849  }
850 
851  /* Only consider this tile if we are closer in time and space to
852  * it than our other worker (if any) travelling to the site. */
853  if (pos.turn < dist
854  && ((enroute && enroute->id == punit->id) || pos.turn < eta
855  || (pos.turn == eta
856  && (real_map_distance(ptask->ptile, unit_tile(punit))
857  < inbound_distance)))) {
858  dist = pos.turn;
859  best = ptask;
860  best_value = value;
861  taskcity = pcity;
862  }
863  }
864  }
865  }
866  }
868  }
870 
871  *best_task = best;
872 
873  if (!path->empty()) {
874  *path = best ? pf_map_path(pfm, best->ptile) : PFPath();
875  }
876 
877  pf_map_destroy(pfm);
878 
879  return taskcity;
880 }
881 
885 void auto_settler_findwork(struct player *pplayer, struct unit *punit,
886  struct settlermap *state, int recursion)
887 {
888  struct worker_task *best_task;
889  enum unit_activity best_act;
890  struct tile *best_tile = nullptr;
891  struct extra_type *best_target;
892  PFPath path;
893  struct city *taskcity;
894 
895  // time it will take worker to complete its given task
896  int completion_time = 0;
897 
898  if (recursion > unit_list_size(pplayer->units)) {
899  fc_assert(recursion <= unit_list_size(pplayer->units));
900  adv_unit_new_task(punit, AUT_NONE, nullptr);
901  set_unit_activity(punit, ACTIVITY_IDLE);
902  send_unit_info(nullptr, punit);
903  return; // avoid further recursion.
904  }
905 
906  CHECK_UNIT(punit);
907 
908  fc_assert_ret(pplayer && punit);
910  || unit_has_type_flag(punit, UTYF_SETTLERS));
911 
912  // Have nearby cities requests?
913 
914  taskcity = settler_evaluate_city_requests(punit, &best_task, &path, state);
915 
916  if (taskcity != nullptr) {
917  if (!path.empty()) {
918  completion_time = path[-1].turn;
919  }
920 
921  adv_unit_new_task(punit, AUT_AUTO_SETTLER, best_tile);
922 
923  best_target = best_task->tgt;
924 
925  if (auto_settler_setup_work(pplayer, punit, state, recursion, &path,
926  best_task->ptile, best_task->act,
927  &best_target, completion_time)) {
928  clear_worker_task(taskcity, best_task);
929  }
930 
931  return;
932  }
933 
934  /*** Try find some work ***/
935 
936  if (unit_has_type_flag(punit, UTYF_SETTLERS)) {
938  settler_evaluate_improvements(punit, &best_act, &best_target, &best_tile,
939  &path, state);
940  if (!path.empty()) {
941  completion_time = path[-1].turn;
942  }
944 
945  adv_unit_new_task(punit, AUT_AUTO_SETTLER, best_tile);
946 
947  auto_settler_setup_work(pplayer, punit, state, recursion, &path,
948  best_tile, best_act, &best_target,
949  completion_time);
950  }
951 }
952 
957 bool auto_settler_setup_work(struct player *pplayer, struct unit *punit,
958  struct settlermap *state, int recursion,
959  PFPath *path, struct tile *best_tile,
960  enum unit_activity best_act,
961  struct extra_type **best_target,
962  int completion_time)
963 {
964  // Run the "autosettler" program
965  if (punit->server.adv->task == AUT_AUTO_SETTLER) {
966  struct pf_map *pfm = nullptr;
967  struct pf_parameter parameter;
968  bool working = false;
969  struct unit *displaced;
970 
971  if (!best_tile) {
972  UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
973  return false; // We cannot do anything
974  }
975 
976  // Mark the square as taken.
977  displaced =
978  player_unit_by_number(pplayer, state[tile_index(best_tile)].enroute);
979 
980  if (displaced) {
981  fc_assert(state[tile_index(best_tile)].enroute == displaced->id);
982  fc_assert(
983  state[tile_index(best_tile)].eta > completion_time
984  || (state[tile_index(best_tile)].eta == completion_time
985  && (real_map_distance(best_tile, unit_tile(punit))
986  < real_map_distance(best_tile, unit_tile(displaced)))));
987  UNIT_LOG(displaced->server.debug ? LOG_AI_TEST : LOG_DEBUG, punit,
988  "%d (%d,%d) has displaced %d (%d,%d) for worksite %d,%d",
989  punit->id, completion_time,
990  real_map_distance(best_tile, unit_tile(punit)), displaced->id,
991  state[tile_index(best_tile)].eta,
992  real_map_distance(best_tile, unit_tile(displaced)),
993  TILE_XY(best_tile));
994  }
995 
996  state[tile_index(best_tile)].enroute = punit->id;
997  state[tile_index(best_tile)].eta = completion_time;
998 
999  if (displaced) {
1000  struct tile *goto_tile = punit->goto_tile;
1001  int saved_id = punit->id;
1002  struct tile *old_pos = unit_tile(punit);
1003 
1004  displaced->goto_tile = nullptr;
1005  auto_settler_findwork(pplayer, displaced, state, recursion + 1);
1006  if (nullptr == player_unit_by_number(pplayer, saved_id)) {
1007  /* Actions of the displaced settler somehow caused this settler
1008  * to die. (maybe by recursively giving control back to this unit)
1009  */
1010  return false;
1011  }
1012  if (goto_tile != punit->goto_tile || old_pos != unit_tile(punit)
1013  || punit->activity != ACTIVITY_IDLE) {
1014  /* Actions of the displaced settler somehow caused this settler
1015  * to get a new job, or to already move toward current job.
1016  * (A displaced B, B displaced C, C displaced A)
1017  */
1018  UNIT_LOG(LOG_DEBUG, punit,
1019  "%d itself acted due to displacement recursion. "
1020  "Was going from (%d, %d) to (%d, %d). "
1021  "Now heading from (%d, %d) to (%d, %d).",
1022  punit->id, TILE_XY(old_pos), TILE_XY(goto_tile),
1023  TILE_XY(unit_tile(punit)), TILE_XY(punit->goto_tile));
1024  return false;
1025  }
1026  }
1027 
1028  UNIT_LOG(LOG_DEBUG, punit, "is heading to do %s(%s) at (%d, %d)",
1029  unit_activity_name(best_act),
1030  best_target && *best_target ? extra_rule_name(*best_target)
1031  : "-",
1032  TILE_XY(best_tile));
1033 
1034  if (!path->empty()) {
1035  pft_fill_unit_parameter(&parameter, punit);
1036  parameter.omniscience = !has_handicap(pplayer, H_MAP);
1037  parameter.get_TB = autosettler_tile_behavior;
1038  pfm = pf_map_new(&parameter);
1039  *path = pf_map_path(pfm, best_tile);
1040  }
1041 
1042  if (!path->empty()) {
1043  bool alive;
1044 
1045  alive = adv_follow_path(punit, *path, best_tile);
1046  *path = PFPath(); // Done moving have an empty path
1047  if (alive && same_pos(unit_tile(punit), best_tile)
1048  && punit->moves_left > 0) {
1049  // Reached destination and can start working immediately
1050  if (activity_requires_target(best_act)) {
1051  unit_activity_handling_targeted(punit, best_act, best_target);
1052  } else {
1053  unit_activity_handling(punit, best_act);
1054  }
1055  send_unit_info(nullptr, punit); // FIXME: probably duplicate
1056 
1057  UNIT_LOG(LOG_DEBUG, punit, "reached its worksite and started work");
1058  working = true;
1059  } else if (alive) {
1060  UNIT_LOG(LOG_DEBUG, punit,
1061  "didn't start work yet; got to (%d, %d) with "
1062  "%d move frags left",
1063  TILE_XY(unit_tile(punit)), punit->moves_left);
1064  }
1065  } else {
1066  UNIT_LOG(LOG_DEBUG, punit, "does not find path (%d, %d) -> (%d, %d)",
1067  TILE_XY(unit_tile(punit)), TILE_XY(best_tile));
1068  }
1069 
1070  if (pfm) {
1071  pf_map_destroy(pfm);
1072  }
1073 
1074  return working;
1075  }
1076 
1077  return false;
1078 }
1079 #undef LOG_SETTLER
1080 
1084 bool adv_settler_safe_tile(const struct player *pplayer, struct unit *punit,
1085  struct tile *ptile)
1086 {
1087  unit_list_iterate(ptile->units, defender)
1088  {
1089  if (is_military_unit(defender)) {
1090  return true;
1091  }
1092  }
1094 
1095  return !is_square_threatened(pplayer, ptile,
1096  !has_handicap(pplayer, H_FOG));
1097 }
1098 
1103 void auto_settlers_player(struct player *pplayer)
1104 {
1105  struct settlermap *state;
1106 
1107  state = new settlermap[MAP_INDEX_SIZE]();
1108 
1111 
1112  if (is_ai(pplayer)) {
1113  // Set up our city map.
1114  citymap_turn_init(pplayer);
1115  }
1116 
1117  whole_map_iterate(&(wld.map), ptile)
1118  {
1119  state[tile_index(ptile)].enroute = -1;
1120  state[tile_index(ptile)].eta = FC_INFINITY;
1121  }
1123 
1124  // Initialize the infrastructure cache, which is used shortly.
1126 
1127  /* An extra consideration for the benefit of cleaning up pollution/fallout.
1128  * This depends heavily on the calculations in update_environmental_upset.
1129  * Aside from that it's more or less a WAG that simply grows incredibly
1130  * large as an environmental disaster approaches. */
1131  pplayer->ai_common.warmth = (WARMING_FACTOR * game.info.heating
1132  / ((game.info.warminglevel + 1) / 2)
1133  + game.info.globalwarming);
1134  pplayer->ai_common.frost = (COOLING_FACTOR * game.info.cooling
1135  / ((game.info.coolinglevel + 1) / 2)
1136  + game.info.nuclearwinter);
1137 
1138  log_debug("Warmth = %d, game.globalwarming=%d", pplayer->ai_common.warmth,
1139  game.info.globalwarming);
1140  log_debug("Frost = %d, game.nuclearwinter=%d", pplayer->ai_common.frost,
1141  game.info.nuclearwinter);
1142 
1143  /* Auto-settle with a settler unit if it's under AI control (e.g. human
1144  * player auto-settler mode) or if the player is an AI. But don't
1145  * auto-settle with a unit under orders even for an AI player - these come
1146  * from the human player and take precedence. */
1147  unit_list_iterate_safe(pplayer->units, punit)
1148  {
1149  if ((punit->ssa_controller == SSA_AUTOSETTLER || is_ai(pplayer))
1150  && (unit_type_get(punit)->adv.worker || unit_is_cityfounder(punit))
1151  && !unit_has_orders(punit) && punit->moves_left > 0) {
1152  log_debug("%s %s at (%d, %d) is controlled by server side agent %s.",
1154  unit_rule_name(punit), TILE_XY(unit_tile(punit)),
1155  server_side_agent_name(SSA_AUTOSETTLER));
1156  if (punit->activity == ACTIVITY_SENTRY) {
1157  unit_activity_handling(punit, ACTIVITY_IDLE);
1158  }
1159  if (punit->activity == ACTIVITY_GOTO && punit->moves_left > 0) {
1160  unit_activity_handling(punit, ACTIVITY_IDLE);
1161  }
1162  if (punit->activity != ACTIVITY_IDLE) {
1163  if (!is_ai(pplayer)) {
1164  if (!adv_settler_safe_tile(pplayer, punit, unit_tile(punit))) {
1165  unit_activity_handling(punit, ACTIVITY_IDLE);
1166  }
1167  } else {
1168  CALL_PLR_AI_FUNC(settler_cont, pplayer, pplayer, punit, state);
1169  }
1170  }
1171  if (punit->activity == ACTIVITY_IDLE) {
1172  if (!is_ai(pplayer)) {
1173  auto_settler_findwork(pplayer, punit, state, 0);
1174  } else {
1175  CALL_PLR_AI_FUNC(settler_run, pplayer, pplayer, punit, state);
1176  }
1177  }
1178  }
1179  }
1181  // Reset auto settler state for the next run.
1182  if (is_ai(pplayer)) {
1183  CALL_PLR_AI_FUNC(settler_reset, pplayer, pplayer);
1184  }
1185 
1186  if (timer_in_use(as_timer)) {
1187  log_time(QStringLiteral("%1 autosettlers consumed %2 milliseconds.")
1188  .arg(nation_rule_name(nation_of_player(pplayer)))
1189  .arg(1000.0 * timer_read_seconds(as_timer)));
1190  }
1191 
1192  delete[] state;
1193 }
1194 
1198 void adv_unit_new_task(struct unit *punit, enum adv_unit_task task,
1199  struct tile *ptile)
1200 {
1201  if (punit->server.adv->task == task) {
1202  // Already that task
1203  return;
1204  }
1205 
1206  punit->server.adv->task = task;
1207 
1208  CALL_PLR_AI_FUNC(unit_task, unit_owner(punit), punit, task, ptile);
1209 }
1210 
1215 bool auto_settlers_speculate_can_act_at(const struct unit *punit,
1216  enum unit_activity activity,
1217  bool omniscient_cheat,
1218  struct extra_type *target,
1219  const struct tile *ptile)
1220 {
1221  struct action *paction = nullptr;
1222 
1223  action_iterate(act_id)
1224  {
1225  paction = action_by_number(act_id);
1226 
1227  if (action_get_actor_kind(paction) != AAK_UNIT) {
1228  // Not relevant.
1229  continue;
1230  }
1231 
1232  if (action_get_activity(paction) == activity) {
1233  // Found one
1234  break;
1235  }
1236  }
1238 
1239  if (paction == nullptr) {
1240  // The action it self isn't there. It can't be enabled.
1241  return false;
1242  }
1243 
1244  switch (action_get_target_kind(paction)) {
1245  case ATK_CITY:
1247  paction->id, punit, unit_home(punit), ptile, omniscient_cheat,
1248  tile_city(ptile)));
1249  case ATK_UNIT:
1250  fc_assert_ret_val(action_get_target_kind(paction) != ATK_UNIT, false);
1251  break;
1252  case ATK_UNITS:
1253  return action_prob_possible(
1254  action_speculate_unit_on_units(paction->id, punit, unit_home(punit),
1255  ptile, omniscient_cheat, ptile));
1256  case ATK_TILE:
1258  paction->id, punit, unit_home(punit), ptile, omniscient_cheat, ptile,
1259  target));
1260  case ATK_SELF:
1262  paction->id, punit, unit_home(punit), ptile, omniscient_cheat));
1263  case ATK_COUNT:
1264  fc_assert_ret_val(action_get_target_kind(paction) != ATK_COUNT, false);
1265  break;
1266  }
1267 
1268  fc_assert(false);
1269  return false;
1270 }
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Get the actor kind of an action.
Definition: actions.cpp:1188
bool action_prob_possible(const struct act_prob probability)
Returns TRUE iff the given action probability belongs to an action that may be possible.
Definition: actions.cpp:5380
void action_list_end(action_id *act_list, int size)
Terminate an action list of the specified size.
Definition: actions.cpp:5881
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)
Returns a speculation about the actor unit's probability of successfully performing the chosen action...
Definition: actions.cpp:5303
void action_list_add_all_by_result(action_id *act_list, int *position, enum action_result result)
Add all actions with the specified result to the specified action list starting at the specified posi...
Definition: actions.cpp:5898
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)
Returns a speculation about the actor unit's probability of successfully performing the chosen action...
Definition: actions.cpp:5243
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)
Returns a speculation about the actor unit's probability of successfully performing the chosen action...
Definition: actions.cpp:5213
struct action * action_by_number(action_id act_id)
Return the action with the given id.
Definition: actions.cpp:1149
enum unit_activity action_get_activity(const struct action *paction)
Returns the unit activity this action may cause or ACTIVITY_LAST if the action doesn't result in a un...
Definition: actions.cpp:1557
enum action_target_kind action_get_target_kind(const struct action *paction)
Get the target kind of an action.
Definition: actions.cpp:1198
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)
Returns a speculation about the actor unit's probability of successfully performing the chosen action...
Definition: actions.cpp:5273
#define action_iterate_end
Definition: actions.h:383
#define MAX_NUM_ACTIONS
Definition: actions.h:223
#define action_id_get_activity(act_id)
Definition: actions.h:583
#define action_iterate(_act_)
Definition: actions.h:378
#define COOLING_FACTOR
Definition: advbuilding.h:28
#define WARMING_FACTOR
Definition: advbuilding.h:27
bool adv_follow_path(struct unit *punit, const PFPath &path, struct tile *ptile)
Move a unit along a path without disturbing its activity, role or assigned destination Return FALSE i...
Definition: advgoto.cpp:43
adv_want amortize(adv_want benefit, int delay)
Amortize means gradually paying off a cost or debt over time.
Definition: advtools.cpp:25
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition: ai.h:383
bool adv_settler_safe_tile(const struct player *pplayer, struct unit *punit, struct tile *ptile)
Do we consider tile safe for autosettler to work?
action_id as_actions_rmextra[MAX_NUM_ACTIONS]
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
Change unit's advisor task.
action_id as_actions_transform[MAX_NUM_ACTIONS]
static enum tile_behavior autosettler_tile_behavior(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Don't enter in enemy territories.
bool auto_settler_setup_work(struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion, PFPath *path, struct tile *best_tile, enum unit_activity best_act, struct extra_type **best_target, int completion_time)
Setup our settler to do the work it has found.
adv_want adv_settlers_road_bonus(struct tile *ptile, struct road_type *proad)
Calculate the attractiveness of building a road/rail at the given tile.
void auto_settler_findwork(struct player *pplayer, struct unit *punit, struct settlermap *state, int recursion)
Find some work for our settlers and/or workers.
void auto_settlers_player(struct player *pplayer)
Run through all the players settlers and let those on ai.control work automagically.
static void consider_settler_action(const struct player *pplayer, enum unit_activity act, struct extra_type *target, adv_want extra, int new_tile_value, int old_tile_value, bool in_use, int delay, adv_want *best_value, int *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)
Compares the best known tile improvement action with improving ptile with activity act.
void auto_settlers_ruleset_init()
Initialize auto settlers based on the ruleset.
static civtimer * as_timer
action_id as_actions_extra[MAX_NUM_ACTIONS]
adv_want settler_evaluate_improvements(struct unit *punit, enum unit_activity *best_act, struct extra_type **best_target, struct tile **best_tile, PFPath *path, struct settlermap *state)
Finds tiles to improve, using punit.
struct city * settler_evaluate_city_requests(struct unit *punit, struct worker_task **best_task, PFPath *path, struct settlermap *state)
Return best city request to fulfill.
void adv_settlers_free()
Free resources allocated for autosettlers system.
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)
Returns TRUE iff the unit can do the targeted activity at the given location.
#define WORKER_FACTOR
#define MAX_DEP_ROADS
#define as_transform_action_iterate_end
Definition: autosettlers.h:69
#define as_rmextra_action_iterate(_act_)
Definition: autosettlers.h:85
#define as_rmextra_action_iterate_end
Definition: autosettlers.h:89
#define as_extra_action_iterate_end
Definition: autosettlers.h:79
#define as_extra_action_iterate(_act_)
Definition: autosettlers.h:75
#define as_transform_action_iterate(_act_)
Definition: autosettlers.h:65
struct extra_type * base_extra_get(const struct base_type *pbase)
Return extra that base is.
Definition: base.cpp:144
#define base_deps_iterate(_reqs, _dep)
Definition: base.h:91
#define base_deps_iterate_end
Definition: base.h:99
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
Definition: city.cpp:130
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Returns TRUE when a tile is available to be worked, or the city itself is currently working the tile ...
Definition: city.cpp:1392
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_tile_iterate_index_end
Definition: city.h:177
#define city_list_iterate_end
Definition: city.h:484
#define city_tile_iterate_index(_radius_sq, _city_tile, _tile, _index)
Definition: city.h:169
void citymap_turn_init(struct player *pplayer)
Initialize citymap by reserving worked tiles and establishing the crowdedness of (virtual) cities.
Definition: citymap.cpp:51
void clear_worker_task(struct city *pcity, struct worker_task *ptask)
Clear worker task from the city and inform owner.
Definition: citytools.cpp:3397
bool empty() const
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Check if extra has given flag.
Definition: extras.cpp:779
enum extra_cause activity_to_extra_cause(enum unit_activity act)
What extra cause activity is considered to be?
Definition: extras.cpp:973
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Returns prev extra by cause that unit or player can remove from tile.
Definition: extras.cpp:732
bool is_extra_caused_by_action(const struct extra_type *pextra, const struct action *paction)
Is the extra caused by specific worker action?
Definition: extras.cpp:953
bool is_extra_removed_by_action(const struct extra_type *pextra, const struct action *paction)
Is the extra removed by specific worker action?
Definition: extras.cpp:963
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
What extra rmcause activity is considered to be?
Definition: extras.cpp:994
const char * extra_rule_name(const struct extra_type *pextra)
Return the (untranslated) rule name of the extra type.
Definition: extras.cpp:174
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Returns next extra by cause that unit or player can build to tile.
Definition: extras.cpp:687
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_iterate_end
Definition: extras.h:285
#define extra_road_get(_e_)
Definition: extras.h:171
#define extra_type_by_cause_iterate_end
Definition: extras.h:307
#define extra_type_by_cause_iterate(_cause, _extra)
Definition: extras.h:299
float adv_want
Definition: fc_types.h:1144
adv_unit_task
Definition: fc_types.h:287
@ AUT_NONE
Definition: fc_types.h:287
@ AUT_AUTO_SETTLER
Definition: fc_types.h:287
int action_id
Definition: fc_types.h:306
#define EC_NONE
Definition: fc_types.h:934
#define ERM_NONE
Definition: fc_types.h:958
#define ADV_WANT_PRINTF
Definition: fc_types.h:1145
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
AI players may have handicaps - allowing them to cheat or preventing them from using certain algorith...
Definition: handicaps.cpp:62
@ H_MAP
Definition: handicaps.h:27
@ H_FOG
Definition: handicaps.h:25
int adv_city_worker_act_get(const struct city *pcity, int city_tile_index, enum unit_activity act_id)
Return the value for activity 'doing' on tile 'city_tile_index' of city 'pcity'.
Definition: infracache.cpp:362
int adv_city_worker_extra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Return the value for extra on tile 'city_tile_index' of city 'pcity'.
Definition: infracache.cpp:434
void initialize_infrastructure_cache(struct player *pplayer)
Do all tile improvement calculations and cache them for later.
Definition: infracache.cpp:245
int adv_city_worker_rmextra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Return the value for extra removal on tile 'city_tile_index' of city 'pcity'.
Definition: infracache.cpp:453
int city_tile_value(const struct city *pcity, const struct tile *ptile, int foodneed, int prodneed)
Returns a measure of goodness of a tile to pcity.
Definition: infracache.cpp:305
void log_time(const QString &msg, bool log)
Definition: log.cpp:253
constexpr auto LOG_DEBUG
Definition: log.h:27
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_debug(message,...)
Definition: log.h:65
struct tile * map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
Return the tile for the given cartesian (map) position.
Definition: map.cpp:391
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Are (x1,y1) and (x2,y2) really the same when adjusted? This function might be necessary ALOT of place...
Definition: map.cpp:887
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Return real distance between two tiles.
Definition: map.cpp:599
struct terrain_misc terrain_control
Definition: map.cpp:40
#define current_topo_has_flag(flag)
Definition: map.h:37
#define MAP_INDEX_SIZE
Definition: map.h:91
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define whole_map_iterate_end
Definition: map.h:480
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition: map.h:164
#define SINGLE_MOVE
Definition: movement.h:17
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
Get info about position at ptile and put it in pos.
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Factory function to create a new map according to the parameter.
PFPath pf_map_path(struct pf_map *pfm, struct tile *ptile)
CHECK DOCS AFTER FULL CONVERSTION OF pf_path to class PFPath Tries to find the best path in the given...
void pf_map_destroy(struct pf_map *pfm)
After usage the map must be destroyed.
tile_behavior
Definition: path_finding.h:276
@ TB_NORMAL
Definition: path_finding.h:277
@ TB_IGNORE
Definition: path_finding.h:278
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct unit *punit)
Fill classic parameters for an unit.
Definition: pf_tools.cpp:822
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
If the specified player owns the unit with the specified id, return pointer to the unit struct.
Definition: player.cpp:1139
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
Definition: player.cpp:1334
#define is_ai(plr)
Definition: player.h:227
Road_type_id road_number(const struct road_type *proad)
Return the road id.
Definition: road.cpp:23
bool road_provides_move_bonus(const struct road_type *proad)
Does road type provide move bonus.
Definition: road.cpp:437
struct extra_type * road_extra_get(const struct road_type *proad)
Return extra that road is.
Definition: road.cpp:33
#define road_deps_iterate(_reqs, _dep)
Definition: road.h:126
#define road_deps_iterate_end
Definition: road.h:134
#define FC_INFINITY
Definition: shared.h:32
#define MAX(x, y)
Definition: shared.h:48
static int recursion[AIT_LAST]
Definition: srv_log.cpp:35
#define LOG_AI_TEST
Definition: srv_log.h:40
@ AIT_WORKERS
Definition: srv_log.h:47
#define UNIT_LOG(_, punit, msg,...)
Definition: srv_log.h:95
@ TIMER_STOP
Definition: srv_log.h:77
@ TIMER_START
Definition: srv_log.h:77
#define TIMING_LOG(timer, activity)
Definition: srv_log.h:121
action_id id
Definition: actions.h:306
Definition: city.h:291
struct packet_game_info info
Definition: game.h:80
struct requirement_vector reqs
Definition: extras.h:90
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition: path_finding.h:380
const struct player * owner
Definition: path_finding.h:356
int warmth
Definition: player.h:114
int frost
Definition: player.h:114
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
struct player_ai ai_common
Definition: player.h:270
struct unit_list * units
Definition: player.h:264
Definition: road.h:54
int move_cost
Definition: road.h:57
Definition: tile.h:42
struct unit_list * units
Definition: tile.h:50
bool worker
Definition: unittype.h:538
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
int moves_left
Definition: unit.h:147
int id
Definition: unit.h:141
struct unit::@76::@79 server
struct tile * goto_tile
Definition: unit.h:152
enum unit_activity act
Definition: workertask.h:17
struct tile * ptile
Definition: workertask.h:16
struct extra_type * tgt
Definition: workertask.h:18
struct civ_map map
Definition: world_object.h:21
int terrain_extra_build_time(const struct terrain *pterrain, enum unit_activity activity, const struct extra_type *tgt)
Time to complete the extra building activity on the given terrain.
Definition: terrain.cpp:579
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Returns TRUE if the given tile has a road of given type on it.
Definition: tile.cpp:868
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_worked(_tile)
Definition: tile.h:97
known_type
Definition: tile.h:28
#define tile_terrain(_tile)
Definition: tile.h:93
#define TILE_XY(ptile)
Definition: tile.h:36
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130
#define tile_owner(_tile)
Definition: tile.h:78
void timer_destroy(civtimer *t)
Deletes timer.
Definition: timing.cpp:66
double timer_read_seconds(civtimer *t)
Read value from timer.
Definition: timing.cpp:137
void timer_start(civtimer *t)
Start timing, adding to previous accumulated time if timer has not been cleared.
Definition: timing.cpp:95
civtimer * timer_renew(civtimer *t, enum timer_timetype type, enum timer_use use)
Allocate a new timer, or reuse t, with specified "type" and "use".
Definition: timing.cpp:51
bool timer_in_use(civtimer *t)
Return whether timer is in use.
Definition: timing.cpp:76
#define TIMER_DEBUG
Definition: timing.h:39
@ TIMER_CPU
Definition: timing.h:20
int get_turns_for_activity_at(const struct unit *punit, enum unit_activity activity, const struct tile *ptile, struct extra_type *tgt)
Return the estimated number of turns for the worker unit to start and complete the activity at the gi...
Definition: unit.cpp:486
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Assign a new untargeted task to a unit.
Definition: unit.cpp:1011
bool is_military_unit(const struct unit *punit)
Military units are capable of enforcing martial law.
Definition: unit.cpp:300
bool is_square_threatened(const struct player *pplayer, const struct tile *ptile, bool omniscient)
Return TRUE iff this tile is threatened from any unit within 2 tiles.
Definition: unit.cpp:327
bool unit_is_cityfounder(const struct unit *punit)
Is a cityfounder unit?
Definition: unit.cpp:2389
const char * get_activity_text(enum unit_activity activity)
Return the name of the activity in a static buffer.
Definition: unit.cpp:586
bool unit_has_orders(const struct unit *punit)
Return TRUE iff the unit is following client-side orders.
Definition: unit.cpp:195
bool activity_requires_target(enum unit_activity activity)
Return TRUE if activity requires some sort of target to be specified.
Definition: unit.cpp:506
#define unit_tile(_pu)
Definition: unit.h:371
#define CHECK_UNIT(punit)
Definition: unit.h:264
#define unit_owner(_pu)
Definition: unit.h:370
#define unit_home(_pu_)
Definition: unit.h:369
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Handle request for changing activity.
Definition: unithand.cpp:5485
bool unit_activity_handling_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type **new_target)
Handle request for targeted activity.
Definition: unithand.cpp:5551
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_safe(unitlist, _unit)
Definition: unitlist.h:33
#define unit_list_iterate_end
Definition: unitlist.h:27
#define unit_list_iterate_safe_end
Definition: unitlist.h:54
void send_unit_info(struct conn_list *dest, struct unit *punit)
Send the unit to the players who need the info.
Definition: unittools.cpp:2808
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
Definition: unittype.cpp:1283
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176
#define worker_task_list_iterate(tasklist, ptask)
Definition: workertask.h:27
#define worker_task_list_iterate_end
Definition: workertask.h:29