Freeciv-3.4
Loading...
Searching...
No Matches
maphand.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "bitvector.h"
20#include "fcintl.h"
21#include "log.h"
22#include "mem.h"
23#include "rand.h"
24#include "support.h"
25
26/* common */
27#include "ai.h"
28#include "base.h"
29#include "borders.h"
30#include "events.h"
31#include "game.h"
32#include "map.h"
33#include "movement.h"
34#include "nation.h"
35#include "packets.h"
36#include "player.h"
37#include "road.h"
38#include "specialist.h"
39#include "unit.h"
40#include "unitlist.h"
41#include "vision.h"
42
43/* server */
44#include "citytools.h"
45#include "cityturn.h"
46#include "notify.h"
47#include "plrhand.h"
48#include "sanitycheck.h"
49#include "sernet.h"
50#include "srv_main.h"
51#include "unithand.h"
52#include "unittools.h"
53
54/* server/advisors */
55#include "advdata.h"
56
57/* server/generator */
58#include "mapgen_utils.h"
59
60#include "maphand.h"
61
62/* Suppress send_tile_info() during game_load() */
64
65static void player_tile_init(struct tile *ptile, struct player *pplayer);
66static void player_tile_free(struct tile *ptile, struct player *pplayer);
68 struct player *pdest,
69 struct tile *ptile);
70static void shared_vision_change_seen(struct player *pplayer,
71 struct tile *ptile,
72 const v_radius_t change,
73 bool can_reveal_tiles);
74static void map_change_seen(struct player *pplayer,
75 struct tile *ptile,
76 const v_radius_t change,
77 bool can_reveal_tiles);
78static void map_change_own_seen(struct player *pplayer,
79 struct tile *ptile,
80 const v_radius_t change);
81static inline int map_get_seen(const struct player *pplayer,
82 const struct tile *ptile,
83 enum vision_layer vlayer);
84static inline bool map_is_also_seen(const struct tile *ptile,
85 const struct player *pplayer,
86 enum vision_layer vlayer);
87
88static bool is_tile_claimable(struct tile *ptile, struct tile *source,
89 struct player *pplayer);
90
91/**********************************************************************/
94static bool is_terrain_ecologically_wet(struct tile *ptile)
95{
96 return (is_terrain_class_near_tile(&(wld.map), ptile, TC_OCEAN)
97 || tile_has_river(ptile)
98 || count_river_near_tile(&(wld.map), ptile, nullptr) > 0);
99}
100
101/**********************************************************************/
105{
107 notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
108 _("Global warming has occurred!"));
109 notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
110 _("Coastlines have been flooded and vast "
111 "ranges of grassland have become deserts."));
112}
113
114/**********************************************************************/
118{
120 notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
121 _("Nuclear winter has occurred!"));
122 notify_player(nullptr, nullptr, E_GLOBAL_ECO, ftc_server,
123 _("Wetlands have dried up and vast "
124 "ranges of grassland have become tundra."));
125}
126
127/**********************************************************************/
132{
133 int k = map_num_tiles();
134 bool used[k];
135 const struct civ_map *nmap = &(wld.map);
136
137 memset(used, 0, sizeof(used));
138
139 log_verbose("Climate change: %s (%d)",
140 warming ? "Global warming" : "Nuclear winter", effect);
141
142 while (effect > 0 && (k--) > 0) {
143 struct terrain *old, *candidates[2], *new;
144 struct tile *ptile;
145 int i;
146
147 do {
148 /* We want to transform a tile at most once due to a climate change. */
149 ptile = rand_map_pos(&(wld.map));
150 } while (used[tile_index(ptile)]);
151 used[tile_index(ptile)] = TRUE;
152
153 old = tile_terrain(ptile);
154 /* Prefer the transformation that's appropriate to the ambient moisture,
155 * but be prepared to fall back in exceptional circumstances */
156 {
157 struct terrain *wetter, *drier;
158
161 if (is_terrain_ecologically_wet(ptile)) {
162 candidates[0] = wetter;
163 candidates[1] = drier;
164 } else {
165 candidates[0] = drier;
166 candidates[1] = wetter;
167 }
168 }
169
170 /* If the preferred transformation is ruled out for some exceptional reason
171 * specific to this tile, fall back to the other, rather than letting this
172 * tile be immune to change. */
173 for (i = 0; i < 2; i++) {
174 new = candidates[i];
175
176 /* If the preferred transformation simply hasn't been specified
177 * for this terrain at all, don't fall back to the other. */
178 if (new == T_NONE) {
179 break;
180 }
181
182 if (tile_city(ptile) != nullptr && terrain_has_flag(new, TER_NO_CITIES)) {
183 /* do not change to a terrain with the flag TER_NO_CITIES if the tile
184 * has a city */
185 continue;
186 }
187
188 /* Only change between water and land at coastlines, and between
189 * frozen and unfrozen at ice margin */
190 if (!terrain_surroundings_allow_change(nmap, ptile, new)) {
191 continue;
192 }
193
194 /* OK! */
195 break;
196 }
197 if (i == 2) {
198 /* Neither transformation was permitted. Give up. */
199 continue;
200 }
201
202 if (new != T_NONE && old != new) {
203 effect--;
204
205 /* Check terrain changing activities.
206 These would not be caught by the check if unit can continue activity
207 after the terrain change has taken place, as the activity itself is still
208 legal, but would be towards different terrain, and terrain types are not
209 activity targets (target is nullptr) */
210 unit_list_iterate(ptile->units, punit) {
211 if (punit->activity_target == nullptr) {
212 /* Target is always nullptr for terrain changing activities. */
217 }
218 }
220
221 /* Really change the terrain. */
222 tile_change_terrain(ptile, new);
225
227
228 } else if (old == new) {
229 /* This counts toward a climate change although nothing is changed. */
230 effect--;
231 }
232 }
233}
234
235/**********************************************************************/
239bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
240{
241 struct tile *ptile = pcity->tile;
242 struct player *pplayer = city_owner(pcity);
243 bool upgradet = FALSE;
244
245 extra_type_iterate(pextra) {
246 if (!tile_has_extra(ptile, pextra)) {
249 && player_can_build_extra(pextra, pplayer, ptile)
250 && !tile_has_conflicting_extra(ptile, pextra))) {
251 tile_add_extra(pcity->tile, pextra);
252 if (gained != nullptr) {
253 if (upgradet) {
254 *gained = nullptr;
255 } else {
256 *gained = pextra;
257 }
258 }
259 upgradet = TRUE;
260 }
261 }
263
264 return upgradet;
265}
266
267/**********************************************************************/
274void upgrade_all_city_extras(struct player *pplayer, bool discovery)
275{
276 int cities_upgradet = 0;
277 struct extra_type *upgradet = nullptr;
278 bool multiple_types = FALSE;
279 int cities_total = city_list_size(pplayer->cities);
280 int percent;
281
283
284 city_list_iterate(pplayer->cities, pcity) {
285 struct extra_type *new_upgrade;
286
290 if (new_upgrade == nullptr) {
291 /* This single city alone had multiple types */
293 } else if (upgradet == nullptr) {
294 /* First gained */
296 } else if (upgradet != new_upgrade) {
297 /* Different type from what another city got. */
299 }
300 }
302
303 if (cities_total > 0) {
305 } else {
306 percent = 0;
307 }
308
309 if (cities_upgradet > 0) {
310 if (discovery) {
311 if (percent >= 75) {
312 notify_player(pplayer, nullptr, E_TECH_GAIN, ftc_server,
313 _("New hope sweeps like fire through the country as "
314 "the discovery of new infrastructure building technology "
315 "is announced."));
316 }
317 } else {
318 if (percent >= 75) {
319 notify_player(pplayer, nullptr, E_TECH_GAIN, ftc_server,
320 _("The people are pleased to hear that your "
321 "scientists finally know about new infrastructure building "
322 "technology."));
323 }
324 }
325
326 if (multiple_types) {
327 notify_player(pplayer, nullptr, E_TECH_GAIN, ftc_server,
328 _("Workers spontaneously gather and upgrade all "
329 "possible cities with better infrastructure."));
330 } else {
331 notify_player(pplayer, nullptr, E_TECH_GAIN, ftc_server,
332 _("Workers spontaneously gather and upgrade all "
333 "possible cities with %s."),
335 }
336 }
337
339}
340
341/**********************************************************************/
345{
346 return BV_ISSET(me->server.really_gives_vision, player_index(them));
347}
348
349/**********************************************************************/
352static void buffer_shared_vision(struct player *pplayer)
353{
355 if (really_gives_vision(pplayer, pplayer2)) {
357 conn_list_do_buffer(pplayer2->connections);
358 }
362}
363
364/**********************************************************************/
367static void unbuffer_shared_vision(struct player *pplayer)
368{
370 if (really_gives_vision(pplayer, pplayer2)) {
371 conn_list_do_unbuffer(pplayer2->connections);
373 }
377}
378
379/**********************************************************************/
395
396/**********************************************************************/
413
414/**********************************************************************/
433
434/**********************************************************************/
444{
445 int tiles_sent;
446
447 if (!dest) {
448 dest = game.est_connections;
449 }
450
451 /* Send whole map piece by piece to each player to balance the load
452 of the send buffers better */
453 tiles_sent = 0;
455
456 whole_map_iterate(&(wld.map), ptile) {
457 tiles_sent++;
458 if ((tiles_sent % MAP_NATIVE_WIDTH) == 0) {
462 }
463
464 send_tile_info(dest, ptile, FALSE);
466
469}
470
471/**********************************************************************/
475{
477
479 return formerly;
480}
481
482/**********************************************************************/
490void send_tile_info(struct conn_list *dest, struct tile *ptile,
491 bool send_unknown)
492{
493 struct packet_tile_info info;
494 const struct player *owner;
495 const struct player *eowner;
496
497 if (dest == nullptr) {
498 CALL_FUNC_EACH_AI(tile_info, ptile);
499 }
500
502 return;
503 }
504
505 if (!dest) {
506 dest = game.est_connections;
507 }
508
509 info.tile = tile_index(ptile);
510
511 if (ptile->spec_sprite) {
512 sz_strlcpy(info.spec_sprite, ptile->spec_sprite);
513 } else {
514 info.spec_sprite[0] = '\0';
515 }
516
517 conn_list_iterate(dest, pconn) {
518 struct player *pplayer = pconn->playing;
519 bool known;
520
521 if (pplayer == nullptr && !pconn->observer) {
522 continue;
523 }
524
525 if (pplayer != nullptr) {
526 known = map_is_known(ptile, pplayer);
527 }
528
529 if (pplayer == nullptr
530 || (known && map_is_also_seen(ptile, pplayer, V_MAIN))) {
531 struct extra_type *resource;
532
533 info.known = TILE_KNOWN_SEEN;
534 info.continent = tile_continent(ptile);
535 owner = tile_owner(ptile);
536 eowner = extra_owner(ptile);
538 info.extras_owner = (eowner ? player_number(eowner) : MAP_TILE_OWNER_NULL);
539 info.worked = (tile_worked(ptile) != nullptr)
540 ? tile_worked(ptile)->id
542
543 info.terrain = (tile_terrain(ptile) != nullptr)
545 : terrain_count();
546
547 resource = tile_resource(ptile);
548 if (resource != nullptr
549 && (pplayer == nullptr
550 || player_knows_extra_exist(pplayer, resource, ptile))) {
552 } else {
554 }
555
556 info.placing = (ptile->placing != nullptr)
557 ? extra_number(ptile->placing)
558 : -1;
559 info.place_turn = (ptile->placing != nullptr)
560 ? game.info.turn + ptile->infra_turns
561 : 0;
562
563 if (pplayer != nullptr) {
564 dbv_to_bv(info.extras.vec, &(map_get_player_tile(ptile, pplayer)->extras));
565 } else {
566 info.extras = ptile->extras;
567 }
568
569 if (ptile->label != nullptr) {
570 /* Always leave final '\0' in place */
571 strncpy(info.label, ptile->label, sizeof(info.label) - 1);
572 } else {
573 info.label[0] = '\0';
574 }
575
576 info.altitude = ptile->altitude;
577
579 } else if (pplayer != nullptr && known) {
580 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
582
584 info.continent = tile_continent(ptile);
586 ? plrtile->owner
587 : tile_owner(ptile));
588 eowner = plrtile->extras_owner;
590 info.extras_owner = (eowner ? player_number(eowner) : MAP_TILE_OWNER_NULL);
591 info.worked = (psite != nullptr)
592 ? psite->identity
594
595 info.terrain = (plrtile->terrain != nullptr)
596 ? terrain_number(plrtile->terrain)
597 : terrain_count();
598 info.resource = (plrtile->resource != nullptr)
599 ? extra_number(plrtile->resource)
601 info.placing = -1;
602 info.place_turn = 0;
603
604 dbv_to_bv(info.extras.vec, &(plrtile->extras));
605
606 /* Labels never change, so they are not subject to fog of war */
607 if (ptile->label != nullptr) {
608 sz_strlcpy(info.label, ptile->label);
609 } else {
610 info.label[0] = '\0';
611 }
612
613 info.altitude = ptile->altitude;
614
616 } else if (send_unknown) {
617 info.known = TILE_UNKNOWN;
618 info.continent = 0;
622
623 info.terrain = terrain_count();
625 info.placing = -1;
626 info.place_turn = 0;
627
628 BV_CLR_ALL(info.extras);
629
630 info.label[0] = '\0';
631
632 info.altitude = 0;
633
635 }
636 }
638}
639
640/**********************************************************************/
646static bool unit_is_on_layer(const struct unit *punit,
647 enum vision_layer vlayer)
648{
649 return unit_type_get(punit)->vlayer == vlayer;
650}
651
652/**********************************************************************/
655void send_map_info(struct conn_list *dest)
656{
657 struct packet_map_info minfo;
658
660 minfo.ysize = MAP_NATIVE_HEIGHT;
661 minfo.topology_id = wld.map.topology_id;
662 minfo.wrap_id = wld.map.wrap_id;
663 minfo.north_latitude = wld.map.north_latitude;
664 minfo.south_latitude = wld.map.south_latitude;
665 minfo.altitude_info = wld.map.altitude_info;
666
668}
669
670/**********************************************************************/
674static void shared_vision_change_seen(struct player *pplayer,
675 struct tile *ptile,
676 const v_radius_t change,
677 bool can_reveal_tiles)
678{
679 map_change_own_seen(pplayer, ptile, change);
680 map_change_seen(pplayer, ptile, change, can_reveal_tiles);
681
683 if (really_gives_vision(pplayer, pplayer2)) {
684 map_change_seen(pplayer2, ptile, change, can_reveal_tiles);
685 }
687}
688
689/**********************************************************************/
692void map_vision_update(struct player *pplayer, struct tile *ptile,
695 bool can_reveal_tiles)
696{
697 v_radius_t change;
698 int max_radius;
699
703 return;
704 }
705
706 /* Determines 'max_radius' value. */
707 max_radius = 0;
709 if (max_radius < old_radius_sq[v]) {
711 }
712 if (max_radius < new_radius_sq[v]) {
714 }
716
717#ifdef FREECIV_DEBUG
718 log_debug("Updating vision at (%d, %d) in a radius of %d.",
719 TILE_XY(ptile), max_radius);
721 log_debug(" vision layer %d is changing from %d to %d.",
722 v, old_radius_sq[v], new_radius_sq[v]);
724#endif /* FREECIV_DEBUG */
725
726 buffer_shared_vision(pplayer);
727 circle_dxyr_iterate(&(wld.map), ptile, max_radius, tile1, dx, dy, dr) {
729 if (dr > old_radius_sq[v] && dr <= new_radius_sq[v]) {
730 change[v] = 1;
731 } else if (dr > new_radius_sq[v] && dr <= old_radius_sq[v]) {
732 change[v] = -1;
733 } else {
734 change[v] = 0;
735 }
737 shared_vision_change_seen(pplayer, tile1, change, can_reveal_tiles);
739 unbuffer_shared_vision(pplayer);
740}
741
742/**********************************************************************/
747void map_set_border_vision(struct player *pplayer,
748 const bool is_enabled)
749{
750 const v_radius_t radius_sq = V_RADIUS(is_enabled ? 1 : -1, 0, 0);
751
752 if (pplayer->server.border_vision == is_enabled) {
753 /* No change. Changing the seen count beyond what already exists would
754 * be a bug. */
755 return;
756 }
757
758 /* Set the new border seer value. */
760
761 whole_map_iterate(&(wld.map), ptile) {
762 if (pplayer == ptile->owner) {
763 /* The tile is within the player's borders. */
764 shared_vision_change_seen(pplayer, ptile, radius_sq, TRUE);
765 }
767}
768
769/**********************************************************************/
775void map_show_tile(struct player *src_player, struct tile *ptile)
776{
777 log_debug("Showing %i,%i to %s", TILE_XY(ptile), player_name(src_player));
778
779#ifndef FREECIV_NDEBUG
780 static int recurse = 0;
781
782 fc_assert(recurse == 0);
783
784 recurse++;
785#endif /* !FREECIV_NDEBUG */
786
787 players_iterate(pplayer) {
788 if (pplayer == src_player || really_gives_vision(src_player, pplayer)) {
789 struct city *pcity;
790
791 if (!map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
792 map_set_known(ptile, pplayer);
793
794 /* As the tile may be fogged send_tile_info won't always do this for us */
795 update_player_tile_knowledge(pplayer, ptile);
796 update_player_tile_last_seen(pplayer, ptile);
797
798 send_tile_info(pplayer->connections, ptile, FALSE);
799
800 /* Remove old cities that exist no more */
801 reality_check_city(pplayer, ptile);
802
803 if ((pcity = tile_city(ptile))) {
804 /* As the tile may be fogged send_city_info won't do this for us */
805 update_dumb_city(pplayer, pcity);
806 send_city_info(pplayer, pcity);
807 }
808
810 if (0 < map_get_seen(pplayer, ptile, v)) {
811 unit_list_iterate(ptile->units, punit) {
812 if (unit_is_on_layer(punit, v)) {
813 send_unit_info(pplayer->connections, punit);
814 }
816 }
818 }
819 }
821
822#ifndef FREECIV_NDEBUG
823 recurse--;
824#endif
825}
826
827/**********************************************************************/
832void map_hide_tile(struct player *src_player, struct tile *ptile)
833{
834 log_debug("Hiding %d,%d to %s", TILE_XY(ptile), player_name(src_player));
835
836#ifndef FREECIV_NDEBUG
837 static int recurse = 0;
838
839 fc_assert(recurse == 0);
840
841 recurse++;
842#endif /* !FREECIV_NDEBUG */
843
844 players_iterate(pplayer) {
845 if (pplayer == src_player || really_gives_vision(src_player, pplayer)) {
846 if (map_is_known(ptile, pplayer)) {
847 if (0 < map_get_seen(pplayer, ptile, V_MAIN)) {
848 update_player_tile_last_seen(pplayer, ptile);
849 }
850
851 /* Remove city. */
852 remove_dumb_city(pplayer, ptile);
853
854 /* Remove units. */
856 if (0 < map_get_seen(pplayer, ptile, v)) {
857 unit_list_iterate(ptile->units, punit) {
858 if (unit_is_on_layer(punit, v)) {
860 }
862 }
864 }
865
866 map_clear_known(ptile, pplayer);
867
868 send_tile_info(pplayer->connections, ptile, TRUE);
869 }
871
872#ifndef FREECIV_NDEBUG
873 recurse--;
874#endif
875}
876
877/**********************************************************************/
881void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
882{
883 buffer_shared_vision(pplayer);
884
885 circle_iterate(&(wld.map), ptile, radius_sq, tile1) {
886 map_show_tile(pplayer, tile1);
888
889 unbuffer_shared_vision(pplayer);
890}
891
892/**********************************************************************/
896void map_show_all(struct player *pplayer)
897{
898 buffer_shared_vision(pplayer);
899
900 whole_map_iterate(&(wld.map), ptile) {
901 map_show_tile(pplayer, ptile);
903
904 unbuffer_shared_vision(pplayer);
905}
906
907/**********************************************************************/
911bool map_is_known(const struct tile *ptile, const struct player *pplayer)
912{
913 if (pplayer->tile_known.vec == nullptr) {
914 /* Player map not initialized yet */
915 return FALSE;
916 }
917
918 return dbv_isset(&pplayer->tile_known, tile_index(ptile));
919}
920
921/**********************************************************************/
926static inline bool map_is_also_seen(const struct tile *ptile,
927 const struct player *pplayer,
928 enum vision_layer vlayer)
929{
930 return map_get_seen(pplayer, ptile, vlayer) > 0;
931}
932
933/**********************************************************************/
937bool map_is_known_and_seen(const struct tile *ptile,
938 const struct player *pplayer,
939 enum vision_layer vlayer)
940{
941 return map_is_known(ptile, pplayer) && map_is_also_seen(ptile, pplayer, vlayer);
942}
943
944/**********************************************************************/
951static inline int map_get_seen(const struct player *pplayer,
952 const struct tile *ptile,
953 enum vision_layer vlayer)
954{
955 return map_get_player_tile(ptile, pplayer)->seen_count[vlayer];
956}
957
958/**********************************************************************/
964void map_change_seen(struct player *pplayer,
965 struct tile *ptile,
966 const v_radius_t change,
967 bool can_reveal_tiles)
968{
969 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
970 bool revealing_tile = FALSE;
971
972#ifdef FREECIV_DEBUG
973 log_debug("%s() for player %s (nb %d) at (%d, %d).",
974 __FUNCTION__, player_name(pplayer), player_number(pplayer),
975 TILE_XY(ptile));
977 log_debug(" vision layer %d is changing from %d to %d.",
978 v, plrtile->seen_count[v], plrtile->seen_count[v] + change[v]);
980#endif /* FREECIV_DEBUG */
981
982 /* Removes units out of vision. First, check invisible layers because
983 * we must remove all units before fog of war because clients expect
984 * the tile is empty when it is fogged. */
985 if (0 > change[V_INVIS]
986 && plrtile->seen_count[V_INVIS] == -change[V_INVIS]) {
987 log_debug("(%d, %d): hiding invisible units to player %s (nb %d).",
988 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
989
990 unit_list_iterate(ptile->units, punit) {
992 && can_player_see_unit(pplayer, punit)
993 && (plrtile->seen_count[V_MAIN] + change[V_MAIN] <= 0
994 || !pplayers_allied(pplayer, unit_owner(punit)))) {
995 /* Allied units on seen tiles (V_MAIN) are always seen.
996 * That's how can_player_see_unit_at() works. */
998 }
1000 }
1001 if (0 > change[V_SUBSURFACE]
1002 && plrtile->seen_count[V_SUBSURFACE] == -change[V_SUBSURFACE]) {
1003 log_debug("(%d, %d): hiding subsurface units to player %s (nb %d).",
1004 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1005
1006 unit_list_iterate(ptile->units, punit) {
1008 && can_player_see_unit(pplayer, punit)) {
1009 unit_goes_out_of_sight(pplayer, punit);
1010 }
1012 }
1013
1014 if (0 > change[V_MAIN]
1015 && plrtile->seen_count[V_MAIN] == -change[V_MAIN]) {
1016 log_debug("(%d, %d): hiding visible units to player %s (nb %d).",
1017 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1018
1019 unit_list_iterate(ptile->units, punit) {
1021 && can_player_see_unit(pplayer, punit)) {
1022 unit_goes_out_of_sight(pplayer, punit);
1023 }
1025 }
1026
1028 /* Avoid underflow. */
1029 fc_assert(0 <= change[v] || -change[v] <= plrtile->seen_count[v]);
1030 plrtile->seen_count[v] += change[v];
1032
1033 /* V_MAIN vision ranges must always be more than invisible ranges
1034 * (see comment in common/vision.h), so we assume that the V_MAIN
1035 * seen count cannot be inferior to V_INVIS or V_SUBSURFACE seen count.
1036 * Moreover, when the fog of war is disabled, V_MAIN has an extra
1037 * seen count point. */
1038 fc_assert(plrtile->seen_count[V_INVIS] + !game.info.fogofwar
1039 <= plrtile->seen_count[V_MAIN]);
1041 <= plrtile->seen_count[V_MAIN]);
1042
1043 if (!map_is_known(ptile, pplayer)) {
1044 if (0 < plrtile->seen_count[V_MAIN] && can_reveal_tiles) {
1045 log_debug("(%d, %d): revealing tile to player %s (nb %d).",
1046 TILE_XY(ptile), player_name(pplayer),
1047 player_number(pplayer));
1048
1049 map_set_known(ptile, pplayer);
1051 } else {
1052 return;
1053 }
1054 }
1055
1056 /* Fog the tile. */
1057 if (0 > change[V_MAIN] && 0 == plrtile->seen_count[V_MAIN]) {
1058 struct city *pcity;
1059
1060 log_debug("(%d, %d): fogging tile for player %s (nb %d).",
1061 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1062
1063 pcity = ptile->worked;
1064
1065 if (pcity != nullptr && city_owner(pcity) == pplayer) {
1067 pcity->specialists[DEFAULT_SPECIALIST]++;
1068 if (pcity->server.needs_arrange == CNA_NOT) {
1069 pcity->server.needs_arrange = CNA_NORMAL;
1070 }
1071 }
1072
1073 update_player_tile_last_seen(pplayer, ptile);
1075 plrtile->owner = tile_owner(ptile);
1076 }
1077 plrtile->extras_owner = extra_owner(ptile);
1078 send_tile_info(pplayer->connections, ptile, FALSE);
1079 }
1080
1081 if ((revealing_tile && 0 < plrtile->seen_count[V_MAIN])
1082 || (0 < change[V_MAIN]
1083 /* plrtile->seen_count[V_MAIN] Always set to 1
1084 * when the fog of war is disabled. */
1085 && (change[V_MAIN] + !game.info.fogofwar
1086 == (plrtile->seen_count[V_MAIN])))) {
1087 struct city *pcity;
1088
1089 log_debug("(%d, %d): unfogging tile for player %s (nb %d).",
1090 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1091
1092 /* Send info about the tile itself.
1093 * It has to be sent first because the client needs correct
1094 * continent number before it can handle following packets
1095 */
1096 update_player_tile_knowledge(pplayer, ptile);
1097 send_tile_info(pplayer->connections, ptile, FALSE);
1098
1099 /* Discover units. */
1100 unit_list_iterate(ptile->units, punit) {
1101 /* Be sure not to revive dead unit on client when it's not yet
1102 * removed from the tile. This could happen when "unit_lost" lua script
1103 * somehow causes tile of the dead unit to unfog again. */
1105 && !punit->server.dying) {
1106 send_unit_info(pplayer->connections, punit);
1107 }
1109
1110 /* Discover cities. */
1111 reality_check_city(pplayer, ptile);
1112
1113 if ((pcity = tile_city(ptile)) != nullptr) {
1114 send_city_info(pplayer, pcity);
1115 }
1116 }
1117
1118 if ((revealing_tile && 0 < plrtile->seen_count[V_INVIS])
1119 || (0 < change[V_INVIS]
1120 && change[V_INVIS] == plrtile->seen_count[V_INVIS])) {
1121 log_debug("(%d, %d): revealing invisible units to player %s (nb %d).",
1122 TILE_XY(ptile), player_name(pplayer),
1123 player_number(pplayer));
1124 /* Discover units. */
1125 unit_list_iterate(ptile->units, punit) {
1127 send_unit_info(pplayer->connections, punit);
1128 }
1130 }
1131 if ((revealing_tile && 0 < plrtile->seen_count[V_SUBSURFACE])
1132 || (0 < change[V_SUBSURFACE]
1133 && change[V_SUBSURFACE] == plrtile->seen_count[V_SUBSURFACE])) {
1134 log_debug("(%d, %d): revealing subsurface units to player %s (nb %d).",
1135 TILE_XY(ptile), player_name(pplayer),
1136 player_number(pplayer));
1137 /* Discover units. */
1138 unit_list_iterate(ptile->units, punit) {
1140 send_unit_info(pplayer->connections, punit);
1141 }
1143 }
1144}
1145
1146/**********************************************************************/
1153static inline int player_tile_own_seen(const struct player_tile *plrtile,
1154 enum vision_layer vlayer)
1155{
1156 return plrtile->own_seen[vlayer];
1157}
1158
1159/**********************************************************************/
1162static void map_change_own_seen(struct player *pplayer,
1163 struct tile *ptile,
1164 const v_radius_t change)
1165{
1166 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1167
1169 plrtile->own_seen[v] += change[v];
1171}
1172
1173/**********************************************************************/
1177 struct vision_site *new_site)
1178{
1179 if (ptile->site == new_site) {
1180 /* Do nothing. */
1181 return;
1182 }
1183
1184 if (ptile->site != nullptr) {
1185 /* Releasing old site from tile */
1186 vision_site_destroy(ptile->site);
1187 }
1188
1189 ptile->site = new_site;
1190}
1191
1192/**********************************************************************/
1195void map_set_known(struct tile *ptile, struct player *pplayer)
1196{
1197 dbv_set(&pplayer->tile_known, tile_index(ptile));
1198}
1199
1200/**********************************************************************/
1203void map_clear_known(struct tile *ptile, struct player *pplayer)
1204{
1205 dbv_clr(&pplayer->tile_known, tile_index(ptile));
1206}
1207
1208/**********************************************************************/
1213void map_know_and_see_all(struct player *pplayer)
1214{
1215 const v_radius_t radius_sq = V_RADIUS(1, 1, 1);
1216
1217 buffer_shared_vision(pplayer);
1218 whole_map_iterate(&(wld.map), ptile) {
1219 map_change_seen(pplayer, ptile, radius_sq, TRUE);
1221 unbuffer_shared_vision(pplayer);
1222}
1223
1224/**********************************************************************/
1228{
1229 players_iterate(pplayer) {
1230 map_know_and_see_all(pplayer);
1232}
1233
1234/**********************************************************************/
1238void player_map_init(struct player *pplayer)
1239{
1240 pplayer->server.private_map
1241 = fc_realloc(pplayer->server.private_map,
1242 MAP_INDEX_SIZE * sizeof(*pplayer->server.private_map));
1243
1244 whole_map_iterate(&(wld.map), ptile) {
1245 player_tile_init(ptile, pplayer);
1247
1249}
1250
1251/**********************************************************************/
1254void player_map_free(struct player *pplayer)
1255{
1256 if (!pplayer->server.private_map) {
1257 return;
1258 }
1259
1260 whole_map_iterate(&(wld.map), ptile) {
1261 player_tile_free(ptile, pplayer);
1263
1264 free(pplayer->server.private_map);
1265 pplayer->server.private_map = nullptr;
1266
1267 dbv_free(&pplayer->tile_known);
1268}
1269
1270/**********************************************************************/
1275void remove_player_from_maps(struct player *pplayer)
1276{
1277 /* only after removing borders! */
1279 whole_map_iterate(&(wld.map), ptile) {
1280 /* Clear all players' knowledge about the removed player, and free
1281 * data structures (including those in removed player's player map). */
1282 bool reality_changed = FALSE;
1283
1285 struct player_tile *aplrtile;
1286 bool changed = FALSE;
1287
1288 if (!aplayer->server.private_map) {
1289 continue;
1290 }
1292
1293 /* Free vision sites (cities) for removed and other players */
1294 if (aplrtile && aplrtile->site
1295 && vision_site_owner(aplrtile->site) == pplayer) {
1297 changed = TRUE;
1298 }
1299
1300 /* Remove references to player from others' maps */
1301 if (aplrtile->owner == pplayer) {
1302 aplrtile->owner = nullptr;
1303 changed = TRUE;
1304 }
1305 if (aplrtile->extras_owner == pplayer) {
1306 aplrtile->extras_owner = nullptr;
1307 changed = TRUE;
1308 }
1309
1310 /* Must ensure references to dying player are gone from clients
1311 * before player is destroyed */
1312 if (changed) {
1313 /* This will use player tile if fogged */
1314 send_tile_info(pplayer->connections, ptile, FALSE);
1315 }
1317
1318 /* Clear removed player's knowledge */
1319 if (pplayer->tile_known.vec) {
1320 map_clear_known(ptile, pplayer);
1321 }
1322
1323 /* Free all claimed tiles. */
1324 if (tile_owner(ptile) == pplayer) {
1325 tile_set_owner(ptile, nullptr, nullptr);
1327 }
1328 if (extra_owner(ptile) == pplayer) {
1329 ptile->extras_owner = nullptr;
1331 }
1332
1333 if (reality_changed) {
1334 /* Update anyone who can see the tile (e.g. global observers) */
1335 send_tile_info(nullptr, ptile, FALSE);
1336 }
1338
1340}
1341
1342/**********************************************************************/
1346static void player_tile_init(struct tile *ptile, struct player *pplayer)
1347{
1348 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1349
1350 plrtile->terrain = T_UNKNOWN;
1351 plrtile->resource = nullptr;
1352 plrtile->owner = nullptr;
1353 plrtile->extras_owner = nullptr;
1354 plrtile->site = nullptr;
1355 dbv_init(&(plrtile->extras), extra_count());
1357 plrtile->last_updated = game.info.turn;
1358 } else {
1359 plrtile->last_updated = game.info.year;
1360 }
1361
1362 plrtile->seen_count[V_MAIN] = !game.server.fogofwar_old;
1363 plrtile->seen_count[V_INVIS] = 0;
1364 plrtile->seen_count[V_SUBSURFACE] = 0;
1365 memcpy(plrtile->own_seen, plrtile->seen_count, sizeof(v_radius_t));
1366}
1367
1368/**********************************************************************/
1371static void player_tile_free(struct tile *ptile, struct player *pplayer)
1372{
1373 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1374
1375 if (plrtile->site != nullptr) {
1377 }
1378
1379 dbv_free(&(plrtile->extras));
1380}
1381
1382/**********************************************************************/
1385struct vision_site *map_get_player_city(const struct tile *ptile,
1386 const struct player *pplayer)
1387{
1388 struct vision_site *psite = map_get_player_site(ptile, pplayer);
1389
1390 fc_assert_ret_val(psite == nullptr || psite->location == ptile, nullptr);
1391
1392 return psite;
1393}
1394
1395/**********************************************************************/
1400struct player_tile *map_get_player_tile(const struct tile *ptile,
1401 const struct player *pplayer)
1402{
1403 fc_assert_ret_val(pplayer->server.private_map, nullptr);
1404
1405 return pplayer->server.private_map + tile_index(ptile);
1406}
1407
1408/**********************************************************************/
1416bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
1417{
1418 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1419
1420 if (plrtile->terrain != ptile->terrain
1421 || !bv_match_dbv(&(plrtile->extras), ptile->extras.vec)
1422 || plrtile->resource != ptile->resource
1423 || plrtile->owner != tile_owner(ptile)
1424 || plrtile->extras_owner != extra_owner(ptile)) {
1425 plrtile->terrain = ptile->terrain;
1426 extra_type_iterate(pextra) {
1427 if (player_knows_extra_exist(pplayer, pextra, ptile)) {
1428 dbv_set(&(plrtile->extras), extra_number(pextra));
1429 } else {
1430 dbv_clr(&(plrtile->extras), extra_number(pextra));
1431 }
1433 if (ptile->resource != nullptr
1434 && player_knows_extra_exist(pplayer, ptile->resource, ptile)) {
1435 plrtile->resource = ptile->resource;
1436 } else {
1437 plrtile->resource = nullptr;
1438 }
1439 plrtile->owner = tile_owner(ptile);
1440 plrtile->extras_owner = extra_owner(ptile);
1441
1442 return TRUE;
1443 }
1444
1445 return FALSE;
1446}
1447
1448/**********************************************************************/
1457void update_tile_knowledge(struct tile *ptile)
1458{
1459 if (server_state() == S_S_INITIAL) {
1460 return;
1461 }
1462
1463 /* Players */
1464 players_iterate(pplayer) {
1465 if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
1466 if (update_player_tile_knowledge(pplayer, ptile)) {
1467 send_tile_info(pplayer->connections, ptile, FALSE);
1468 }
1469 }
1471
1472 /* Global observers */
1474 struct player *pplayer = pconn->playing;
1475
1476 if (pplayer == nullptr && pconn->observer) {
1477 send_tile_info(pconn->self, ptile, FALSE);
1478 }
1480}
1481
1482/**********************************************************************/
1486 struct tile *ptile)
1487{
1489 map_get_player_tile(ptile, pplayer)->last_updated = game.info.turn;
1490 } else {
1491 map_get_player_tile(ptile, pplayer)->last_updated = game.info.year;
1492 }
1493}
1494
1495/**********************************************************************/
1504 struct player *pdest,
1505 struct tile *ptile)
1506{
1507 if (!map_is_known_and_seen(ptile, pdest, V_MAIN)) {
1508 /* I can just hear people scream as they try to comprehend this if :).
1509 * Let me try in words:
1510 * 1) if the tile is seen by pfrom the info is sent to pdest
1511 * OR
1512 * 2) if the tile is known by pfrom AND (they have more recent info
1513 * OR it is not known by pdest)
1514 */
1516 || (map_is_known(ptile, pfrom)
1517 && (((map_get_player_tile(ptile, pfrom)->last_updated
1518 > map_get_player_tile(ptile, pdest)->last_updated))
1519 || !map_is_known(ptile, pdest)))) {
1520 struct player_tile *from_tile, *dest_tile;
1521
1523 dest_tile = map_get_player_tile(ptile, pdest);
1524 /* Update and send tile knowledge */
1525 map_set_known(ptile, pdest);
1526 dest_tile->terrain = from_tile->terrain;
1527 dbv_copy(&(dest_tile->extras), &(from_tile->extras));
1528 dest_tile->resource = from_tile->resource;
1529 dest_tile->owner = from_tile->owner;
1530 dest_tile->extras_owner = from_tile->extras_owner;
1531 dest_tile->last_updated = from_tile->last_updated;
1532 send_tile_info(pdest->connections, ptile, FALSE);
1533
1534 /* Update and send city knowledge */
1535 /* Remove outdated cities */
1536 if (dest_tile->site) {
1537 if (!from_tile->site) {
1538 /* As the city was gone on the newer from_tile
1539 it will be removed by this function */
1540 reality_check_city(pdest, ptile);
1541 } else { /* We have a dest_city. update */
1542 if (from_tile->site->identity
1543 != dest_tile->site->identity) {
1544 /* As the city was gone on the newer from_tile
1545 it will be removed by this function */
1546 reality_check_city(pdest, ptile);
1547 }
1548 }
1549 }
1550
1551 /* Set and send new city info */
1552 if (from_tile->site) {
1553 if (!dest_tile->site) {
1554 /* We cannot assign new vision site with change_playertile_site(),
1555 * since location is not yet set up for new site */
1556 dest_tile->site = vision_site_copy(from_tile->site);
1557 }
1558 /* Note that we don't care if receiver knows vision source city
1559 * or not. */
1560 send_city_info_at_tile(pdest, pdest->connections, nullptr, ptile);
1561 }
1562
1564
1565 return TRUE;
1566 }
1567 }
1568
1569 return FALSE;
1570}
1571
1572/**********************************************************************/
1586
1587/**********************************************************************/
1597 struct player *pdest,
1598 struct tile *ptile)
1599{
1601
1605 }
1607
1608 return updt;
1609}
1610
1611/**********************************************************************/
1617{
1618 int added;
1619
1620 players_iterate(pplayer) {
1621 pplayer->server.really_gives_vision = pplayer->gives_shared_vision;
1623
1624 /* In words: This terminates when it has run a round without adding
1625 a dependency. One loop only propagates dependencies one level deep,
1626 which is why we keep doing it as long as changes occur. */
1627 do {
1628 added = 0;
1629 players_iterate(pplayer) {
1631 if (really_gives_vision(pplayer, pplayer2)
1632 && pplayer != pplayer2) {
1635 && !really_gives_vision(pplayer, pplayer3)
1636 && pplayer != pplayer3) {
1637 BV_SET(pplayer->server.really_gives_vision, player_index(pplayer3));
1638 added++;
1639 }
1641 }
1644 } while (added > 0);
1645}
1646
1647/**********************************************************************/
1651{
1653
1654 if (pfrom == pto) {
1655 return;
1656 }
1657
1659 log_error("Trying to give shared vision from %s to %s, "
1660 "but that vision is already given!",
1662 return;
1663 }
1664
1665 players_iterate(pplayer) {
1666 save_vision[player_index(pplayer)] = pplayer->server.really_gives_vision;
1668
1669 BV_SET(pfrom->gives_shared_vision, player_index(pto));
1671 log_debug("giving shared vision from %s to %s",
1673
1674 players_iterate(pplayer) {
1675 buffer_shared_vision(pplayer);
1677 if (really_gives_vision(pplayer, pplayer2)
1678 && !BV_ISSET(save_vision[player_index(pplayer)],
1680 log_debug("really giving shared vision from %s to %s",
1681 player_name(pplayer), player_name(pplayer2));
1682 whole_map_iterate(&(wld.map), ptile) {
1683 const struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1684 const v_radius_t change =
1688
1689 if (0 < change[V_MAIN] || 0 < change[V_INVIS]) {
1690 map_change_seen(pplayer2, ptile, change,
1691 map_is_known(ptile, pplayer));
1692 }
1694
1695 /* Squares that are not seen, but which pfrom may have more recent
1696 knowledge of */
1698 }
1700 unbuffer_shared_vision(pplayer);
1702
1703 if (S_S_RUNNING == server_state()) {
1704 send_player_info_c(pfrom, nullptr);
1705 }
1706}
1707
1708/**********************************************************************/
1712{
1714
1716 if (!gives_shared_vision(pfrom, pto)) {
1717 log_error("Tried removing the shared vision from %s to %s, "
1718 "but it did not exist in the first place!",
1720 return;
1721 }
1722
1723 players_iterate(pplayer) {
1724 save_vision[player_index(pplayer)] = pplayer->server.really_gives_vision;
1726
1727 log_debug("removing shared vision from %s to %s",
1729
1730 BV_CLR(pfrom->gives_shared_vision, player_index(pto));
1732
1733 players_iterate(pplayer) {
1734 buffer_shared_vision(pplayer);
1736 if (!really_gives_vision(pplayer, pplayer2)
1737 && BV_ISSET(save_vision[player_index(pplayer)],
1739 log_debug("really removing shared vision from %s to %s",
1740 player_name(pplayer), player_name(pplayer2));
1741 whole_map_iterate(&(wld.map), ptile) {
1742 const struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1743 const v_radius_t change =
1747
1748 if (0 > change[V_MAIN] || 0 > change[V_INVIS]) {
1749 map_change_seen(pplayer2, ptile, change, FALSE);
1750 }
1752 }
1754 unbuffer_shared_vision(pplayer);
1756
1757 if (S_S_RUNNING == server_state()) {
1758 send_player_info_c(pfrom, nullptr);
1759 }
1760}
1761
1762/**********************************************************************/
1766{
1767 const v_radius_t radius_sq = V_RADIUS(-1, 0, 0);
1768
1770
1771 buffer_shared_vision(pplayer);
1772 whole_map_iterate(&(wld.map), ptile) {
1773 map_change_seen(pplayer, ptile, radius_sq, FALSE);
1775 unbuffer_shared_vision(pplayer);
1776}
1777
1778/**********************************************************************/
1782{
1783 players_iterate(pplayer) {
1784 enable_fog_of_war_player(pplayer);
1786}
1787
1788/**********************************************************************/
1792{
1793 const v_radius_t radius_sq = V_RADIUS(1, 0, 0);
1794
1796
1797 buffer_shared_vision(pplayer);
1798 whole_map_iterate(&(wld.map), ptile) {
1799 map_change_seen(pplayer, ptile, radius_sq, FALSE);
1801 unbuffer_shared_vision(pplayer);
1802}
1803
1804/**********************************************************************/
1808{
1809 players_iterate(pplayer) {
1812}
1813
1814/**********************************************************************/
1823static void ocean_to_land_fix_rivers(struct tile *ptile)
1824{
1825 cardinal_adjc_iterate(&(wld.map), ptile, tile1) {
1826 bool ocean_near = FALSE;
1827
1829 if (is_ocean_tile(tile2))
1830 ocean_near = TRUE;
1832
1833 if (!ocean_near) {
1834 /* If ruleset has several river types defined, this
1835 * may cause same tile to contain more than one river. */
1839 tile_add_extra(ptile, priver);
1840 }
1842 }
1844}
1845
1846/**********************************************************************/
1850 struct tile *from)
1851{
1852 bool unit_alive = TRUE;
1853 struct player *owner = unit_owner(punit);
1854
1855 /* Look for a nearby safe tile */
1856 adjc_iterate(&(wld.map), from, ptile2) {
1861 log_verbose("Moved %s %s due to changing terrain at (%d,%d).",
1866 _("Moved your %s due to changing terrain."),
1867 unit_link(punit));
1868
1869 /* TODO: Should a unit be able to bounce to a transport like is
1870 * done below? What if the unit can't legally enter the transport,
1871 * say because the transport is Unreachable and the unit doesn't
1872 * have it in its embarks field or because "Transport Embark"
1873 * isn't enabled? Kept like it was to preserve the old rules for
1874 * now. -- Sveinung */
1876 nullptr, TRUE, FALSE, FALSE, FALSE, FALSE);
1879 }
1880 break;
1881 }
1883
1884 if (unit_alive && unit_tile(punit) == from) {
1885 /* If we get here we could not move punit. */
1886
1887 /* Try to bounce transported units. */
1889 struct unit_list *pcargo_units;
1890
1895 }
1896 }
1897}
1898
1899/**********************************************************************/
1905static void check_units_single_tile(struct tile *ptile)
1906{
1907 const struct civ_map *nmap = &(wld.map);
1908
1910 int id = punit->id;
1911
1912 /* Top-level transports only. Each handle their own cargo */
1914 && !can_unit_exist_at_tile(nmap, punit, ptile)) {
1916
1917 if (unit_is_alive(id) && unit_tile(punit) == ptile) {
1918 log_verbose("Disbanded %s %s due to changing terrain "
1919 "at (%d, %d).",
1921 unit_rule_name(punit), TILE_XY(ptile));
1924 _("Disbanded your %s due to changing terrain."),
1927 }
1928 }
1930}
1931
1932/**********************************************************************/
1940{
1941 const struct civ_map *nmap = &(wld.map);
1942
1943 /* Check this tile for direct effect on its units */
1945 /* We have to check adjacent tiles too, in case units in cities are now
1946 * illegal (e.g., boat in a city that has become landlocked),
1947 * and in case of CoastStrict units losing their adjacent coast. */
1948 adjc_iterate(nmap, ptile, ptile2) {
1951}
1952
1953/**********************************************************************/
1958 const struct terrain *newter)
1959{
1961
1962 if (!oldter || !newter) {
1963 return FALSE;
1964 }
1965
1968
1969 return (old_is_ocean && !new_is_ocean)
1970 || (!old_is_ocean && new_is_ocean);
1971}
1972
1973/**********************************************************************/
1976void terrain_changed(struct tile *ptile)
1977{
1978 struct city *pcity = tile_city(ptile);
1979
1980 if (pcity != nullptr) {
1981 /* Tile is city center and new terrain may support better extras. */
1982 upgrade_city_extras(pcity, nullptr);
1983 }
1984
1986}
1987
1988/**********************************************************************/
1996 struct terrain *oldter,
1997 bool extend_rivers)
1998{
1999 if (is_ocean(oldter) && !is_ocean_tile(ptile)) {
2000 if (extend_rivers) {
2002 }
2004 }
2005
2006 terrain_changed(ptile);
2007}
2008
2009/**********************************************************************/
2015void check_terrain_change(struct tile *ptile, struct terrain *oldter)
2016{
2017 struct terrain *newter = tile_terrain(ptile);
2018 struct tile *claimer;
2019 bool cont_reassigned = FALSE;
2020
2021 /* Check if new terrain is a freshwater terrain next to non-freshwater.
2022 * In that case, the new terrain is *changed*. */
2024 bool nonfresh = FALSE;
2025
2026 adjc_iterate(&(wld.map), ptile, atile) {
2029 nonfresh = TRUE;
2030 break;
2031 }
2033 if (nonfresh) {
2034 /* Need to pick a new, non-freshwater ocean type for this tile.
2035 * We don't want e.g. Deep Ocean to be propagated to this tile
2036 * and then to a whole lake by the flooding below, so we pick
2037 * the shallowest non-fresh oceanic type.
2038 * Prefer terrain that matches the frozenness of the target. */
2041 }
2042 }
2043
2047
2048 phase_players_iterate(pplayer) {
2049 if (is_adv_data_phase_open(pplayer)) {
2050 /* Player is using continent numbers that they would assume to remain accurate.
2051 * Force refresh:
2052 * 1) Close the phase, so that it can be opened
2053 * 2) Open the phase, recalculating
2054 */
2055 adv_data_phase_done(pplayer);
2056 adv_data_phase_init(pplayer, FALSE);
2057 }
2059 }
2060
2062
2063 /* Check for saltwater filling freshwater lake */
2066 adjc_iterate(&(wld.map), ptile, atile) {
2068 struct terrain *aold = tile_terrain(atile);
2069
2072 TER_FROZEN)));
2073
2074 /* Recursive, but as lakes are of limited size, this
2075 * won't recurse so much as to cause stack problems. */
2078 }
2080 }
2081
2082 if (cont_reassigned) {
2083 send_all_known_tiles(nullptr);
2084 }
2085
2086 claimer = tile_claimer(ptile);
2087 if (claimer != nullptr) {
2088 /* Make sure map_claim_border() conditions are still satisfied */
2089 if (!is_tile_claimable(ptile, claimer, tile_owner(ptile))) {
2090 map_clear_border(ptile);
2091 }
2092 }
2093
2094 sanity_check_tile(ptile);
2095}
2096
2097/**********************************************************************/
2101static bool is_tile_claimable(struct tile *ptile, struct tile *source,
2102 struct player *pplayer)
2103{
2104 if (ptile == source) {
2105 /* Source itself is always claimable. */
2106 return TRUE;
2107 }
2108
2109 return 0 < get_target_bonus_effects(nullptr,
2110 &(const struct req_context) {
2111 .tile = ptile,
2112 .player = pplayer,
2113 },
2114 &(const struct req_context) {
2115 .tile = source,
2116 },
2118}
2119
2120/**********************************************************************/
2123static void map_unit_homecity_enqueue(struct tile *ptile)
2124{
2125 unit_list_iterate(ptile->units, punit) {
2127
2128 if (phome == nullptr) {
2129 continue;
2130 }
2131
2134}
2135
2136/**********************************************************************/
2139static void map_claim_border_ownership(struct tile *ptile,
2140 struct player *powner,
2141 struct tile *psource)
2142{
2143 struct player *ploser = tile_owner(ptile);
2144
2145 if ((ploser != powner && ploser != nullptr)
2148 || ploser->server.border_vision)) {
2149 const v_radius_t radius_sq = V_RADIUS(-1, 0, 0);
2150
2151 shared_vision_change_seen(ploser, ptile, radius_sq, FALSE);
2152 }
2153
2154 if (powner != nullptr
2157 || powner->server.border_vision)) {
2158 const v_radius_t radius_sq = V_RADIUS(1, 0, 0);
2159
2160 shared_vision_change_seen(powner, ptile, radius_sq, TRUE);
2161 }
2162
2163 tile_set_owner(ptile, powner, psource);
2164
2165 /* Needed only when foggedborders enabled, but we do it unconditionally
2166 * in case foggedborders ever gets enabled later. Better to have correct
2167 * information in player map just in case. */
2168 update_tile_knowledge(ptile);
2169
2170 if (ploser != powner) {
2173 }
2174
2175 if (!city_map_update_tile_frozen(ptile)) {
2176 send_tile_info(nullptr, ptile, FALSE);
2177 }
2178 }
2179}
2180
2181/**********************************************************************/
2184void map_claim_ownership(struct tile *ptile, struct player *powner,
2185 struct tile *psource, bool claim_bases)
2186{
2187 map_claim_border_ownership(ptile, powner, psource);
2188
2189 if (claim_bases) {
2190 tile_claim_bases(ptile, powner);
2191 }
2192}
2193
2194/**********************************************************************/
2197void tile_claim_bases(struct tile *ptile, struct player *powner)
2198{
2199 struct player *base_loser = extra_owner(ptile);
2200
2201 /* This MUST be before potentially recursive call to map_claim_base(),
2202 * so that the recursive call will get new owner == base_loser and
2203 * abort recursion. */
2204 ptile->extras_owner = powner;
2205
2207 map_claim_base(ptile, pextra, powner, base_loser);
2209}
2210
2211/**********************************************************************/
2214void map_clear_border(struct tile *ptile)
2215{
2216 int radius_sq = tile_border_source_radius_sq(ptile);
2217
2218 circle_dxyr_iterate(&(wld.map), ptile, radius_sq, dtile, dx, dy, dr) {
2219 struct tile *claimer = tile_claimer(dtile);
2220
2221 if (claimer == ptile) {
2222 map_claim_ownership(dtile, nullptr, nullptr, FALSE);
2223 }
2225}
2226
2227/**********************************************************************/
2231void map_update_border(struct tile *ptile, struct player *owner,
2233{
2235 /* No change */
2236 return;
2237 }
2238
2240 return;
2241 }
2242
2245 } else {
2246 circle_dxyr_iterate(&(wld.map), ptile, old_radius_sq, dtile, dx, dy, dr) {
2247 if (dr > new_radius_sq) {
2248 struct tile *claimer = tile_claimer(dtile);
2249
2250 if (claimer == ptile) {
2251 map_claim_ownership(dtile, nullptr, nullptr, FALSE);
2252 }
2253 }
2255 }
2256}
2257
2258/**********************************************************************/
2263void map_claim_border(struct tile *ptile, struct player *owner,
2264 int radius_sq)
2265{
2267 return;
2268 }
2269
2270 if (owner == nullptr) {
2271 /* Clear the border instead of claiming. Code below this block
2272 * cannot handle nullptr owner. */
2273 map_clear_border(ptile);
2274
2275 return;
2276 }
2277
2278 if (radius_sq < 0) {
2279 radius_sq = tile_border_source_radius_sq(ptile);
2280 }
2281
2282 circle_dxyr_iterate(&(wld.map), ptile, radius_sq, dtile, dx, dy, dr) {
2283 struct tile *dclaimer = tile_claimer(dtile);
2284
2285 if (dclaimer == ptile) {
2286 /* Already claimed by the ptile */
2287 continue;
2288 }
2289
2290 if (dr != 0 && is_border_source(dtile)) {
2291 /* Do not claim border sources other than self */
2292 /* Note that this is extremely important at the moment for
2293 * base claiming to work correctly in case there's two
2294 * fortresses near each other. There could be infinite
2295 * recursion in them claiming each other. */
2296 continue;
2297 }
2298
2300 continue;
2301 }
2302
2303 /* Always claim source itself (distance, dr, to it 0) */
2304 if (dr != 0 && dclaimer != nullptr && dclaimer != ptile) {
2305 struct city *ccity = tile_city(dclaimer);
2307
2308 if (ccity != nullptr) {
2309 /* Previously claimed by city */
2310 int city_x, city_y;
2311
2313
2317 /* Tile is within region permanently claimed by city */
2318 continue;
2319 }
2320 }
2321
2324
2325 if (strength_new <= strength_old) {
2326 /* Stronger shall prevail,
2327 * in case of equal strength older shall prevail */
2328 continue;
2329 }
2330 }
2331
2332 /* Only certain tiles are claimable */
2333 if (is_tile_claimable(dtile, ptile, owner)) {
2334 map_claim_ownership(dtile, owner, ptile, dr == 0);
2335 }
2337}
2338
2339/**********************************************************************/
2343{
2345 return;
2346 }
2347
2348 if (wld.map.tiles == nullptr) {
2349 /* Map not yet initialized */
2350 return;
2351 }
2352
2353 log_verbose("map_calculate_borders()");
2354
2355 whole_map_iterate(&(wld.map), ptile) {
2356 if (is_border_source(ptile)) {
2357 map_claim_border(ptile, ptile->owner, -1);
2358 }
2360
2361 log_verbose("map_calculate_borders() workers");
2364}
2365
2366/**********************************************************************/
2369void map_claim_base(struct tile *ptile, struct extra_type *pextra,
2370 struct player *powner, struct player *ploser)
2371{
2372 struct base_type *pbase;
2373 bv_player *could_see_unit = nullptr;
2374 int units_num = 0;
2375 int ul_size;
2376
2377 if (!tile_has_extra(ptile, pextra)) {
2378 return;
2379 }
2380
2381 if (pextra->eus != EUS_NORMAL) {
2382 ul_size = unit_list_size(ptile->units);
2383 } else {
2384 ul_size = 0;
2385 }
2386
2387 int stored_units[ul_size + 1];
2388
2389 if (ul_size > 0) {
2390 int i;
2391
2393
2394 unit_list_iterate(ptile->units, aunit) {
2395 stored_units[units_num++] = aunit->id;
2397
2399
2400 for (i = 0; i < units_num; i++) {
2402
2407 }
2409 }
2410 }
2411
2412 pbase = extra_base_get(pextra);
2413
2414 fc_assert_ret(pbase != nullptr);
2415
2416 /* Transfer base provided vision to new owner */
2417 if (powner != nullptr) {
2418 const v_radius_t old_radius_sq = V_RADIUS(-1, -1, -1);
2419 const v_radius_t new_radius_sq = V_RADIUS(pbase->vision_main_sq,
2420 pbase->vision_invis_sq,
2421 pbase->vision_subs_sq);
2422
2425 }
2426
2427 if (ploser != nullptr) {
2428 const v_radius_t old_radius_sq = V_RADIUS(pbase->vision_main_sq,
2429 pbase->vision_invis_sq,
2430 pbase->vision_subs_sq);
2431 const v_radius_t new_radius_sq = V_RADIUS(-1, -1, -1);
2432
2435 }
2436
2438 && territory_claiming_base(pbase) && powner != ploser) {
2439 /* Clear borders from old owner. New owner may not know all those
2440 * tiles and thus does not claim them when borders mode is less
2441 * than EXPAND. */
2442 if (ploser != nullptr) {
2443 /* Set this particular tile owner by nullptr so in recursion
2444 * both loser and owner will be nullptr. */
2445 map_claim_border_ownership(ptile, nullptr, ptile);
2446 map_clear_border(ptile);
2447 }
2448
2449 /* We here first claim this tile ownership -> now on extra_owner()
2450 * will return new owner. Then we claim border, which will recursively
2451 * lead to this tile and base being claimed. But at that point
2452 * ploser == powner and above check will abort the recursion. */
2453 if (powner != nullptr) {
2454 map_claim_border_ownership(ptile, powner, ptile);
2455 map_claim_border(ptile, powner, -1);
2456 }
2459 }
2460
2461 if (units_num > 0) {
2462 int i;
2463
2464 for (i = 0; i < units_num; i++) {
2466
2470 send_unit_info(aplayer->connections, aunit);
2471 }
2472 } else {
2475 }
2476 }
2478 }
2479
2481 }
2482}
2483
2484/**********************************************************************/
2490void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
2491{
2493 radius_sq, vision->can_reveal_tiles);
2494 memcpy(vision->radius_sq, radius_sq, sizeof(v_radius_t));
2495}
2496
2497/**********************************************************************/
2503{
2504 const v_radius_t vision_radius_sq = V_RADIUS(-1, -1, -1);
2505
2506 vision_change_sight(vision, vision_radius_sq);
2507
2508 /* Owner of some city might have lost vision of a tile previously worked */
2509 players_iterate(pplayer) {
2510 city_list_iterate(pplayer->cities, pcity) {
2511 /* We are not interested about CNA_BROADCAST_PENDING, as the vision loss has
2512 * not set it, and whatever set it should take care of it. */
2513 if (pcity->server.needs_arrange == CNA_NORMAL) {
2516 pcity->server.needs_arrange = CNA_NOT;
2517 }
2520}
2521
2522/**********************************************************************/
2525void create_extra(struct tile *ptile, struct extra_type *pextra,
2526 struct player *pplayer)
2527{
2528 bool extras_removed = FALSE;
2529
2531 if (tile_has_extra(ptile, old_extra)
2532 && !can_extras_coexist(old_extra, pextra)) {
2533 destroy_extra(ptile, old_extra);
2535 }
2537
2538 if (pextra->eus != EUS_NORMAL) {
2539 unit_list_iterate(ptile->units, aunit) {
2542 if (!pplayers_allied(pplayer, aplayer)
2545 }
2547 }
2549 }
2550
2551 tile_add_extra(ptile, pextra);
2552
2553 /* Watchtower might become effective. */
2555
2556 if (pextra->data.base != nullptr) {
2557 /* Claim bases on tile */
2558 if (pplayer) {
2559 struct player *old_owner = extra_owner(ptile);
2560
2561 /* Created base from nullptr -> pplayer */
2562 map_claim_base(ptile, pextra, pplayer, nullptr);
2563
2564 if (old_owner != pplayer) {
2565 /* Existing bases from old_owner -> pplayer */
2567 if (oldbase != pextra) {
2568 map_claim_base(ptile, oldbase, pplayer, old_owner);
2569 }
2571
2572 ptile->extras_owner = pplayer;
2573 }
2574 } else {
2575 /* Player who already owns bases on tile claims new base */
2576 map_claim_base(ptile, pextra, extra_owner(ptile), nullptr);
2577 }
2578 }
2579
2580 if (extras_removed) {
2581 /* Maybe conflicting extra that was removed was the only thing
2582 * making tile native to some unit. */
2584 }
2585}
2586
2587/**********************************************************************/
2590void destroy_extra(struct tile *ptile, struct extra_type *pextra)
2591{
2593 bool real = tile_map_check(&(wld.map), ptile);
2594
2595 /* Remember what players were able to see the base. */
2596 if (real) {
2598 players_iterate(pplayer) {
2599 if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
2600 BV_SET(base_seen, player_index(pplayer));
2601 }
2603 }
2604
2605 if (real && is_extra_caused_by(pextra, EC_BASE)) {
2606 struct base_type *pbase = extra_base_get(pextra);
2607 struct player *owner = extra_owner(ptile);
2608
2610 map_clear_border(ptile);
2611 }
2612
2613 if (owner != nullptr
2614 && (0 <= pbase->vision_main_sq || 0 <= pbase->vision_invis_sq)) {
2615 /* Base provides vision, but no borders. */
2617 V_RADIUS(0 <= pbase->vision_main_sq ? pbase->vision_main_sq : -1,
2618 0 <= pbase->vision_invis_sq ? pbase->vision_invis_sq : -1,
2619 0 <= pbase->vision_subs_sq ? pbase->vision_subs_sq : -1);
2620 const v_radius_t new_radius_sq = V_RADIUS(-1, -1, -1);
2621
2624 }
2625 }
2626
2627 tile_remove_extra(ptile, pextra);
2628
2629 if (real) {
2630 /* Remove base from vision of players which were able to see the base. */
2631 players_iterate(pplayer) {
2632 if (BV_ISSET(base_seen, player_index(pplayer))
2633 && update_player_tile_knowledge(pplayer, ptile)) {
2634 send_tile_info(pplayer->connections, ptile, FALSE);
2635 }
2637
2638 if (pextra->eus != EUS_NORMAL) {
2639 struct player *eowner = extra_owner(ptile);
2640
2641 unit_list_iterate(ptile->units, aunit) {
2645 && !pplayers_allied(aplayer, eowner)) {
2646 send_unit_info(aplayer->connections, aunit);
2647 }
2649 }
2651 }
2652 }
2653}
2654
2655/**********************************************************************/
2666 int prob, bool reveal_cities)
2667{
2668 bool updt = FALSE;
2669
2671
2672 whole_map_iterate(&(wld.map), ptile) {
2673 if (fc_rand(100) < prob) {
2675 } else if (reveal_cities && tile_city(ptile) != nullptr) {
2677 }
2679
2681
2682 return updt;
2683}
2684
2685/**********************************************************************/
2694{
2695 struct city *pcity = ptile->worked;
2696
2697 /* Check the unit activities. */
2699
2700 if (pcity != nullptr && !is_free_worked(pcity, ptile)
2701 && get_city_tile_output_bonus(pcity, ptile, nullptr,
2702 EFT_TILE_WORKABLE) <= 0) {
2704 pcity->specialists[DEFAULT_SPECIALIST]++;
2705
2706 if (refresh_city) {
2708 send_city_info(nullptr, pcity);
2709 }
2710 }
2711}
#define ACTION_NONE
Definition actions.h:59
bool is_adv_data_phase_open(struct player *pplayer)
Definition advdata.c:250
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Definition advdata.c:270
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:574
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:390
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:163
bool bv_match_dbv(const struct dbv *match, const unsigned char *src)
Definition bitvector.c:197
void dbv_init(struct dbv *pdbv, int bits)
Definition bitvector.c:50
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c:142
bool dbv_isset(const struct dbv *pdbv, int bit)
Definition bitvector.c:120
void dbv_copy(struct dbv *dest, const struct dbv *src)
Definition bitvector.c:214
void dbv_free(struct dbv *pdbv)
Definition bitvector.c:95
void dbv_clr(struct dbv *pdbv, int bit)
Definition bitvector.c:163
void dbv_to_bv(unsigned char *dest, const struct dbv *src)
Definition bitvector.c:227
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
#define BV_CLR(bv, bit)
Definition bitvector.h:94
int tile_border_source_radius_sq(struct tile *ptile)
Definition borders.c:33
bool is_border_source(struct tile *ptile)
Definition borders.c:116
int tile_border_strength(struct tile *ptile, struct tile *source)
Definition borders.c:101
bool is_free_worked(const struct city *pcity, const struct tile *ptile)
Definition city.c:3718
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:778
@ CNA_NOT
Definition city.h:304
@ CNA_NORMAL
Definition city.h:305
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:565
#define city_owner(_pcity_)
Definition city.h:564
#define city_list_iterate_end
Definition city.h:510
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:228
#define city_tile_iterate_end
Definition city.h:236
void city_map_update_empty(struct city *pcity, struct tile *ptile)
Definition citytools.c:3290
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2374
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2791
void sync_cities(void)
Definition citytools.c:3364
bool city_map_update_tile_frozen(struct tile *ptile)
Definition citytools.c:3347
void remove_dumb_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2883
void city_landlocked_sell_coastal_improvements(struct tile *ptile)
Definition citytools.c:3417
void send_city_info_at_tile(struct player *pviewer, struct conn_list *dest, struct city *pcity, struct tile *ptile)
Definition citytools.c:2426
void city_thaw_workers_queue(void)
Definition citytools.c:197
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2862
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
void city_refresh_queue_add(struct city *pcity)
Definition cityturn.c:198
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
void city_refresh_queue_processing(void)
Definition cityturn.c:214
char * incite_cost
Definition comments.c:77
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:368
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Definition connection.c:734
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:358
void conn_list_compression_freeze(const struct conn_list *pconn_list)
Definition connection.c:722
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
#define conn_list_iterate_end
Definition connection.h:110
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:77
int get_city_tile_output_bonus(const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:913
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
int extra_number(const struct extra_type *pextra)
Definition extras.c:161
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:875
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:468
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
bool is_native_extra_to_utype(const struct extra_type *pextra, const struct unit_type *punittype)
Definition extras.c:866
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:1017
int extra_count(void)
Definition extras.c:153
bool player_knows_extra_exist(const struct player *pplayer, const struct extra_type *pextra, const struct tile *ptile)
Definition extras.c:1167
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:194
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_iterate_end
Definition extras.h:321
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_base_get(_e_)
Definition extras.h:190
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
@ HB_DISABLED
Definition fc_types.h:986
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
@ BORDERS_DISABLED
Definition fc_types.h:732
@ BORDERS_SEE_INSIDE
Definition fc_types.h:734
@ BORDERS_EXPAND
Definition fc_types.h:735
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:94
#define _(String)
Definition fcintl.h:67
const struct ft_color ftc_server
const char * unit_link(const struct unit *punit)
const char * unit_tile_link(const struct unit *punit)
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:115
struct city * game_city_by_number(int id)
Definition game.c:106
struct city * owner
Definition citydlg.c:226
static GtkWidget * source
Definition gotodlg.c:58
#define fc_assert_ret(condition)
Definition log.h:192
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
void dlsend_packet_edit_fogofwar_state(struct conn_list *dest, bool enabled)
void lsend_packet_map_info(struct conn_list *dest, const struct packet_map_info *packet)
int send_packet_tile_info(struct connection *pc, const struct packet_tile_info *packet)
int map_num_tiles(void)
Definition map.c:1161
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1237
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:659
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:796
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1222
#define adjc_iterate_end
Definition map.h:439
#define circle_dxyr_iterate(nmap, center_tile, sq_radius, _tile, dx, dy, dr)
Definition map.h:415
#define cardinal_adjc_iterate_end
Definition map.h:465
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:434
#define circle_dxyr_iterate_end
Definition map.h:426
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:461
#define circle_iterate(nmap, center_tile, sq_radius, tile_itr)
Definition map.h:407
#define whole_map_iterate(_map, _tile)
Definition map.h:582
#define MAP_TILE_OWNER_NULL
Definition map.h:639
#define whole_map_iterate_end
Definition map.h:591
#define circle_iterate_end
Definition map.h:410
void assign_continent_numbers(void)
struct terrain * most_shallow_ocean(bool frozen)
void player_map_init(struct player *pplayer)
Definition maphand.c:1238
static void terrain_change_bounce_single_unit(struct unit *punit, struct tile *from)
Definition maphand.c:1849
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1485
static void shared_vision_change_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change, bool can_reveal_tiles)
Definition maphand.c:674
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2502
void map_claim_base(struct tile *ptile, struct extra_type *pextra, struct player *powner, struct player *ploser)
Definition maphand.c:2369
void map_set_border_vision(struct player *pplayer, const bool is_enabled)
Definition maphand.c:747
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2184
static int player_tile_own_seen(const struct player_tile *plrtile, enum vision_layer vlayer)
Definition maphand.c:1153
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:911
static bool map_is_also_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:926
void send_map_info(struct conn_list *dest)
Definition maphand.c:655
static bool really_give_tile_info_from_player_to_player(struct player *pfrom, struct player *pdest, struct tile *ptile)
Definition maphand.c:1503
static bool is_tile_claimable(struct tile *ptile, struct tile *source, struct player *pplayer)
Definition maphand.c:2101
bool send_tile_suppression(bool now)
Definition maphand.c:474
void destroy_extra(struct tile *ptile, struct extra_type *pextra)
Definition maphand.c:2590
static void check_units_single_tile(struct tile *ptile)
Definition maphand.c:1905
static void really_give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Definition maphand.c:1576
void disable_fog_of_war(void)
Definition maphand.c:1807
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:344
static bool unit_is_on_layer(const struct unit *punit, enum vision_layer vlayer)
Definition maphand.c:646
void map_know_and_see_all(struct player *pplayer)
Definition maphand.c:1213
static void map_change_own_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change)
Definition maphand.c:1162
void show_map_to_all(void)
Definition maphand.c:1227
void send_tile_info(struct conn_list *dest, struct tile *ptile, bool send_unknown)
Definition maphand.c:490
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1416
static int map_get_seen(const struct player *pplayer, const struct tile *ptile, enum vision_layer vlayer)
Definition maphand.c:951
static void ocean_to_land_fix_rivers(struct tile *ptile)
Definition maphand.c:1823
void give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Definition maphand.c:383
void send_all_known_tiles(struct conn_list *dest)
Definition maphand.c:443
void bounce_units_on_terrain_change(struct tile *ptile)
Definition maphand.c:1939
void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest)
Definition maphand.c:399
void remove_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1711
bool need_to_reassign_continents(const struct terrain *oldter, const struct terrain *newter)
Definition maphand.c:1957
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1385
static bool is_terrain_ecologically_wet(struct tile *ptile)
Definition maphand.c:94
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2197
void disable_fog_of_war_player(struct player *pplayer)
Definition maphand.c:1791
void climate_change(bool warming, int effect)
Definition maphand.c:131
void enable_fog_of_war(void)
Definition maphand.c:1781
static bool send_tile_suppressed
Definition maphand.c:63
static void create_vision_dependencies(void)
Definition maphand.c:1616
void upgrade_all_city_extras(struct player *pplayer, bool discovery)
Definition maphand.c:274
void create_extra(struct tile *ptile, struct extra_type *pextra, struct player *pplayer)
Definition maphand.c:2525
void map_update_border(struct tile *ptile, struct player *owner, int old_radius_sq, int new_radius_sq)
Definition maphand.c:2231
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1195
void map_show_all(struct player *pplayer)
Definition maphand.c:896
static void map_unit_homecity_enqueue(struct tile *ptile)
Definition maphand.c:2123
static void map_change_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change, bool can_reveal_tiles)
Definition maphand.c:964
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:775
void give_citymap_from_player_to_player(struct city *pcity, struct player *pfrom, struct player *pdest)
Definition maphand.c:417
void nuclear_winter(int effect)
Definition maphand.c:117
void tile_change_side_effects(struct tile *ptile, bool refresh_city)
Definition maphand.c:2693
static void player_tile_init(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1346
void terrain_changed(struct tile *ptile)
Definition maphand.c:1976
void player_map_free(struct player *pplayer)
Definition maphand.c:1254
static void unbuffer_shared_vision(struct player *pplayer)
Definition maphand.c:367
static void map_claim_border_ownership(struct tile *ptile, struct player *powner, struct tile *psource)
Definition maphand.c:2139
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:937
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1176
void map_calculate_borders(void)
Definition maphand.c:2342
void fix_tile_on_terrain_change(struct tile *ptile, struct terrain *oldter, bool extend_rivers)
Definition maphand.c:1995
void enable_fog_of_war_player(struct player *pplayer)
Definition maphand.c:1765
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:881
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)
Definition maphand.c:692
void map_claim_border(struct tile *ptile, struct player *owner, int radius_sq)
Definition maphand.c:2263
void update_tile_knowledge(struct tile *ptile)
Definition maphand.c:1457
void remove_player_from_maps(struct player *pplayer)
Definition maphand.c:1275
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1650
void check_terrain_change(struct tile *ptile, struct terrain *oldter)
Definition maphand.c:2015
bool give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Definition maphand.c:2665
void map_hide_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:832
static void buffer_shared_vision(struct player *pplayer)
Definition maphand.c:352
static bool give_tile_info_from_player_to_player(struct player *pfrom, struct player *pdest, struct tile *ptile)
Definition maphand.c:1596
void global_warming(int effect)
Definition maphand.c:104
bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
Definition maphand.c:239
void map_clear_border(struct tile *ptile)
Definition maphand.c:2214
void map_clear_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1203
static void player_tile_free(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1371
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1400
void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
Definition maphand.c:2490
#define map_get_player_site(_ptile_, _pplayer_)
Definition maphand.h:93
#define map_get_playermap_site(_plrtile_)
Definition maphand.h:92
#define fc_realloc(ptr, sz)
Definition mem.h:36
#define fc_malloc(sz)
Definition mem.h:34
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:461
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
int player_slot_count(void)
Definition player.c:415
int player_number(const struct player *pplayer)
Definition player.c:826
const char * player_name(const struct player *pplayer)
Definition player.c:885
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1095
int player_index(const struct player *pplayer)
Definition player.c:818
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1397
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1477
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
#define phase_players_iterate(pplayer)
Definition plrhand.h:113
#define phase_players_iterate_end
Definition plrhand.h:118
#define fc_rand(_size)
Definition rand.h:56
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:417
int count_river_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver)
Definition road.c:341
#define sanity_check_tile(x)
Definition sanitycheck.h:43
void flush_packets(void)
Definition sernet.c:376
#define DEFAULT_SPECIALIST
Definition specialist.h:43
enum server_states server_state(void)
Definition srv_main.c:341
Definition city.h:318
bool last_updated_year
Definition game.h:243
bool vision_reveal_tiles
Definition game.h:207
bool fogofwar_old
Definition game.h:241
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
bool foggedborders
Definition game.h:154
struct civ_game::@32::@36 server
struct tile * tiles
Definition map_types.h:95
int north_latitude
Definition map_types.h:80
int south_latitude
Definition map_types.h:81
bool altitude_info
Definition map_types.h:74
int topology_id
Definition map_types.h:72
int wrap_id
Definition map_types.h:73
unsigned char * vec
Definition bitvector.h:34
struct resource_type * resource
Definition extras.h:156
struct extra_type::@26 data
enum extra_unit_seen_type eus
Definition extras.h:128
struct base_type * base
Definition extras.h:154
enum borders_mode borders
enum happyborders_type happyborders
int border_city_permanent_radius_sq
Resource_type_id resource
enum known_type known
Continent_id continent
char spec_sprite[MAX_LEN_NAME]
Terrain_type_id terrain
char label[MAX_LEN_MAP_LABEL]
struct player * extras_owner
Definition maphand.h:35
v_radius_t seen_count
Definition maphand.h:43
struct vision_site * site
Definition maphand.h:31
struct terrain * terrain
Definition maphand.h:33
struct dbv extras
Definition maphand.h:36
short last_updated
Definition maphand.h:44
struct player * owner
Definition maphand.h:34
struct extra_type * resource
Definition maphand.h:32
struct city_list * cities
Definition player.h:281
struct dbv tile_known
Definition player.h:310
struct conn_list * connections
Definition player.h:298
struct player::@73::@75 server
struct player_tile * private_map
Definition player.h:324
bool border_vision
Definition player.h:327
struct terrain * cooler_wetter_result
Definition terrain.h:135
struct terrain * cooler_drier_result
Definition terrain.h:135
struct terrain * warmer_wetter_result
Definition terrain.h:134
struct terrain * warmer_drier_result
Definition terrain.h:134
Definition tile.h:50
char * spec_sprite
Definition tile.h:67
char * label
Definition tile.h:66
int altitude
Definition tile.h:65
bv_extras extras
Definition tile.h:55
struct extra_type * resource
Definition tile.h:56
struct unit_list * units
Definition tile.h:58
struct player * extras_owner
Definition tile.h:63
struct terrain * terrain
Definition tile.h:57
int infra_turns
Definition tile.h:62
struct extra_type * placing
Definition tile.h:61
struct city * worked
Definition tile.h:59
struct tile * claimer
Definition tile.h:64
enum vision_layer vlayer
Definition unittype.h:576
Definition unit.h:139
enum unit_activity activity
Definition unit.h:158
int id
Definition unit.h:146
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:141
struct extra_type * activity_target
Definition unit.h:166
int homecity
Definition unit.h:147
bool dying
Definition unit.h:253
int identity
Definition vision.h:114
struct tile * tile
Definition vision.h:87
bool can_reveal_tiles
Definition vision.h:88
v_radius_t radius_sq
Definition vision.h:91
struct player * player
Definition vision.h:86
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:615
Terrain_type_id terrain_count(void)
Definition terrain.c:119
Terrain_type_id terrain_number(const struct terrain *pterrain)
Definition terrain.c:148
#define T_UNKNOWN
Definition terrain.h:62
#define is_ocean(pterrain)
Definition terrain.h:195
#define is_ocean_tile(ptile)
Definition terrain.h:197
#define T_NONE
Definition terrain.h:61
#define terrain_has_flag(terr, flag)
Definition terrain.h:177
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:956
bool tile_has_river(const struct tile *ptile)
Definition tile.c:853
bool tile_map_check(struct civ_map *nmap, struct tile *vtile)
Definition tile.c:1068
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:966
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:497
bool tile_has_conflicting_extra(const struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:902
void tile_set_owner(struct tile *ptile, struct player *pplayer, struct tile *claimer)
Definition tile.c:69
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_claimer(_tile)
Definition tile.h:101
#define tile_index(_pt_)
Definition tile.h:89
#define tile_worked(_tile)
Definition tile.h:119
#define tile_resource(_tile)
Definition tile.h:103
@ TILE_KNOWN_UNSEEN
Definition tile.h:37
@ TILE_UNKNOWN
Definition tile.h:36
@ TILE_KNOWN_SEEN
Definition tile.h:38
#define tile_terrain(_tile)
Definition tile.h:115
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_continent(_tile)
Definition tile.h:93
#define tile_has_extra(ptile, pextra)
Definition tile.h:152
#define tile_owner(_tile)
Definition tile.h:97
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1841
bool unit_is_alive(int id)
Definition unit.c:2307
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2512
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Definition unit.c:2534
#define unit_tile(_pu)
Definition unit.h:408
#define unit_owner(_pu)
Definition unit.h:407
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:446
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6714
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
Definition unittools.c:2882
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2895
void unit_activities_cancel(struct unit *punit)
Definition unittools.c:809
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2157
void unit_activities_cancel_all_illegal_area(const struct tile *ptile)
Definition unittools.c:854
bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed, bool conquer_extras_allowed, bool enter_hut, bool frighten_hut)
Definition unittools.c:4096
void unit_list_refresh_vision(struct unit_list *punitlist)
Definition unittools.c:5046
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:126
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1613
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:215
struct vision_site * vision_site_copy(const struct vision_site *psite)
Definition vision.c:150
void vision_site_destroy(struct vision_site *psite)
Definition vision.c:74
#define V_RADIUS(main_sq, invis_sq, subs_sq)
Definition vision.h:95
#define vision_layer_iterate(v)
Definition vision.h:76
#define vision_site_owner(v)
Definition vision.h:128
short int v_radius_t[V_COUNT]
Definition vision.h:82
#define vision_layer_iterate_end
Definition vision.h:79
#define MAP_NATIVE_WIDTH
#define MAP_INDEX_SIZE
#define MAP_NATIVE_HEIGHT