Freeciv-3.1
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#define MAXIMUM_CLAIMED_OCEAN_SIZE (20)
63
64/* Suppress send_tile_info() during game_load() */
66
67static void player_tile_init(struct tile *ptile, struct player *pplayer);
68static void player_tile_free(struct tile *ptile, struct player *pplayer);
69static bool give_tile_info_from_player_to_player(struct player *pfrom,
70 struct player *pdest,
71 struct tile *ptile);
72static void shared_vision_change_seen(struct player *pplayer,
73 struct tile *ptile,
74 const v_radius_t change,
75 bool can_reveal_tiles);
76static void map_change_seen(struct player *pplayer,
77 struct tile *ptile,
78 const v_radius_t change,
79 bool can_reveal_tiles);
80static void map_change_own_seen(struct player *pplayer,
81 struct tile *ptile,
82 const v_radius_t change);
83static inline int map_get_seen(const struct player *pplayer,
84 const struct tile *ptile,
85 enum vision_layer vlayer);
86
87static bool is_claimable_ocean(struct tile *ptile, struct tile *source,
88 struct player *pplayer);
89
90/**********************************************************************/
93static bool is_terrain_ecologically_wet(struct tile *ptile)
94{
95 return (is_terrain_class_near_tile(&(wld.map), ptile, TC_OCEAN)
96 || tile_has_river(ptile)
97 || count_river_near_tile(&(wld.map), ptile, NULL) > 0);
98}
99
100/**********************************************************************/
104{
106 notify_player(NULL, NULL, E_GLOBAL_ECO, ftc_server,
107 _("Global warming has occurred!"));
108 notify_player(NULL, NULL, E_GLOBAL_ECO, ftc_server,
109 _("Coastlines have been flooded and vast "
110 "ranges of grassland have become deserts."));
111}
112
113/**********************************************************************/
117{
119 notify_player(NULL, NULL, E_GLOBAL_ECO, ftc_server,
120 _("Nuclear winter has occurred!"));
121 notify_player(NULL, NULL, E_GLOBAL_ECO, ftc_server,
122 _("Wetlands have dried up and vast "
123 "ranges of grassland have become tundra."));
124}
125
126/**********************************************************************/
130void climate_change(bool warming, int effect)
131{
132 int k = map_num_tiles();
133 bool used[k];
134 const struct civ_map *nmap = &(wld.map);
135
136 memset(used, 0, sizeof(used));
137
138 log_verbose("Climate change: %s (%d)",
139 warming ? "Global warming" : "Nuclear winter", effect);
140
141 while (effect > 0 && (k--) > 0) {
142 struct terrain *old, *candidates[2], *new;
143 struct tile *ptile;
144 int i;
145
146 do {
147 /* We want to transform a tile at most once due to a climate change. */
148 ptile = rand_map_pos(&(wld.map));
149 } while (used[tile_index(ptile)]);
150 used[tile_index(ptile)] = TRUE;
151
152 old = tile_terrain(ptile);
153 /* Prefer the transformation that's appropriate to the ambient moisture,
154 * but be prepared to fall back in exceptional circumstances */
155 {
156 struct terrain *wetter, *drier;
157
158 wetter = warming ? old->warmer_wetter_result : old->cooler_wetter_result;
159 drier = warming ? old->warmer_drier_result : old->cooler_drier_result;
160 if (is_terrain_ecologically_wet(ptile)) {
161 candidates[0] = wetter;
162 candidates[1] = drier;
163 } else {
164 candidates[0] = drier;
165 candidates[1] = wetter;
166 }
167 }
168
169 /* If the preferred transformation is ruled out for some exceptional reason
170 * specific to this tile, fall back to the other, rather than letting this
171 * tile be immune to change. */
172 for (i = 0; i < 2; i++) {
173 new = candidates[i];
174
175 /* If the preferred transformation simply hasn't been specified
176 * for this terrain at all, don't fall back to the other. */
177 if (new == T_NONE) {
178 break;
179 }
180
181 if (tile_city(ptile) != NULL && terrain_has_flag(new, TER_NO_CITIES)) {
182 /* do not change to a terrain with the flag TER_NO_CITIES if the tile
183 * has a city */
184 continue;
185 }
186
187 /* Only change between water and land at coastlines, and between
188 * frozen and unfrozen at ice margin */
189 if (!terrain_surroundings_allow_change(nmap, ptile, new)) {
190 continue;
191 }
192
193 /* OK! */
194 break;
195 }
196 if (i == 2) {
197 /* Neither transformation was permitted. Give up. */
198 continue;
199 }
200
201 if (new != T_NONE && old != new) {
202 effect--;
203
204 /* Check terrain changing activities.
205 These would not be caught by the check if unit can continue activity
206 after the terrain change has taken place, as the activity itself is still
207 legal, but would be towards different terrain, and terrain types are not
208 activity targets (target is NULL) */
209 unit_list_iterate(ptile->units, punit) {
210 if (punit->activity_target == NULL) {
211 /* Target is always NULL for terrain changing activities. */
212 if (punit->activity == ACTIVITY_CULTIVATE
213 || punit->activity == ACTIVITY_PLANT
214 || punit->activity == ACTIVITY_TRANSFORM) {
216 }
217 }
219
220 /* Really change the terrain. */
221 tile_change_terrain(ptile, new);
222 check_terrain_change(ptile, old);
224
226
227 } else if (old == new) {
228 /* This counts toward a climate change although nothing is changed. */
229 effect--;
230 }
231 }
232}
233
234/**********************************************************************/
238bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
239{
240 struct tile *ptile = pcity->tile;
241 struct player *pplayer = city_owner(pcity);
242 bool upgradet = FALSE;
243
244 extra_type_iterate(pextra) {
245 if (!tile_has_extra(ptile, pextra)) {
246 if (extra_has_flag(pextra, EF_ALWAYS_ON_CITY_CENTER)
247 || (extra_has_flag(pextra, EF_AUTO_ON_CITY_CENTER)
248 && player_can_build_extra(pextra, pplayer, ptile)
249 && !tile_has_conflicting_extra(ptile, pextra))) {
250 tile_add_extra(pcity->tile, pextra);
251 if (gained != NULL) {
252 if (upgradet) {
253 *gained = NULL;
254 } else {
255 *gained = pextra;
256 }
257 }
258 upgradet = TRUE;
259 }
260 }
262
263 return upgradet;
264}
265
266/**********************************************************************/
273void upgrade_all_city_extras(struct player *pplayer, bool discovery)
274{
275 int cities_upgradet = 0;
276 struct extra_type *upgradet = NULL;
277 bool multiple_types = FALSE;
278 int cities_total = city_list_size(pplayer->cities);
279 int percent;
280
282
283 city_list_iterate(pplayer->cities, pcity) {
284 struct extra_type *new_upgrade;
285
286 if (upgrade_city_extras(pcity, &new_upgrade)) {
287 update_tile_knowledge(pcity->tile);
288 cities_upgradet++;
289 if (new_upgrade == NULL) {
290 /* This single city alone had multiple types */
291 multiple_types = TRUE;
292 } else if (upgradet == NULL) {
293 /* First gained */
294 upgradet = new_upgrade;
295 } else if (upgradet != new_upgrade) {
296 /* Different type from what another city got. */
297 multiple_types = TRUE;
298 }
299 }
301
302 if (cities_total > 0) {
303 percent = cities_upgradet * 100 / cities_total;
304 } else {
305 percent = 0;
306 }
307
308 if (cities_upgradet > 0) {
309 if (discovery) {
310 if (percent >= 75) {
311 notify_player(pplayer, NULL, E_TECH_GAIN, ftc_server,
312 _("New hope sweeps like fire through the country as "
313 "the discovery of new infrastructure building technology "
314 "is announced."));
315 }
316 } else {
317 if (percent >= 75) {
318 notify_player(pplayer, NULL, E_TECH_GAIN, ftc_server,
319 _("The people are pleased to hear that your "
320 "scientists finally know about new infrastructure building "
321 "technology."));
322 }
323 }
324
325 if (multiple_types) {
326 notify_player(pplayer, NULL, E_TECH_GAIN, ftc_server,
327 _("Workers spontaneously gather and upgrade all "
328 "possible cities with better infrastructure."));
329 } else {
330 notify_player(pplayer, NULL, E_TECH_GAIN, ftc_server,
331 _("Workers spontaneously gather and upgrade all "
332 "possible cities with %s."), extra_name_translation(upgradet));
333 }
334 }
335
337}
338
339/**********************************************************************/
342bool really_gives_vision(struct player *me, struct player *them)
343{
345}
346
347/**********************************************************************/
350static void buffer_shared_vision(struct player *pplayer)
351{
352 players_iterate(pplayer2) {
353 if (really_gives_vision(pplayer, pplayer2)) {
354 conn_list_compression_freeze(pplayer2->connections);
355 conn_list_do_buffer(pplayer2->connections);
356 }
360}
361
362/**********************************************************************/
365static void unbuffer_shared_vision(struct player *pplayer)
366{
367 players_iterate(pplayer2) {
368 if (really_gives_vision(pplayer, pplayer2)) {
369 conn_list_do_unbuffer(pplayer2->connections);
370 conn_list_compression_thaw(pplayer2->connections);
371 }
375}
376
377/**********************************************************************/
381void give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
382{
384
385 whole_map_iterate(&(wld.map), ptile) {
386 give_tile_info_from_player_to_player(pfrom, pdest, ptile);
388
391 sync_cities();
392}
393
394/**********************************************************************/
397void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest)
398{
400
401 whole_map_iterate(&(wld.map), ptile) {
402 if (is_ocean_tile(ptile)) {
403 give_tile_info_from_player_to_player(pfrom, pdest, ptile);
404 }
406
409 sync_cities();
410}
411
412/**********************************************************************/
416 struct player *pfrom, struct player *pdest)
417{
418 struct tile *pcenter = city_tile(pcity);
419 const struct civ_map *nmap = &(wld.map);
420
422
423 city_tile_iterate(nmap, city_map_radius_sq_get(pcity), pcenter, ptile) {
424 give_tile_info_from_player_to_player(pfrom, pdest, ptile);
426
429 sync_cities();
430}
431
432/**********************************************************************/
441void send_all_known_tiles(struct conn_list *dest)
442{
443 int tiles_sent;
444
445 if (!dest) {
446 dest = game.est_connections;
447 }
448
449 /* send whole map piece by piece to each player to balance the load
450 of the send buffers better */
451 tiles_sent = 0;
453
454 whole_map_iterate(&(wld.map), ptile) {
455 tiles_sent++;
456 if ((tiles_sent % wld.map.xsize) == 0) {
460 }
461
462 send_tile_info(dest, ptile, FALSE);
464
467}
468
469/**********************************************************************/
473{
474 bool formerly = send_tile_suppressed;
475
477 return formerly;
478}
479
480/**********************************************************************/
488void send_tile_info(struct conn_list *dest, struct tile *ptile,
489 bool send_unknown)
490{
491 struct packet_tile_info info;
492 const struct player *owner;
493 const struct player *eowner;
494
495 if (dest == NULL) {
496 CALL_FUNC_EACH_AI(tile_info, ptile);
497 }
498
500 return;
501 }
502
503 if (!dest) {
504 dest = game.est_connections;
505 }
506
507 info.tile = tile_index(ptile);
508
509 if (ptile->spec_sprite) {
510 sz_strlcpy(info.spec_sprite, ptile->spec_sprite);
511 } else {
512 info.spec_sprite[0] = '\0';
513 }
514
515 conn_list_iterate(dest, pconn) {
516 struct player *pplayer = pconn->playing;
517
518 if (NULL == pplayer && !pconn->observer) {
519 continue;
520 }
521
522 if (!pplayer || map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
523 struct extra_type *resource;
524
525 info.known = TILE_KNOWN_SEEN;
526 info.continent = tile_continent(ptile);
527 owner = tile_owner(ptile);
528 eowner = extra_owner(ptile);
530 info.extras_owner = (eowner ? player_number(eowner) : MAP_TILE_OWNER_NULL);
531 info.worked32 = (NULL != tile_worked(ptile))
532 ? tile_worked(ptile)->id
534 info.worked16 = info.worked32;
535
536 info.terrain = (NULL != tile_terrain(ptile))
538 : terrain_count();
539
540 resource = tile_resource(ptile);
541 if (resource != NULL
542 && (pplayer == NULL
543 || player_knows_extra_exist(pplayer, resource, ptile))) {
545 } else {
547 }
548
549 info.placing = (NULL != ptile->placing)
550 ? extra_number(ptile->placing)
551 : -1;
552 info.place_turn = (NULL != ptile->placing)
553 ? game.info.turn + ptile->infra_turns
554 : 0;
555
556 if (pplayer != NULL) {
557 info.extras = map_get_player_tile(ptile, pplayer)->extras;
558 } else {
559 info.extras = ptile->extras;
560 }
561
562 if (ptile->label != NULL) {
563 /* Always leave final '\0' in place */
564 strncpy(info.label, ptile->label, sizeof(info.label) - 1);
565 } else {
566 info.label[0] = '\0';
567 }
568
569 send_packet_tile_info(pconn, &info);
570 } else if (pplayer && map_is_known(ptile, pplayer)) {
571 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
572 struct vision_site *psite = map_get_player_site(ptile, pplayer);
573
575 info.continent = tile_continent(ptile);
577 ? plrtile->owner
578 : tile_owner(ptile));
579 eowner = plrtile->extras_owner;
581 info.extras_owner = (eowner ? player_number(eowner) : MAP_TILE_OWNER_NULL);
582 info.worked32 = (NULL != psite)
583 ? psite->identity
585 info.worked16 = info.worked32;
586
587 info.terrain = (NULL != plrtile->terrain)
588 ? terrain_number(plrtile->terrain)
589 : terrain_count();
590 info.resource = (NULL != plrtile->resource)
591 ? extra_number(plrtile->resource)
593 info.placing = -1;
594 info.place_turn = 0;
595
596 info.extras = plrtile->extras;
597
598 /* Labels never change, so they are not subject to fog of war */
599 if (ptile->label != NULL) {
600 sz_strlcpy(info.label, ptile->label);
601 } else {
602 info.label[0] = '\0';
603 }
604
605 send_packet_tile_info(pconn, &info);
606 } else if (send_unknown) {
607 info.known = TILE_UNKNOWN;
608 info.continent = 0;
613
614 info.terrain = terrain_count();
616 info.placing = -1;
617 info.place_turn = 0;
618
619 BV_CLR_ALL(info.extras);
620
621 info.label[0] = '\0';
622
623 send_packet_tile_info(pconn, &info);
624 }
625 }
627}
628
629/**********************************************************************/
635static bool unit_is_on_layer(const struct unit *punit,
636 enum vision_layer vlayer)
637{
638 return unit_type_get(punit)->vlayer == vlayer;
639}
640
641/**********************************************************************/
644void send_map_info(struct conn_list *dest)
645{
646 struct packet_map_info minfo;
647
648 minfo.xsize = wld.map.xsize;
649 minfo.ysize = wld.map.ysize;
651
652 lsend_packet_map_info(dest, &minfo);
653}
654
655/**********************************************************************/
659static void shared_vision_change_seen(struct player *pplayer,
660 struct tile *ptile,
661 const v_radius_t change,
662 bool can_reveal_tiles)
663{
664 map_change_own_seen(pplayer, ptile, change);
665 map_change_seen(pplayer, ptile, change, can_reveal_tiles);
666
667 players_iterate(pplayer2) {
668 if (really_gives_vision(pplayer, pplayer2)) {
669 map_change_seen(pplayer2, ptile, change, can_reveal_tiles);
670 }
672}
673
674/**********************************************************************/
677void map_vision_update(struct player *pplayer, struct tile *ptile,
678 const v_radius_t old_radius_sq,
679 const v_radius_t new_radius_sq,
680 bool can_reveal_tiles)
681{
682 v_radius_t change;
683 int max_radius;
684
685 if (old_radius_sq[V_MAIN] == new_radius_sq[V_MAIN]
686 && old_radius_sq[V_INVIS] == new_radius_sq[V_INVIS]
687 && old_radius_sq[V_SUBSURFACE] == new_radius_sq[V_SUBSURFACE]) {
688 return;
689 }
690
691 /* Determines 'max_radius' value. */
692 max_radius = 0;
694 if (max_radius < old_radius_sq[v]) {
695 max_radius = old_radius_sq[v];
696 }
697 if (max_radius < new_radius_sq[v]) {
698 max_radius = new_radius_sq[v];
699 }
701
702#ifdef FREECIV_DEBUG
703 log_debug("Updating vision at (%d, %d) in a radius of %d.",
704 TILE_XY(ptile), max_radius);
706 log_debug(" vision layer %d is changing from %d to %d.",
707 v, old_radius_sq[v], new_radius_sq[v]);
709#endif /* FREECIV_DEBUG */
710
711 buffer_shared_vision(pplayer);
712 circle_dxyr_iterate(&(wld.map), ptile, max_radius, tile1, dx, dy, dr) {
714 if (dr > old_radius_sq[v] && dr <= new_radius_sq[v]) {
715 change[v] = 1;
716 } else if (dr > new_radius_sq[v] && dr <= old_radius_sq[v]) {
717 change[v] = -1;
718 } else {
719 change[v] = 0;
720 }
722 shared_vision_change_seen(pplayer, tile1, change, can_reveal_tiles);
724 unbuffer_shared_vision(pplayer);
725}
726
727/**********************************************************************/
732void map_set_border_vision(struct player *pplayer,
733 const bool is_enabled)
734{
735 const v_radius_t radius_sq = V_RADIUS(is_enabled ? 1 : -1, 0, 0);
736
737 if (pplayer->server.border_vision == is_enabled) {
738 /* No change. Changing the seen count beyond what already exists would
739 * be a bug. */
740 return;
741 }
742
743 /* Set the new border seer value. */
744 pplayer->server.border_vision = is_enabled;
745
746 whole_map_iterate(&(wld.map), ptile) {
747 if (pplayer == ptile->owner) {
748 /* The tile is within the player's borders. */
749 shared_vision_change_seen(pplayer, ptile, radius_sq, TRUE);
750 }
752}
753
754/**********************************************************************/
760void map_show_tile(struct player *src_player, struct tile *ptile)
761{
762 static int recurse = 0;
763
764 log_debug("Showing %i,%i to %s", TILE_XY(ptile), player_name(src_player));
765
766 fc_assert(recurse == 0);
767 recurse++;
768
769 players_iterate(pplayer) {
770 if (pplayer == src_player || really_gives_vision(src_player, pplayer)) {
771 struct city *pcity;
772
773 if (!map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
774 map_set_known(ptile, pplayer);
775
776 /* As the tile may be fogged send_tile_info won't always do this for us */
777 update_player_tile_knowledge(pplayer, ptile);
778 update_player_tile_last_seen(pplayer, ptile);
779
780 send_tile_info(pplayer->connections, ptile, FALSE);
781
782 /* Remove old cities that exist no more */
783 reality_check_city(pplayer, ptile);
784
785 if ((pcity = tile_city(ptile))) {
786 /* As the tile may be fogged send_city_info won't do this for us */
787 update_dumb_city(pplayer, pcity);
788 send_city_info(pplayer, pcity);
789 }
790
792 if (0 < map_get_seen(pplayer, ptile, v)) {
793 unit_list_iterate(ptile->units, punit) {
794 if (unit_is_on_layer(punit, v)) {
795 send_unit_info(pplayer->connections, punit);
796 }
798 }
800 }
801 }
803
804 recurse--;
805}
806
807/**********************************************************************/
812void map_hide_tile(struct player *src_player, struct tile *ptile)
813{
814 static int recurse = 0;
815
816 log_debug("Hiding %d,%d to %s", TILE_XY(ptile), player_name(src_player));
817
818 fc_assert(recurse == 0);
819 recurse++;
820
821 players_iterate(pplayer) {
822 if (pplayer == src_player || really_gives_vision(src_player, pplayer)) {
823 if (map_is_known(ptile, pplayer)) {
824 if (0 < map_get_seen(pplayer, ptile, V_MAIN)) {
825 update_player_tile_last_seen(pplayer, ptile);
826 }
827
828 /* Remove city. */
829 remove_dumb_city(pplayer, ptile);
830
831 /* Remove units. */
833 if (0 < map_get_seen(pplayer, ptile, v)) {
834 unit_list_iterate(ptile->units, punit) {
835 if (unit_is_on_layer(punit, v)) {
837 }
839 }
841 }
842
843 map_clear_known(ptile, pplayer);
844
845 send_tile_info(pplayer->connections, ptile, TRUE);
846 }
848
849 recurse--;
850}
851
852/**********************************************************************/
856void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
857{
858 buffer_shared_vision(pplayer);
859
860 circle_iterate(&(wld.map), ptile, radius_sq, tile1) {
861 map_show_tile(pplayer, tile1);
863
864 unbuffer_shared_vision(pplayer);
865}
866
867/**********************************************************************/
871void map_show_all(struct player *pplayer)
872{
873 buffer_shared_vision(pplayer);
874
875 whole_map_iterate(&(wld.map), ptile) {
876 map_show_tile(pplayer, ptile);
878
879 unbuffer_shared_vision(pplayer);
880}
881
882/**********************************************************************/
886bool map_is_known(const struct tile *ptile, const struct player *pplayer)
887{
888 if (pplayer->tile_known.vec == NULL) {
889 /* Player map not initialized yet */
890 return FALSE;
891 }
892
893 return dbv_isset(&pplayer->tile_known, tile_index(ptile));
894}
895
896/**********************************************************************/
900bool map_is_known_and_seen(const struct tile *ptile,
901 const struct player *pplayer,
902 enum vision_layer vlayer)
903{
904 return (map_is_known(ptile, pplayer)
905 && 0 < map_get_seen(pplayer, ptile, vlayer));
906}
907
908/**********************************************************************/
915static inline int map_get_seen(const struct player *pplayer,
916 const struct tile *ptile,
917 enum vision_layer vlayer)
918{
919 return map_get_player_tile(ptile, pplayer)->seen_count[vlayer];
920}
921
922/**********************************************************************/
928void map_change_seen(struct player *pplayer,
929 struct tile *ptile,
930 const v_radius_t change,
931 bool can_reveal_tiles)
932{
933 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
934 bool revealing_tile = FALSE;
935
936#ifdef FREECIV_DEBUG
937 log_debug("%s() for player %s (nb %d) at (%d, %d).",
938 __FUNCTION__, player_name(pplayer), player_number(pplayer),
939 TILE_XY(ptile));
941 log_debug(" vision layer %d is changing from %d to %d.",
942 v, plrtile->seen_count[v], plrtile->seen_count[v] + change[v]);
944#endif /* FREECIV_DEBUG */
945
946 /* Removes units out of vision. First, check invisible layers because
947 * we must remove all units before fog of war because clients expect
948 * the tile is empty when it is fogged. */
949 if (0 > change[V_INVIS]
950 && plrtile->seen_count[V_INVIS] == -change[V_INVIS]) {
951 log_debug("(%d, %d): hiding invisible units to player %s (nb %d).",
952 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
953
954 unit_list_iterate(ptile->units, punit) {
955 if (unit_is_on_layer(punit, V_INVIS)
956 && can_player_see_unit(pplayer, punit)
957 && (plrtile->seen_count[V_MAIN] + change[V_MAIN] <= 0
958 || !pplayers_allied(pplayer, unit_owner(punit)))) {
959 /* Allied units on seen tiles (V_MAIN) are always seen.
960 * That's how can_player_see_unit_at() works. */
962 }
964 }
965 if (0 > change[V_SUBSURFACE]
966 && plrtile->seen_count[V_SUBSURFACE] == -change[V_SUBSURFACE]) {
967 log_debug("(%d, %d): hiding subsurface units to player %s (nb %d).",
968 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
969
970 unit_list_iterate(ptile->units, punit) {
971 if (unit_is_on_layer(punit, V_SUBSURFACE)
972 && can_player_see_unit(pplayer, punit)) {
974 }
976 }
977
978 if (0 > change[V_MAIN]
979 && plrtile->seen_count[V_MAIN] == -change[V_MAIN]) {
980 log_debug("(%d, %d): hiding visible units to player %s (nb %d).",
981 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
982
983 unit_list_iterate(ptile->units, punit) {
984 if (unit_is_on_layer(punit, V_MAIN)
985 && can_player_see_unit(pplayer, punit)) {
987 }
989 }
990
992 /* Avoid underflow. */
993 fc_assert(0 <= change[v] || -change[v] <= plrtile->seen_count[v]);
994 plrtile->seen_count[v] += change[v];
996
997 /* V_MAIN vision ranges must always be more than invisible ranges
998 * (see comment in common/vision.h), so we assume that the V_MAIN
999 * seen count cannot be inferior to V_INVIS or V_SUBSURFACE seen count.
1000 * Moreover, when the fog of war is disabled, V_MAIN has an extra
1001 * seen count point. */
1002 fc_assert(plrtile->seen_count[V_INVIS] + !game.info.fogofwar
1003 <= plrtile->seen_count[V_MAIN]);
1004 fc_assert(plrtile->seen_count[V_SUBSURFACE] + !game.info.fogofwar
1005 <= plrtile->seen_count[V_MAIN]);
1006
1007 if (!map_is_known(ptile, pplayer)) {
1008 if (0 < plrtile->seen_count[V_MAIN] && can_reveal_tiles) {
1009 log_debug("(%d, %d): revealing tile to player %s (nb %d).",
1010 TILE_XY(ptile), player_name(pplayer),
1011 player_number(pplayer));
1012
1013 map_set_known(ptile, pplayer);
1014 revealing_tile = TRUE;
1015 } else {
1016 return;
1017 }
1018 }
1019
1020 /* Fog the tile. */
1021 if (0 > change[V_MAIN] && 0 == plrtile->seen_count[V_MAIN]) {
1022 struct city *pcity;
1023
1024 log_debug("(%d, %d): fogging tile for player %s (nb %d).",
1025 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1026
1027 pcity = ptile->worked;
1028
1029 if (pcity != NULL && city_owner(pcity) == pplayer) {
1030 city_map_update_empty(pcity, ptile);
1032 if (pcity->server.needs_arrange == CNA_NOT) {
1034 }
1035 }
1036
1037 update_player_tile_last_seen(pplayer, ptile);
1039 plrtile->owner = tile_owner(ptile);
1040 }
1041 plrtile->extras_owner = extra_owner(ptile);
1042 send_tile_info(pplayer->connections, ptile, FALSE);
1043 }
1044
1045 if ((revealing_tile && 0 < plrtile->seen_count[V_MAIN])
1046 || (0 < change[V_MAIN]
1047 /* plrtile->seen_count[V_MAIN] Always set to 1
1048 * when the fog of war is disabled. */
1049 && (change[V_MAIN] + !game.info.fogofwar
1050 == (plrtile->seen_count[V_MAIN])))) {
1051 struct city *pcity;
1052
1053 log_debug("(%d, %d): unfogging tile for player %s (nb %d).",
1054 TILE_XY(ptile), player_name(pplayer), player_number(pplayer));
1055
1056 /* Send info about the tile itself.
1057 * It has to be sent first because the client needs correct
1058 * continent number before it can handle following packets
1059 */
1060 update_player_tile_knowledge(pplayer, ptile);
1061 send_tile_info(pplayer->connections, ptile, FALSE);
1062
1063 /* Discover units. */
1064 unit_list_iterate(ptile->units, punit) {
1065 /* Be sure not to revive dead unit on client when it's not yet
1066 * removed from the tile. This could happen when "unit_lost" lua script
1067 * somehow causes tile of the dead unit to unfog again. */
1068 if (unit_is_on_layer(punit, V_MAIN)
1069 && !punit->server.dying) {
1070 send_unit_info(pplayer->connections, punit);
1071 }
1073
1074 /* Discover cities. */
1075 reality_check_city(pplayer, ptile);
1076
1077 if (NULL != (pcity = tile_city(ptile))) {
1078 send_city_info(pplayer, pcity);
1079 }
1080 }
1081
1082 if ((revealing_tile && 0 < plrtile->seen_count[V_INVIS])
1083 || (0 < change[V_INVIS]
1084 && change[V_INVIS] == plrtile->seen_count[V_INVIS])) {
1085 log_debug("(%d, %d): revealing invisible units to player %s (nb %d).",
1086 TILE_XY(ptile), player_name(pplayer),
1087 player_number(pplayer));
1088 /* Discover units. */
1089 unit_list_iterate(ptile->units, punit) {
1090 if (unit_is_on_layer(punit, V_INVIS)) {
1091 send_unit_info(pplayer->connections, punit);
1092 }
1094 }
1095 if ((revealing_tile && 0 < plrtile->seen_count[V_SUBSURFACE])
1096 || (0 < change[V_SUBSURFACE]
1097 && change[V_SUBSURFACE] == plrtile->seen_count[V_SUBSURFACE])) {
1098 log_debug("(%d, %d): revealing subsurface units to player %s (nb %d).",
1099 TILE_XY(ptile), player_name(pplayer),
1100 player_number(pplayer));
1101 /* Discover units. */
1102 unit_list_iterate(ptile->units, punit) {
1103 if (unit_is_on_layer(punit, V_SUBSURFACE)) {
1104 send_unit_info(pplayer->connections, punit);
1105 }
1107 }
1108}
1109
1110/**********************************************************************/
1117static inline int player_tile_own_seen(const struct player_tile *plrtile,
1118 enum vision_layer vlayer)
1119{
1120 return plrtile->own_seen[vlayer];
1121}
1122
1123/**********************************************************************/
1126static void map_change_own_seen(struct player *pplayer,
1127 struct tile *ptile,
1128 const v_radius_t change)
1129{
1130 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1131
1133 plrtile->own_seen[v] += change[v];
1135}
1136
1137/**********************************************************************/
1141 struct vision_site *new_site)
1142{
1143 if (ptile->site == new_site) {
1144 /* Do nothing. */
1145 return;
1146 }
1147
1148 if (ptile->site != NULL) {
1149 /* Releasing old site from tile */
1150 vision_site_destroy(ptile->site);
1151 }
1152
1153 ptile->site = new_site;
1154}
1155
1156/**********************************************************************/
1159void map_set_known(struct tile *ptile, struct player *pplayer)
1160{
1161 dbv_set(&pplayer->tile_known, tile_index(ptile));
1162}
1163
1164/**********************************************************************/
1167void map_clear_known(struct tile *ptile, struct player *pplayer)
1168{
1169 dbv_clr(&pplayer->tile_known, tile_index(ptile));
1170}
1171
1172/**********************************************************************/
1177void map_know_and_see_all(struct player *pplayer)
1178{
1179 const v_radius_t radius_sq = V_RADIUS(1, 1, 1);
1180
1181 buffer_shared_vision(pplayer);
1182 whole_map_iterate(&(wld.map), ptile) {
1183 map_change_seen(pplayer, ptile, radius_sq, TRUE);
1185 unbuffer_shared_vision(pplayer);
1186}
1187
1188/**********************************************************************/
1192{
1193 players_iterate(pplayer) {
1194 map_know_and_see_all(pplayer);
1196}
1197
1198/**********************************************************************/
1202void player_map_init(struct player *pplayer)
1203{
1204 pplayer->server.private_map
1205 = fc_realloc(pplayer->server.private_map,
1206 MAP_INDEX_SIZE * sizeof(*pplayer->server.private_map));
1207
1208 whole_map_iterate(&(wld.map), ptile) {
1209 player_tile_init(ptile, pplayer);
1211
1213}
1214
1215/**********************************************************************/
1218void player_map_free(struct player *pplayer)
1219{
1220 if (!pplayer->server.private_map) {
1221 return;
1222 }
1223
1224 whole_map_iterate(&(wld.map), ptile) {
1225 player_tile_free(ptile, pplayer);
1227
1228 free(pplayer->server.private_map);
1229 pplayer->server.private_map = NULL;
1230
1231 dbv_free(&pplayer->tile_known);
1232}
1233
1234/**********************************************************************/
1239void remove_player_from_maps(struct player *pplayer)
1240{
1241 /* only after removing borders! */
1243 whole_map_iterate(&(wld.map), ptile) {
1244 /* Clear all players' knowledge about the removed player, and free
1245 * data structures (including those in removed player's player map). */
1246 bool reality_changed = FALSE;
1247
1248 players_iterate(aplayer) {
1249 struct player_tile *aplrtile;
1250 bool changed = FALSE;
1251
1252 if (!aplayer->server.private_map) {
1253 continue;
1254 }
1255 aplrtile = map_get_player_tile(ptile, aplayer);
1256
1257 /* Free vision sites (cities) for removed and other players */
1258 if (aplrtile && aplrtile->site
1259 && vision_site_owner(aplrtile->site) == pplayer) {
1260 change_playertile_site(aplrtile, NULL);
1261 changed = TRUE;
1262 }
1263
1264 /* Remove references to player from others' maps */
1265 if (aplrtile->owner == pplayer) {
1266 aplrtile->owner = NULL;
1267 changed = TRUE;
1268 }
1269 if (aplrtile->extras_owner == pplayer) {
1270 aplrtile->extras_owner = NULL;
1271 changed = TRUE;
1272 }
1273
1274 /* Must ensure references to dying player are gone from clients
1275 * before player is destroyed */
1276 if (changed) {
1277 /* This will use player tile if fogged */
1278 send_tile_info(pplayer->connections, ptile, FALSE);
1279 }
1281
1282 /* Clear removed player's knowledge */
1283 if (pplayer->tile_known.vec) {
1284 map_clear_known(ptile, pplayer);
1285 }
1286
1287 /* Free all claimed tiles. */
1288 if (tile_owner(ptile) == pplayer) {
1289 tile_set_owner(ptile, NULL, NULL);
1290 reality_changed = TRUE;
1291 }
1292 if (extra_owner(ptile) == pplayer) {
1293 ptile->extras_owner = NULL;
1294 reality_changed = TRUE;
1295 }
1296
1297 if (reality_changed) {
1298 /* Update anyone who can see the tile (e.g. global observers) */
1299 send_tile_info(NULL, ptile, FALSE);
1300 }
1303}
1304
1305/**********************************************************************/
1309static void player_tile_init(struct tile *ptile, struct player *pplayer)
1310{
1311 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1312
1313 plrtile->terrain = T_UNKNOWN;
1314 plrtile->resource = NULL;
1315 plrtile->owner = NULL;
1316 plrtile->extras_owner = NULL;
1317 plrtile->site = NULL;
1318 BV_CLR_ALL(plrtile->extras);
1320 plrtile->last_updated = game.info.turn;
1321 } else {
1322 plrtile->last_updated = game.info.year;
1323 }
1324
1325 plrtile->seen_count[V_MAIN] = !game.server.fogofwar_old;
1326 plrtile->seen_count[V_INVIS] = 0;
1327 plrtile->seen_count[V_SUBSURFACE] = 0;
1328 memcpy(plrtile->own_seen, plrtile->seen_count, sizeof(v_radius_t));
1329}
1330
1331/**********************************************************************/
1334static void player_tile_free(struct tile *ptile, struct player *pplayer)
1335{
1336 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1337
1338 if (plrtile->site != NULL) {
1339 vision_site_destroy(plrtile->site);
1340 }
1341}
1342
1343/**********************************************************************/
1346struct vision_site *map_get_player_city(const struct tile *ptile,
1347 const struct player *pplayer)
1348{
1349 struct vision_site *psite = map_get_player_site(ptile, pplayer);
1350
1351 fc_assert_ret_val(psite == NULL || psite->location == ptile, NULL);
1352
1353 return psite;
1354}
1355
1356/**********************************************************************/
1359struct vision_site *map_get_player_site(const struct tile *ptile,
1360 const struct player *pplayer)
1361{
1362 return map_get_player_tile(ptile, pplayer)->site;
1363}
1364
1365/**********************************************************************/
1370struct player_tile *map_get_player_tile(const struct tile *ptile,
1371 const struct player *pplayer)
1372{
1373 fc_assert_ret_val(pplayer->server.private_map, NULL);
1374
1375 return pplayer->server.private_map + tile_index(ptile);
1376}
1377
1378/**********************************************************************/
1386bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
1387{
1388 struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1389
1390 if (plrtile->terrain != ptile->terrain
1391 || !BV_ARE_EQUAL(plrtile->extras, ptile->extras)
1392 || plrtile->resource != ptile->resource
1393 || plrtile->owner != tile_owner(ptile)
1394 || plrtile->extras_owner != extra_owner(ptile)) {
1395 plrtile->terrain = ptile->terrain;
1396 extra_type_iterate(pextra) {
1397 if (player_knows_extra_exist(pplayer, pextra, ptile)) {
1398 BV_SET(plrtile->extras, extra_number(pextra));
1399 } else {
1400 BV_CLR(plrtile->extras, extra_number(pextra));
1401 }
1403 if (ptile->resource != NULL
1404 && player_knows_extra_exist(pplayer, ptile->resource, ptile)) {
1405 plrtile->resource = ptile->resource;
1406 } else {
1407 plrtile->resource = NULL;
1408 }
1409 plrtile->owner = tile_owner(ptile);
1410 plrtile->extras_owner = extra_owner(ptile);
1411
1412 return TRUE;
1413 }
1414
1415 return FALSE;
1416}
1417
1418/**********************************************************************/
1427void update_tile_knowledge(struct tile *ptile)
1428{
1429 if (server_state() == S_S_INITIAL) {
1430 return;
1431 }
1432
1433 /* Players */
1434 players_iterate(pplayer) {
1435 if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
1436 if (update_player_tile_knowledge(pplayer, ptile)) {
1437 send_tile_info(pplayer->connections, ptile, FALSE);
1438 }
1439 }
1441
1442 /* Global observers */
1444 struct player *pplayer = pconn->playing;
1445
1446 if (NULL == pplayer && pconn->observer) {
1447 send_tile_info(pconn->self, ptile, FALSE);
1448 }
1450}
1451
1452/**********************************************************************/
1456 struct tile *ptile)
1457{
1459 map_get_player_tile(ptile, pplayer)->last_updated = game.info.turn;
1460 } else {
1461 map_get_player_tile(ptile, pplayer)->last_updated = game.info.year;
1462 }
1463}
1464
1465/**********************************************************************/
1474 struct player *pdest,
1475 struct tile *ptile)
1476{
1477 struct player_tile *from_tile, *dest_tile;
1478
1479 if (!map_is_known_and_seen(ptile, pdest, V_MAIN)) {
1480 /* I can just hear people scream as they try to comprehend this if :).
1481 * Let me try in words:
1482 * 1) if the tile is seen by pfrom the info is sent to pdest
1483 * OR
1484 * 2) if the tile is known by pfrom AND (they have more recent info
1485 * OR it is not known by pdest)
1486 */
1487 if (map_is_known_and_seen(ptile, pfrom, V_MAIN)
1488 || (map_is_known(ptile, pfrom)
1489 && (((map_get_player_tile(ptile, pfrom)->last_updated
1490 > map_get_player_tile(ptile, pdest)->last_updated))
1491 || !map_is_known(ptile, pdest)))) {
1492 from_tile = map_get_player_tile(ptile, pfrom);
1493 dest_tile = map_get_player_tile(ptile, pdest);
1494 /* Update and send tile knowledge */
1495 map_set_known(ptile, pdest);
1496 dest_tile->terrain = from_tile->terrain;
1497 dest_tile->extras = from_tile->extras;
1498 dest_tile->resource = from_tile->resource;
1499 dest_tile->owner = from_tile->owner;
1500 dest_tile->extras_owner = from_tile->extras_owner;
1501 dest_tile->last_updated = from_tile->last_updated;
1502 send_tile_info(pdest->connections, ptile, FALSE);
1503
1504 /* Update and send city knowledge */
1505 /* Remove outdated cities */
1506 if (dest_tile->site) {
1507 if (!from_tile->site) {
1508 /* As the city was gone on the newer from_tile
1509 it will be removed by this function */
1510 reality_check_city(pdest, ptile);
1511 } else { /* We have a dest_city. update */
1512 if (from_tile->site->identity
1513 != dest_tile->site->identity) {
1514 /* As the city was gone on the newer from_tile
1515 it will be removed by this function */
1516 reality_check_city(pdest, ptile);
1517 }
1518 }
1519 }
1520
1521 /* Set and send new city info */
1522 if (from_tile->site) {
1523 if (!dest_tile->site) {
1524 /* We cannot assign new vision site with change_playertile_site(),
1525 * since location is not yet set up for new site */
1526 dest_tile->site = vision_site_copy(from_tile->site);
1527 }
1528 /* Note that we don't care if receiver knows vision source city
1529 * or not. */
1530 send_city_info_at_tile(pdest, pdest->connections, NULL, ptile);
1531 }
1532
1534
1535 return TRUE;
1536 }
1537 }
1538
1539 return FALSE;
1540}
1541
1542/**********************************************************************/
1547 struct player *pdest)
1548{
1549 whole_map_iterate(&(wld.map), ptile) {
1552
1554 sync_cities();
1555}
1556
1557/**********************************************************************/
1567 struct player *pdest,
1568 struct tile *ptile)
1569{
1570 bool updt = really_give_tile_info_from_player_to_player(pfrom, pdest, ptile);
1571
1572 players_iterate(pplayer2) {
1573 if (really_gives_vision(pdest, pplayer2)) {
1574 updt |= really_give_tile_info_from_player_to_player(pfrom, pplayer2, ptile);
1575 }
1577
1578 return updt;
1579}
1580
1581/**********************************************************************/
1587{
1588 int added;
1589
1590 players_iterate(pplayer) {
1591 pplayer->server.really_gives_vision = pplayer->gives_shared_vision;
1593
1594 /* In words: This terminates when it has run a round without adding
1595 a dependency. One loop only propagates dependencies one level deep,
1596 which is why we keep doing it as long as changes occur. */
1597 do {
1598 added = 0;
1599 players_iterate(pplayer) {
1600 players_iterate(pplayer2) {
1601 if (really_gives_vision(pplayer, pplayer2)
1602 && pplayer != pplayer2) {
1603 players_iterate(pplayer3) {
1604 if (really_gives_vision(pplayer2, pplayer3)
1605 && !really_gives_vision(pplayer, pplayer3)
1606 && pplayer != pplayer3) {
1607 BV_SET(pplayer->server.really_gives_vision, player_index(pplayer3));
1608 added++;
1609 }
1611 }
1614 } while (added > 0);
1615}
1616
1617/**********************************************************************/
1620void give_shared_vision(struct player *pfrom, struct player *pto)
1621{
1622 bv_player save_vision[player_slot_count()];
1623
1624 if (pfrom == pto) {
1625 return;
1626 }
1627
1628 if (gives_shared_vision(pfrom, pto)) {
1629 log_error("Trying to give shared vision from %s to %s, "
1630 "but that vision is already given!",
1631 player_name(pfrom), player_name(pto));
1632 return;
1633 }
1634
1635 players_iterate(pplayer) {
1636 save_vision[player_index(pplayer)] = pplayer->server.really_gives_vision;
1638
1641 log_debug("giving shared vision from %s to %s",
1642 player_name(pfrom), player_name(pto));
1643
1644 players_iterate(pplayer) {
1645 buffer_shared_vision(pplayer);
1646 players_iterate(pplayer2) {
1647 if (really_gives_vision(pplayer, pplayer2)
1648 && !BV_ISSET(save_vision[player_index(pplayer)],
1649 player_index(pplayer2))) {
1650 log_debug("really giving shared vision from %s to %s",
1651 player_name(pplayer), player_name(pplayer2));
1652 whole_map_iterate(&(wld.map), ptile) {
1653 const struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1654 const v_radius_t change =
1655 V_RADIUS(player_tile_own_seen(plrtile, V_MAIN),
1656 player_tile_own_seen(plrtile, V_INVIS),
1657 player_tile_own_seen(plrtile, V_SUBSURFACE));
1658
1659 if (0 < change[V_MAIN] || 0 < change[V_INVIS]) {
1660 map_change_seen(pplayer2, ptile, change,
1661 map_is_known(ptile, pplayer));
1662 }
1664
1665 /* Squares that are not seen, but which pfrom may have more recent
1666 knowledge of */
1667 really_give_map_from_player_to_player(pplayer, pplayer2);
1668 }
1670 unbuffer_shared_vision(pplayer);
1672
1673 if (S_S_RUNNING == server_state()) {
1674 send_player_info_c(pfrom, NULL);
1675 }
1676}
1677
1678/**********************************************************************/
1681void remove_shared_vision(struct player *pfrom, struct player *pto)
1682{
1683 bv_player save_vision[player_slot_count()];
1684
1685 fc_assert_ret(pfrom != pto);
1686 if (!gives_shared_vision(pfrom, pto)) {
1687 log_error("Tried removing the shared vision from %s to %s, "
1688 "but it did not exist in the first place!",
1689 player_name(pfrom), player_name(pto));
1690 return;
1691 }
1692
1693 players_iterate(pplayer) {
1694 save_vision[player_index(pplayer)] = pplayer->server.really_gives_vision;
1696
1697 log_debug("removing shared vision from %s to %s",
1698 player_name(pfrom), player_name(pto));
1699
1702
1703 players_iterate(pplayer) {
1704 buffer_shared_vision(pplayer);
1705 players_iterate(pplayer2) {
1706 if (!really_gives_vision(pplayer, pplayer2)
1707 && BV_ISSET(save_vision[player_index(pplayer)],
1708 player_index(pplayer2))) {
1709 log_debug("really removing shared vision from %s to %s",
1710 player_name(pplayer), player_name(pplayer2));
1711 whole_map_iterate(&(wld.map), ptile) {
1712 const struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1713 const v_radius_t change =
1714 V_RADIUS(-player_tile_own_seen(plrtile, V_MAIN),
1715 -player_tile_own_seen(plrtile, V_INVIS),
1716 -player_tile_own_seen(plrtile, V_SUBSURFACE));
1717
1718 if (0 > change[V_MAIN] || 0 > change[V_INVIS]) {
1719 map_change_seen(pplayer2, ptile, change, FALSE);
1720 }
1722 }
1724 unbuffer_shared_vision(pplayer);
1726
1727 if (S_S_RUNNING == server_state()) {
1728 send_player_info_c(pfrom, NULL);
1729 }
1730}
1731
1732/**********************************************************************/
1736{
1737 const v_radius_t radius_sq = V_RADIUS(-1, 0, 0);
1738
1739 buffer_shared_vision(pplayer);
1740 whole_map_iterate(&(wld.map), ptile) {
1741 map_change_seen(pplayer, ptile, radius_sq, FALSE);
1743 unbuffer_shared_vision(pplayer);
1744}
1745
1746/**********************************************************************/
1750{
1751 players_iterate(pplayer) {
1752 enable_fog_of_war_player(pplayer);
1754}
1755
1756/**********************************************************************/
1760{
1761 const v_radius_t radius_sq = V_RADIUS(1, 0, 0);
1762
1763 buffer_shared_vision(pplayer);
1764 whole_map_iterate(&(wld.map), ptile) {
1765 map_change_seen(pplayer, ptile, radius_sq, FALSE);
1767 unbuffer_shared_vision(pplayer);
1768}
1769
1770/**********************************************************************/
1774{
1775 players_iterate(pplayer) {
1778}
1779
1780/**********************************************************************/
1789static void ocean_to_land_fix_rivers(struct tile *ptile)
1790{
1791 cardinal_adjc_iterate(&(wld.map), ptile, tile1) {
1792 bool ocean_near = FALSE;
1793
1794 cardinal_adjc_iterate(&(wld.map), tile1, tile2) {
1795 if (is_ocean_tile(tile2))
1796 ocean_near = TRUE;
1798
1799 if (!ocean_near) {
1800 /* If ruleset has several river types defined, this
1801 * may cause same tile to contain more than one river. */
1802 extra_type_by_cause_iterate(EC_ROAD, priver) {
1803 if (tile_has_extra(tile1, priver)
1804 && road_has_flag(extra_road_get(priver), RF_RIVER)) {
1805 tile_add_extra(ptile, priver);
1806 }
1808 }
1810}
1811
1812/**********************************************************************/
1816 struct tile *from)
1817{
1818 bool unit_alive = TRUE;
1819
1820 /* Look for a nearby safe tile */
1821 adjc_iterate(&(wld.map), from, ptile2) {
1822 if (can_unit_exist_at_tile(&(wld.map), punit, ptile2)
1825 log_verbose("Moved %s %s due to changing terrain at (%d,%d).",
1829 E_UNIT_RELOCATED, ftc_server,
1830 _("Moved your %s due to changing terrain."),
1831 unit_link(punit));
1832
1833 /* TODO: should a unit be able to bounce to a transport like is
1834 * done below? What if the unit can't legally enter the transport,
1835 * say because the transport is Unreachable and the unit doesn't
1836 * have it in its embarks field or because "Transport Embark"
1837 * isn't enabled? Kept like it was to preserve the old rules for
1838 * now. -- Sveinung */
1839 unit_alive = unit_move(punit, ptile2, 0,
1840 NULL, TRUE, FALSE, FALSE, FALSE, FALSE);
1841 if (unit_alive && punit->activity == ACTIVITY_SENTRY) {
1842 unit_activity_handling(punit, ACTIVITY_IDLE);
1843 }
1844 break;
1845 }
1847
1848 if (unit_alive && unit_tile(punit) == from) {
1849 /* If we get here we could not move punit. */
1850
1851 /* Try to bounce transported units. */
1853 struct unit_list *pcargo_units;
1854
1855 pcargo_units = unit_transport_cargo(punit);
1856 unit_list_iterate_safe(pcargo_units, pcargo) {
1859 }
1860 }
1861}
1862
1863/**********************************************************************/
1869static void check_units_single_tile(struct tile *ptile)
1870{
1871 const struct civ_map *nmap = &(wld.map);
1872
1874 int id = punit->id;
1875
1876 /* Top-level transports only. Each handle their own cargo */
1878 && !can_unit_exist_at_tile(nmap, punit, ptile)) {
1880
1881 if (unit_is_alive(id) && unit_tile(punit) == ptile) {
1882 log_verbose("Disbanded %s %s due to changing terrain "
1883 "at (%d, %d).",
1885 unit_rule_name(punit), TILE_XY(ptile));
1887 E_UNIT_LOST_MISC, ftc_server,
1888 _("Disbanded your %s due to changing terrain."),
1890 wipe_unit(punit, ULR_NONNATIVE_TERR, NULL);
1891 }
1892 }
1894}
1895
1896/**********************************************************************/
1904{
1905 const struct civ_map *nmap = &(wld.map);
1906
1907 /* Check this tile for direct effect on its units */
1909 /* We have to check adjacent tiles too, in case units in cities are now
1910 * illegal (e.g., boat in a city that has become landlocked),
1911 * and in case of CoastStrict units losing their adjacent coast. */
1912 adjc_iterate(nmap, ptile, ptile2) {
1915}
1916
1917/**********************************************************************/
1921bool need_to_reassign_continents(const struct terrain *oldter,
1922 const struct terrain *newter)
1923{
1924 bool old_is_ocean, new_is_ocean;
1925
1926 if (!oldter || !newter) {
1927 return FALSE;
1928 }
1929
1930 old_is_ocean = is_ocean(oldter);
1931 new_is_ocean = is_ocean(newter);
1932
1933 return (old_is_ocean && !new_is_ocean)
1934 || (!old_is_ocean && new_is_ocean);
1935}
1936
1937/**********************************************************************/
1940void terrain_changed(struct tile *ptile)
1941{
1942 struct city *pcity = tile_city(ptile);
1943
1944 if (pcity != NULL) {
1945 /* Tile is city center and new terrain may support better extras. */
1946 upgrade_city_extras(pcity, NULL);
1947 }
1948
1950}
1951
1952/**********************************************************************/
1960 struct terrain *oldter,
1961 bool extend_rivers)
1962{
1963 if (is_ocean(oldter) && !is_ocean_tile(ptile)) {
1964 if (extend_rivers) {
1966 }
1968 }
1969
1970 terrain_changed(ptile);
1971}
1972
1973/**********************************************************************/
1979void check_terrain_change(struct tile *ptile, struct terrain *oldter)
1980{
1981 struct terrain *newter = tile_terrain(ptile);
1982 struct tile *claimer;
1983 bool cont_reassigned = FALSE;
1984
1985 /* Check if new terrain is a freshwater terrain next to non-freshwater.
1986 * In that case, the new terrain is *changed*. */
1987 if (is_ocean(newter) && terrain_has_flag(newter, TER_FRESHWATER)) {
1988 bool nonfresh = FALSE;
1989
1990 adjc_iterate(&(wld.map), ptile, atile) {
1991 if (is_ocean(tile_terrain(atile))
1992 && !terrain_has_flag(tile_terrain(atile), TER_FRESHWATER)) {
1993 nonfresh = TRUE;
1994 break;
1995 }
1997 if (nonfresh) {
1998 /* Need to pick a new, non-freshwater ocean type for this tile.
1999 * We don't want e.g. Deep Ocean to be propagated to this tile
2000 * and then to a whole lake by the flooding below, so we pick
2001 * the shallowest non-fresh oceanic type.
2002 * Prefer terrain that matches the frozenness of the target. */
2003 newter = most_shallow_ocean(terrain_has_flag(newter, TER_FROZEN));
2004 tile_change_terrain(ptile, newter);
2005 }
2006 }
2007
2008 if (need_to_reassign_continents(oldter, newter)) {
2010 cont_reassigned = TRUE;
2011
2012 phase_players_iterate(pplayer) {
2013 if (is_adv_data_phase_open(pplayer)) {
2014 /* Player is using continent numbers that they would assume to remain accurate.
2015 * Force refresh:
2016 * 1) Close the phase, so that it can be opened
2017 * 2) Open the phase, recalculating
2018 */
2019 adv_data_phase_done(pplayer);
2020 adv_data_phase_init(pplayer, FALSE);
2021 }
2023 }
2024
2025 fix_tile_on_terrain_change(ptile, oldter, TRUE);
2026
2027 /* Check for saltwater filling freshwater lake */
2029 && is_ocean(newter) && !terrain_has_flag(newter, TER_FRESHWATER)) {
2030 adjc_iterate(&(wld.map), ptile, atile) {
2031 if (terrain_has_flag(tile_terrain(atile), TER_FRESHWATER)) {
2032 struct terrain *aold = tile_terrain(atile);
2033
2034 tile_change_terrain(atile,
2036 TER_FROZEN)));
2037
2038 /* Recursive, but as lakes are of limited size, this
2039 * won't recurse so much as to cause stack problems. */
2040 check_terrain_change(atile, aold);
2041 update_tile_knowledge(atile);
2042 }
2044 }
2045
2046 if (cont_reassigned) {
2048 }
2049
2050 claimer = tile_claimer(ptile);
2051 if (claimer != NULL) {
2052 /* Make sure map_claim_border() conditions are still satisfied */
2053 if (is_ocean_tile(ptile)) {
2054 /* Only certain water tiles are claimable */
2055 if (!is_claimable_ocean(ptile, claimer, tile_owner(ptile))) {
2056 map_clear_border(ptile);
2057 }
2058 } else {
2059 /* Only land tiles on the same island as the border source
2060 * are claimable */
2061 if (tile_continent(ptile) != tile_continent(claimer)) {
2062 map_clear_border(ptile);
2063 }
2064 }
2065 }
2066
2067 sanity_check_tile(ptile);
2068}
2069
2070/**********************************************************************/
2081static bool is_claimable_ocean(struct tile *ptile, struct tile *source,
2082 struct player *pplayer)
2083{
2084 Continent_id cont = tile_continent(ptile);
2085 Continent_id source_cont = tile_continent(source);
2086 int ocean_tiles;
2087 bool other_continent;
2088
2090 && get_lake_surrounders(cont) == source_cont) {
2091 return TRUE;
2092 }
2093
2094 if (ptile == source) {
2095 /* Source itself is always claimable. */
2096 return TRUE;
2097 }
2098
2099 if (num_known_tech_with_flag(pplayer, TF_CLAIM_OCEAN) > 0
2100 || (source_cont < 0 && num_known_tech_with_flag(pplayer, TF_CLAIM_OCEAN_LIMITED) > 0)) {
2101 return TRUE;
2102 }
2103
2104 ocean_tiles = 0;
2105 other_continent = FALSE;
2106 adjc_iterate(&(wld.map), ptile, adj_tile) {
2107 Continent_id adj_cont = tile_continent(adj_tile);
2108 if (adj_tile == source) {
2109 /* Water next to border source is always claimable */
2110 return TRUE;
2111 }
2112 if (adj_cont == cont) {
2113 ocean_tiles++;
2114 } else if (adj_cont != source_cont) {
2115 /* This water is adjacent to a continent different from the one
2116 * the border source is on */
2117 other_continent = TRUE;
2118 }
2120 if (!other_continent && ocean_tiles <= 2) {
2121 return TRUE;
2122 } else {
2123 return FALSE;
2124 }
2125}
2126
2127/**********************************************************************/
2130static void map_unit_homecity_enqueue(struct tile *ptile)
2131{
2132 unit_list_iterate(ptile->units, punit) {
2133 struct city *phome = game_city_by_number(punit->homecity);
2134
2135 if (NULL == phome) {
2136 continue;
2137 }
2138
2141}
2142
2143/**********************************************************************/
2146static void map_claim_border_ownership(struct tile *ptile,
2147 struct player *powner,
2148 struct tile *psource)
2149{
2150 struct player *ploser = tile_owner(ptile);
2151
2152 if ((ploser != powner && ploser != NULL)
2155 || ploser->server.border_vision)) {
2156 const v_radius_t radius_sq = V_RADIUS(-1, 0, 0);
2157
2158 shared_vision_change_seen(ploser, ptile, radius_sq, FALSE);
2159 }
2160
2161 if (powner != NULL
2164 || powner->server.border_vision)) {
2165 const v_radius_t radius_sq = V_RADIUS(1, 0, 0);
2166
2167 shared_vision_change_seen(powner, ptile, radius_sq, TRUE);
2168 }
2169
2170 tile_set_owner(ptile, powner, psource);
2171
2172 /* Needed only when foggedborders enabled, but we do it unconditionally
2173 * in case foggedborders ever gets enabled later. Better to have correct
2174 * information in player map just in case. */
2175 update_tile_knowledge(ptile);
2176
2177 if (ploser != powner) {
2178 if (S_S_RUNNING == server_state() && game.info.happyborders != HB_DISABLED) {
2180 }
2181
2182 if (!city_map_update_tile_frozen(ptile)) {
2183 send_tile_info(NULL, ptile, FALSE);
2184 }
2185 }
2186}
2187
2188/**********************************************************************/
2191void map_claim_ownership(struct tile *ptile, struct player *powner,
2192 struct tile *psource, bool claim_bases)
2193{
2194 map_claim_border_ownership(ptile, powner, psource);
2195
2196 if (claim_bases) {
2197 tile_claim_bases(ptile, powner);
2198 }
2199}
2200
2201/**********************************************************************/
2204void tile_claim_bases(struct tile *ptile, struct player *powner)
2205{
2206 struct player *base_loser = extra_owner(ptile);
2207
2208 /* This MUST be before potentially recursive call to map_claim_base(),
2209 * so that the recursive call will get new owner == base_loser and
2210 * abort recursion. */
2211 ptile->extras_owner = powner;
2212
2213 extra_type_by_cause_iterate(EC_BASE, pextra) {
2214 map_claim_base(ptile, pextra, powner, base_loser);
2216}
2217
2218/**********************************************************************/
2221void map_clear_border(struct tile *ptile)
2222{
2223 int radius_sq = tile_border_source_radius_sq(ptile);
2224
2225 circle_dxyr_iterate(&(wld.map), ptile, radius_sq, dtile, dx, dy, dr) {
2226 struct tile *claimer = tile_claimer(dtile);
2227
2228 if (claimer == ptile) {
2229 map_claim_ownership(dtile, NULL, NULL, FALSE);
2230 }
2232}
2233
2234/**********************************************************************/
2238void map_update_border(struct tile *ptile, struct player *owner,
2239 int old_radius_sq, int new_radius_sq)
2240{
2241 if (old_radius_sq == new_radius_sq) {
2242 /* No change */
2243 return;
2244 }
2245
2247 return;
2248 }
2249
2250 if (old_radius_sq < new_radius_sq) {
2251 map_claim_border(ptile, owner, new_radius_sq);
2252 } else {
2253 circle_dxyr_iterate(&(wld.map), ptile, old_radius_sq, dtile, dx, dy, dr) {
2254 if (dr > new_radius_sq) {
2255 struct tile *claimer = tile_claimer(dtile);
2256
2257 if (claimer == ptile) {
2258 map_claim_ownership(dtile, NULL, NULL, FALSE);
2259 }
2260 }
2262 }
2263}
2264
2265/**********************************************************************/
2270void map_claim_border(struct tile *ptile, struct player *owner,
2271 int radius_sq)
2272{
2274 return;
2275 }
2276
2277 if (owner == NULL) {
2278 /* Clear the border instead of claiming. Code below this block
2279 * cannot handle NULL owner. */
2280 map_clear_border(ptile);
2281
2282 return;
2283 }
2284
2285 if (radius_sq < 0) {
2286 radius_sq = tile_border_source_radius_sq(ptile);
2287 }
2288
2289 circle_dxyr_iterate(&(wld.map), ptile, radius_sq, dtile, dx, dy, dr) {
2290 struct tile *dclaimer = tile_claimer(dtile);
2291
2292 if (dclaimer == ptile) {
2293 /* Already claimed by the ptile */
2294 continue;
2295 }
2296
2297 if (dr != 0 && is_border_source(dtile)) {
2298 /* Do not claim border sources other than self */
2299 /* Note that this is extremely important at the moment for
2300 * base claiming to work correctly in case there's two
2301 * fortresses near each other. There could be infinite
2302 * recursion in them claiming each other. */
2303 continue;
2304 }
2305
2306 if (!map_is_known(dtile, owner) && game.info.borders < BORDERS_EXPAND) {
2307 continue;
2308 }
2309
2310 /* Always claim source itself (distance, dr, to it 0) */
2311 if (dr != 0 && NULL != dclaimer && dclaimer != ptile) {
2312 struct city *ccity = tile_city(dclaimer);
2313 int strength_old, strength_new;
2314
2315 if (ccity != NULL) {
2316 /* Previously claimed by city */
2317 int city_x, city_y;
2318
2319 map_distance_vector(&city_x, &city_y, ccity->tile, dtile);
2320
2321 if (map_vector_to_sq_distance(city_x, city_y)
2322 <= city_map_radius_sq_get(ccity)
2324 /* Tile is within region permanently claimed by city */
2325 continue;
2326 }
2327 }
2328
2329 strength_old = tile_border_strength(dtile, dclaimer);
2330 strength_new = tile_border_strength(dtile, ptile);
2331
2332 if (strength_new <= strength_old) {
2333 /* Stronger shall prevail,
2334 * in case of equal strength older shall prevail */
2335 continue;
2336 }
2337 }
2338
2339 if (is_ocean_tile(dtile)) {
2340 /* Only certain water tiles are claimable */
2341 if (is_claimable_ocean(dtile, ptile, owner)) {
2342 map_claim_ownership(dtile, owner, ptile, dr == 0);
2343 }
2344 } else {
2345 /* Only land tiles on the same island as the border source
2346 * are claimable */
2347 if (tile_continent(dtile) == tile_continent(ptile)) {
2348 map_claim_ownership(dtile, owner, ptile, dr == 0);
2349 }
2350 }
2352}
2353
2354/**********************************************************************/
2358{
2360 return;
2361 }
2362
2363 if (wld.map.tiles == NULL) {
2364 /* Map not yet initialized */
2365 return;
2366 }
2367
2368 log_verbose("map_calculate_borders()");
2369
2370 whole_map_iterate(&(wld.map), ptile) {
2371 if (is_border_source(ptile)) {
2372 map_claim_border(ptile, ptile->owner, -1);
2373 }
2375
2376 log_verbose("map_calculate_borders() workers");
2379}
2380
2381/**********************************************************************/
2384void map_claim_base(struct tile *ptile, struct extra_type *pextra,
2385 struct player *powner, struct player *ploser)
2386{
2387 struct base_type *pbase;
2388 bv_player *could_see_unit = NULL;
2389 int units_num = 0;
2390 int ul_size;
2391
2392 if (!tile_has_extra(ptile, pextra)) {
2393 return;
2394 }
2395
2396 if (pextra->eus != EUS_NORMAL) {
2397 ul_size = unit_list_size(ptile->units);
2398 } else {
2399 ul_size = 0;
2400 }
2401
2402 int stored_units[ul_size + 1];
2403
2404 if (ul_size > 0) {
2405 int i;
2406
2407 could_see_unit = fc_malloc(sizeof(*could_see_unit) * ul_size);
2408
2409 unit_list_iterate(ptile->units, aunit) {
2410 stored_units[units_num++] = aunit->id;
2412
2413 fc_assert(units_num == ul_size);
2414
2415 for (i = 0; i < units_num; i++) {
2416 struct unit *aunit = game_unit_by_number(stored_units[i]);
2417
2418 BV_CLR_ALL(could_see_unit[i]);
2419 players_iterate(aplayer) {
2420 if (can_player_see_unit(aplayer, aunit)) {
2421 BV_SET(could_see_unit[i], player_index(aplayer));
2422 }
2424 }
2425 }
2426
2427 pbase = extra_base_get(pextra);
2428
2429 fc_assert_ret(pbase != NULL);
2430
2431 /* Transfer base provided vision to new owner */
2432 if (powner != NULL) {
2433 const v_radius_t old_radius_sq = V_RADIUS(-1, -1, -1);
2434 const v_radius_t new_radius_sq = V_RADIUS(pbase->vision_main_sq,
2435 pbase->vision_invis_sq,
2436 pbase->vision_subs_sq);
2437
2438 map_vision_update(powner, ptile, old_radius_sq, new_radius_sq,
2440 }
2441
2442 if (ploser != NULL) {
2443 const v_radius_t old_radius_sq = V_RADIUS(pbase->vision_main_sq,
2444 pbase->vision_invis_sq,
2445 pbase->vision_subs_sq);
2446 const v_radius_t new_radius_sq = V_RADIUS(-1, -1, -1);
2447
2448 map_vision_update(ploser, ptile, old_radius_sq, new_radius_sq,
2450 }
2451
2453 && territory_claiming_base(pbase) && powner != ploser) {
2454 /* Clear borders from old owner. New owner may not know all those
2455 * tiles and thus does not claim them when borders mode is less
2456 * than EXPAND. */
2457 if (ploser != NULL) {
2458 /* Set this particular tile owner by NULL so in recursion
2459 * both loser and owner will be NULL. */
2460 map_claim_border_ownership(ptile, NULL, ptile);
2461 map_clear_border(ptile);
2462 }
2463
2464 /* We here first claim this tile ownership -> now on extra_owner()
2465 * will return new owner. Then we claim border, which will recursively
2466 * lead to this tile and base being claimed. But at that point
2467 * ploser == powner and above check will abort the recursion. */
2468 if (powner != NULL) {
2469 map_claim_border_ownership(ptile, powner, ptile);
2470 map_claim_border(ptile, powner, -1);
2471 }
2474 }
2475
2476 if (units_num > 0) {
2477 int i;
2478
2479 for (i = 0; i < units_num; i++) {
2480 struct unit *aunit = game_unit_by_number(stored_units[i]);
2481
2482 players_iterate(aplayer) {
2483 if (can_player_see_unit(aplayer, aunit)) {
2484 if (!BV_ISSET(could_see_unit[i], player_index(aplayer))) {
2485 send_unit_info(aplayer->connections, aunit);
2486 }
2487 } else {
2488 if (BV_ISSET(could_see_unit[i], player_index(aplayer))) {
2489 unit_goes_out_of_sight(aplayer, aunit);
2490 }
2491 }
2493 }
2494
2495 free(could_see_unit);
2496 }
2497}
2498
2499/**********************************************************************/
2505void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
2506{
2508 radius_sq, vision->can_reveal_tiles);
2509 memcpy(vision->radius_sq, radius_sq, sizeof(v_radius_t));
2510}
2511
2512/**********************************************************************/
2518{
2519 const v_radius_t vision_radius_sq = V_RADIUS(-1, -1, -1);
2520
2521 vision_change_sight(vision, vision_radius_sq);
2522
2523 /* Owner of some city might have lost vision of a tile previously worked */
2524 players_iterate(pplayer) {
2525 city_list_iterate(pplayer->cities, pcity) {
2526 /* We are not interested about CNA_BROADCAST_PENDING, as the vision loss has
2527 * not set it, and whatever set it should take care of it. */
2528 if (pcity->server.needs_arrange == CNA_NORMAL) {
2529 city_refresh(pcity);
2530 auto_arrange_workers(pcity);
2531 pcity->server.needs_arrange = CNA_NOT;
2532 }
2535}
2536
2537/**********************************************************************/
2540void create_extra(struct tile *ptile, struct extra_type *pextra,
2541 struct player *pplayer)
2542{
2543 bool extras_removed = FALSE;
2544
2545 extra_type_iterate(old_extra) {
2546 if (tile_has_extra(ptile, old_extra)
2547 && !can_extras_coexist(old_extra, pextra)) {
2548 destroy_extra(ptile, old_extra);
2549 extras_removed = TRUE;
2550 }
2552
2553 if (pextra->eus != EUS_NORMAL) {
2554 unit_list_iterate(ptile->units, aunit) {
2555 if (is_native_extra_to_utype(pextra, unit_type_get(aunit))) {
2556 players_iterate(aplayer) {
2557 if (!pplayers_allied(pplayer, aplayer)
2558 && can_player_see_unit(aplayer, aunit)) {
2559 unit_goes_out_of_sight(aplayer, aunit);
2560 }
2562 }
2564 }
2565
2566 tile_add_extra(ptile, pextra);
2567
2568 /* Watchtower might become effective. */
2570
2571 if (pextra->data.base != NULL) {
2572 /* Claim bases on tile */
2573 if (pplayer) {
2574 struct player *old_owner = extra_owner(ptile);
2575
2576 /* Created base from NULL -> pplayer */
2577 map_claim_base(ptile, pextra, pplayer, NULL);
2578
2579 if (old_owner != pplayer) {
2580 /* Existing bases from old_owner -> pplayer */
2581 extra_type_by_cause_iterate(EC_BASE, oldbase) {
2582 if (oldbase != pextra) {
2583 map_claim_base(ptile, oldbase, pplayer, old_owner);
2584 }
2586
2587 ptile->extras_owner = pplayer;
2588 }
2589 } else {
2590 /* Player who already owns bases on tile claims new base */
2591 map_claim_base(ptile, pextra, extra_owner(ptile), NULL);
2592 }
2593 }
2594
2595 if (extras_removed) {
2596 /* Maybe conflicting extra that was removed was the only thing
2597 * making tile native to some unit. */
2599 }
2600}
2601
2602/**********************************************************************/
2605void destroy_extra(struct tile *ptile, struct extra_type *pextra)
2606{
2607 bv_player base_seen;
2608 bool real = tile_map_check(&(wld.map), ptile);
2609
2610 /* Remember what players were able to see the base. */
2611 if (real) {
2612 BV_CLR_ALL(base_seen);
2613 players_iterate(pplayer) {
2614 if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
2615 BV_SET(base_seen, player_index(pplayer));
2616 }
2618 }
2619
2620 if (real && is_extra_caused_by(pextra, EC_BASE)) {
2621 struct base_type *pbase = extra_base_get(pextra);
2622 struct player *owner = extra_owner(ptile);
2623
2624 if (territory_claiming_base(pbase)) {
2625 map_clear_border(ptile);
2626 }
2627
2628 if (NULL != owner
2629 && (0 <= pbase->vision_main_sq || 0 <= pbase->vision_invis_sq)) {
2630 /* Base provides vision, but no borders. */
2631 const v_radius_t old_radius_sq =
2632 V_RADIUS(0 <= pbase->vision_main_sq ? pbase->vision_main_sq : -1,
2633 0 <= pbase->vision_invis_sq ? pbase->vision_invis_sq : -1,
2634 0 <= pbase->vision_subs_sq ? pbase->vision_subs_sq : -1);
2635 const v_radius_t new_radius_sq = V_RADIUS(-1, -1, -1);
2636
2637 map_vision_update(owner, ptile, old_radius_sq, new_radius_sq,
2639 }
2640 }
2641
2642 tile_remove_extra(ptile, pextra);
2643
2644 if (real) {
2645 /* Remove base from vision of players which were able to see the base. */
2646 players_iterate(pplayer) {
2647 if (BV_ISSET(base_seen, player_index(pplayer))
2648 && update_player_tile_knowledge(pplayer, ptile)) {
2649 send_tile_info(pplayer->connections, ptile, FALSE);
2650 }
2652
2653 if (pextra->eus != EUS_NORMAL) {
2654 struct player *eowner = extra_owner(ptile);
2655
2656 unit_list_iterate(ptile->units, aunit) {
2657 if (is_native_extra_to_utype(pextra, unit_type_get(aunit))) {
2658 players_iterate(aplayer) {
2659 if (can_player_see_unit(aplayer, aunit)
2660 && !pplayers_allied(aplayer, eowner)) {
2661 send_unit_info(aplayer->connections, aunit);
2662 }
2664 }
2666 }
2667 }
2668}
2669
2670/**********************************************************************/
2680bool give_distorted_map(struct player *pfrom, struct player *pto,
2681 int prob, bool reveal_cities)
2682{
2683 bool updt = FALSE;
2684
2686
2687 whole_map_iterate(&(wld.map), ptile) {
2688 if (fc_rand(100) < prob) {
2689 updt |= give_tile_info_from_player_to_player(pfrom, pto, ptile);
2690 } else if (reveal_cities && NULL != tile_city(ptile)) {
2691 updt|= give_tile_info_from_player_to_player(pfrom, pto, ptile);
2692 }
2694
2696
2697 return updt;
2698}
2699
2700/**********************************************************************/
2708void tile_change_side_effects(struct tile *ptile, bool refresh_city)
2709{
2710 struct city *pcity = ptile->worked;
2711
2712 /* Check the unit activities. */
2714
2715 if (pcity != NULL && !is_free_worked(pcity, ptile)
2716 && get_city_tile_output_bonus(pcity, ptile, NULL, EFT_TILE_WORKABLE) <= 0) {
2717 city_map_update_empty(pcity, ptile);
2719
2720 if (refresh_city) {
2721 auto_arrange_workers(pcity);
2722 send_city_info(NULL, pcity);
2723 }
2724 }
2725}
bool is_adv_data_phase_open(struct player *pplayer)
Definition advdata.c:242
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Definition advdata.c:262
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:553
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:384
bool territory_claiming_base(const struct base_type *pbase)
Definition base.c:158
void dbv_init(struct dbv *pdbv, int bits)
Definition bitvector.c:50
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c:144
bool dbv_isset(const struct dbv *pdbv, int bit)
Definition bitvector.c:120
void dbv_free(struct dbv *pdbv)
Definition bitvector.c:95
void dbv_clr(struct dbv *pdbv, int bit)
Definition bitvector.c:167
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ARE_EQUAL(vec1, vec2)
Definition bitvector.h:113
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_CLR(bv, bit)
Definition bitvector.h:86
int tile_border_source_radius_sq(struct tile *ptile)
Definition borders.c:33
bool is_border_source(struct tile *ptile)
Definition borders.c:114
int tile_border_strength(struct tile *ptile, struct tile *source)
Definition borders.c:99
bool is_free_worked(const struct city *pcity, const struct tile *ptile)
Definition city.c:3500
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:748
@ CNA_NOT
Definition city.h:298
@ CNA_NORMAL
Definition city.h:299
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
#define city_owner(_pcity_)
Definition city.h:543
#define city_list_iterate_end
Definition city.h:490
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:222
#define city_tile_iterate_end
Definition city.h:230
void city_map_update_empty(struct city *pcity, struct tile *ptile)
Definition citytools.c:3164
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2327
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2683
void sync_cities(void)
Definition citytools.c:3238
bool city_map_update_tile_frozen(struct tile *ptile)
Definition citytools.c:3221
void remove_dumb_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2773
void city_landlocked_sell_coastal_improvements(struct tile *ptile)
Definition citytools.c:3291
void send_city_info_at_tile(struct player *pviewer, struct conn_list *dest, struct city *pcity, struct tile *ptile)
Definition citytools.c:2376
void city_thaw_workers_queue(void)
Definition citytools.c:196
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2751
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:369
void city_refresh_queue_add(struct city *pcity)
Definition cityturn.c:200
bool city_refresh(struct city *pcity)
Definition cityturn.c:161
void city_refresh_queue_processing(void)
Definition cityturn.c:216
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:365
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Definition connection.c:729
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:355
void conn_list_compression_freeze(const struct conn_list *pconn_list)
Definition connection.c:717
#define conn_list_iterate(connlist, pconn)
Definition connection.h:113
#define conn_list_iterate_end
Definition connection.h:115
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
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:838
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1068
int extra_number(const struct extra_type *pextra)
Definition extras.c:153
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:810
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:442
bool is_native_extra_to_utype(const struct extra_type *pextra, const struct unit_type *punittype)
Definition extras.c:801
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:952
bool player_knows_extra_exist(const struct player *pplayer, const struct extra_type *pextra, const struct tile *ptile)
Definition extras.c:1103
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:186
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_type_iterate_end
Definition extras.h:297
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_base_get(_e_)
Definition extras.h:184
#define extra_road_get(_e_)
Definition extras.h:185
#define extra_type_by_cause_iterate_end
Definition extras.h:315
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:309
@ HB_DISABLED
Definition fc_types.h:1142
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
signed short Continent_id
Definition fc_types.h:342
@ BORDERS_DISABLED
Definition fc_types.h:891
@ BORDERS_SEE_INSIDE
Definition fc_types.h:893
@ BORDERS_EXPAND
Definition fc_types.h:894
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:82
#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:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct city * game_city_by_number(int id)
Definition game.c:102
struct city * owner
Definition citydlg.c:219
static GtkWidget * source
Definition gotodlg.c:58
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define log_error(message,...)
Definition log.h:103
int map_num_tiles(void)
Definition map.c:1012
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1086
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:612
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:740
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1071
#define adjc_iterate_end
Definition map.h:427
#define MAP_INDEX_SIZE
Definition map.h:131
#define circle_dxyr_iterate(nmap, center_tile, sq_radius, _tile, dx, dy, dr)
Definition map.h:403
#define cardinal_adjc_iterate_end
Definition map.h:453
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:422
#define circle_dxyr_iterate_end
Definition map.h:414
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:449
#define circle_iterate(nmap, center_tile, sq_radius, tile_itr)
Definition map.h:395
#define whole_map_iterate(_map, _tile)
Definition map.h:539
#define MAP_TILE_OWNER_NULL
Definition map.h:568
#define whole_map_iterate_end
Definition map.h:548
#define circle_iterate_end
Definition map.h:398
void assign_continent_numbers(void)
int get_ocean_size(Continent_id id)
struct terrain * most_shallow_ocean(bool frozen)
int get_lake_surrounders(Continent_id cont)
void player_map_init(struct player *pplayer)
Definition maphand.c:1202
static void terrain_change_bounce_single_unit(struct unit *punit, struct tile *from)
Definition maphand.c:1815
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1455
static void shared_vision_change_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change, bool can_reveal_tiles)
Definition maphand.c:659
void vision_clear_sight(struct vision *vision)
Definition maphand.c:2517
void map_claim_base(struct tile *ptile, struct extra_type *pextra, struct player *powner, struct player *ploser)
Definition maphand.c:2384
void map_set_border_vision(struct player *pplayer, const bool is_enabled)
Definition maphand.c:732
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2191
static int player_tile_own_seen(const struct player_tile *plrtile, enum vision_layer vlayer)
Definition maphand.c:1117
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:886
void send_map_info(struct conn_list *dest)
Definition maphand.c:644
static bool really_give_tile_info_from_player_to_player(struct player *pfrom, struct player *pdest, struct tile *ptile)
Definition maphand.c:1473
bool send_tile_suppression(bool now)
Definition maphand.c:472
void destroy_extra(struct tile *ptile, struct extra_type *pextra)
Definition maphand.c:2605
static void check_units_single_tile(struct tile *ptile)
Definition maphand.c:1869
static void really_give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Definition maphand.c:1546
void disable_fog_of_war(void)
Definition maphand.c:1773
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:342
static bool unit_is_on_layer(const struct unit *punit, enum vision_layer vlayer)
Definition maphand.c:635
void map_know_and_see_all(struct player *pplayer)
Definition maphand.c:1177
static void map_change_own_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change)
Definition maphand.c:1126
void show_map_to_all(void)
Definition maphand.c:1191
void send_tile_info(struct conn_list *dest, struct tile *ptile, bool send_unknown)
Definition maphand.c:488
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1386
static int map_get_seen(const struct player *pplayer, const struct tile *ptile, enum vision_layer vlayer)
Definition maphand.c:915
static void ocean_to_land_fix_rivers(struct tile *ptile)
Definition maphand.c:1789
void give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
Definition maphand.c:381
void send_all_known_tiles(struct conn_list *dest)
Definition maphand.c:441
void bounce_units_on_terrain_change(struct tile *ptile)
Definition maphand.c:1903
void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest)
Definition maphand.c:397
void remove_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1681
bool need_to_reassign_continents(const struct terrain *oldter, const struct terrain *newter)
Definition maphand.c:1921
static bool is_claimable_ocean(struct tile *ptile, struct tile *source, struct player *pplayer)
Definition maphand.c:2081
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1346
static bool is_terrain_ecologically_wet(struct tile *ptile)
Definition maphand.c:93
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2204
void disable_fog_of_war_player(struct player *pplayer)
Definition maphand.c:1759
void climate_change(bool warming, int effect)
Definition maphand.c:130
void enable_fog_of_war(void)
Definition maphand.c:1749
static bool send_tile_suppressed
Definition maphand.c:65
static void create_vision_dependencies(void)
Definition maphand.c:1586
void upgrade_all_city_extras(struct player *pplayer, bool discovery)
Definition maphand.c:273
void create_extra(struct tile *ptile, struct extra_type *pextra, struct player *pplayer)
Definition maphand.c:2540
void map_update_border(struct tile *ptile, struct player *owner, int old_radius_sq, int new_radius_sq)
Definition maphand.c:2238
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1159
void map_show_all(struct player *pplayer)
Definition maphand.c:871
static void map_unit_homecity_enqueue(struct tile *ptile)
Definition maphand.c:2130
static void map_change_seen(struct player *pplayer, struct tile *ptile, const v_radius_t change, bool can_reveal_tiles)
Definition maphand.c:928
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:760
void give_citymap_from_player_to_player(struct city *pcity, struct player *pfrom, struct player *pdest)
Definition maphand.c:415
void nuclear_winter(int effect)
Definition maphand.c:116
void tile_change_side_effects(struct tile *ptile, bool refresh_city)
Definition maphand.c:2708
static void player_tile_init(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1309
void terrain_changed(struct tile *ptile)
Definition maphand.c:1940
void player_map_free(struct player *pplayer)
Definition maphand.c:1218
static void unbuffer_shared_vision(struct player *pplayer)
Definition maphand.c:365
static void map_claim_border_ownership(struct tile *ptile, struct player *powner, struct tile *psource)
Definition maphand.c:2146
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:900
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1140
void map_calculate_borders(void)
Definition maphand.c:2357
void fix_tile_on_terrain_change(struct tile *ptile, struct terrain *oldter, bool extend_rivers)
Definition maphand.c:1959
void enable_fog_of_war_player(struct player *pplayer)
Definition maphand.c:1735
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:856
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:677
void map_claim_border(struct tile *ptile, struct player *owner, int radius_sq)
Definition maphand.c:2270
void update_tile_knowledge(struct tile *ptile)
Definition maphand.c:1427
void remove_player_from_maps(struct player *pplayer)
Definition maphand.c:1239
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1620
void check_terrain_change(struct tile *ptile, struct terrain *oldter)
Definition maphand.c:1979
bool give_distorted_map(struct player *pfrom, struct player *pto, int prob, bool reveal_cities)
Definition maphand.c:2680
void map_hide_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:812
struct vision_site * map_get_player_site(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1359
static void buffer_shared_vision(struct player *pplayer)
Definition maphand.c:350
static bool give_tile_info_from_player_to_player(struct player *pfrom, struct player *pdest, struct tile *ptile)
Definition maphand.c:1566
void global_warming(int effect)
Definition maphand.c:103
bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
Definition maphand.c:238
void map_clear_border(struct tile *ptile)
Definition maphand.c:2221
void map_clear_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1167
static void player_tile_free(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1334
#define MAXIMUM_CLAIMED_OCEAN_SIZE
Definition maphand.c:62
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1370
void vision_change_sight(struct vision *vision, const v_radius_t radius_sq)
Definition maphand.c:2505
#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:304
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:137
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:462
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
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 num_known_tech_with_flag(const struct player *pplayer, enum tech_flag_id flag)
Definition player.c:1249
int player_slot_count(void)
Definition player.c:411
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
bool can_player_see_unit(const struct player *pplayer, const struct unit *punit)
Definition player.c:1084
int player_index(const struct player *pplayer)
Definition player.c:820
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
bool gives_shared_vision(const struct player *me, const struct player *them)
Definition player.c:1461
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1000
#define phase_players_iterate(pplayer)
Definition plrhand.h:111
#define phase_players_iterate_end
Definition plrhand.h:116
#define fc_rand(_size)
Definition rand.h:34
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
int count_river_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver)
Definition road.c:334
#define sanity_check_tile(x)
Definition sanitycheck.h:42
void flush_packets(void)
Definition sernet.c:379
#define DEFAULT_SPECIALIST
Definition specialist.h:43
enum server_states server_state(void)
Definition srv_main.c:323
int vision_main_sq
Definition base.h:45
int vision_invis_sq
Definition base.h:46
int vision_subs_sq
Definition base.h:47
Definition city.h:309
enum city_needs_arrange needs_arrange
Definition city.h:424
citizens specialists[SP_MAX]
Definition city.h:324
struct tile * tile
Definition city.h:311
struct city::@17::@19 server
bool last_updated_year
Definition game.h:234
struct civ_game::@30::@34 server
bool vision_reveal_tiles
Definition game.h:199
bool fogofwar_old
Definition game.h:232
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:146
struct tile * tiles
Definition map_types.h:80
int xsize
Definition map_types.h:77
int ysize
Definition map_types.h:77
int topology_id
Definition map_types.h:72
unsigned char * vec
Definition bitvector.h:34
struct resource_type * resource
Definition extras.h:150
struct extra_type::@24 data
enum extra_unit_seen_type eus
Definition extras.h:124
struct base_type * base
Definition extras.h:148
enum borders_mode borders
enum happyborders_type happyborders
int border_city_permanent_radius_sq
Resource_type_id resource
enum known_type known
char label[MAX_LEN_MAP_LABEL]
Continent_id continent
Terrain_type_id terrain
char spec_sprite[MAX_LEN_NAME]
bv_extras extras
Definition maphand.h:36
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
v_radius_t own_seen
Definition maphand.h:42
struct terrain * terrain
Definition maphand.h:33
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:306
struct conn_list * connections
Definition player.h:298
bv_player gives_shared_vision
Definition player.h:299
struct player_tile * private_map
Definition player.h:324
bv_player really_gives_vision
Definition player.h:329
bool border_vision
Definition player.h:327
struct player::@69::@71 server
struct terrain * cooler_wetter_result
Definition terrain.h:227
struct terrain * cooler_drier_result
Definition terrain.h:227
struct terrain * warmer_wetter_result
Definition terrain.h:226
struct terrain * warmer_drier_result
Definition terrain.h:226
Definition tile.h:49
char * spec_sprite
Definition tile.h:65
char * label
Definition tile.h:64
bv_extras extras
Definition tile.h:54
struct extra_type * resource
Definition tile.h:55
struct unit_list * units
Definition tile.h:57
struct player * extras_owner
Definition tile.h:62
struct terrain * terrain
Definition tile.h:56
int infra_turns
Definition tile.h:61
struct extra_type * placing
Definition tile.h:60
struct city * worked
Definition tile.h:58
struct tile * claimer
Definition tile.h:63
enum vision_layer vlayer
Definition unittype.h:550
Definition unit.h:138
enum unit_activity activity
Definition unit.h:157
int id
Definition unit.h:145
struct extra_type * activity_target
Definition unit.h:164
struct unit::@80::@83 server
int homecity
Definition unit.h:146
bool dying
Definition unit.h:248
struct tile * location
Definition vision.h:111
int identity
Definition vision.h:114
struct tile * tile
Definition vision.h:88
bool can_reveal_tiles
Definition vision.h:89
v_radius_t radius_sq
Definition vision.h:92
struct player * player
Definition vision.h:87
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:167
#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:600
Terrain_type_id terrain_count(void)
Definition terrain.c:106
Terrain_type_id terrain_number(const struct terrain *pterrain)
Definition terrain.c:135
#define T_UNKNOWN
Definition terrain.h:57
#define is_ocean(pterrain)
Definition terrain.h:287
#define is_ocean_tile(ptile)
Definition terrain.h:289
#define T_NONE
Definition terrain.h:56
#define terrain_has_flag(terr, flag)
Definition terrain.h:269
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:940
bool tile_has_river(const struct tile *ptile)
Definition tile.c:837
bool tile_map_check(struct civ_map *nmap, struct tile *vtile)
Definition tile.c:1050
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:950
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:473
bool tile_has_conflicting_extra(const struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:886
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:99
#define tile_index(_pt_)
Definition tile.h:87
#define tile_worked(_tile)
Definition tile.h:113
#define tile_resource(_tile)
Definition tile.h:101
@ TILE_KNOWN_UNSEEN
Definition tile.h:36
@ TILE_UNKNOWN
Definition tile.h:35
@ TILE_KNOWN_SEEN
Definition tile.h:37
#define tile_terrain(_tile)
Definition tile.h:109
#define TILE_XY(ptile)
Definition tile.h:42
#define tile_continent(_tile)
Definition tile.h:91
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
#define tile_owner(_tile)
Definition tile.h:95
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1767
bool unit_is_alive(int id)
Definition unit.c:2237
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Definition unit.c:2435
#define unit_tile(_pu)
Definition unit.h:395
#define unit_owner(_pu)
Definition unit.h:394
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:430
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6179
#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:2781
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2794
void unit_activities_cancel(struct unit *punit)
Definition unittools.c:788
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2247
void unit_activities_cancel_all_illegal_area(const struct tile *ptile)
Definition unittools.c:833
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:3884
void unit_list_refresh_vision(struct unit_list *punitlist)
Definition unittools.c:4869
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
struct vision_site * vision_site_copy(const struct vision_site *psite)
Definition vision.c:135
void vision_site_destroy(struct vision_site *psite)
Definition vision.c:74
#define V_RADIUS(main_sq, invis_sq, subs_sq)
Definition vision.h:96
#define vision_layer_iterate(v)
Definition vision.h:77
#define vision_site_owner(v)
Definition vision.h:128
short int v_radius_t[V_COUNT]
Definition vision.h:83
#define vision_layer_iterate_end
Definition vision.h:80