Freeciv21
Develop your civilization from humble roots to a global empire
movement.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  /\/\ part of Freeciv21. Freeciv21 is free software: you can
4  \_\ _..._ redistribute it and/or modify it under the terms of the
5  (" )(_..._) GNU General Public License as published by the Free
6  ^^ // \\ Software Foundation, either version 3 of the License,
7  or (at your option) any later version. You should have
8 received a copy of the GNU General Public License along with Freeciv21.
9  If not, see https://www.gnu.org/licenses/.
10  */
11 
12 #include <QBitArray>
13 
14 // utility
15 #include "bitvector.h"
16 #include "log.h"
17 #include "shared.h"
18 #include "support.h"
19 // common
20 #include "fc_types.h"
21 #include "game.h"
22 #include "map.h"
23 #include "road.h"
24 #include "terrain.h"
25 #include "unit.h"
26 #include "unitlist.h"
27 #include "unittype.h"
28 
29 #include "movement.h"
30 
38 int utype_move_rate(const struct unit_type *utype, const struct tile *ptile,
39  const struct player *pplayer, int veteran_level,
40  int hitpoints)
41 {
42  const struct unit_class *uclass;
43  const struct veteran_level *vlevel;
44  int base_move_rate, move_rate;
45 
46  fc_assert_ret_val(nullptr != utype, 0);
47  fc_assert_ret_val(nullptr != pplayer, 0);
48  vlevel = utype_veteran_level(utype, veteran_level);
49  fc_assert_ret_val(nullptr != vlevel, 0);
50  uclass = utype_class(utype);
51 
52  base_move_rate = utype->move_rate + vlevel->move_bonus;
53  move_rate = base_move_rate;
54 
55  if (uclass_has_flag(uclass, UCF_DAMAGE_SLOWS)) {
56  // Scale the MP based on how many HP the unit has.
57  move_rate = (move_rate * hitpoints) / utype->hp;
58  }
59 
60  /* Add on effects bonus (Magellan's Expedition, Lighthouse,
61  * Nuclear Power). */
62  move_rate += (get_unittype_bonus(pplayer, ptile, utype, EFT_MOVE_BONUS)
63  * SINGLE_MOVE);
64 
65  /* Don't let the move_rate be less than min_speed unless the base_move_rate
66  * is also less than min_speed. */
67  if (move_rate < uclass->min_speed) {
68  move_rate = MIN(uclass->min_speed, base_move_rate);
69  }
70 
71  return move_rate;
72 }
73 
78 int unit_move_rate(const struct unit *punit)
79 {
80  fc_assert_ret_val(nullptr != punit, 0);
81 
82  return utype_move_rate(unit_type_get(punit), unit_tile(punit),
83  unit_owner(punit), punit->veteran, punit->hp);
84 }
85 
93 int utype_unknown_move_cost(const struct unit_type *utype)
94 {
95  const struct unit_class *uclass = utype_class(utype);
96  int move_cost;
97 
98  if (!uclass_has_flag(uclass, UCF_TERRAIN_SPEED)) {
99  // Unit is not subject to terrain movement costs.
100  move_cost = SINGLE_MOVE;
101  } else if (utype_has_flag(utype, UTYF_IGTER)) {
102  // All terrain movement costs are equal!
103  move_cost = MOVE_COST_IGTER;
104  } else {
105  // Unit is subject to terrain movement costs.
106  move_cost = 1; // Arbitrary minimum.
107  terrain_type_iterate(pterrain)
108  {
109  if (is_native_to_class(uclass, pterrain, nullptr)
110  && pterrain->movement_cost > move_cost) {
111  /* Exact movement cost matters only if we can enter
112  * the tile. */
113  move_cost = pterrain->movement_cost;
114  }
115  }
117  move_cost *= SINGLE_MOVE; // Real value.
118  }
119 
120  /* Let's see if we can cross over all terrain types, else apply a malus.
121  * We want units that may encounter unsuitable terrain explore less.
122  * N.B.: We don't take in account terrain no unit can enter here. */
123  terrain_type_iterate(pterrain)
124  {
125  if (BV_ISSET_ANY(pterrain->native_to)
126  && !is_native_to_class(uclass, pterrain, nullptr)) {
127  // Units that may encounter unsuitable terrain explore less.
128  move_cost *= 2;
129  break;
130  }
131  }
133 
134  return move_cost;
135 }
136 
142 bool unit_can_defend_here(const struct civ_map *nmap,
143  const struct unit *punit)
144 {
145  struct unit *ptrans = unit_transport_get(punit);
146 
147  /* Do not just check if unit is transported.
148  * Even transported units may step out from transport to fight,
149  * if this is their native terrain. */
150  return (can_unit_exist_at_tile(nmap, punit, unit_tile(punit))
151  && (ptrans == nullptr
152  // Don't care if unloaded by the transport or alight itself
153  /* FIXME: should being able to be unloaded by the transport
154  * count as being able to defend (like it does now) or should
155  * a unit that can't alight be considered useless as a
156  * defender? */
157  || can_unit_alight_or_be_unloaded(punit, ptrans)));
158 }
159 
165 {
166  return uclass_has_flag(utype_class(utype), UCF_ATTACK_NON_NATIVE)
167  && (utype_can_do_action_result(utype, ACTRES_ATTACK)
168  || utype_can_do_action_result(utype, ACTRES_BOMBARD))
169  && utype->attack_strength > 0
170  && !utype_has_flag(utype, UTYF_ONLY_NATIVE_ATTACK);
171 }
172 
178 {
179  return (utype_can_do_act_when_ustate(utype, ACTION_ATTACK, USP_NATIVE_TILE,
180  false)
181  || utype_can_do_act_when_ustate(utype, ACTION_SUICIDE_ATTACK,
182  USP_NATIVE_TILE, false)
183  || utype_can_do_act_when_ustate(utype, ACTION_CONQUER_CITY2,
184  USP_LIVABLE_TILE, false)
185  || utype_can_do_act_when_ustate(utype, ACTION_CONQUER_CITY,
186  USP_LIVABLE_TILE, false));
187 }
188 
192 bool is_city_channel_tile(const struct unit_class *punitclass,
193  const struct tile *ptile,
194  const struct tile *pexclude)
195 {
196  struct tile_list *process_queue = tile_list_new();
197  bool found = false;
198 
199  QBitArray tile_processed(map_num_tiles());
200  for (;;) {
201  tile_processed.setBit(tile_index(ptile));
202  adjc_iterate(&(wld.map), ptile, piter)
203  {
204  if (tile_processed.at(tile_index(piter))) {
205  continue;
206  } else if (piter != pexclude
207  && is_native_to_class(punitclass, tile_terrain(piter),
208  tile_extras(piter))) {
209  found = true;
210  break;
211  } else if (piter != pexclude && nullptr != tile_city(piter)) {
212  tile_list_append(process_queue, piter);
213  } else {
214  tile_processed.setBit(tile_index(piter));
215  }
216  }
218 
219  if (found || 0 == tile_list_size(process_queue)) {
220  break; // No more tile to process.
221  } else {
222  ptile = tile_list_front(process_queue);
223  tile_list_pop_front(process_queue);
224  }
225  }
226 
227  tile_list_destroy(process_queue);
228  return found;
229 }
230 
236 bool can_exist_at_tile(const struct civ_map *nmap,
237  const struct unit_type *utype,
238  const struct tile *ptile)
239 {
240  /* Cities are safe havens except for units in the middle of non-native
241  * terrain. This can happen if adjacent terrain is changed after unit
242  * arrived to city. */
243  if (nullptr != tile_city(ptile)
244  && (uclass_has_flag(utype_class(utype), UCF_BUILD_ANYWHERE)
245  || is_native_near_tile(nmap, utype_class(utype), ptile)
246  || (1 == game.info.citymindist
247  && is_city_channel_tile(utype_class(utype), ptile,
248  nullptr)))) {
249  return true;
250  }
251 
252  /* UTYF_COAST_STRICT unit cannot exist in an ocean tile without access to
253  * land. */
254  if (utype_has_flag(utype, UTYF_COAST_STRICT)
255  && !is_safe_ocean(nmap, ptile)) {
256  return false;
257  }
258 
259  return is_native_tile(utype, ptile);
260 }
261 
267 bool can_unit_exist_at_tile(const struct civ_map *nmap,
268  const struct unit *punit,
269  const struct tile *ptile)
270 {
271  return can_exist_at_tile(nmap, unit_type_get(punit), ptile);
272 }
273 
279 bool is_native_tile(const struct unit_type *punittype,
280  const struct tile *ptile)
281 {
282  return is_native_to_class(utype_class(punittype), tile_terrain(ptile),
283  tile_extras(ptile));
284 }
285 
290 bool is_native_to_class(const struct unit_class *punitclass,
291  const struct terrain *pterrain,
292  const bv_extras *extras)
293 {
294  if (!pterrain) {
295  // Unknown is considered native terrain
296  return true;
297  }
298 
299  if (BV_ISSET(pterrain->native_to, uclass_index(punitclass))) {
300  return true;
301  }
302 
303  if (extras != nullptr) {
305  {
306  if (BV_ISSET(*extras, extra_index(pextra))) {
307  return true;
308  }
309  }
311  }
312 
313  return false;
314 }
315 
322 bool is_native_move(const struct unit_class *punitclass,
323  const struct tile *src_tile, const struct tile *dst_tile)
324 {
325  const struct road_type *proad;
326 
327  if (is_native_to_class(punitclass, tile_terrain(dst_tile), nullptr)) {
328  // We aren't using extras to make the destination native.
329  return true;
330  } else if (!is_native_tile_to_class(punitclass, src_tile)) {
331  // Disembarking or leaving port, so ignore road connectivity.
332  return true;
333  } else if (is_native_to_class(punitclass, tile_terrain(src_tile),
334  nullptr)) {
335  /* Native source terrain depends entirely on destination tile nativity.
336  */
337  return is_native_tile_to_class(punitclass, dst_tile);
338  }
339 
340  // Check for non-road native extras on the source tile.
342  {
343  if (tile_has_extra(src_tile, pextra)
344  && !is_extra_caused_by(pextra, EC_ROAD)
345  && is_native_tile_to_class(punitclass, dst_tile)) {
346  /* If there is one, and the destination is native, the move is native.
347  */
348  return true;
349  }
350  }
352 
354  {
355  if (!tile_has_extra(dst_tile, pextra)) {
356  continue;
357  } else if (!is_extra_caused_by(pextra, EC_ROAD)) {
358  // The destination is native because of a non-road extra.
359  return true;
360  }
361 
362  proad = extra_road_get(pextra);
363 
364  if (road_has_flag(proad, RF_JUMP_TO)) {
366  {
367  if (pextra != jextra && is_extra_caused_by(jextra, EC_ROAD)
368  && tile_has_extra(src_tile, jextra)
369  && road_has_flag(jextra->data.road, RF_JUMP_FROM)) {
370  return true;
371  }
372  }
374  }
375 
376  extra_type_list_iterate(proad->integrators, iextra)
377  {
378  if (!tile_has_extra(src_tile, iextra)) {
379  continue;
380  }
381  if (ALL_DIRECTIONS_CARDINAL()) {
382  // move_mode does not matter as all of them accept cardinal move
383  return true;
384  }
385  switch (extra_road_get(iextra)->move_mode) {
386  case RMM_FAST_ALWAYS:
387  // Road connects source and destination, so we're fine.
388  return true;
389  case RMM_CARDINAL:
390  // Road connects source and destination if cardinal move.
391  if (is_move_cardinal(&(wld.map), src_tile, dst_tile)) {
392  return true;
393  }
394  break;
395  case RMM_RELAXED:
396  if (is_move_cardinal(&(wld.map), src_tile, dst_tile)) {
397  // Cardinal moves have no between tiles, so connected.
398  return true;
399  }
400  cardinal_between_iterate(&(wld.map), src_tile, dst_tile, between)
401  {
402  if (tile_has_extra(between, iextra)
403  || (pextra != iextra && tile_has_extra(between, pextra))) {
404  /* We have a link for the connection.
405  * 'pextra != iextra' is there just to avoid tile_has_extra()
406  * in by far more common case that 'pextra == iextra' */
407  return true;
408  }
409  }
411  break;
412  }
413  }
415  }
417 
418  return false;
419 }
420 
424 bool is_native_near_tile(const struct civ_map *nmap,
425  const struct unit_class *uclass,
426  const struct tile *ptile)
427 {
428  if (is_native_tile_to_class(uclass, ptile)) {
429  return true;
430  }
431 
432  adjc_iterate(nmap, ptile, ptile2)
433  {
434  if (is_native_tile_to_class(uclass, ptile2)) {
435  return true;
436  }
437  }
439 
440  return false;
441 }
442 
452 bool can_unit_survive_at_tile(const struct civ_map *nmap,
453  const struct unit *punit,
454  const struct tile *ptile)
455 {
456  if (!can_unit_exist_at_tile(nmap, punit, ptile)) {
457  return false;
458  }
459 
460  if (tile_city(ptile)) {
461  return true;
462  }
463 
464  if (tile_has_refuel_extra(ptile, unit_type_get(punit))) {
465  // Unit can always survive at refueling base
466  return true;
467  }
468 
469  if (unit_has_type_flag(punit, UTYF_COAST) && is_safe_ocean(nmap, ptile)) {
470  // Refueling coast
471  return true;
472  }
473 
474  if (utype_fuel(unit_type_get(punit))) {
475  // Unit requires fuel and this is not refueling tile
476  return false;
477  }
478 
479  if (is_losing_hp(punit)) {
480  // Unit is losing HP over time in this tile (no city or native base)
481  return false;
482  }
483 
484  return true;
485 }
486 
499 bool can_step_taken_wrt_to_zoc(const struct unit_type *punittype,
500  const struct player *unit_owner,
501  const struct tile *src_tile,
502  const struct tile *dst_tile,
503  const struct civ_map *zmap)
504 {
505  if (unit_type_really_ignores_zoc(punittype)) {
506  return true;
507  }
508  if (is_allied_unit_tile(dst_tile, unit_owner)) {
509  return true;
510  }
511  if (tile_city(src_tile) || tile_city(dst_tile)) {
512  return true;
513  }
514  const auto src_terrain = tile_terrain(src_tile);
515  const auto dst_terrain = tile_terrain(dst_tile);
516  if ((src_terrain && terrain_has_flag(src_terrain, TER_NO_ZOC))
517  || (dst_terrain && terrain_has_flag(dst_terrain, TER_NO_ZOC))) {
518  return true;
519  }
520 
521  return (is_my_zoc(unit_owner, src_tile, zmap)
522  || is_my_zoc(unit_owner, dst_tile, zmap));
523 }
524 
531 bool unit_can_move_to_tile(const struct civ_map *nmap,
532  const struct unit *punit,
533  const struct tile *dst_tile, bool igzoc,
534  bool enter_enemy_city)
535 {
536  return (MR_OK
537  == unit_move_to_tile_test(nmap, punit, punit->activity,
538  unit_tile(punit), dst_tile, igzoc,
539  nullptr, enter_enemy_city));
540 }
541 
565 enum unit_move_result
566 unit_move_to_tile_test(const struct civ_map *nmap, const struct unit *punit,
567  enum unit_activity activity,
568  const struct tile *src_tile,
569  const struct tile *dst_tile, bool igzoc,
570  struct unit *embark_to, bool enter_enemy_city)
571 {
572  bool zoc;
573  struct city *pcity;
574  const struct unit_type *punittype = unit_type_get(punit);
575  const struct player *puowner = unit_owner(punit);
576 
577  // 1)
578  if (activity != ACTIVITY_IDLE && activity != ACTIVITY_GOTO) {
579  // For other activities the unit must be stationary.
580  return MR_BAD_ACTIVITY;
581  }
582 
583  // 2)
584  if (punit->stay) {
585  return MR_UNIT_STAY;
586  }
587 
588  // 3)
589  if (!is_tiles_adjacent(src_tile, dst_tile)) {
590  // Of course you can only move to adjacent positions.
591  return MR_BAD_DESTINATION;
592  }
593 
594  // 4)
595  if (is_non_allied_unit_tile(dst_tile, puowner)) {
596  /* You can't move onto a tile with non-allied units on it (try
597  * attacking instead). */
599  }
600 
601  // 5)
602  if (puowner->ai_common.barbarian_type == ANIMAL_BARBARIAN
603  && dst_tile->terrain->animal != punittype) {
604  return MR_ANIMAL_DISALLOWED;
605  }
606 
607  // 6)
608  if (embark_to != nullptr) {
609  if (!could_unit_load(punit, embark_to)) {
611  }
612  } else if (!(can_exist_at_tile(nmap, punittype, dst_tile)
613  || unit_could_load_at(punit, dst_tile))) {
615  }
616 
617  // 7)
618  if (is_non_attack_unit_tile(dst_tile, puowner)) {
619  /* You can't move into a non-allied tile.
620  *
621  * FIXME: this should never happen since it should be caught by check
622  * #3. */
623  return MR_NO_WAR;
624  }
625 
626  // 8)
627  if ((pcity = tile_city(dst_tile))) {
628  if (enter_enemy_city) {
629  if (pplayers_non_attack(city_owner(pcity), puowner)) {
630  /* You can't move into an empty city of a civilization you're at
631  * peace with - you must first either declare war or make an
632  * alliance. */
633  return MR_NO_WAR;
634  }
635  } else {
636  if (!pplayers_allied(city_owner(pcity), puowner)) {
637  /* You can't move into an empty city of a civilization you're not
638  * allied to. Assume that the player tried to attack. */
639  return MR_NO_WAR;
640  }
641  }
642  }
643 
644  // 9)
645  zoc = igzoc
646  || can_step_taken_wrt_to_zoc(punittype, puowner, src_tile, dst_tile,
647  nmap);
648  if (!zoc) {
649  // The move is illegal because of zones of control.
650  return MR_ZOC;
651  }
652 
653  // 10)
654  if (utype_has_flag(punittype, UTYF_COAST_STRICT)
655  && !is_safe_ocean(&(wld.map), dst_tile)) {
656  return MR_TRIREME;
657  }
658 
659  // 11)
660  if (!utype_has_flag(punittype, UTYF_CIVILIAN)
661  && !player_can_invade_tile(puowner, dst_tile)) {
662  return MR_PEACE;
663  }
664 
665  // 12)
666  if (unit_transported(punit)
667  && !can_unit_unload(punit, unit_transport_get(punit))) {
668  return MR_CANNOT_DISEMBARK;
669  }
670 
671  // 13)
672  if (!(is_native_move(utype_class(punittype), src_tile, dst_tile)
673  // Allow non-native moves into cities or boarding transport.
674  || pcity || unit_could_load_at(punit, dst_tile))) {
675  return MR_NON_NATIVE_MOVE;
676  }
677 
678  return MR_OK;
679 }
680 
684 bool can_unit_transport(const struct unit *transporter,
685  const struct unit *transported)
686 {
687  fc_assert_ret_val(transporter != nullptr, false);
688  fc_assert_ret_val(transported != nullptr, false);
689 
690  return can_unit_type_transport(unit_type_get(transporter),
691  unit_class_get(transported));
692 }
693 
698 bool can_unit_type_transport(const struct unit_type *transporter,
699  const struct unit_class *transported)
700 {
701  if (transporter->transport_capacity <= 0) {
702  return false;
703  }
704 
705  return BV_ISSET(transporter->cargo, uclass_index(transported));
706 }
707 
713 bool unit_can_load(const struct unit *punit)
714 {
715  if (unit_transported(punit)) {
716  // In another transport already. Can it unload first?
717  if (!can_unit_unload(punit, punit->transporter)) {
718  return false;
719  }
720  }
721 
722  unit_list_iterate(unit_tile(punit)->units, ptransport)
723  {
724  /* could_unit_load() instead of can_unit_load() since latter
725  * would check against unit already being transported, and we need
726  * to support unload+load to a new transport. */
727  if (ptransport != punit->transporter) {
728  if (could_unit_load(punit, ptransport)) {
729  return true;
730  }
731  }
732  }
734 
735  return false;
736 }
737 
743 bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
744 {
745  unit_list_iterate(ptile->units, ptransport)
746  {
747  if (could_unit_load(punit, ptransport)) {
748  return true;
749  }
750  }
752 
753  return false;
754 }
755 
759 bool is_unit_being_refueled(const struct unit *punit)
760 {
761  if (unit_transported(punit) // Carrier
762  || tile_city(unit_tile(punit)) // City
764  unit_type_get(punit))) { // Airbase
765  return true;
766  }
767  if (unit_has_type_flag(punit, UTYF_COAST)) {
768  return is_safe_ocean(&(wld.map), unit_tile(punit));
769  }
770 
771  return false;
772 }
773 
778 {
779  char denomstr[10];
780  /* String length of maximum denominator for fractional representation of
781  * movement points, for padding of text representation */
782  fc_snprintf(denomstr, sizeof(denomstr), "%d", SINGLE_MOVE);
783 }
784 
797 const char *move_points_text_full(int mp, bool reduce, const char *prefix,
798  const char *none, bool align)
799 {
800  QString str;
801 
802  if (!prefix) {
803  prefix = "";
804  }
805  if ((mp == 0 && none) || SINGLE_MOVE == 0) {
806  // No movement points, and we have a special representation to use
807  /* (Also used when SINGLE_MOVE == 0, to avoid dividing by zero, which is
808  * important for client before ruleset has been received. Doesn't much
809  * matter what we print in this case.) */
810  str = QStringLiteral("%1").arg(none ? none : "");
811  } else if ((mp % SINGLE_MOVE) == 0) {
812  // Integer move points
813  str = QStringLiteral("%1%2%3").arg(
814  prefix, QString::number(mp / SINGLE_MOVE), "");
815  } else {
816  // Fractional part
817  int cancel;
818 
819  fc_assert(SINGLE_MOVE > 1);
820  if (reduce) {
821  // Reduce to lowest terms
822  int gcd = mp;
823  // Calculate greatest common divisor with Euclid's algorithm
824  int b = SINGLE_MOVE;
825 
826  while (b != 0) {
827  int t = b;
828  b = gcd % b;
829  gcd = t;
830  }
831  cancel = gcd;
832  } else {
833  // No cancellation
834  cancel = 1;
835  }
836  if (mp < SINGLE_MOVE) {
837  // Fractional move points
838  str += QStringLiteral("%1%2/%3").arg(
839  prefix, QString::number((mp % SINGLE_MOVE) / cancel),
840  QString::number(SINGLE_MOVE / cancel));
841  } else {
842  // Integer + fractional move points
843  str += QStringLiteral("%1%2 %3/%4")
844  .arg(prefix, QString::number(mp / SINGLE_MOVE),
845  QString::number((mp % SINGLE_MOVE) / cancel),
846  QString::number(SINGLE_MOVE / cancel));
847  }
848  }
849  return qstrdup(qUtf8Printable(str));
850 }
851 
856 const char *move_points_text(int mp, bool reduce)
857 {
858  return move_points_text_full(mp, reduce, nullptr, nullptr, false);
859 }
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
#define BV_ISSET_ANY(vec)
Definition: bitvector.h:76
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
char * extras
Definition: comments.cpp:34
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, enum effect_type effect_type, enum vision_layer vision_layer)
Returns the effect bonus that applies at a tile for a given unittype.
Definition: effects.cpp:841
#define extra_type_list_iterate(extralist, pextra)
Definition: extras.h:145
#define is_extra_caused_by(e, c)
Definition: extras.h:182
#define extra_index(_e_)
Definition: extras.h:163
#define extra_type_list_iterate_end
Definition: extras.h:147
#define extra_road_get(_e_)
Definition: extras.h:171
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
bool is_move_cardinal(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Returns TRUE iff the move from the position (start_x,start_y) to (end_x,end_y) is a cardinal one.
Definition: map.cpp:1306
int map_num_tiles()
Returns the total number of (real) positions (or tiles) on the map.
Definition: map.cpp:954
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Are two tiles adjacent to each other.
Definition: map.cpp:878
bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
Return TRUE if this ocean terrain is adjacent to a safe coastline.
Definition: map.cpp:636
#define adjc_iterate_end
Definition: map.h:358
#define cardinal_between_iterate(nmap, tile1, tile2, between)
Definition: map.h:402
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define ALL_DIRECTIONS_CARDINAL()
Definition: map.h:39
#define cardinal_between_iterate_end
Definition: map.h:409
const char * move_points_text_full(int mp, bool reduce, const char *prefix, const char *none, bool align)
Render positive movement points as text, including fractional movement points, scaled by SINGLE_MOVE.
Definition: movement.cpp:797
bool can_exist_at_tile(const struct civ_map *nmap, const struct unit_type *utype, const struct tile *ptile)
Return TRUE iff a unit of the given unit type can "exist" at this location.
Definition: movement.cpp:236
bool is_city_channel_tile(const struct unit_class *punitclass, const struct tile *ptile, const struct tile *pexclude)
Check for a city channel.
Definition: movement.cpp:192
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "exist" at this location.
Definition: movement.cpp:267
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
This tile is native to unit.
Definition: movement.cpp:279
bool can_step_taken_wrt_to_zoc(const struct unit_type *punittype, const struct player *unit_owner, const struct tile *src_tile, const struct tile *dst_tile, const struct civ_map *zmap)
Returns whether the unit is allowed (by ZOC) to move from src_tile to dest_tile (assumed adjacent).
Definition: movement.cpp:499
int utype_unknown_move_cost(const struct unit_type *utype)
This function calculates the movement cost to unknown tiles.
Definition: movement.cpp:93
bool unit_can_load(const struct unit *punit)
Return whether we can find a suitable transporter for given unit at current location.
Definition: movement.cpp:713
bool can_unit_transport(const struct unit *transporter, const struct unit *transported)
Return true iff transporter has ability to transport transported.
Definition: movement.cpp:684
int unit_move_rate(const struct unit *punit)
This function calculates the move rate of the unit.
Definition: movement.cpp:78
bool unit_could_load_at(const struct unit *punit, const struct tile *ptile)
Return whether we could find a suitable transporter for given unit at 'ptile'.
Definition: movement.cpp:743
bool can_attack_from_non_native(const struct unit_type *utype)
This unit can attack from non-native tiles (Marines can attack from transport, ships from harbour cit...
Definition: movement.cpp:177
bool unit_can_move_to_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *dst_tile, bool igzoc, bool enter_enemy_city)
Returns whether the unit can move from its current tile to the destination tile.
Definition: movement.cpp:531
bool unit_can_defend_here(const struct civ_map *nmap, const struct unit *punit)
Return TRUE iff the unit can be a defender at its current location.
Definition: movement.cpp:142
bool is_native_to_class(const struct unit_class *punitclass, const struct terrain *pterrain, const bv_extras *extras)
This terrain is native to unit class.
Definition: movement.cpp:290
int utype_move_rate(const struct unit_type *utype, const struct tile *ptile, const struct player *pplayer, int veteran_level, int hitpoints)
This function calculates the move rate of the unit, taking into account the penalty for reduced hitpo...
Definition: movement.cpp:38
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "survive" at this location.
Definition: movement.cpp:452
bool is_unit_being_refueled(const struct unit *punit)
Is unit being refueled in its current position.
Definition: movement.cpp:759
bool is_native_near_tile(const struct civ_map *nmap, const struct unit_class *uclass, const struct tile *ptile)
Is there native tile adjacent to given tile.
Definition: movement.cpp:424
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Return TRUE iff transporter type has ability to transport transported class.
Definition: movement.cpp:698
bool is_native_move(const struct unit_class *punitclass, const struct tile *src_tile, const struct tile *dst_tile)
Is the move under consideration a native move? Note that this function does not check for possible mo...
Definition: movement.cpp:322
void init_move_fragments()
Call whenever terrain_control.move_fragments / SINGLE_MOVE changes.
Definition: movement.cpp:777
bool can_attack_non_native(const struct unit_type *utype)
This unit can attack non-native tiles (eg.
Definition: movement.cpp:164
const char * move_points_text(int mp, bool reduce)
Simple version of move_points_text_full() – render positive movement points as text without any prefi...
Definition: movement.cpp:856
enum unit_move_result unit_move_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool igzoc, struct unit *embark_to, bool enter_enemy_city)
Returns whether the unit can move from its current tile to the destination tile.
Definition: movement.cpp:566
#define SINGLE_MOVE
Definition: movement.h:17
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition: movement.h:73
unit_move_result
Definition: movement.h:25
@ MR_CANNOT_DISEMBARK
Definition: movement.h:38
@ MR_OK
Definition: movement.h:26
@ MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT
Definition: movement.h:35
@ MR_TRIREME
Definition: movement.h:37
@ MR_NON_NATIVE_MOVE
Definition: movement.h:39
@ MR_BAD_ACTIVITY
Definition: movement.h:32
@ MR_ANIMAL_DISALLOWED
Definition: movement.h:40
@ MR_PEACE
Definition: movement.h:30
@ MR_ZOC
Definition: movement.h:31
@ MR_NO_WAR
Definition: movement.h:29
@ MR_BAD_DESTINATION
Definition: movement.h:33
@ MR_NO_TRANSPORTER_CAPACITY
Definition: movement.h:36
@ MR_UNIT_STAY
Definition: movement.h:41
#define MOVE_COST_IGTER
Definition: movement.h:18
bool player_can_invade_tile(const struct player *pplayer, const struct tile *ptile)
Return TRUE iff the player can invade a particular tile (linked with borders and diplomatic states).
Definition: player.cpp:236
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
Definition: player.cpp:1334
bool pplayers_non_attack(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players have peace, cease-fire, or armistice.
Definition: player.cpp:1388
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Check if road provides effect.
Definition: road.cpp:367
#define MIN(x, y)
Definition: shared.h:49
Definition: city.h:291
struct packet_game_info info
Definition: game.h:80
enum barbarian_type barbarian_type
Definition: player.h:115
Definition: player.h:231
struct player_ai ai_common
Definition: player.h:270
struct unit_list * units
Definition: player.h:264
Definition: road.h:54
enum road_move_mode move_mode
Definition: road.h:58
struct extra_type_list * integrators
Definition: road.h:72
bv_unit_classes native_to
Definition: terrain.h:236
const struct unit_type * animal
Definition: terrain.h:216
Definition: tile.h:42
struct unit_list * units
Definition: tile.h:50
struct terrain * terrain
Definition: tile.h:49
struct unit_class::@81 cache
struct extra_type_list * native_tile_extras
Definition: unittype.h:141
int min_speed
Definition: unittype.h:125
int transport_capacity
Definition: unittype.h:488
bv_unit_classes cargo
Definition: unittype.h:521
int move_rate
Definition: unittype.h:481
int hp
Definition: unittype.h:489
int attack_strength
Definition: unittype.h:479
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
int hp
Definition: unit.h:148
bool stay
Definition: unit.h:202
struct unit * transporter
Definition: unit.h:180
const struct unit_type * utype
Definition: unit.h:135
int veteran
Definition: unit.h:149
int move_bonus
Definition: unittype.h:454
struct civ_map map
Definition: world_object.h:21
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
#define terrain_type_iterate(_p)
Definition: terrain.h:331
#define terrain_type_iterate_end
Definition: terrain.h:337
#define terrain_has_flag(terr, flag)
Definition: terrain.h:260
bool tile_has_refuel_extra(const struct tile *ptile, const struct unit_type *punittype)
Check if tile contains refuel extra native for unit.
Definition: tile.cpp:309
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_terrain(_tile)
Definition: tile.h:93
static const bv_extras * tile_extras(const struct tile *ptile)
Definition: tile.h:102
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130
bool unit_type_really_ignores_zoc(const struct unit_type *punittype)
Takes into account unit class flag UCF_ZOC as well as IGZOC.
Definition: unit.cpp:1385
bool is_my_zoc(const struct player *pplayer, const struct tile *ptile0, const struct civ_map *zmap)
Is this square controlled by the pplayer?
Definition: unit.cpp:1341
bool is_losing_hp(const struct unit *punit)
Does unit lose hitpoints each turn?
Definition: unit.cpp:1992
struct unit * is_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Returns true if the tile contains an allied unit and only allied units.
Definition: unit.cpp:1211
struct unit * is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Is there an non-allied unit on this tile?
Definition: unit.cpp:1252
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
Definition: unit.cpp:2189
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Return TRUE iff the given unit could be loaded into the transporter if we moved there.
Definition: unit.cpp:646
bool can_unit_alight_or_be_unloaded(const struct unit *pcargo, const struct unit *ptrans)
Return TRUE iff the given unit can leave its current transporter without doing any other action or mo...
Definition: unit.cpp:745
struct unit * is_non_attack_unit_tile(const struct tile *ptile, const struct player *pplayer)
Is there an unit we have peace or ceasefire with on this tile?
Definition: unit.cpp:1286
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Return TRUE iff the given unit can be unloaded from its current transporter.
Definition: unit.cpp:720
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
struct unit_class * unit_class_get(const struct unit *punit)
Returns unit class pointer for a unit.
Definition: unittype.cpp:2151
bool utype_can_do_act_when_ustate(const struct unit_type *punit_type, const action_id act_id, const enum ustate_prop prop, const bool is_there)
Return TRUE iff the unit type can do the specified (action enabler controlled) action while its unit ...
Definition: unittype.cpp:746
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Return TRUE iff units of the given type can do any enabler controlled action with the specified actio...
Definition: unittype.cpp:402
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
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Return veteran level properties of given unit in given veterancy level.
Definition: unittype.cpp:2224
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition: unittype.h:704
#define utype_class(_t_)
Definition: unittype.h:691
#define utype_fuel(ptype)
Definition: unittype.h:772
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition: unittype.h:584
#define uclass_index(_c_)
Definition: unittype.h:684