Freeciv21
Develop your civilization from humble roots to a global empire
maphand.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 #include <QBitArray>
15 
16 // utility
17 #include "bitvector.h"
18 #include "fcintl.h"
19 #include "log.h"
20 #include "rand.h"
21 #include "support.h"
22 
23 // common
24 #include "ai.h"
25 #include "base.h"
26 #include "borders.h"
27 #include "events.h"
28 #include "game.h"
29 #include "map.h"
30 #include "movement.h"
31 #include "nation.h"
32 #include "packets.h"
33 #include "player.h"
34 #include "road.h"
35 #include "unit.h"
36 #include "unitlist.h"
37 #include "vision.h"
38 
39 // server
40 #include "citytools.h"
41 #include "cityturn.h"
42 #include "notify.h"
43 #include "plrhand.h"
44 #include "sanitycheck.h"
45 #include "sernet.h"
46 #include "srv_main.h"
47 #include "unithand.h"
48 #include "unittools.h"
49 
50 /* server/generator */
51 #include "mapgen_utils.h"
52 
53 #include "maphand.h"
54 
55 #define MAXIMUM_CLAIMED_OCEAN_SIZE (20)
56 
57 // Suppress send_tile_info() during game_load()
58 static bool send_tile_suppressed = false;
59 
60 static void player_tile_init(struct tile *ptile, struct player *pplayer);
61 static void player_tile_free(struct tile *ptile, struct player *pplayer);
62 static void give_tile_info_from_player_to_player(struct player *pfrom,
63  struct player *pdest,
64  struct tile *ptile);
65 static void shared_vision_change_seen(struct player *pplayer,
66  struct tile *ptile,
67  const v_radius_t change,
68  bool can_reveal_tiles);
69 static void map_change_seen(struct player *pplayer, struct tile *ptile,
70  const v_radius_t change, bool can_reveal_tiles);
71 static void map_change_own_seen(struct player *pplayer, struct tile *ptile,
72  const v_radius_t change);
73 static inline int map_get_seen(const struct player *pplayer,
74  const struct tile *ptile,
75  enum vision_layer vlayer);
76 static inline int map_get_own_seen(const struct player *pplayer,
77  const struct tile *ptile,
78  enum vision_layer vlayer);
79 
80 static bool is_claimable_ocean(struct tile *ptile, struct tile *source,
81  struct player *pplayer);
82 
86 static bool is_terrain_ecologically_wet(struct tile *ptile)
87 {
88  return (is_terrain_class_near_tile(ptile, TC_OCEAN)
89  || tile_has_river(ptile)
90  || count_river_near_tile(ptile, nullptr) > 0);
91 }
92 
97 {
98  climate_change(true, effect);
99  notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
100  _("Global warming has occurred!"));
101  notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
102  _("Coastlines have been flooded and vast "
103  "ranges of grassland have become deserts."));
104 }
105 
110 {
111  climate_change(false, effect);
112  notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
113  _("Nuclear winter has occurred!"));
114  notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
115  _("Wetlands have dried up and vast "
116  "ranges of grassland have become tundra."));
117 }
118 
123 void climate_change(bool warming, int effect)
124 {
125  int k = map_num_tiles();
126  bool used[k];
127  memset(used, 0, sizeof(used));
128 
129  qDebug("Climate change: %s (%d)",
130  warming ? "Global warming" : "Nuclear winter", effect);
131 
132  while (effect > 0 && (k--) > 0) {
133  struct terrain *old, *candidates[2], *tnew;
134  struct tile *ptile;
135  int i;
136 
137  do {
138  // We want to transform a tile at most once due to a climate change.
139  ptile = rand_map_pos(&(wld.map));
140  } while (used[tile_index(ptile)]);
141  used[tile_index(ptile)] = true;
142 
143  old = tile_terrain(ptile);
144  /* Prefer the transformation that's appropriate to the ambient moisture,
145  * but be prepared to fall back in exceptional circumstances */
146  {
147  struct terrain *wetter, *drier;
148  wetter =
149  warming ? old->warmer_wetter_result : old->cooler_wetter_result;
150  drier = warming ? old->warmer_drier_result : old->cooler_drier_result;
151  if (is_terrain_ecologically_wet(ptile)) {
152  candidates[0] = wetter;
153  candidates[1] = drier;
154  } else {
155  candidates[0] = drier;
156  candidates[1] = wetter;
157  }
158  }
159 
160  /* If the preferred transformation is ruled out for some exceptional
161  * reason specific to this tile, fall back to the other, rather than
162  * letting this tile be immune to change. */
163  for (i = 0; i < 2; i++) {
164  tnew = candidates[i];
165 
166  /* If the preferred transformation simply hasn't been specified
167  * for this terrain at all, don't fall back to the other. */
168  if (tnew == T_NONE) {
169  break;
170  }
171 
172  if (tile_city(ptile) != nullptr
173  && terrain_has_flag(tnew, TER_NO_CITIES)) {
174  /* do not change to a terrain with the flag TER_NO_CITIES if the tile
175  * has a city */
176  continue;
177  }
178 
179  /* Only change between water and land at coastlines, and between
180  * frozen and unfrozen at ice margin */
181  if (!terrain_surroundings_allow_change(ptile, tnew)) {
182  continue;
183  }
184 
185  // OK!
186  break;
187  }
188  if (i == 2) {
189  // Neither transformation was permitted. Give up.
190  continue;
191  }
192 
193  if (tnew != T_NONE && old != tnew) {
194  effect--;
195 
196  // Really change the terrain.
197  tile_change_terrain(ptile, tnew);
198  check_terrain_change(ptile, old);
199  update_tile_knowledge(ptile);
200 
201  // Check the unit activities.
203  } else if (old == tnew) {
204  // This counts toward a climate change although nothing is changed.
205  effect--;
206  }
207  }
208 }
209 
214 bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
215 {
216  struct tile *ptile = pcity->tile;
217  struct player *pplayer = city_owner(pcity);
218  bool upgradet = false;
219 
220  extra_type_iterate(pextra)
221  {
222  if (!tile_has_extra(ptile, pextra)) {
223  if (extra_has_flag(pextra, EF_ALWAYS_ON_CITY_CENTER)
224  || (extra_has_flag(pextra, EF_AUTO_ON_CITY_CENTER)
225  && player_can_build_extra(pextra, pplayer, ptile)
226  && !tile_has_conflicting_extra(ptile, pextra))) {
227  tile_add_extra(pcity->tile, pextra);
228  if (gained != nullptr) {
229  if (upgradet) {
230  *gained = nullptr;
231  } else {
232  *gained = pextra;
233  }
234  }
235  upgradet = true;
236  }
237  }
238  }
240 
241  return upgradet;
242 }
243 
251 void upgrade_all_city_extras(struct player *pplayer, bool discovery)
252 {
253  int cities_upgradet = 0;
254  struct extra_type *upgradet = nullptr;
255  bool multiple_types = false;
256  int cities_total = city_list_size(pplayer->cities);
257  int percent;
258 
260 
261  city_list_iterate(pplayer->cities, pcity)
262  {
263  struct extra_type *new_upgrade;
264 
265  if (upgrade_city_extras(pcity, &new_upgrade)) {
266  update_tile_knowledge(pcity->tile);
267  cities_upgradet++;
268  if (new_upgrade == nullptr) {
269  // This single city alone had multiple types
270  multiple_types = true;
271  } else if (upgradet == nullptr) {
272  // First gained
273  upgradet = new_upgrade;
274  } else if (upgradet != new_upgrade) {
275  // Different type from what another city got.
276  multiple_types = true;
277  }
278  }
279  }
281 
282  if (cities_total > 0) {
283  percent = cities_upgradet * 100 / cities_total;
284  } else {
285  percent = 0;
286  }
287 
288  if (cities_upgradet > 0) {
289  if (discovery) {
290  if (percent >= 75) {
292  pplayer, nullptr, E_TECH_GAIN, ftc_server,
293  _("New hope sweeps like fire through the country as "
294  "the discovery of new infrastructure building technology "
295  "is announced."));
296  }
297  } else {
298  if (percent >= 75) {
300  pplayer, nullptr, E_TECH_GAIN, ftc_server,
301  _("The people are pleased to hear that your "
302  "scientists finally know about new infrastructure building "
303  "technology."));
304  }
305  }
306 
307  if (multiple_types) {
308  notify_player(pplayer, nullptr, E_TECH_GAIN, ftc_server,
309  _("Workers spontaneously gather and upgrade all "
310  "possible cities with better infrastructure."));
311  } else {
312  notify_player(pplayer, nullptr, E_TECH_GAIN, ftc_server,
313  _("Workers spontaneously gather and upgrade all "
314  "possible cities with %s."),
315  extra_name_translation(upgradet));
316  }
317  }
318 
320 }
321 
325 bool really_gives_vision(struct player *me, struct player *them)
326 {
327  return BV_ISSET(me->server.really_gives_vision, player_index(them));
328 }
329 
333 static void buffer_shared_vision(struct player *pplayer)
334 {
335  players_iterate(pplayer2)
336  {
337  if (really_gives_vision(pplayer, pplayer2)) {
338  conn_list_compression_freeze(pplayer2->connections);
339  conn_list_do_buffer(pplayer2->connections);
340  }
341  }
345 }
346 
350 static void unbuffer_shared_vision(struct player *pplayer)
351 {
352  players_iterate(pplayer2)
353  {
354  if (really_gives_vision(pplayer, pplayer2)) {
355  conn_list_do_unbuffer(pplayer2->connections);
356  conn_list_compression_thaw(pplayer2->connections);
357  }
358  }
362 }
363 
369  struct player *pdest)
370 {
371  buffer_shared_vision(pdest);
372 
373  whole_map_iterate(&(wld.map), ptile)
374  {
375  give_tile_info_from_player_to_player(pfrom, pdest, ptile);
376  }
378 
379  unbuffer_shared_vision(pdest);
381  sync_cities();
382 }
383 
388  struct player *pdest)
389 {
390  buffer_shared_vision(pdest);
391 
392  whole_map_iterate(&(wld.map), ptile)
393  {
394  if (is_ocean_tile(ptile)) {
395  give_tile_info_from_player_to_player(pfrom, pdest, ptile);
396  }
397  }
399 
400  unbuffer_shared_vision(pdest);
402  sync_cities();
403 }
404 
409  struct player *pfrom,
410  struct player *pdest)
411 {
412  struct tile *pcenter = city_tile(pcity);
413 
414  buffer_shared_vision(pdest);
415 
416  city_tile_iterate(city_map_radius_sq_get(pcity), pcenter, ptile)
417  {
418  give_tile_info_from_player_to_player(pfrom, pdest, ptile);
419  }
421 
422  unbuffer_shared_vision(pdest);
424  sync_cities();
425 }
426 
436 void send_all_known_tiles(struct conn_list *dest)
437 {
438  int tiles_sent;
439 
440  if (!dest) {
441  dest = game.est_connections;
442  }
443 
444  /* send whole map piece by piece to each player to balance the load
445  of the send buffers better */
446  tiles_sent = 0;
447  conn_list_do_buffer(dest);
448 
449  whole_map_iterate(&(wld.map), ptile)
450  {
451  tiles_sent++;
452  if ((tiles_sent % wld.map.xsize) == 0) {
453  conn_list_do_unbuffer(dest);
454  flush_packets();
455  conn_list_do_buffer(dest);
456  }
457 
458  send_tile_info(dest, ptile, false);
459  }
461 
462  conn_list_do_unbuffer(dest);
463  flush_packets();
464 }
465 
469 bool send_tile_suppression(bool now)
470 {
471  bool formerly = send_tile_suppressed;
472 
473  send_tile_suppressed = now;
474  return formerly;
475 }
476 
485 void send_tile_info(struct conn_list *dest, struct tile *ptile,
486  bool send_unknown)
487 {
488  struct packet_tile_info info;
489  const struct player *owner;
490  const struct player *eowner;
491 
492  if (dest == nullptr) {
493  CALL_FUNC_EACH_AI(tile_info, ptile);
494  }
495 
496  if (send_tile_suppressed) {
497  return;
498  }
499 
500  if (!dest) {
501  dest = game.est_connections;
502  }
503 
504  info.tile = tile_index(ptile);
505 
506  if (ptile->spec_sprite) {
507  sz_strlcpy(info.spec_sprite, ptile->spec_sprite);
508  } else {
509  info.spec_sprite[0] = '\0';
510  }
511 
512  conn_list_iterate(dest, pconn)
513  {
514  struct player *pplayer = pconn->playing;
515 
516  if (nullptr == pplayer && !pconn->observer) {
517  continue;
518  }
519 
520  if (!pplayer || map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
521  info.known = TILE_KNOWN_SEEN;
522  info.continent = tile_continent(ptile);
523  owner = tile_owner(ptile);
524  eowner = extra_owner(ptile);
525  info.owner = (owner ? player_number(owner) : MAP_TILE_OWNER_NULL);
526  info.extras_owner =
527  (eowner ? player_number(eowner) : MAP_TILE_OWNER_NULL);
528  info.worked = (nullptr != tile_worked(ptile)) ? tile_worked(ptile)->id
530 
531  info.terrain = (nullptr != tile_terrain(ptile))
532  ? terrain_number(tile_terrain(ptile))
533  : terrain_count();
534  info.resource = (nullptr != tile_resource(ptile))
535  ? extra_number(tile_resource(ptile))
536  : MAX_EXTRA_TYPES;
537  info.placing =
538  (nullptr != ptile->placing) ? extra_number(ptile->placing) : -1;
539  info.place_turn = (nullptr != ptile->placing)
540  ? game.info.turn + ptile->infra_turns
541  : 0;
542 
543  if (pplayer != nullptr) {
544  info.extras = map_get_player_tile(ptile, pplayer)->extras;
545  } else {
546  info.extras = ptile->extras;
547  }
548 
549  if (ptile->label != nullptr) {
550  // Always leave final '/* Always leave final '\0' in place */' in
551  // place
552  qstrncpy(info.label, ptile->label, sizeof(info.label) - 1);
553  } else {
554  info.label[0] = '\0';
555  }
556 
557  send_packet_tile_info(pconn, &info);
558  } else if (pplayer && map_is_known(ptile, pplayer)) {
559  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
560  const vision_site *psite = map_get_player_site(ptile, pplayer);
561 
562  info.known = TILE_KNOWN_UNSEEN;
563  info.continent = tile_continent(ptile);
564  owner =
565  (game.server.foggedborders ? plrtile->owner : tile_owner(ptile));
566  eowner = plrtile->extras_owner;
567  info.owner = (owner ? player_number(owner) : MAP_TILE_OWNER_NULL);
568  info.extras_owner =
569  (eowner ? player_number(eowner) : MAP_TILE_OWNER_NULL);
570  info.worked =
571  (nullptr != psite) ? psite->identity : IDENTITY_NUMBER_ZERO;
572 
573  info.terrain = (nullptr != plrtile->terrain)
574  ? terrain_number(plrtile->terrain)
575  : terrain_count();
576  info.resource = (nullptr != plrtile->resource)
577  ? extra_number(plrtile->resource)
578  : MAX_EXTRA_TYPES;
579  info.placing = -1;
580  info.place_turn = 0;
581 
582  info.extras = plrtile->extras;
583 
584  // Labels never change, so they are not subject to fog of war
585  if (ptile->label != nullptr) {
586  sz_strlcpy(info.label, ptile->label);
587  } else {
588  info.label[0] = '\0';
589  }
590 
591  send_packet_tile_info(pconn, &info);
592  } else if (send_unknown) {
593  info.known = TILE_UNKNOWN;
594  info.continent = 0;
595  info.owner = MAP_TILE_OWNER_NULL;
596  info.extras_owner = MAP_TILE_OWNER_NULL;
597  info.worked = IDENTITY_NUMBER_ZERO;
598 
599  info.terrain = terrain_count();
600  info.resource = MAX_EXTRA_TYPES;
601  info.placing = -1;
602  info.place_turn = 0;
603 
604  BV_CLR_ALL(info.extras);
605 
606  info.label[0] = '\0';
607 
608  send_packet_tile_info(pconn, &info);
609  }
610  }
612 }
613 
617 void send_map_info(struct conn_list *dest)
618 {
619  struct packet_map_info minfo;
620 
621  minfo.xsize = wld.map.xsize;
622  minfo.ysize = wld.map.ysize;
623  minfo.topology_id = wld.map.topology_id;
624 
625  lsend_packet_map_info(dest, &minfo);
626 }
627 
632 static void shared_vision_change_seen(struct player *pplayer,
633  struct tile *ptile,
634  const v_radius_t change,
635  bool can_reveal_tiles)
636 {
637  map_change_own_seen(pplayer, ptile, change);
638  map_change_seen(pplayer, ptile, change, can_reveal_tiles);
639 
640  players_iterate(pplayer2)
641  {
642  if (really_gives_vision(pplayer, pplayer2)) {
643  map_change_seen(pplayer2, ptile, change, can_reveal_tiles);
644  }
645  }
647 }
648 
652 void map_vision_update(struct player *pplayer, struct tile *ptile,
653  const v_radius_t old_radius_sq,
654  const v_radius_t new_radius_sq, bool can_reveal_tiles)
655 {
656  v_radius_t change;
657  int max_radius;
658 
659  if (old_radius_sq[V_MAIN] == new_radius_sq[V_MAIN]
660  && old_radius_sq[V_INVIS] == new_radius_sq[V_INVIS]
661  && old_radius_sq[V_SUBSURFACE] == new_radius_sq[V_SUBSURFACE]) {
662  return;
663  }
664 
665  // Determines 'max_radius' value.
666  max_radius = 0;
668  {
669  if (max_radius < old_radius_sq[v]) {
670  max_radius = old_radius_sq[v];
671  }
672  if (max_radius < new_radius_sq[v]) {
673  max_radius = new_radius_sq[v];
674  }
675  }
677 
678 #ifdef FREECIV_DEBUG
679  log_debug("Updating vision at (%d, %d) in a radius of %d.", TILE_XY(ptile),
680  max_radius);
682  {
683  log_debug(" vision layer %d is changing from %d to %d.", v,
684  old_radius_sq[v], new_radius_sq[v]);
685  }
687 #endif // FREECIV_DEBUG
688 
689  buffer_shared_vision(pplayer);
690  circle_dxyr_iterate(&(wld.map), ptile, max_radius, tile1, dx, dy, dr)
691  {
693  {
694  if (dr > old_radius_sq[v] && dr <= new_radius_sq[v]) {
695  change[v] = 1;
696  } else if (dr > new_radius_sq[v] && dr <= old_radius_sq[v]) {
697  change[v] = -1;
698  } else {
699  change[v] = 0;
700  }
701  }
703  shared_vision_change_seen(pplayer, tile1, change, can_reveal_tiles);
704  }
706  unbuffer_shared_vision(pplayer);
707 }
708 
714 void map_set_border_vision(struct player *pplayer, const bool is_enabled)
715 {
716  const v_radius_t radius_sq = V_RADIUS(is_enabled ? 1 : -1, 0, 0);
717 
718  if (pplayer->server.border_vision == is_enabled) {
719  /* No change. Changing the seen count beyond what already exists would
720  * be a bug. */
721  return;
722  }
723 
724  // Set the new border seer value.
725  pplayer->server.border_vision = is_enabled;
726 
727  whole_map_iterate(&(wld.map), ptile)
728  {
729  if (pplayer == ptile->owner) {
730  // The tile is within the player's borders.
731  shared_vision_change_seen(pplayer, ptile, radius_sq, true);
732  }
733  }
735 }
736 
743 void map_show_tile(struct player *src_player, struct tile *ptile)
744 {
745  static int recurse = 0;
746 
747  log_debug("Showing %i,%i to %s", TILE_XY(ptile), player_name(src_player));
748 
749  fc_assert(recurse == 0);
750  recurse++;
751 
752  players_iterate(pplayer)
753  {
754  if (pplayer == src_player || really_gives_vision(src_player, pplayer)) {
755  struct city *pcity;
756 
757  if (!map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
758  map_set_known(ptile, pplayer);
759 
760  /* as the tile may be fogged send_tile_info won't always do this for
761  * us */
762  update_player_tile_knowledge(pplayer, ptile);
763  update_player_tile_last_seen(pplayer, ptile);
764 
765  send_tile_info(pplayer->connections, ptile, false);
766 
767  // remove old cities that exist no more
768  reality_check_city(pplayer, ptile);
769 
770  if ((pcity = tile_city(ptile))) {
771  // as the tile may be fogged send_city_info won't do this for us
772  update_dumb_city(pplayer, pcity);
773  send_city_info(pplayer, pcity);
774  }
775 
777  {
778  if (0 < map_get_seen(pplayer, ptile, v)) {
779  unit_list_iterate(ptile->units, punit)
780  {
781  if (v == unit_type_get(punit)->vlayer) {
782  send_unit_info(pplayer->connections, punit);
783  }
784  }
786  }
787  }
789  }
790  }
791  }
793 
794  recurse--;
795 }
796 
802 void map_hide_tile(struct player *src_player, struct tile *ptile)
803 {
804  static int recurse = 0;
805 
806  log_debug("Hiding %d,%d to %s", TILE_XY(ptile), player_name(src_player));
807 
808  fc_assert(recurse == 0);
809  recurse++;
810 
811  players_iterate(pplayer)
812  {
813  if (pplayer == src_player || really_gives_vision(src_player, pplayer)) {
814  if (map_is_known(ptile, pplayer)) {
815  if (0 < map_get_seen(pplayer, ptile, V_MAIN)) {
816  update_player_tile_last_seen(pplayer, ptile);
817  }
818 
819  // Remove city.
820  remove_dumb_city(pplayer, ptile);
821 
822  // Remove units.
824  {
825  if (0 < map_get_seen(pplayer, ptile, v)) {
826  unit_list_iterate(ptile->units, punit)
827  {
828  if (v == unit_type_get(punit)->vlayer) {
829  unit_goes_out_of_sight(pplayer, punit);
830  }
831  }
833  }
834  }
836  }
837 
838  map_clear_known(ptile, pplayer);
839 
840  send_tile_info(pplayer->connections, ptile, true);
841  }
842  }
844 
845  recurse--;
846 }
847 
852 void map_show_circle(struct player *pplayer, struct tile *ptile,
853  int radius_sq)
854 {
855  buffer_shared_vision(pplayer);
856 
857  circle_iterate(&(wld.map), ptile, radius_sq, tile1)
858  {
859  map_show_tile(pplayer, tile1);
860  }
862 
863  unbuffer_shared_vision(pplayer);
864 }
865 
870 void map_show_all(struct player *pplayer)
871 {
872  buffer_shared_vision(pplayer);
873 
874  whole_map_iterate(&(wld.map), ptile) { map_show_tile(pplayer, ptile); }
876 
877  unbuffer_shared_vision(pplayer);
878 }
879 
884 bool map_is_known(const struct tile *ptile, const struct player *pplayer)
885 {
886  return !pplayer->tile_known->isEmpty()
887  && pplayer->tile_known->at(tile_index(ptile));
888 }
889 
894 bool map_is_known_and_seen(const struct tile *ptile,
895  const struct player *pplayer,
896  enum vision_layer vlayer)
897 {
898  return (map_is_known(ptile, pplayer)
899  && 0 < map_get_seen(pplayer, ptile, vlayer));
900 }
901 
909 static inline int map_get_seen(const struct player *pplayer,
910  const struct tile *ptile,
911  enum vision_layer vlayer)
912 {
913  return map_get_player_tile(ptile, pplayer)->seen_count[vlayer];
914 }
915 
922 void map_change_seen(struct player *pplayer, struct tile *ptile,
923  const v_radius_t change, bool can_reveal_tiles)
924 {
925  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
926  bool revealing_tile = false;
927 
928 #ifdef FREECIV_DEBUG
929  log_debug("%s() for player %s (nb %d) at (%d, %d).", __FUNCTION__,
930  player_name(pplayer), player_number(pplayer), TILE_XY(ptile));
932  {
933  log_debug(" vision layer %d is changing from %d to %d.", v,
934  plrtile->seen_count[v], plrtile->seen_count[v] + change[v]);
935  }
937 #endif // FREECIV_DEBUG
938 
939  /* Removes units out of vision. First, check invisible layers because
940  * we must remove all units before fog of war because clients expect
941  * the tile is empty when it is fogged. */
942  if (0 > change[V_INVIS]
943  && plrtile->seen_count[V_INVIS] == -change[V_INVIS]) {
944  log_debug("(%d, %d): hiding invisible units to player %s (nb %d).",
945  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
946 
947  unit_list_iterate(ptile->units, punit)
948  {
949  if (V_INVIS == unit_type_get(punit)->vlayer
950  && can_player_see_unit(pplayer, punit)) {
951  unit_goes_out_of_sight(pplayer, punit);
952  }
953  }
955  }
956  if (0 > change[V_SUBSURFACE]
957  && plrtile->seen_count[V_SUBSURFACE] == -change[V_SUBSURFACE]) {
958  log_debug("(%d, %d): hiding subsurface units to player %s (nb %d).",
959  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
960 
961  unit_list_iterate(ptile->units, punit)
962  {
963  if (V_SUBSURFACE == unit_type_get(punit)->vlayer
964  && can_player_see_unit(pplayer, punit)) {
965  unit_goes_out_of_sight(pplayer, punit);
966  }
967  }
969  }
970 
971  if (0 > change[V_MAIN] && plrtile->seen_count[V_MAIN] == -change[V_MAIN]) {
972  log_debug("(%d, %d): hiding visible units to player %s (nb %d).",
973  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
974 
975  unit_list_iterate(ptile->units, punit)
976  {
977  if (V_MAIN == unit_type_get(punit)->vlayer
978  && can_player_see_unit(pplayer, punit)) {
979  unit_goes_out_of_sight(pplayer, punit);
980  }
981  }
983  }
984 
986  {
987  // Avoid underflow.
988  fc_assert(0 <= change[v] || -change[v] <= plrtile->seen_count[v]);
989  plrtile->seen_count[v] += change[v];
990  }
992 
993  /* V_MAIN vision ranges must always be more than invisible ranges
994  * (see comment in common/vision.h), so we assume that the V_MAIN
995  * seen count cannot be inferior to V_INVIS or V_SUBSURFACE seen count.
996  * Moreover, when the fog of war is disabled, V_MAIN has an extra
997  * seen count point. */
998  fc_assert(plrtile->seen_count[V_INVIS] + !game.info.fogofwar
999  <= plrtile->seen_count[V_MAIN]);
1000  fc_assert(plrtile->seen_count[V_SUBSURFACE] + !game.info.fogofwar
1001  <= plrtile->seen_count[V_MAIN]);
1002 
1003  if (!map_is_known(ptile, pplayer)) {
1004  if (0 < plrtile->seen_count[V_MAIN] && can_reveal_tiles) {
1005  log_debug("(%d, %d): revealing tile to player %s (nb %d).",
1006  TILE_XY(ptile), player_name(pplayer),
1007  player_number(pplayer));
1008 
1009  map_set_known(ptile, pplayer);
1010  revealing_tile = true;
1011  } else {
1012  return;
1013  }
1014  }
1015 
1016  // Fog the tile.
1017  if (0 > change[V_MAIN] && 0 == plrtile->seen_count[V_MAIN]) {
1018  log_debug("(%d, %d): fogging tile for player %s (nb %d).",
1019  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1020 
1021  update_player_tile_last_seen(pplayer, ptile);
1022  if (game.server.foggedborders) {
1023  plrtile->owner = tile_owner(ptile);
1024  }
1025  plrtile->extras_owner = extra_owner(ptile);
1026  send_tile_info(pplayer->connections, ptile, false);
1027  }
1028 
1029  if ((revealing_tile && 0 < plrtile->seen_count[V_MAIN])
1030  || (0 < change[V_MAIN]
1031  /* plrtile->seen_count[V_MAIN] Always set to 1
1032  * when the fog of war is disabled. */
1033  && (change[V_MAIN] + !game.info.fogofwar
1034  == (plrtile->seen_count[V_MAIN])))) {
1035  struct city *pcity;
1036 
1037  log_debug("(%d, %d): unfogging tile for player %s (nb %d).",
1038  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1039 
1040  /* Send info about the tile itself.
1041  * It has to be sent first because the client needs correct
1042  * continent number before it can handle following packets
1043  */
1044  update_player_tile_knowledge(pplayer, ptile);
1045  send_tile_info(pplayer->connections, ptile, false);
1046 
1047  // Discover units.
1048  unit_list_iterate(ptile->units, punit)
1049  {
1050  if (V_MAIN == unit_type_get(punit)->vlayer) {
1051  send_unit_info(pplayer->connections, punit);
1052  }
1053  }
1055 
1056  // Discover cities.
1057  reality_check_city(pplayer, ptile);
1058 
1059  if (nullptr != (pcity = tile_city(ptile))) {
1060  send_city_info(pplayer, pcity);
1061  }
1062  }
1063 
1064  if ((revealing_tile && 0 < plrtile->seen_count[V_INVIS])
1065  || (0 < change[V_INVIS]
1066  && change[V_INVIS] == plrtile->seen_count[V_INVIS])) {
1067  log_debug("(%d, %d): revealing invisible units to player %s (nb %d).",
1068  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1069  // Discover units.
1070  unit_list_iterate(ptile->units, punit)
1071  {
1072  if (V_INVIS == unit_type_get(punit)->vlayer) {
1073  send_unit_info(pplayer->connections, punit);
1074  }
1075  }
1077  }
1078  if ((revealing_tile && 0 < plrtile->seen_count[V_SUBSURFACE])
1079  || (0 < change[V_SUBSURFACE]
1080  && change[V_SUBSURFACE] == plrtile->seen_count[V_SUBSURFACE])) {
1081  log_debug("(%d, %d): revealing subsurface units to player %s (nb %d).",
1082  TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1083  // Discover units.
1084  unit_list_iterate(ptile->units, punit)
1085  {
1086  if (V_SUBSURFACE == unit_type_get(punit)->vlayer) {
1087  send_unit_info(pplayer->connections, punit);
1088  }
1089  }
1091  }
1092 }
1093 
1100 static inline int map_get_own_seen(const struct player *pplayer,
1101  const struct tile *ptile,
1102  enum vision_layer vlayer)
1103 {
1104  return map_get_player_tile(ptile, pplayer)->own_seen[vlayer];
1105 }
1106 
1110 static void map_change_own_seen(struct player *pplayer, struct tile *ptile,
1111  const v_radius_t change)
1112 {
1113  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1114 
1115  vision_layer_iterate(v) { plrtile->own_seen[v] += change[v]; }
1117 }
1118 
1123  struct vision_site *new_site)
1124 {
1125  if (ptile->site.get() != new_site) {
1126  ptile->site.reset(new_site);
1127  }
1128 }
1129 
1133 void map_set_known(struct tile *ptile, struct player *pplayer)
1134 {
1135  pplayer->tile_known->setBit(tile_index(ptile));
1136 }
1137 
1141 void map_clear_known(struct tile *ptile, struct player *pplayer)
1142 {
1143  pplayer->tile_known->setBit(tile_index(ptile), false);
1144 }
1145 
1151 void map_know_and_see_all(struct player *pplayer)
1152 {
1153  const v_radius_t radius_sq = V_RADIUS(1, 1, 1);
1154 
1155  buffer_shared_vision(pplayer);
1156  whole_map_iterate(&(wld.map), ptile)
1157  {
1158  map_change_seen(pplayer, ptile, radius_sq, true);
1159  }
1161  unbuffer_shared_vision(pplayer);
1162 }
1163 
1168 {
1169  players_iterate(pplayer) { map_know_and_see_all(pplayer); }
1171 }
1172 
1177 void player_map_init(struct player *pplayer)
1178 {
1179  delete[] pplayer->server.private_map;
1180  pplayer->server.private_map = new player_tile[MAP_INDEX_SIZE];
1181 
1182  whole_map_iterate(&(wld.map), ptile) { player_tile_init(ptile, pplayer); }
1184 
1185  pplayer->tile_known->resize(MAP_INDEX_SIZE);
1186 }
1187 
1191 void player_map_free(struct player *pplayer)
1192 {
1193  if (!pplayer->server.private_map) {
1194  return;
1195  }
1196 
1197  whole_map_iterate(&(wld.map), ptile) { player_tile_free(ptile, pplayer); }
1199 
1200  delete[] pplayer->server.private_map;
1201  pplayer->server.private_map = nullptr;
1202  pplayer->tile_known->clear();
1203 }
1204 
1210 void remove_player_from_maps(struct player *pplayer)
1211 {
1212  // only after removing borders!
1214  whole_map_iterate(&(wld.map), ptile)
1215  {
1216  /* Clear all players' knowledge about the removed player, and free
1217  * data structures (including those in removed player's player map). */
1218  bool reality_changed = false;
1219 
1220  players_iterate(aplayer)
1221  {
1222  struct player_tile *aplrtile;
1223  bool changed = false;
1224 
1225  if (!aplayer->server.private_map) {
1226  continue;
1227  }
1228  aplrtile = map_get_player_tile(ptile, aplayer);
1229 
1230  // Free vision sites (cities) for removed and other players
1231  if (aplrtile && aplrtile->site
1232  && vision_site_owner(aplrtile->site) == pplayer) {
1233  change_playertile_site(aplrtile, nullptr);
1234  changed = true;
1235  }
1236 
1237  // Remove references to player from others' maps
1238  if (aplrtile->owner == pplayer) {
1239  aplrtile->owner = nullptr;
1240  changed = true;
1241  }
1242  if (aplrtile->extras_owner == pplayer) {
1243  aplrtile->extras_owner = nullptr;
1244  changed = true;
1245  }
1246 
1247  /* Must ensure references to dying player are gone from clients
1248  * before player is destroyed */
1249  if (changed) {
1250  // This will use player tile if fogged
1251  send_tile_info(pplayer->connections, ptile, false);
1252  }
1253  }
1255 
1256  // Clear removed player's knowledge
1257  if (pplayer->tile_known->size()) {
1258  map_clear_known(ptile, pplayer);
1259  }
1260 
1261  // Free all claimed tiles.
1262  if (tile_owner(ptile) == pplayer) {
1263  tile_set_owner(ptile, nullptr, nullptr);
1264  reality_changed = true;
1265  }
1266  if (extra_owner(ptile) == pplayer) {
1267  ptile->extras_owner = nullptr;
1268  reality_changed = true;
1269  }
1270 
1271  if (reality_changed) {
1272  // Update anyone who can see the tile (e.g. global observers)
1273  send_tile_info(nullptr, ptile, false);
1274  }
1275  }
1278 }
1279 
1284 static void player_tile_init(struct tile *ptile, struct player *pplayer)
1285 {
1286  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1287 
1288  plrtile->terrain = T_UNKNOWN;
1289  plrtile->resource = nullptr;
1290  plrtile->owner = nullptr;
1291  plrtile->extras_owner = nullptr;
1292  plrtile->site = nullptr;
1293  BV_CLR_ALL(plrtile->extras);
1294  if (!game.server.last_updated_year) {
1295  plrtile->last_updated = game.info.turn;
1296  } else {
1297  plrtile->last_updated = game.info.year;
1298  }
1299 
1300  plrtile->seen_count[V_MAIN] = !game.server.fogofwar_old;
1301  plrtile->seen_count[V_INVIS] = 0;
1302  plrtile->seen_count[V_SUBSURFACE] = 0;
1303  memcpy(plrtile->own_seen, plrtile->seen_count, sizeof(v_radius_t));
1304 }
1305 
1309 static void player_tile_free(struct tile *ptile, struct player *pplayer)
1310 {
1311  map_get_player_tile(ptile, pplayer)->site = nullptr;
1312 }
1313 
1317 struct vision_site *map_get_player_city(const struct tile *ptile,
1318  const struct player *pplayer)
1319 {
1320  struct vision_site *psite = map_get_player_site(ptile, pplayer);
1321 
1322  fc_assert_ret_val(psite == nullptr || psite->location == ptile, nullptr);
1323 
1324  return psite;
1325 }
1326 
1330 struct vision_site *map_get_player_site(const struct tile *ptile,
1331  const struct player *pplayer)
1332 {
1333  return map_get_player_tile(ptile, pplayer)->site.get();
1334 }
1335 
1341 struct player_tile *map_get_player_tile(const struct tile *ptile,
1342  const struct player *pplayer)
1343 {
1344  fc_assert_ret_val(pplayer->server.private_map, nullptr);
1345 
1346  return pplayer->server.private_map + tile_index(ptile);
1347 }
1348 
1357 bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
1358 {
1359  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1360 
1361  if (plrtile->terrain != ptile->terrain
1362  || !BV_ARE_EQUAL(plrtile->extras, ptile->extras)
1363  || plrtile->resource != ptile->resource
1364  || plrtile->owner != tile_owner(ptile)
1365  || plrtile->extras_owner != extra_owner(ptile)) {
1366  plrtile->terrain = ptile->terrain;
1367  extra_type_iterate(pextra)
1368  {
1369  if (player_knows_extra_exist(pplayer, pextra, ptile)) {
1370  BV_SET(plrtile->extras, extra_number(pextra));
1371  } else {
1372  BV_CLR(plrtile->extras, extra_number(pextra));
1373  }
1374  }
1376  plrtile->resource = ptile->resource;
1377  plrtile->owner = tile_owner(ptile);
1378  plrtile->extras_owner = extra_owner(ptile);
1379 
1380  return true;
1381  }
1382 
1383  return false;
1384 }
1385 
1395 void update_tile_knowledge(struct tile *ptile)
1396 {
1397  if (server_state() == S_S_INITIAL) {
1398  return;
1399  }
1400 
1401  // Players
1402  players_iterate(pplayer)
1403  {
1404  if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
1405  if (update_player_tile_knowledge(pplayer, ptile)) {
1406  send_tile_info(pplayer->connections, ptile, false);
1407  }
1408  }
1409  }
1411 
1412  // Global observers
1414  {
1415  struct player *pplayer = pconn->playing;
1416 
1417  if (nullptr == pplayer && pconn->observer) {
1418  send_tile_info(pconn->self, ptile, false);
1419  }
1420  }
1422 }
1423 
1427 void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
1428 {
1429  if (!game.server.last_updated_year) {
1430  map_get_player_tile(ptile, pplayer)->last_updated = game.info.turn;
1431  } else {
1432  map_get_player_tile(ptile, pplayer)->last_updated = game.info.year;
1433  }
1434 }
1435 
1440  struct player *pdest,
1441  struct tile *ptile)
1442 {
1443  // No need to transfer if pdest can see the tile
1444  if (map_is_known_and_seen(ptile, pdest, V_MAIN)) {
1445  return;
1446  }
1447 
1448  // Nothing to transfer if the pfrom doesn't know the tile
1449  if (!map_is_known(ptile, pfrom)) {
1450  return;
1451  }
1452 
1453  // If pdest knows the tile, check that pfrom has more recent info
1454  if (map_is_known(ptile, pdest)
1455  && !map_is_known_and_seen(ptile, pfrom, V_MAIN)
1456  && map_get_player_tile(ptile, pfrom)->last_updated
1457  <= map_get_player_tile(ptile, pdest)->last_updated) {
1458  return;
1459  }
1460 
1461  // Transfer knowldege
1462  auto from_tile = map_get_player_tile(ptile, pfrom);
1463  auto dest_tile = map_get_player_tile(ptile, pdest);
1464 
1465  // Update and send tile knowledge
1466  map_set_known(ptile, pdest);
1467  dest_tile->terrain = from_tile->terrain;
1468  dest_tile->extras = from_tile->extras;
1469  dest_tile->resource = from_tile->resource;
1470  dest_tile->owner = from_tile->owner;
1471  dest_tile->extras_owner = from_tile->extras_owner;
1472  dest_tile->last_updated = from_tile->last_updated;
1473  send_tile_info(pdest->connections, ptile, false);
1474 
1475  // Set and send latest city info
1476  if (from_tile->site) {
1477  change_playertile_site(dest_tile, new vision_site(*from_tile->site));
1478  // Note that we don't care if receiver knows vision source city or not.
1479  send_city_info_at_tile(pdest, pdest->connections, nullptr, ptile);
1480  }
1481 
1483 }
1484 
1490  struct player *pdest)
1491 {
1492  whole_map_iterate(&(wld.map), ptile)
1493  {
1494  really_give_tile_info_from_player_to_player(pfrom, pdest, ptile);
1495  }
1497 
1499  sync_cities();
1500 }
1501 
1507  struct player *pdest,
1508  struct tile *ptile)
1509 {
1510  really_give_tile_info_from_player_to_player(pfrom, pdest, ptile);
1511 
1512  players_iterate(pplayer2)
1513  {
1514  if (really_gives_vision(pdest, pplayer2)) {
1515  really_give_tile_info_from_player_to_player(pfrom, pplayer2, ptile);
1516  }
1517  }
1519 }
1520 
1527 {
1528  int added;
1529 
1530  players_iterate(pplayer)
1531  {
1532  pplayer->server.really_gives_vision = pplayer->gives_shared_vision;
1533  }
1535 
1536  /* In words: This terminates when it has run a round without adding
1537  a dependency. One loop only propagates dependencies one level deep,
1538  which is why we keep doing it as long as changes occur. */
1539  do {
1540  added = 0;
1541  players_iterate(pplayer)
1542  {
1543  players_iterate(pplayer2)
1544  {
1545  if (really_gives_vision(pplayer, pplayer2) && pplayer != pplayer2) {
1546  players_iterate(pplayer3)
1547  {
1548  if (really_gives_vision(pplayer2, pplayer3)
1549  && !really_gives_vision(pplayer, pplayer3)
1550  && pplayer != pplayer3) {
1551  BV_SET(pplayer->server.really_gives_vision,
1552  player_index(pplayer3));
1553  added++;
1554  }
1555  }
1557  }
1558  }
1560  }
1562  } while (added > 0);
1563 }
1564 
1568 void give_shared_vision(struct player *pfrom, struct player *pto)
1569 {
1570  bv_player save_vision[MAX_NUM_PLAYER_SLOTS];
1571  if (pfrom == pto) {
1572  return;
1573  }
1574  if (gives_shared_vision(pfrom, pto)) {
1575  qCritical("Trying to give shared vision from %s to %s, "
1576  "but that vision is already given!",
1577  player_name(pfrom), player_name(pto));
1578  return;
1579  }
1580 
1581  players_iterate(pplayer)
1582  {
1583  save_vision[player_index(pplayer)] = pplayer->server.really_gives_vision;
1584  }
1586 
1587  BV_SET(pfrom->gives_shared_vision, player_index(pto));
1589  log_debug("giving shared vision from %s to %s", player_name(pfrom),
1590  player_name(pto));
1591 
1592  players_iterate(pplayer)
1593  {
1594  buffer_shared_vision(pplayer);
1595  players_iterate(pplayer2)
1596  {
1597  if (really_gives_vision(pplayer, pplayer2)
1598  && !BV_ISSET(save_vision[player_index(pplayer)],
1599  player_index(pplayer2))) {
1600  log_debug("really giving shared vision from %s to %s",
1601  player_name(pplayer), player_name(pplayer2));
1602  whole_map_iterate(&(wld.map), ptile)
1603  {
1604  const v_radius_t change =
1605  V_RADIUS(map_get_own_seen(pplayer, ptile, V_MAIN),
1606  map_get_own_seen(pplayer, ptile, V_INVIS),
1607  map_get_own_seen(pplayer, ptile, V_SUBSURFACE));
1608 
1609  if (0 < change[V_MAIN] || 0 < change[V_INVIS]) {
1610  map_change_seen(pplayer2, ptile, change,
1611  map_is_known(ptile, pplayer));
1612  }
1613  }
1615 
1616  /* squares that are not seen, but which pfrom may have more recent
1617  knowledge of */
1618  really_give_map_from_player_to_player(pplayer, pplayer2);
1619  }
1620  }
1622  unbuffer_shared_vision(pplayer);
1623  }
1625 
1626  if (S_S_RUNNING == server_state()) {
1627  send_player_info_c(pfrom, nullptr);
1628  }
1629 }
1630 
1634 void remove_shared_vision(struct player *pfrom, struct player *pto)
1635 {
1636  bv_player save_vision[MAX_NUM_PLAYER_SLOTS];
1637 
1638  fc_assert_ret(pfrom != pto);
1639  if (!gives_shared_vision(pfrom, pto)) {
1640  qCritical("Tried removing the shared vision from %s to %s, "
1641  "but it did not exist in the first place!",
1642  player_name(pfrom), player_name(pto));
1643  return;
1644  }
1645 
1646  players_iterate(pplayer)
1647  {
1648  save_vision[player_index(pplayer)] = pplayer->server.really_gives_vision;
1649  }
1651 
1652  log_debug("removing shared vision from %s to %s", player_name(pfrom),
1653  player_name(pto));
1654 
1655  BV_CLR(pfrom->gives_shared_vision, player_index(pto));
1657 
1658  players_iterate(pplayer)
1659  {
1660  buffer_shared_vision(pplayer);
1661  players_iterate(pplayer2)
1662  {
1663  if (!really_gives_vision(pplayer, pplayer2)
1664  && BV_ISSET(save_vision[player_index(pplayer)],
1665  player_index(pplayer2))) {
1666  log_debug("really removing shared vision from %s to %s",
1667  player_name(pplayer), player_name(pplayer2));
1668  whole_map_iterate(&(wld.map), ptile)
1669  {
1670  const v_radius_t change =
1671  V_RADIUS(-map_get_own_seen(pplayer, ptile, V_MAIN),
1672  -map_get_own_seen(pplayer, ptile, V_INVIS),
1673  -map_get_own_seen(pplayer, ptile, V_SUBSURFACE));
1674 
1675  if (0 > change[V_MAIN] || 0 > change[V_INVIS]) {
1676  map_change_seen(pplayer2, ptile, change, false);
1677  }
1678  }
1680  }
1681  }
1683  unbuffer_shared_vision(pplayer);
1684  }
1686 
1687  if (S_S_RUNNING == server_state()) {
1688  send_player_info_c(pfrom, nullptr);
1689  }
1690 }
1691 
1695 void enable_fog_of_war_player(struct player *pplayer)
1696 {
1697  const v_radius_t radius_sq = V_RADIUS(-1, 0, 0);
1698 
1699  buffer_shared_vision(pplayer);
1700  whole_map_iterate(&(wld.map), ptile)
1701  {
1702  map_change_seen(pplayer, ptile, radius_sq, false);
1703  }
1705  unbuffer_shared_vision(pplayer);
1706 }
1707 
1712 {
1713  players_iterate(pplayer) { enable_fog_of_war_player(pplayer); }
1715 }
1716 
1720 void disable_fog_of_war_player(struct player *pplayer)
1721 {
1722  const v_radius_t radius_sq = V_RADIUS(1, 0, 0);
1723 
1724  buffer_shared_vision(pplayer);
1725  whole_map_iterate(&(wld.map), ptile)
1726  {
1727  map_change_seen(pplayer, ptile, radius_sq, false);
1728  }
1730  unbuffer_shared_vision(pplayer);
1731 }
1732 
1737 {
1738  players_iterate(pplayer) { disable_fog_of_war_player(pplayer); }
1740 }
1741 
1751 static void ocean_to_land_fix_rivers(struct tile *ptile)
1752 {
1753  cardinal_adjc_iterate(&(wld.map), ptile, tile1)
1754  {
1755  bool ocean_near = false;
1756 
1757  cardinal_adjc_iterate(&(wld.map), tile1, tile2)
1758  {
1759  if (is_ocean_tile(tile2)) {
1760  ocean_near = true;
1761  }
1762  }
1764 
1765  if (!ocean_near) {
1766  /* If ruleset has several river types defined, this
1767  * may cause same tile to contain more than one river. */
1768  extra_type_by_cause_iterate(EC_ROAD, priver)
1769  {
1770  if (tile_has_extra(tile1, priver)
1771  && road_has_flag(extra_road_get(priver), RF_RIVER)) {
1772  tile_add_extra(ptile, priver);
1773  }
1774  }
1776  }
1777  }
1779 }
1780 
1785 static void check_units_single_tile(struct tile *ptile)
1786 {
1787  unit_list_iterate_safe(ptile->units, punit)
1788  {
1789  if (unit_tile(punit) == ptile && !unit_transported(punit)
1790  && !can_unit_exist_at_tile(&(wld.map), punit, ptile)) {
1791  bounce_unit(punit, true, bounce_reason::terrain_change, 1);
1792  }
1793  }
1795 }
1796 
1803 {
1804  // Check this tile for direct effect on its units
1805  check_units_single_tile(ptile);
1806  /* We have to check adjacent tiles too, in case units in cities are now
1807  * illegal (e.g., boat in a city that has become landlocked). */
1808  adjc_iterate(&(wld.map), ptile, ptile2)
1809  {
1810  check_units_single_tile(ptile2);
1811  }
1813 }
1814 
1819 bool need_to_reassign_continents(const struct terrain *oldter,
1820  const struct terrain *newter)
1821 {
1822  bool old_is_ocean, new_is_ocean;
1823 
1824  if (!oldter || !newter) {
1825  return false;
1826  }
1827 
1828  old_is_ocean = is_ocean(oldter);
1829  new_is_ocean = is_ocean(newter);
1830 
1831  return (old_is_ocean && !new_is_ocean) || (!old_is_ocean && new_is_ocean);
1832 }
1833 
1837 void terrain_changed(struct tile *ptile)
1838 {
1839  struct city *pcity = tile_city(ptile);
1840 
1841  if (pcity != nullptr) {
1842  // Tile is city center and new terrain may support better extras.
1843  upgrade_city_extras(pcity, nullptr);
1844  }
1845 
1847 }
1848 
1856 void fix_tile_on_terrain_change(struct tile *ptile, struct terrain *oldter,
1857  bool extend_rivers)
1858 {
1859  if (is_ocean(oldter) && !is_ocean_tile(ptile)) {
1860  if (extend_rivers) {
1861  ocean_to_land_fix_rivers(ptile);
1862  }
1864  }
1865 
1866  terrain_changed(ptile);
1867 }
1868 
1875 void check_terrain_change(struct tile *ptile, struct terrain *oldter)
1876 {
1877  struct terrain *newter = tile_terrain(ptile);
1878  struct tile *claimer;
1879 
1880  /* Check if new terrain is a freshwater terrain next to non-freshwater.
1881  * In that case, the new terrain is *changed*. */
1882  if (is_ocean(newter) && terrain_has_flag(newter, TER_FRESHWATER)) {
1883  bool nonfresh = false;
1884 
1885  adjc_iterate(&(wld.map), ptile, atile)
1886  {
1887  if (is_ocean(tile_terrain(atile))
1888  && !terrain_has_flag(tile_terrain(atile), TER_FRESHWATER)) {
1889  nonfresh = true;
1890  break;
1891  }
1892  }
1894  if (nonfresh) {
1895  /* Need to pick a new, non-freshwater ocean type for this tile.
1896  * We don't want e.g. Deep Ocean to be propagated to this tile
1897  * and then to a whole lake by the flooding below, so we pick
1898  * the shallowest non-fresh oceanic type.
1899  * Prefer terrain that matches the frozenness of the target. */
1900  newter = most_shallow_ocean(terrain_has_flag(newter, TER_FROZEN));
1901  tile_change_terrain(ptile, newter);
1902  }
1903  }
1904 
1905  fix_tile_on_terrain_change(ptile, oldter, true);
1906 
1907  // Check for saltwater filling freshwater lake
1908  if (game.scenario.lake_flooding && is_ocean(newter)
1909  && !terrain_has_flag(newter, TER_FRESHWATER)) {
1910  adjc_iterate(&(wld.map), ptile, atile)
1911  {
1912  if (terrain_has_flag(tile_terrain(atile), TER_FRESHWATER)) {
1913  struct terrain *aold = tile_terrain(atile);
1914 
1916  atile, most_shallow_ocean(terrain_has_flag(aold, TER_FROZEN)));
1917 
1918  /* Recursive, but as lakes are of limited size, this
1919  * won't recurse so much as to cause stack problems. */
1920  check_terrain_change(atile, aold);
1921  update_tile_knowledge(atile);
1922  }
1923  }
1925  }
1926 
1927  if (need_to_reassign_continents(oldter, newter)) {
1929  send_all_known_tiles(nullptr);
1930  }
1931 
1932  claimer = tile_claimer(ptile);
1933  if (claimer != nullptr && is_ocean_tile(ptile)) {
1934  if (!is_claimable_ocean(ptile, claimer, tile_owner(ptile))) {
1935  map_clear_border(ptile);
1936  }
1937  }
1938 
1939  sanity_check_tile(ptile);
1940 }
1941 
1953 static bool is_claimable_ocean(struct tile *ptile, struct tile *source,
1954  struct player *pplayer)
1955 {
1956  Continent_id cont = tile_continent(ptile);
1957  Continent_id cont1 = tile_continent(source);
1958  Continent_id cont2;
1959  int ocean_tiles;
1960  bool other_continent;
1961 
1963  && get_lake_surrounders(cont) == cont1) {
1964  return true;
1965  }
1966 
1967  if (ptile == source) {
1968  // Source itself is always claimable.
1969  return true;
1970  }
1971 
1972  if (num_known_tech_with_flag(pplayer, TF_CLAIM_OCEAN) > 0
1973  || (cont1 < 0
1974  && num_known_tech_with_flag(pplayer, TF_CLAIM_OCEAN_LIMITED)
1975  > 0)) {
1976  return true;
1977  }
1978 
1979  ocean_tiles = 0;
1980  other_continent = false;
1981  adjc_iterate(&(wld.map), ptile, tile2)
1982  {
1983  cont2 = tile_continent(tile2);
1984  if (tile2 == source) {
1985  // Water next to border source is always claimable
1986  return true;
1987  }
1988  if (cont2 == cont) {
1989  ocean_tiles++;
1990  } else if (cont1 <= 0) {
1991  // First adjacent land (only if border source is not on land)
1992  cont1 = cont2;
1993  } else if (cont2 != cont1) {
1994  /* This water has two land continents adjacent, or land adjacent
1995  * that is of a different continent from the border source */
1996  other_continent = true;
1997  }
1998  }
2000  return !other_continent && ocean_tiles <= 2;
2001 }
2002 
2006 static void map_unit_homecity_enqueue(struct tile *ptile)
2007 {
2008  unit_list_iterate(ptile->units, punit)
2009  {
2010  struct city *phome = game_city_by_number(punit->homecity);
2011 
2012  if (nullptr == phome) {
2013  continue;
2014  }
2015 
2016  city_refresh_queue_add(phome);
2017  }
2019 }
2020 
2024 static void map_claim_border_ownership(struct tile *ptile,
2025  struct player *powner,
2026  struct tile *psource)
2027 {
2028  struct player *ploser = tile_owner(ptile);
2029 
2030  if ((ploser != powner && ploser != nullptr)
2031  && (BORDERS_SEE_INSIDE == game.info.borders
2032  || BORDERS_EXPAND == game.info.borders
2033  || ploser->server.border_vision)) {
2034  const v_radius_t radius_sq = V_RADIUS(-1, 0, 0);
2035 
2036  shared_vision_change_seen(ploser, ptile, radius_sq, false);
2037  }
2038 
2039  if (powner != nullptr
2040  && (BORDERS_SEE_INSIDE == game.info.borders
2041  || BORDERS_EXPAND == game.info.borders
2042  || powner->server.border_vision)) {
2043  const v_radius_t radius_sq = V_RADIUS(1, 0, 0);
2044 
2045  shared_vision_change_seen(powner, ptile, radius_sq, true);
2046  }
2047 
2048  tile_set_owner(ptile, powner, psource);
2049 
2050  /* Needed only when foggedborders enabled, but we do it unconditionally
2051  * in case foggedborders ever gets enabled later. Better to have correct
2052  * information in player map just in case. */
2053  update_tile_knowledge(ptile);
2054 
2055  if (ploser != powner) {
2056  if (S_S_RUNNING == server_state()
2057  && game.info.happyborders != HB_DISABLED) {
2059  }
2060 
2061  if (!city_map_update_tile_frozen(ptile)) {
2062  send_tile_info(nullptr, ptile, false);
2063  }
2064  }
2065 }
2066 
2070 void map_claim_ownership(struct tile *ptile, struct player *powner,
2071  struct tile *psource, bool claim_bases)
2072 {
2073  map_claim_border_ownership(ptile, powner, psource);
2074 
2075  if (claim_bases) {
2076  tile_claim_bases(ptile, powner);
2077  }
2078 }
2079 
2083 void tile_claim_bases(struct tile *ptile, struct player *powner)
2084 {
2085  struct player *base_loser = extra_owner(ptile);
2086 
2087  /* This MUST be before potentially recursive call to map_claim_base(),
2088  * so that the recursive call will get new owner == base_loser and
2089  * abort recursion. */
2090  ptile->extras_owner = powner;
2091 
2092  extra_type_by_cause_iterate(EC_BASE, pextra)
2093  {
2094  map_claim_base(ptile, pextra, powner, base_loser);
2095  }
2097 }
2098 
2102 void map_clear_border(struct tile *ptile)
2103 {
2104  int radius_sq = tile_border_source_radius_sq(ptile);
2105 
2106  circle_dxyr_iterate(&(wld.map), ptile, radius_sq, dtile, dx, dy, dr)
2107  {
2108  struct tile *claimer = tile_claimer(dtile);
2109 
2110  if (claimer == ptile) {
2111  map_claim_ownership(dtile, nullptr, nullptr, false);
2112  }
2113  }
2115 }
2116 
2121 void map_update_border(struct tile *ptile, struct player *owner,
2122  int old_radius_sq, int new_radius_sq)
2123 {
2124  if (old_radius_sq == new_radius_sq) {
2125  // No change
2126  return;
2127  }
2128 
2129  if (BORDERS_DISABLED == game.info.borders) {
2130  return;
2131  }
2132 
2133  if (old_radius_sq < new_radius_sq) {
2134  map_claim_border(ptile, owner, new_radius_sq);
2135  } else {
2136  circle_dxyr_iterate(&(wld.map), ptile, old_radius_sq, dtile, dx, dy, dr)
2137  {
2138  if (dr > new_radius_sq) {
2139  struct tile *claimer = tile_claimer(dtile);
2140 
2141  if (claimer == ptile) {
2142  map_claim_ownership(dtile, nullptr, nullptr, false);
2143  }
2144  }
2145  }
2147  }
2148 }
2149 
2155 void map_claim_border(struct tile *ptile, struct player *owner,
2156  int radius_sq)
2157 {
2158  if (BORDERS_DISABLED == game.info.borders) {
2159  return;
2160  }
2161 
2162  if (owner == nullptr) {
2163  /* Clear the border instead of claiming. Code below this block
2164  * cannot handle nullptr owner. */
2165  map_clear_border(ptile);
2166 
2167  return;
2168  }
2169 
2170  if (radius_sq < 0) {
2171  radius_sq = tile_border_source_radius_sq(ptile);
2172  }
2173 
2174  circle_dxyr_iterate(&(wld.map), ptile, radius_sq, dtile, dx, dy, dr)
2175  {
2176  struct tile *dclaimer = tile_claimer(dtile);
2177 
2178  if (dclaimer == ptile) {
2179  // Already claimed by the ptile
2180  continue;
2181  }
2182 
2183  if (dr != 0 && is_border_source(dtile)) {
2184  // Do not claim border sources other than self
2185  /* Note that this is extremely important at the moment for
2186  * base claiming to work correctly in case there's two
2187  * fortresses near each other. There could be infinite
2188  * recursion in them claiming each other. */
2189  continue;
2190  }
2191 
2192  if (!map_is_known(dtile, owner) && game.info.borders < BORDERS_EXPAND) {
2193  continue;
2194  }
2195 
2196  // Always claim source itself (distance, dr, to it 0)
2197  if (dr != 0 && nullptr != dclaimer && dclaimer != ptile) {
2198  struct city *ccity = tile_city(dclaimer);
2199  int strength_old, strength_new;
2200 
2201  if (ccity != nullptr) {
2202  // Previously claimed by city
2203  int city_x, city_y;
2204 
2205  map_distance_vector(&city_x, &city_y, ccity->tile, dtile);
2206 
2207  if (map_vector_to_sq_distance(city_x, city_y)
2208  <= city_map_radius_sq_get(ccity)
2209  + game.info.border_city_permanent_radius_sq) {
2210  // Tile is within region permanently claimed by city
2211  continue;
2212  }
2213  }
2214 
2215  strength_old = tile_border_strength(dtile, dclaimer);
2216  strength_new = tile_border_strength(dtile, ptile);
2217 
2218  if (strength_new <= strength_old) {
2219  /* Stronger shall prevail,
2220  * in case of equal strength older shall prevail */
2221  continue;
2222  }
2223  }
2224 
2225  if (is_ocean_tile(dtile)) {
2226  // Only certain water tiles are claimable
2227  if (is_claimable_ocean(dtile, ptile, owner)) {
2228  map_claim_ownership(dtile, owner, ptile, dr == 0);
2229  }
2230  } else {
2231  /* Only land tiles on the same island as the border source
2232  * are claimable */
2233  if (tile_continent(dtile) == tile_continent(ptile)) {
2234  map_claim_ownership(dtile, owner, ptile, dr == 0);
2235  }
2236  }
2237  }
2239 }
2240 
2245 {
2246  if (BORDERS_DISABLED == game.info.borders) {
2247  return;
2248  }
2249 
2250  if (wld.map.tiles == nullptr) {
2251  // Map not yet initialized
2252  return;
2253  }
2254 
2255  qDebug("map_calculate_borders()");
2256 
2257  whole_map_iterate(&(wld.map), ptile)
2258  {
2259  if (is_border_source(ptile)) {
2260  map_claim_border(ptile, ptile->owner, -1);
2261  }
2262  }
2264 
2265  qDebug("map_calculate_borders() workers");
2268 }
2269 
2273 void map_claim_base(struct tile *ptile, const extra_type *pextra,
2274  struct player *powner, struct player *ploser)
2275 {
2276  struct base_type *pbase;
2277  int units_num;
2278  int i;
2279 
2280  if (!tile_has_extra(ptile, pextra)) {
2281  return;
2282  }
2283 
2284  units_num = unit_list_size(ptile->units);
2285  auto could_see_unit =
2286  (units_num > 0 ? std::make_unique<bv_player[]>(units_num) : nullptr);
2287 
2288  i = 0;
2289  if (pextra->eus != EUS_NORMAL) {
2290  unit_list_iterate(ptile->units, aunit)
2291  {
2292  BV_CLR_ALL(could_see_unit[i]);
2293  players_iterate(aplayer)
2294  {
2295  if (can_player_see_unit(aplayer, aunit)) {
2296  BV_SET(could_see_unit[i], player_index(aplayer));
2297  }
2298  }
2300  i++;
2301  }
2303  }
2304 
2305  pbase = extra_base_get(pextra);
2306 
2307  fc_assert_ret(pbase != nullptr);
2308 
2309  // Transfer base provided vision to new owner
2310  if (powner != nullptr) {
2311  const v_radius_t old_radius_sq = V_RADIUS(-1, -1, -1);
2312  const v_radius_t new_radius_sq =
2313  V_RADIUS(pbase->vision_main_sq, pbase->vision_invis_sq,
2314  pbase->vision_subs_sq);
2315 
2316  map_vision_update(powner, ptile, old_radius_sq, new_radius_sq,
2317  game.server.vision_reveal_tiles);
2318  }
2319 
2320  if (ploser != nullptr) {
2321  const v_radius_t old_radius_sq =
2322  V_RADIUS(pbase->vision_main_sq, pbase->vision_invis_sq,
2323  pbase->vision_subs_sq);
2324  const v_radius_t new_radius_sq = V_RADIUS(-1, -1, -1);
2325 
2326  map_vision_update(ploser, ptile, old_radius_sq, new_radius_sq,
2327  game.server.vision_reveal_tiles);
2328  }
2329 
2330  if (BORDERS_DISABLED != game.info.borders && territory_claiming_base(pbase)
2331  && powner != ploser) {
2332  /* Clear borders from old owner. New owner may not know all those
2333  * tiles and thus does not claim them when borders mode is less
2334  * than EXPAND. */
2335  if (ploser != nullptr) {
2336  /* Set this particular tile owner by nullptr so in recursion
2337  * both loser and owner will be nullptr. */
2338  map_claim_border_ownership(ptile, nullptr, ptile);
2339  map_clear_border(ptile);
2340  }
2341 
2342  /* We here first claim this tile ownership -> now on extra_owner()
2343  * will return new owner. Then we claim border, which will recursively
2344  * lead to this tile and base being claimed. But at that point
2345  * ploser == powner and above check will abort the recursion. */
2346  if (powner != nullptr) {
2347  map_claim_border_ownership(ptile, powner, ptile);
2348  map_claim_border(ptile, powner, -1);
2349  }
2352  }
2353 
2354  i = 0;
2355  if (pextra->eus != EUS_NORMAL) {
2356  unit_list_iterate(ptile->units, aunit)
2357  {
2358  players_iterate(aplayer)
2359  {
2360  if (can_player_see_unit(aplayer, aunit)) {
2361  if (!BV_ISSET(could_see_unit[i], player_index(aplayer))) {
2362  send_unit_info(aplayer->connections, aunit);
2363  }
2364  } else {
2365  if (BV_ISSET(could_see_unit[i], player_index(aplayer))) {
2366  unit_goes_out_of_sight(aplayer, aunit);
2367  }
2368  }
2369  }
2371  i++;
2372  }
2374  }
2375 }
2376 
2383 void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
2384 {
2386  radius_sq, vision->can_reveal_tiles);
2387  memcpy(vision->radius_sq, radius_sq, sizeof(v_radius_t));
2388 }
2389 
2396 {
2397  const v_radius_t vision_radius_sq = V_RADIUS(-1, -1, -1);
2398 
2399  vision_change_sight(vision, vision_radius_sq);
2400 }
2401 
2405 void create_extra(struct tile *ptile, const extra_type *pextra,
2406  struct player *pplayer)
2407 {
2408  bool extras_removed = false;
2409 
2410  extra_type_iterate(old_extra)
2411  {
2412  if (tile_has_extra(ptile, old_extra)
2413  && !can_extras_coexist(old_extra, pextra)) {
2414  destroy_extra(ptile, old_extra);
2415  extras_removed = true;
2416  }
2417  }
2419 
2420  if (pextra->eus != EUS_NORMAL) {
2421  unit_list_iterate(ptile->units, aunit)
2422  {
2423  if (is_native_extra_to_utype(pextra, unit_type_get(aunit))) {
2424  players_iterate(aplayer)
2425  {
2426  if (!pplayers_allied(pplayer, aplayer)
2427  && can_player_see_unit(aplayer, aunit)) {
2428  unit_goes_out_of_sight(aplayer, aunit);
2429  }
2430  }
2432  }
2433  }
2435  }
2436 
2437  tile_add_extra(ptile, pextra);
2438 
2439  // Watchtower might become effective.
2441 
2442  if (pextra->data.base != nullptr) {
2443  // Claim bases on tile
2444  if (pplayer) {
2445  struct player *old_owner = extra_owner(ptile);
2446 
2447  // Created base from nullptr -> pplayer
2448  map_claim_base(ptile, pextra, pplayer, nullptr);
2449 
2450  if (old_owner != pplayer) {
2451  // Existing bases from old_owner -> pplayer
2452  extra_type_by_cause_iterate(EC_BASE, oldbase)
2453  {
2454  if (oldbase != pextra) {
2455  map_claim_base(ptile, oldbase, pplayer, old_owner);
2456  }
2457  }
2459 
2460  ptile->extras_owner = pplayer;
2461  }
2462  } else {
2463  // Player who already owns bases on tile claims new base
2464  map_claim_base(ptile, pextra, extra_owner(ptile), nullptr);
2465  }
2466  }
2467 
2468  if (extras_removed) {
2469  /* Maybe conflicting extra that was removed was the only thing
2470  * making tile native to some unit. */
2472  }
2473 }
2474 
2478 void destroy_extra(struct tile *ptile, struct extra_type *pextra)
2479 {
2480  bv_player base_seen;
2481  bool is_virtual = tile_virtual_check(ptile);
2482 
2483  // Remember what players were able to see the base.
2484  if (!is_virtual) {
2485  BV_CLR_ALL(base_seen);
2486  players_iterate(pplayer)
2487  {
2488  if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
2489  BV_SET(base_seen, player_index(pplayer));
2490  }
2491  }
2493  }
2494 
2495  if (!is_virtual && is_extra_caused_by(pextra, EC_BASE)) {
2496  struct base_type *pbase = extra_base_get(pextra);
2497  struct player *owner = extra_owner(ptile);
2498 
2499  if (territory_claiming_base(pbase)) {
2500  map_clear_border(ptile);
2501  }
2502 
2503  if (nullptr != owner
2504  && (0 <= pbase->vision_main_sq || 0 <= pbase->vision_invis_sq)) {
2505  // Base provides vision, but no borders.
2506  const v_radius_t old_radius_sq =
2507  V_RADIUS(0 <= pbase->vision_main_sq ? pbase->vision_main_sq : -1,
2508  0 <= pbase->vision_invis_sq ? pbase->vision_invis_sq : -1,
2509  0 <= pbase->vision_subs_sq ? pbase->vision_subs_sq : -1);
2510  const v_radius_t new_radius_sq = V_RADIUS(-1, -1, -1);
2511 
2512  map_vision_update(owner, ptile, old_radius_sq, new_radius_sq,
2513  game.server.vision_reveal_tiles);
2514  }
2515  }
2516 
2517  tile_remove_extra(ptile, pextra);
2518 
2519  if (!is_virtual) {
2520  // Remove base from vision of players which were able to see the base.
2521  players_iterate(pplayer)
2522  {
2523  if (BV_ISSET(base_seen, player_index(pplayer))
2524  && update_player_tile_knowledge(pplayer, ptile)) {
2525  send_tile_info(pplayer->connections, ptile, false);
2526  }
2527  }
2529 
2530  if (pextra->eus != EUS_NORMAL) {
2531  struct player *eowner = extra_owner(ptile);
2532 
2533  unit_list_iterate(ptile->units, aunit)
2534  {
2535  if (is_native_extra_to_utype(pextra, unit_type_get(aunit))) {
2536  players_iterate(aplayer)
2537  {
2538  if (can_player_see_unit(aplayer, aunit)
2539  && !pplayers_allied(aplayer, eowner)) {
2540  send_unit_info(aplayer->connections, aunit);
2541  }
2542  }
2544  }
2545  }
2547  }
2548  }
2549 }
2550 
2558 void give_distorted_map(struct player *pfrom, struct player *pto, int prob,
2559  bool reveal_cities)
2560 {
2561  buffer_shared_vision(pto);
2562 
2563  whole_map_iterate(&(wld.map), ptile)
2564  {
2565  if (fc_rand(100) < prob) {
2566  give_tile_info_from_player_to_player(pfrom, pto, ptile);
2567  } else if (reveal_cities && nullptr != tile_city(ptile)) {
2568  give_tile_info_from_player_to_player(pfrom, pto, ptile);
2569  }
2570  }
2572 
2574 }
#define CALL_FUNC_EACH_AI(_func,...)
Definition: ai.h:393
bool territory_claiming_base(const struct base_type *pbase)
Does this base type claim territory?
Definition: base.cpp:196
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
#define BV_ARE_EQUAL(vec1, vec2)
Definition: bitvector.h:80
#define BV_CLR(bv, bit)
Definition: bitvector.h:49
int tile_border_source_radius_sq(struct tile *ptile)
Border radius sq from given border source tile.
Definition: borders.cpp:27
bool is_border_source(struct tile *ptile)
Is given tile source to borders.
Definition: borders.cpp:110
int tile_border_strength(struct tile *ptile, struct tile *source)
Border source strength at tile.
Definition: borders.cpp:95
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
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
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_tile_iterate(_radius_sq, _city_tile, _tile)
Definition: city.h:202
#define city_list_iterate_end
Definition: city.h:484
#define city_tile_iterate_end
Definition: city.h:209
void send_city_info(struct player *dest, struct city *pcity)
A wrapper, accessing either broadcast_city_info() (dest == nullptr), or a convenience case of send_ci...
Definition: citytools.cpp:2295
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Updates a players knowledge about a city.
Definition: citytools.cpp:2637
void city_thaw_workers_queue()
Process the frozen workers.
Definition: citytools.cpp:171
bool city_map_update_tile_frozen(struct tile *ptile)
Updates the worked status of a tile.
Definition: citytools.cpp:3133
void remove_dumb_city(struct player *pplayer, struct tile *ptile)
Removes a dumb city.
Definition: citytools.cpp:2722
void city_landlocked_sell_coastal_improvements(struct tile *ptile)
For each city adjacent to ptile, check all the buildings in the city.
Definition: citytools.cpp:3210
void send_city_info_at_tile(struct player *pviewer, struct conn_list *dest, struct city *pcity, struct tile *ptile)
Send info about a city, as seen by pviewer, to dest (usually dest will be pviewer->connections).
Definition: citytools.cpp:2344
void sync_cities()
Make sure all players (clients) have up-to-date information about all their cities.
Definition: citytools.cpp:3150
void reality_check_city(struct player *pplayer, struct tile *ptile)
Removes outdated (nonexistant) cities from a player.
Definition: citytools.cpp:2704
void city_refresh_queue_add(struct city *pcity)
Queue pending city_refresh() for later.
Definition: cityturn.cpp:188
void city_refresh_queue_processing()
Refresh the listed cities.
Definition: cityturn.cpp:204
void conn_list_do_unbuffer(struct conn_list *dest)
Convenience functions to unbuffer a list of connections.
Definition: connection.cpp:319
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Thaw a connection list.
Definition: connection.cpp:665
void conn_list_do_buffer(struct conn_list *dest)
Convenience functions to buffer a list of connections.
Definition: connection.cpp:310
void conn_list_compression_freeze(const struct conn_list *pconn_list)
Freeze a connection list.
Definition: connection.cpp:656
#define conn_list_iterate(connlist, pconn)
Definition: connection.h:99
#define conn_list_iterate_end
Definition: connection.h:101
struct player * extra_owner(const struct tile *ptile)
Who owns extras on tile.
Definition: extras.cpp:1013
int extra_number(const struct extra_type *pextra)
Return the extra id.
Definition: extras.cpp:132
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Check if extra has given flag.
Definition: extras.cpp:779
const char * extra_name_translation(const struct extra_type *pextra)
Return the (translated) name of the extra type.
Definition: extras.cpp:165
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Tells if player can build extra to tile with suitable unit.
Definition: extras.cpp:414
bool is_native_extra_to_utype(const struct extra_type *pextra, const struct unit_type *punittype)
Is extra native to unit type?
Definition: extras.cpp:770
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Can two extras coexist in same tile?
Definition: extras.cpp:902
bool player_knows_extra_exist(const struct player *pplayer, const struct extra_type *pextra, const struct tile *ptile)
Extra is not hidden from the user.
Definition: extras.cpp:1051
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_iterate_end
Definition: extras.h:285
#define is_extra_caused_by(e, c)
Definition: extras.h:182
#define extra_base_get(_e_)
Definition: extras.h:170
#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
#define MAX_NUM_PLAYER_SLOTS
Definition: fc_types.h:24
@ HB_DISABLED
Definition: fc_types.h:1094
#define MAX_EXTRA_TYPES
Definition: fc_types.h:42
signed short Continent_id
Definition: fc_types.h:289
@ BORDERS_DISABLED
Definition: fc_types.h:863
@ BORDERS_SEE_INSIDE
Definition: fc_types.h:865
@ BORDERS_EXPAND
Definition: fc_types.h:866
#define IDENTITY_NUMBER_ZERO
Definition: fc_types.h:76
#define _(String)
Definition: fcintl.h:50
const struct ft_color ftc_server
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
#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
bool terrain_surroundings_allow_change(const struct tile *ptile, const struct terrain *pterrain)
Returns FALSE if a terrain change to 'pterrain' would be prevented by not having enough similar terra...
Definition: map.cpp:706
struct tile * rand_map_pos(const struct civ_map *nmap)
Random square anywhere on the map.
Definition: map.cpp:1026
int map_num_tiles()
Returns the total number of (real) positions (or tiles) on the map.
Definition: map.cpp:954
int map_vector_to_sq_distance(int dx, int dy)
Return the sq_distance for a given vector.
Definition: map.cpp:583
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Topology function to find the vector which has the minimum "real" distance between the map positions ...
Definition: map.cpp:1012
#define adjc_iterate_end
Definition: map.h:358
#define MAP_INDEX_SIZE
Definition: map.h:91
#define circle_dxyr_iterate(nmap, center_tile, sq_radius, _tile, dx, dy, dr)
Definition: map.h:329
#define cardinal_adjc_iterate_end
Definition: map.h:384
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define circle_dxyr_iterate_end
Definition: map.h:342
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:380
#define circle_iterate(nmap, center_tile, sq_radius, tile_itr)
Definition: map.h:322
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define MAP_TILE_OWNER_NULL
Definition: map.h:500
#define whole_map_iterate_end
Definition: map.h:480
#define circle_iterate_end
Definition: map.h:325
struct terrain * most_shallow_ocean(bool frozen)
Return most shallow ocean terrain type.
int get_ocean_size(Continent_id id)
Return size in tiles of the given ocean.
void assign_continent_numbers()
Assigns continent and ocean numbers to all tiles, and set map.num_continents and map....
int get_lake_surrounders(Continent_id cont)
Get continent surrounding lake, or -1 if there is multiple continents.
void disable_fog_of_war()
Turns FoW off for everyone.
Definition: maphand.cpp:1736
void player_map_init(struct player *pplayer)
Allocate space for map, and initialise the tiles.
Definition: maphand.cpp:1177
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Remember that tile was last seen this year.
Definition: maphand.cpp:1427
static void shared_vision_change_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change, bool can_reveal_tiles)
Change the seen count of a tile for a pplayer.
Definition: maphand.cpp:632
void vision_clear_sight(struct vision *vision)
Clear all sight points from this vision source.
Definition: maphand.cpp:2395
void map_calculate_borders()
Update borders for all sources.
Definition: maphand.cpp:2244
void map_set_border_vision(struct player *pplayer, const bool is_enabled)
Turn a players ability to see inside his borders on or off.
Definition: maphand.cpp:714
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Claim ownership of a single tile.
Definition: maphand.cpp:2070
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Return whether the player knows the tile.
Definition: maphand.cpp:884
void send_map_info(struct conn_list *dest)
Send basic map information: map size, topology, and is_earth.
Definition: maphand.cpp:617
bool send_tile_suppression(bool now)
Suppress send_tile_info() during game_load()
Definition: maphand.cpp:469
void destroy_extra(struct tile *ptile, struct extra_type *pextra)
Remove extra from tile.
Definition: maphand.cpp:2478
void map_claim_base(struct tile *ptile, const extra_type *pextra, struct player *powner, struct player *ploser)
Claim base to player's ownership.
Definition: maphand.cpp:2273
static void check_units_single_tile(struct tile *ptile)
Helper function for bounce_units_on_terrain_change() that checks units on a single tile.
Definition: maphand.cpp:1785
static void really_give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Give information about whole map (all tiles) from player to player.
Definition: maphand.cpp:1489
bool really_gives_vision(struct player *me, struct player *them)
Return TRUE iff the player me really gives shared vision to player them.
Definition: maphand.cpp:325
void map_know_and_see_all(struct player *pplayer)
Call this function to unfog all tiles.
Definition: maphand.cpp:1151
static int map_get_own_seen(const struct player *pplayer, const struct tile *ptile, enum vision_layer vlayer)
Returns the own seen count of a tile for a player.
Definition: maphand.cpp:1100
static void map_change_own_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change)
Changes the own seen count of a tile for a player.
Definition: maphand.cpp:1110
void send_tile_info(struct conn_list *dest, struct tile *ptile, bool send_unknown)
Send tile information to all the clients in dest which know and see the tile.
Definition: maphand.cpp:485
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Give pplayer the correct knowledge about tile; return TRUE iff knowledge changed.
Definition: maphand.cpp:1357
static int map_get_seen(const struct player *pplayer, const struct tile *ptile, enum vision_layer vlayer)
Return whether the player can see the tile.
Definition: maphand.cpp:909
static void ocean_to_land_fix_rivers(struct tile *ptile)
Set the tile to be a river if required.
Definition: maphand.cpp:1751
void give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Give information about whole map (all tiles) from player to player.
Definition: maphand.cpp:368
void send_all_known_tiles(struct conn_list *dest)
Send all tiles known to specified clients.
Definition: maphand.cpp:436
void bounce_units_on_terrain_change(struct tile *ptile)
Check ptile and nearby tiles to see if all units can remain at their current locations,...
Definition: maphand.cpp:1802
void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest)
Give information about all oceanic tiles from player to player.
Definition: maphand.cpp:387
void remove_shared_vision(struct player *pfrom, struct player *pto)
Removes shared vision from between two players.
Definition: maphand.cpp:1634
bool need_to_reassign_continents(const struct terrain *oldter, const struct terrain *newter)
Returns TRUE if the terrain change from 'oldter' to 'newter' may require expensive reassignment of co...
Definition: maphand.cpp:1819
void give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Transfer (random parts of) player pfrom's world map to pto.
Definition: maphand.cpp:2558
static bool is_claimable_ocean(struct tile *ptile, struct tile *source, struct player *pplayer)
Ocean tile can be claimed iff one of the following conditions stands: a) it is an inland lake not lar...
Definition: maphand.cpp:1953
void show_map_to_all()
Unfogs all tiles for all players.
Definition: maphand.cpp:1167
static bool is_terrain_ecologically_wet(struct tile *ptile)
Used only in global_warming() and nuclear_winter() below.
Definition: maphand.cpp:86
void tile_claim_bases(struct tile *ptile, struct player *powner)
Claim ownership of bases on single tile.
Definition: maphand.cpp:2083
void disable_fog_of_war_player(struct player *pplayer)
Turns FoW off for player.
Definition: maphand.cpp:1720
void climate_change(bool warming, int effect)
Do a climate change.
Definition: maphand.cpp:123
static bool send_tile_suppressed
Definition: maphand.cpp:58
void upgrade_all_city_extras(struct player *pplayer, bool discovery)
To be called when a player gains some better extra building tech for the first time.
Definition: maphand.cpp:251
void map_update_border(struct tile *ptile, struct player *owner, int old_radius_sq, int new_radius_sq)
Update borders for this source.
Definition: maphand.cpp:2121
void map_set_known(struct tile *ptile, struct player *pplayer)
Set known status of the tile.
Definition: maphand.cpp:1133
void enable_fog_of_war()
Turns FoW on for everyone.
Definition: maphand.cpp:1711
void map_show_all(struct player *pplayer)
Shows the area to the player.
Definition: maphand.cpp:870
static void map_unit_homecity_enqueue(struct tile *ptile)
For each unit at the tile, queue any unique home city.
Definition: maphand.cpp:2006
static void map_change_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change, bool can_reveal_tiles)
This function changes the seen state of one player for all vision layers of a tile.
Definition: maphand.cpp:922
void map_show_tile(struct player *src_player, struct tile *ptile)
Shows the area to the player.
Definition: maphand.cpp:743
void give_citymap_from_player_to_player(struct city *pcity, struct player *pfrom, struct player *pdest)
Give information about tiles within city radius from player to player.
Definition: maphand.cpp:408
void nuclear_winter(int effect)
Wrapper for climate_change().
Definition: maphand.cpp:109
void create_extra(struct tile *ptile, const extra_type *pextra, struct player *pplayer)
Create extra to tile.
Definition: maphand.cpp:2405
static void player_tile_init(struct tile *ptile, struct player *pplayer)
We need to use fogofwar_old here, so the player's tiles get in the same state as the other players' t...
Definition: maphand.cpp:1284
static void really_give_tile_info_from_player_to_player(struct player *pfrom, struct player *pdest, struct tile *ptile)
Give tile information from one player to one player.
Definition: maphand.cpp:1439
void terrain_changed(struct tile *ptile)
Handle local side effects for a terrain change.
Definition: maphand.cpp:1837
void player_map_free(struct player *pplayer)
Free a player's private map.
Definition: maphand.cpp:1191
static void unbuffer_shared_vision(struct player *pplayer)
Stop buffering shared vision.
Definition: maphand.cpp:350
static void map_claim_border_ownership(struct tile *ptile, struct player *powner, struct tile *psource)
Claim ownership of a single tile.
Definition: maphand.cpp:2024
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Returns whether the layer 'vlayer' of the tile 'ptile' is known and seen by the player 'pplayer'.
Definition: maphand.cpp:894
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Changes site information for player tile.
Definition: maphand.cpp:1122
void fix_tile_on_terrain_change(struct tile *ptile, struct terrain *oldter, bool extend_rivers)
Handles local side effects for a terrain change (tile and its surroundings).
Definition: maphand.cpp:1856
void enable_fog_of_war_player(struct player *pplayer)
Turns FoW on for player.
Definition: maphand.cpp:1695
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Shows the area to the player.
Definition: maphand.cpp:852
void map_vision_update(struct player *pplayer, struct tile *ptile, const v_radius_t old_radius_sq, const v_radius_t new_radius_sq, bool can_reveal_tiles)
There doesn't have to be a city.
Definition: maphand.cpp:652
void map_claim_border(struct tile *ptile, struct player *owner, int radius_sq)
Update borders for this source.
Definition: maphand.cpp:2155
void update_tile_knowledge(struct tile *ptile)
Update playermap knowledge for everybody who sees the tile, and send a packet to everyone whose info ...
Definition: maphand.cpp:1395
void remove_player_from_maps(struct player *pplayer)
Remove all knowledge of a player from main map and other players' private maps, and send updates to c...
Definition: maphand.cpp:1210
void give_shared_vision(struct player *pfrom, struct player *pto)
Starts shared vision between two players.
Definition: maphand.cpp:1568
void check_terrain_change(struct tile *ptile, struct terrain *oldter)
Handles local and global side effects for a terrain change for a single tile.
Definition: maphand.cpp:1875
static void give_tile_info_from_player_to_player(struct player *pfrom, struct player *pdest, struct tile *ptile)
Give tile information from player to player.
Definition: maphand.cpp:1506
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Players' information of tiles is tracked so that fogged area can be kept consistent even when the cli...
Definition: maphand.cpp:1341
void map_hide_tile(struct player *src_player, struct tile *ptile)
Hides the area to the player.
Definition: maphand.cpp:802
struct vision_site * map_get_player_site(const struct tile *ptile, const struct player *pplayer)
Returns site located at given tile from player map.
Definition: maphand.cpp:1330
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Returns city located at given tile from player map.
Definition: maphand.cpp:1317
static void buffer_shared_vision(struct player *pplayer)
Start buffering shared vision.
Definition: maphand.cpp:333
void global_warming(int effect)
Wrapper for climate_change().
Definition: maphand.cpp:96
bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
Check city for extra upgrade.
Definition: maphand.cpp:214
static void create_vision_dependencies()
This updates all players' really_gives_vision field.
Definition: maphand.cpp:1526
void map_clear_border(struct tile *ptile)
Remove border for this source.
Definition: maphand.cpp:2102
void map_clear_known(struct tile *ptile, struct player *pplayer)
Clear known status of the tile.
Definition: maphand.cpp:1141
static void player_tile_free(struct tile *ptile, struct player *pplayer)
Free the memory stored into the player tile.
Definition: maphand.cpp:1309
#define MAXIMUM_CLAIMED_OCEAN_SIZE
Definition: maphand.cpp:55
void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
Change the sight points for the vision source, fogging or unfogging tiles as needed.
Definition: maphand.cpp:2383
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
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Similar to notify_conn_packet (see also), but takes player as "destination".
Definition: notify.cpp:284
int num_known_tech_with_flag(const struct player *pplayer, enum tech_flag_id flag)
Returns the number of techs the player has researched which has this flag.
Definition: player.cpp:1181
int player_number(const struct player *pplayer)
Return the player index/number/id.
Definition: player.cpp:756
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Checks if a unit can be seen by pplayer at its current location.
Definition: player.cpp:1016
int player_index(const struct player *pplayer)
Return the player index.
Definition: player.cpp:748
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
Definition: player.cpp:1334
bool gives_shared_vision(const struct player *me, const struct player *them)
Return TRUE iff the player me gives shared vision to player them.
Definition: player.cpp:1414
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
void send_player_info_c(struct player *src, struct conn_list *dest)
Send information about player slot 'src', or all valid (i.e.
Definition: plrhand.cpp:1048
#define fc_rand(_size)
Definition: rand.h:16
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Check if road provides effect.
Definition: road.cpp:367
int count_river_near_tile(const struct tile *ptile, const struct extra_type *priver)
Count tiles with any river near the tile.
Definition: road.cpp:290
#define sanity_check_tile(x)
Definition: sanitycheck.h:36
void flush_packets()
Attempt to flush all information in the send buffers for upto 'netwait' seconds.
Definition: sernet.cpp:187
enum server_states server_state()
Return current server state.
Definition: srv_main.cpp:238
Definition: base.h:43
int vision_main_sq
Definition: base.h:47
int vision_invis_sq
Definition: base.h:48
int vision_subs_sq
Definition: base.h:49
Definition: city.h:291
struct player * owner
Definition: city.h:294
struct tile * tile
Definition: city.h:293
struct civ_game::@28::@32 server
struct conn_list * est_connections
Definition: game.h:88
struct packet_game_info info
Definition: game.h:80
struct packet_scenario_info scenario
Definition: game.h:78
struct tile * tiles
Definition: map_types.h:76
int xsize
Definition: map_types.h:73
int ysize
Definition: map_types.h:73
int topology_id
Definition: map_types.h:68
struct extra_type::@22 data
enum extra_unit_seen_type eus
Definition: extras.h:111
struct base_type * base
Definition: extras.h:134
bv_extras extras
Definition: maphand.h:33
struct player * extras_owner
Definition: maphand.h:32
v_radius_t seen_count
Definition: maphand.h:40
v_radius_t own_seen
Definition: maphand.h:39
struct terrain * terrain
Definition: maphand.h:30
std::unique_ptr< vision_site > site
Definition: maphand.h:28
short last_updated
Definition: maphand.h:41
struct player * owner
Definition: maphand.h:31
struct extra_type * resource
Definition: maphand.h:29
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
struct player::@65::@67 server
struct conn_list * connections
Definition: player.h:280
bv_player gives_shared_vision
Definition: player.h:281
QBitArray * tile_known
Definition: player.h:291
struct terrain * cooler_wetter_result
Definition: terrain.h:220
struct terrain * cooler_drier_result
Definition: terrain.h:220
struct terrain * warmer_wetter_result
Definition: terrain.h:219
struct terrain * warmer_drier_result
Definition: terrain.h:219
Definition: tile.h:42
char * spec_sprite
Definition: tile.h:58
char * label
Definition: tile.h:57
bv_extras extras
Definition: tile.h:47
struct extra_type * resource
Definition: tile.h:48
struct unit_list * units
Definition: tile.h:50
struct player * extras_owner
Definition: tile.h:55
struct terrain * terrain
Definition: tile.h:49
int infra_turns
Definition: tile.h:54
struct extra_type * placing
Definition: tile.h:53
struct player * owner
Definition: tile.h:52
struct tile * claimer
Definition: tile.h:56
struct tile * location
Definition: vision.h:115
int identity
Definition: vision.h:118
Definition: vision.h:83
struct tile * tile
Definition: vision.h:86
bool can_reveal_tiles
Definition: vision.h:87
v_radius_t radius_sq
Definition: vision.h:90
struct player * player
Definition: vision.h:85
struct civ_map map
Definition: world_object.h:21
#define sz_strlcpy(dest, src)
Definition: support.h:140
Terrain_type_id terrain_count()
Return the number of terrains.
Definition: terrain.cpp:93
bool is_terrain_class_near_tile(const struct tile *ptile, enum terrain_class tclass)
Is there terrain of the given class near tile? (Does not check ptile itself.)
Definition: terrain.cpp:495
Terrain_type_id terrain_number(const struct terrain *pterrain)
Return the terrain index.
Definition: terrain.cpp:119
#define T_UNKNOWN
Definition: terrain.h:51
#define is_ocean(pterrain)
Definition: terrain.h:276
#define is_ocean_tile(ptile)
Definition: terrain.h:279
#define T_NONE
Definition: terrain.h:50
#define terrain_has_flag(terr, flag)
Definition: terrain.h:260
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Adds extra to tile.
Definition: tile.cpp:974
bool tile_has_river(const struct tile *ptile)
Tile has any river type.
Definition: tile.cpp:876
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Removes extra from tile if such exist.
Definition: tile.cpp:984
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Change the terrain to the given type.
Definition: tile.cpp:491
bool tile_virtual_check(const tile *vtile)
Check if the given tile is a virtual one or not.
Definition: tile.cpp:1085
bool tile_has_conflicting_extra(const struct tile *ptile, const struct extra_type *pextra)
Returns TRUE if the given tile has a extra conflicting with the given one.
Definition: tile.cpp:930
void tile_set_owner(struct tile *ptile, struct player *pplayer, struct tile *claimer)
Set the owner of a tile (may be nullptr).
Definition: tile.cpp:58
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_claimer(_tile)
Definition: tile.h:82
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_worked(_tile)
Definition: tile.h:97
#define tile_resource(_tile)
Definition: tile.h:84
@ TILE_KNOWN_UNSEEN
Definition: tile.h:30
@ TILE_UNKNOWN
Definition: tile.h:29
@ TILE_KNOWN_SEEN
Definition: tile.h:31
#define tile_terrain(_tile)
Definition: tile.h:93
#define TILE_XY(ptile)
Definition: tile.h:36
#define tile_continent(_tile)
Definition: tile.h:74
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130
#define tile_owner(_tile)
Definition: tile.h:78
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
#define unit_tile(_pu)
Definition: unit.h:371
#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 bounce_unit(struct unit *punit, bool verbose, bounce_reason reason, int max_distance)
Move or remove a unit due to stack conflicts.
Definition: unittools.cpp:1327
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
void unit_goes_out_of_sight(struct player *pplayer, const unit *punit)
Handle situation where unit goes out of player sight.
Definition: unittools.cpp:2795
void unit_activities_cancel_all_illegal_area(const struct tile *ptile)
Cancel all illegal activities done by units at the specified tile, and surrounding tiles.
Definition: unittools.cpp:801
void unit_list_refresh_vision(struct unit_list *punitlist)
Refresh the vision of all units in the list - see unit_refresh_vision.
Definition: unittools.cpp:4834
@ terrain_change
We need to do it because of changing terrain.
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
#define V_RADIUS(main_sq, invis_sq, subs_sq)
Definition: vision.h:94
#define vision_layer_iterate(v)
Definition: vision.h:72
#define vision_site_owner(v)
Definition: vision.h:132
short int v_radius_t[V_COUNT]
Definition: vision.h:81
#define vision_layer_iterate_end
Definition: vision.h:77