Freeciv-3.2: /fast/freeciv/nightly/S3_2/server/sanitycheck.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
sanitycheck.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 "log.h"
21
22/* common */
23#include "city.h"
24#include "game.h"
25#include "government.h"
26#include "map.h"
27#include "movement.h"
28#include "nation.h"
29#include "player.h"
30#include "research.h"
31#include "specialist.h"
32#include "terrain.h"
33#include "unit.h"
34#include "unitlist.h"
35
36/* server */
37#include "citytools.h"
38#include "cityturn.h" /* city_repair_size() */
39#include "diplhand.h" /* valid_dst_closest() */
40#include "maphand.h"
41#include "plrhand.h"
42#include "srv_main.h"
43#include "unittools.h"
44
45#include "sanitycheck.h"
46
47
48#ifdef SANITY_CHECKING
49
50#define SANITY_FAIL(format, ...) \
51 fc_assert_fail(file, function, line, NULL, format, ## __VA_ARGS__)
52
53#define SANITY_CHECK(check) \
54 fc_assert_full(file, function, line, check, , NOLOGMSG, NOLOGMSG)
55
56#define SANITY_CITY(_city, check) \
57 fc_assert_full(file, function, line, check, , \
58 "(%4d, %4d) in \"%s\"[%d]", TILE_XY((_city)->tile), \
59 city_name_get(_city), city_size_get(_city))
60
61#define SANITY_TERRAIN(_tile, check) \
62 fc_assert_full(file, function, line, check, , \
63 "(%4d, %4d) at \"%s\"", TILE_XY(_tile), \
64 terrain_rule_name(tile_terrain(_tile)))
65
66#define SANITY_TILE(_tile, check) \
67 do { \
68 struct city *_tile##_city = tile_city(_tile); \
69 if (NULL != _tile##_city) { \
70 SANITY_CITY(_tile##_city, check); \
71 } else { \
72 SANITY_TERRAIN(_tile, check); \
73 } \
74 } while (FALSE)
75
76static void check_city_feelings(const struct city *pcity, const char *file,
77 const char *function, int line);
78
79/**********************************************************************/
82static void check_specials(const char *file, const char *function, int line)
83{
84 whole_map_iterate(&(wld.map), ptile) {
85 const struct terrain *pterrain = tile_terrain(ptile);
86
87 extra_type_iterate(pextra) {
88 if (tile_has_extra(ptile, pextra)) {
89 extra_deps_iterate(&(pextra->reqs), pdep) {
90 SANITY_TILE(ptile, tile_has_extra(ptile, pdep));
91 } extra_deps_iterate_end;
92 }
93 } extra_type_iterate_end;
94
95 extra_type_by_cause_iterate(EC_MINE, pextra) {
96 if (tile_has_extra(ptile, pextra)) {
97 SANITY_TILE(ptile, pterrain->mining_time != 0);
98 }
99 } extra_type_by_cause_iterate_end;
100 extra_type_by_cause_iterate(EC_IRRIGATION, pextra) {
101 if (tile_has_extra(ptile, pextra)) {
102 SANITY_TILE(ptile, pterrain->irrigation_time != 0);
103 }
104 } extra_type_by_cause_iterate_end;
105
106 SANITY_TILE(ptile, terrain_index(pterrain) >= T_FIRST
107 && terrain_index(pterrain) < terrain_count());
108 } whole_map_iterate_end;
109}
110
111/**********************************************************************/
114static void check_fow(const char *file, const char *function, int line)
115{
116 if (!game_was_started()) {
117 /* The private map of the players is only allocated at game start. */
118 return;
119 }
120
121 whole_map_iterate(&(wld.map), ptile) {
122 players_iterate(pplayer) {
123 struct player_tile *plr_tile = map_get_player_tile(ptile, pplayer);
124
125 vision_layer_iterate(v) {
126 /* underflow of unsigned int */
127 SANITY_TILE(ptile, plr_tile->seen_count[v] < 30000);
128 SANITY_TILE(ptile, plr_tile->own_seen[v] < 30000);
129 SANITY_TILE(ptile, plr_tile->own_seen[v] <= plr_tile->seen_count[v]);
130 } vision_layer_iterate_end;
131
132 /* Lots of server bits depend on this. */
133 SANITY_TILE(ptile, plr_tile->seen_count[V_INVIS]
134 <= plr_tile->seen_count[V_MAIN]);
135 SANITY_TILE(ptile, plr_tile->own_seen[V_INVIS]
136 <= plr_tile->own_seen[V_MAIN]);
137 } players_iterate_end;
138 } whole_map_iterate_end;
139
140 SANITY_CHECK(game.government_during_revolution != NULL);
141 SANITY_CHECK(game.government_during_revolution
142 == government_by_number(game.info.government_during_revolution_id));
143}
144
145/**********************************************************************/
148static void check_misc(const char *file, const char *function, int line)
149{
150 int nplayers = 0, nbarbs = 0;
151
152 /* Do not use player_slots_iterate as we want to check the index! */
153 player_slots_iterate(pslot) {
154 if (player_slot_is_used(pslot)) {
155 if (is_barbarian(player_slot_get_player(pslot))) {
156 nbarbs++;
157 }
158 nplayers++;
159 }
160 } player_slots_iterate_end;
161
162 SANITY_CHECK(nplayers == player_count());
163 SANITY_CHECK(nbarbs == server.nbarbarians);
164
165 SANITY_CHECK(player_count() <= player_slot_count());
166 SANITY_CHECK(team_count() <= MAX_NUM_TEAM_SLOTS);
167 SANITY_CHECK(normal_player_count() <= game.server.max_players);
168}
169
170/**********************************************************************/
173static void check_map(const char *file, const char *function, int line)
174{
175 whole_map_iterate(&(wld.map), ptile) {
176 struct city *pcity = tile_city(ptile);
177 int cont = tile_continent(ptile);
178
179 CHECK_INDEX(tile_index(ptile));
180
181 if (NULL != pcity) {
182 SANITY_TILE(ptile, same_pos(pcity->tile, ptile));
183 SANITY_TILE(ptile, tile_owner(ptile) != NULL);
184 }
185
186 if (NULL == pcity && BORDERS_DISABLED == game.info.borders) {
187 /* Only city tiles are claimed when borders are disabled */
188 SANITY_TILE(ptile, tile_owner(ptile) == NULL);
189 }
190
191 if (is_ocean_tile(ptile)) {
192 SANITY_TILE(ptile, cont < 0);
193 adjc_iterate(&(wld.map), ptile, tile1) {
194 if (is_ocean_tile(tile1)) {
195 SANITY_TILE(ptile, tile_continent(tile1) == cont);
196 }
197 } adjc_iterate_end;
198 } else {
199 SANITY_TILE(ptile, cont > 0);
200 adjc_iterate(&(wld.map), ptile, tile1) {
201 if (!is_ocean_tile(tile1)) {
202 SANITY_TILE(ptile, tile_continent(tile1) == cont);
203 }
204 } adjc_iterate_end;
205 }
206
207 unit_list_iterate(ptile->units, punit) {
208 SANITY_TILE(ptile, same_pos(unit_tile(punit), ptile));
209
210 /* Check diplomatic status of stacked units. */
211 unit_list_iterate(ptile->units, punit2) {
212 SANITY_TILE(ptile, pplayers_allied(unit_owner(punit),
213 unit_owner(punit2)));
214 } unit_list_iterate_end;
215 if (pcity) {
216 SANITY_TILE(ptile, pplayers_allied(unit_owner(punit),
217 city_owner(pcity)));
218 }
219 } unit_list_iterate_end;
220 } whole_map_iterate_end;
221}
222
223/**********************************************************************/
226static bool check_city_good(struct city *pcity, const char *file,
227 const char *function, int line)
228{
229 struct player *pplayer = city_owner(pcity);
230 struct tile *pcenter = city_tile(pcity);
231
232 if (NULL == pcenter) {
233 /* Editor! */
234 SANITY_FAIL("(----,----) city has no tile (skipping remaining tests), "
235 "at %s \"%s\"[%d]%s",
236 nation_rule_name(nation_of_player(pplayer)),
237 city_name_get(pcity), city_size_get(pcity),
238 "{city center}");
239 return FALSE;
240 }
241
242 SANITY_CITY(pcity, !terrain_has_flag(tile_terrain(pcenter), TER_NO_CITIES));
243
244 SANITY_CITY(pcity, NULL != tile_owner(pcenter));
245 SANITY_CITY(pcity, city_owner(pcity) == tile_owner(pcenter));
246
247 if (NULL != tile_owner(pcenter)) {
248 if (tile_owner(pcenter) != pplayer) {
249 SANITY_FAIL("(%4d,%4d) tile owned by %s, at %s \"%s\"[%d]%s",
250 TILE_XY(pcenter),
251 nation_rule_name(nation_of_player(tile_owner(pcenter))),
252 nation_rule_name(nation_of_player(pplayer)),
253 city_name_get(pcity), city_size_get(pcity),
254 "{city center}");
255 }
256 }
257
258 unit_list_iterate(pcity->units_supported, punit) {
259 SANITY_CITY(pcity, punit->homecity == pcity->id);
260 SANITY_CITY(pcity, unit_owner(punit) == pplayer);
261 } unit_list_iterate_end;
262
263 city_built_iterate(pcity, pimprove) {
264 if (is_small_wonder(pimprove)) {
265 SANITY_CITY(pcity, city_from_small_wonder(pplayer, pimprove) == pcity);
266 } else if (is_great_wonder(pimprove)) {
267 SANITY_CITY(pcity, city_from_great_wonder(pimprove) == pcity);
268 }
269 } city_built_iterate_end;
270
271 trade_routes_iterate(pcity, proute) {
272 struct city *partner = game_city_by_number(proute->partner);
273
274 if (partner != NULL) {
275 struct trade_route *back_route = NULL;
276
277 trade_routes_iterate(partner, pback) {
278 if (pback->partner == pcity->id) {
279 back_route = pback;
280 break;
281 }
282 } trade_routes_iterate_end;
283
284 SANITY_CITY(pcity, back_route != NULL);
285
286 if (back_route != NULL) {
287 switch (back_route->dir) {
288 case RDIR_TO:
289 SANITY_CITY(pcity, proute->dir == RDIR_FROM);
290 break;
291 case RDIR_FROM:
292 SANITY_CITY(pcity, proute->dir == RDIR_TO);
293 break;
294 case RDIR_BIDIRECTIONAL:
295 SANITY_CITY(pcity, proute->dir == RDIR_BIDIRECTIONAL);
296 break;
297 case RDIR_NONE:
298 SANITY_CITY(pcity, back_route->dir != RDIR_NONE);
299 break;
300 }
301
302 SANITY_CITY(pcity, proute->goods == back_route->goods);
303 }
304 }
305 } trade_routes_iterate_end;
306
307 worker_task_list_iterate(pcity->task_reqs, ptask) {
308 if (!worker_task_is_sane(ptask)) {
309 SANITY_FAIL("(%4d,%4d) Bad worker task %d in \"%s\", removing...",
310 TILE_XY(pcity->tile),
311 ptask->act,
312 city_name_get(pcity));
313 worker_task_list_remove(pcity->task_reqs, ptask);
314 free(ptask);
315 ptask = NULL;
316 }
317 } worker_task_list_iterate_end;
318
319 return TRUE;
320}
321
322/**********************************************************************/
325static void check_city_size(struct city *pcity, const char *file,
326 const char *function, int line)
327{
328 int delta;
329 int citizen_count = 0;
330 struct tile *pcenter = city_tile(pcity);
331 const struct civ_map *nmap = &(wld.map);
332
333 SANITY_CITY(pcity, city_size_get(pcity) >= 1);
334
335 city_tile_iterate_skip_free_worked(nmap, city_map_radius_sq_get(pcity), pcenter,
336 ptile, _index, _x, _y) {
337 if (tile_worked(ptile) == pcity) {
338 citizen_count++;
339 }
340 } city_tile_iterate_skip_free_worked_end;
341
342 citizen_count += city_specialists(pcity);
343 delta = city_size_get(pcity) - citizen_count;
344 if (0 != delta) {
345 SANITY_FAIL("(%4d,%4d) %d citizens not equal [size], "
346 "repairing \"%s\"[%d]", TILE_XY(pcity->tile),
347 citizen_count, city_name_get(pcity), city_size_get(pcity));
348
349 citylog_map_workers(LOG_DEBUG, pcity);
350 log_debug("[%s (%d)] specialists: %d", city_name_get(pcity), pcity->id,
351 city_specialists(pcity));
352
353 city_repair_size(pcity, delta);
354 city_refresh_from_main_map(pcity, NULL);
355 }
356}
357
358/**********************************************************************/
362static void check_city_feelings(const struct city *pcity, const char *file,
363 const char *function, int line)
364{
365 int feel;
366 int spe = city_specialists(pcity);
367
368 for (feel = FEELING_BASE; feel < FEELING_LAST; feel++) {
369 int sum = 0;
370 int ccategory;
371
372 for (ccategory = CITIZEN_HAPPY; ccategory < CITIZEN_LAST; ccategory++) {
373 sum += pcity->feel[ccategory][feel];
374 }
375
376 /* While loading savegame, we want to check sanity of values read from the
377 * savegame despite the fact that city workers_frozen level of the city
378 * is above zero -> can't limit sanitycheck callpoints by that. Instead
379 * we check even more relevant needs_arrange. */
380 SANITY_CITY(pcity, pcity->server.needs_arrange == CNA_NOT);
381
382 SANITY_CITY(pcity, city_size_get(pcity) - spe == sum);
383 }
384}
385
386/**********************************************************************/
389void real_sanity_check_city(struct city *pcity, const char *file,
390 const char *function, int line)
391{
392 if (check_city_good(pcity, file, function, line)) {
393 check_city_size(pcity, file, function, line);
394 check_city_feelings(pcity, file, function, line);
395 }
396}
397
398/**********************************************************************/
401static void check_cities(const char *file, const char *function, int line)
402{
403 players_iterate(pplayer) {
404 city_list_iterate(pplayer->cities, pcity) {
405 SANITY_CITY(pcity, city_owner(pcity) == pplayer);
406
407 real_sanity_check_city(pcity, file, function, line);
408 } city_list_iterate_end;
409 } players_iterate_end;
410}
411
412/**********************************************************************/
415static void check_units(const char *file, const char *function, int line)
416{
417 players_iterate(pplayer) {
418 unit_list_iterate(pplayer->units, punit) {
419 struct tile *ptile = unit_tile(punit);
420 struct city *pcity;
421 struct city *phome;
422 struct unit *ptrans = unit_transport_get(punit);
423
424 SANITY_CHECK(unit_owner(punit) == pplayer);
425
426 if (IDENTITY_NUMBER_ZERO != punit->homecity) {
427 SANITY_CHECK(phome = player_city_by_number(pplayer,
428 punit->homecity));
429 if (phome) {
430 SANITY_CHECK(city_owner(phome) == pplayer);
431 }
432 }
433
434 /* Unit in the correct player list? */
435 SANITY_CHECK(player_unit_by_number(unit_owner(punit),
436 punit->id) != NULL);
437
438 if (!can_unit_continue_current_activity(&(wld.map), punit)) {
439 SANITY_FAIL("(%4d,%4d) %s has activity %s, "
440 "but it can't continue at %s",
441 TILE_XY(ptile), unit_rule_name(punit),
442 get_activity_text(punit->activity),
443 tile_get_info_text(ptile, TRUE, 0));
444 }
445
446 if (activity_requires_target(punit->activity)) {
447 SANITY_CHECK(punit->activity_target != NULL);
448 }
449
450 pcity = tile_city(ptile);
451 if (pcity) {
452 SANITY_CHECK(pplayers_allied(city_owner(pcity), pplayer));
453 }
454
455 SANITY_CHECK(punit->moves_left >= 0);
456 SANITY_CHECK(punit->hp > 0);
457
458 /* Check for ground units in the ocean. */
459 SANITY_CHECK(can_unit_exist_at_tile(&(wld.map), punit, ptile)
460 || ptrans != NULL);
461
462 /* Check for over-full transports. */
463 SANITY_CHECK(get_transporter_occupancy(punit)
464 <= get_transporter_capacity(punit));
465
466 /* Check transporter. This should be last as the pointer ptrans will
467 * be modified. */
468 if (ptrans != NULL) {
469 struct unit *plevel = punit;
470 int level = 0;
471
472 /* Make sure the transporter is on the tile. */
473 SANITY_CHECK(same_pos(unit_tile(punit), unit_tile(ptrans)));
474
475 /* Can punit be cargo for its transporter? */
476 SANITY_CHECK(unit_transport_check(punit, ptrans));
477
478 /* Check that the unit is listed as transported. */
479 SANITY_CHECK(unit_list_search(unit_transport_cargo(ptrans),
480 punit) != NULL);
481
482 /* Check the depth of the transportation. */
483 while (ptrans) {
484 struct unit_list *pcargos = unit_transport_cargo(ptrans);
485
486 SANITY_CHECK(pcargos != NULL);
487 SANITY_CHECK(level < GAME_TRANSPORT_MAX_RECURSIVE);
488
489 /* Check for next level. */
490 plevel = ptrans;
491 ptrans = unit_transport_get(plevel);
492 level++;
493 }
494
495 /* Transporter capacity will be checked when transporter itself
496 * is checked */
497 }
498
499 /* Check that cargo is marked as transported with this unit */
500 unit_list_iterate(unit_transport_cargo(punit), pcargo) {
501 SANITY_CHECK(unit_transport_get(pcargo) == punit);
502 } unit_list_iterate_end;
503 } unit_list_iterate_end;
504 } players_iterate_end;
505}
506
507/**********************************************************************/
510static void check_players(const char *file, const char *function, int line)
511{
512 players_iterate(pplayer) {
513 int found_primary_capital = 0;
514
515 if (!pplayer->is_alive) {
516 /* Dead players' units and cities are disbanded in kill_player(). */
517 SANITY_CHECK(unit_list_size(pplayer->units) == 0);
518 SANITY_CHECK(city_list_size(pplayer->cities) == 0);
519
520 continue;
521 }
522
523 SANITY_CHECK(pplayer->server.adv != NULL);
524 SANITY_CHECK(!pplayer->nation || pplayer->nation->player == pplayer);
525 SANITY_CHECK(player_list_search(team_members(pplayer->team), pplayer));
526
527 SANITY_CHECK(player_has_flag(pplayer, PLRF_FIRST_CITY)
528 || city_list_size(pplayer->cities) == 0);
529
530 city_list_iterate(pplayer->cities, pcity) {
531 if (pcity->capital == CAPITAL_PRIMARY) {
532 found_primary_capital++;
533 }
534 SANITY_CITY(pcity, found_primary_capital <= 1);
535 } city_list_iterate_end;
536
537 players_iterate(pplayer2) {
538 struct player_diplstate *state1, *state2;
539
540 if (pplayer2 == pplayer) {
541 break; /* Do diplomatic sanity check only once per player couple. */
542 }
543
544 state1 = player_diplstate_get(pplayer, pplayer2);
545 state2 = player_diplstate_get(pplayer2, pplayer);
546 SANITY_CHECK(state1->type == state2->type);
547 SANITY_CHECK(state1->max_state == state2->max_state);
548 SANITY_CHECK(valid_dst_closest(state1) == state1->max_state);
549 if (state1->type == DS_CEASEFIRE
550 || state1->type == DS_ARMISTICE) {
551 SANITY_CHECK(state1->turns_left == state2->turns_left);
552 }
553 if (state1->type == DS_TEAM) {
554 SANITY_CHECK(players_on_same_team(pplayer, pplayer2));
555 SANITY_CHECK(player_has_real_embassy(pplayer, pplayer2));
556 SANITY_CHECK(player_has_real_embassy(pplayer2, pplayer));
557 if (pplayer->is_alive && pplayer2->is_alive) {
558 SANITY_CHECK(really_gives_vision(pplayer, pplayer2));
559 SANITY_CHECK(really_gives_vision(pplayer2, pplayer));
560 }
561 }
562 if (pplayer->is_alive
563 && pplayer2->is_alive
564 && pplayers_allied(pplayer, pplayer2)) {
565 enum dipl_reason allied_players_can_be_allied =
566 pplayer_can_make_treaty(pplayer, pplayer2, DS_ALLIANCE);
567
568 SANITY_CHECK(allied_players_can_be_allied
569 != DIPL_ALLIANCE_PROBLEM_US);
570 SANITY_CHECK(allied_players_can_be_allied
571 != DIPL_ALLIANCE_PROBLEM_THEM);
572 }
573 } players_iterate_end;
574
575 if (pplayer->revolution_finishes == -1) {
576 if (government_of_player(pplayer) == game.government_during_revolution) {
577 SANITY_FAIL("%s government is anarchy, but does not finish!",
578 nation_rule_name(nation_of_player(pplayer)));
579 }
580 SANITY_CHECK(government_of_player(pplayer) != game.government_during_revolution);
581 } else if (pplayer->revolution_finishes > game.info.turn) {
582 SANITY_CHECK(government_of_player(pplayer) == game.government_during_revolution);
583 } else {
584 /* Things may vary in this case depending on when the sanity_check
585 * call is made. No better check is possible. */
586 }
587
588 /* Dying players shouldn't be left around. But they are. */
589 SANITY_CHECK(!BV_ISSET(pplayer->server.status, PSTATUS_DYING));
590 } players_iterate_end;
591
592 nations_iterate(pnation) {
593 SANITY_CHECK(!pnation->player || pnation->player->nation == pnation);
594 } nations_iterate_end;
595
596 teams_iterate(pteam) {
597 player_list_iterate(team_members(pteam), pplayer) {
598 SANITY_CHECK(pplayer->team == pteam);
599 } player_list_iterate_end;
600 } teams_iterate_end;
601}
602
603/**********************************************************************/
606static void check_teams(const char *file, const char *function, int line)
607{
608 int count[MAX_NUM_TEAM_SLOTS];
609
610 memset(count, 0, sizeof(count));
611 players_iterate(pplayer) {
612 /* For the moment, all players have teams. */
613 SANITY_CHECK(pplayer->team != NULL);
614 if (pplayer->team) {
615 count[team_index(pplayer->team)]++;
616 }
617 } players_iterate_end;
618
619 team_slots_iterate(tslot) {
620 if (team_slot_is_used(tslot)) {
621 struct team *pteam = team_slot_get_team(tslot);
622 fc_assert_exit(pteam);
623 SANITY_CHECK(player_list_size(team_members(pteam))
624 == count[team_slot_index(tslot)]);
625 }
626 } team_slots_iterate_end;
627}
628
629/**********************************************************************/
632static void
633 check_researches(const char *file, const char *function, int line)
634{
635 researches_iterate(presearch) {
636 SANITY_CHECK(S_S_RUNNING != server_state()
637 || A_UNSET == presearch->researching
638 || is_future_tech(presearch->researching)
639 || (A_NONE != presearch->researching
640 && valid_advance_by_number(presearch->researching)));
641 SANITY_CHECK(A_UNSET == presearch->tech_goal
642 || (A_NONE != presearch->tech_goal
643 && valid_advance_by_number(presearch->tech_goal)));
644 SANITY_CHECK(presearch->techs_researched
645 == recalculate_techs_researched(presearch));
646 } researches_iterate_end;
647}
648
649/**********************************************************************/
652static void check_connections(const char *file, const char *function,
653 int line)
654{
655 int all = conn_list_size(game.all_connections);
656
657 /* Other lists are subsets of all_connections */
658 SANITY_CHECK(all >= conn_list_size(game.est_connections));
659 SANITY_CHECK(all >= conn_list_size(game.web_client_connections));
660}
661
662/**********************************************************************/
671void real_sanity_check(const char *file, const char *function, int line)
672{
673 if (!map_is_empty()) {
674 /* Don't sanity-check the map if it hasn't been created yet (this
675 * happens when loading scenarios). */
676 check_specials(file, function, line);
677 check_map(file, function, line);
678 check_cities(file, function, line);
679 check_units(file, function, line);
680 check_fow(file, function, line);
681 }
682 check_misc(file, function, line);
683 check_players(file, function, line);
684 check_teams(file, function, line);
685 check_researches(file, function, line);
686 check_connections(file, function, line);
687}
688
689/**********************************************************************/
693void real_sanity_check_tile(struct tile *ptile, const char *file,
694 const char *function, int line)
695{
696 SANITY_CHECK(ptile != NULL);
697 SANITY_CHECK(ptile->terrain != NULL);
698
699 unit_list_iterate(ptile->units, punit) {
700 /* Check if the units can survive on the tile (terrain). Here only the
701 * 'easy' test if the unit is transported is done. A complete check is
702 * done by check_units() in real_sanity_check(). */
703 if (!can_unit_exist_at_tile(&(wld.map), punit, ptile)
704 && !unit_transported(punit)) {
705 SANITY_FAIL("(%4d,%4d) %s can't survive on %s", TILE_XY(ptile),
706 unit_rule_name(punit), tile_get_info_text(ptile, TRUE, 0));
707 }
708 } unit_list_iterate_end;
709}
710
711#endif /* SANITY_CHECKING */
bitvector.h
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1128
city_refresh_from_main_map
void city_refresh_from_main_map(struct city *pcity, bool *workers_map)
Definition city.c:3165
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:136
citylog_map_workers
void citylog_map_workers(enum log_level level, struct city *pcity)
Definition city.c:445
city_specialists
citizens city_specialists(const struct city *pcity)
Definition city.c:3305
city.h
CNA_NOT
@ CNA_NOT
Definition city.h:306
city_list_iterate
#define city_list_iterate(citylist, pcity)
Definition city.h:508
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
city_tile_iterate_skip_free_worked
#define city_tile_iterate_skip_free_worked(_nmap, _radius_sq, _city_tile, _tile, _index, _x, _y)
Definition city.h:214
CITIZEN_LAST
@ CITIZEN_LAST
Definition city.h:272
CITIZEN_HAPPY
@ CITIZEN_HAPPY
Definition city.h:268
city_owner
#define city_owner(_pcity_)
Definition city.h:563
city_tile_iterate_skip_free_worked_end
#define city_tile_iterate_skip_free_worked_end
Definition city.h:222
city_list_iterate_end
#define city_list_iterate_end
Definition city.h:510
FEELING_LAST
@ FEELING_LAST
Definition city.h:285
FEELING_BASE
@ FEELING_BASE
Definition city.h:279
city_built_iterate
#define city_built_iterate(_pcity, _p)
Definition city.h:822
city_built_iterate_end
#define city_built_iterate_end
Definition city.h:828
citytools.h
city_repair_size
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:851
cityturn.h
incite_cost
char * incite_cost
Definition comments.c:74
punit
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:74
valid_dst_closest
enum diplstate_type valid_dst_closest(struct player_diplstate *dst)
Definition diplhand.c:111
diplhand.h
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_deps_iterate
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:371
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
extra_deps_iterate_end
#define extra_deps_iterate_end
Definition extras.h:379
extra_type_by_cause_iterate_end
#define extra_type_by_cause_iterate_end
Definition extras.h:339
extra_type_by_cause_iterate
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
BORDERS_DISABLED
@ BORDERS_DISABLED
Definition fc_types.h:1038
IDENTITY_NUMBER_ZERO
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:92
game
struct civ_game game
Definition game.c:62
wld
struct world wld
Definition game.c:63
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:107
game.h
GAME_TRANSPORT_MAX_RECURSIVE
#define GAME_TRANSPORT_MAX_RECURSIVE
Definition game.h:754
government_by_number
struct government * government_by_number(const Government_type_id gov)
Definition government.c:103
government_of_player
struct government * government_of_player(const struct player *pplayer)
Definition government.c:114
government.h
is_great_wonder
bool is_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:772
city_from_small_wonder
struct city * city_from_small_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Definition improvement.c:1076
city_from_great_wonder
struct city * city_from_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:1016
is_small_wonder
bool is_small_wonder(const struct impr_type *pimprove)
Definition improvement.c:780
log.h
log_debug
#define log_debug(message,...)
Definition log.h:115
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
fc_assert_exit
#define fc_assert_exit(condition)
Definition log.h:197
same_pos
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:940
map_is_empty
bool map_is_empty(void)
Definition map.c:149
map.h
adjc_iterate_end
#define adjc_iterate_end
Definition map.h:433
CHECK_INDEX
#define CHECK_INDEX(mindex)
Definition map.h:149
adjc_iterate
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
whole_map_iterate
#define whole_map_iterate(_map, _tile)
Definition map.h:545
whole_map_iterate_end
#define whole_map_iterate_end
Definition map.h:554
really_gives_vision
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:345
map_get_player_tile
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1379
maphand.h
can_unit_exist_at_tile
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:319
movement.h
nation_rule_name
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
nation_of_player
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
nation.h
nations_iterate_end
#define nations_iterate_end
Definition nation.h:336
nations_iterate
#define nations_iterate(NAME_pnation)
Definition nation.h:333
player_slot_is_used
bool player_slot_is_used(const struct player_slot *pslot)
Definition player.c:448
player_unit_by_number
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
players_on_same_team
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1476
player_count
int player_count(void)
Definition player.c:817
player_slot_count
int player_slot_count(void)
Definition player.c:418
pplayer_can_make_treaty
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Definition player.c:159
player_has_flag
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1990
player_has_real_embassy
bool player_has_real_embassy(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:240
player_city_by_number
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
player_diplstate_get
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
pplayers_allied
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
player_slot_get_player
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:437
player.h
players_iterate_end
#define players_iterate_end
Definition player.h:537
dipl_reason
dipl_reason
Definition player.h:190
DIPL_ALLIANCE_PROBLEM_THEM
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition player.h:192
DIPL_ALLIANCE_PROBLEM_US
@ DIPL_ALLIANCE_PROBLEM_US
Definition player.h:192
players_iterate
#define players_iterate(_pplayer)
Definition player.h:532
player_list_iterate
#define player_list_iterate(playerlist, pplayer)
Definition player.h:555
is_barbarian
static bool is_barbarian(const struct player *pplayer)
Definition player.h:489
player_slots_iterate
#define player_slots_iterate(_pslot)
Definition player.h:523
player_list_iterate_end
#define player_list_iterate_end
Definition player.h:557
player_slots_iterate_end
#define player_slots_iterate_end
Definition player.h:527
normal_player_count
int normal_player_count(void)
Definition plrhand.c:3200
plrhand.h
recalculate_techs_researched
int recalculate_techs_researched(const struct research *presearch)
Definition research.c:1345
research.h
researches_iterate
#define researches_iterate(_presearch)
Definition research.h:155
researches_iterate_end
#define researches_iterate_end
Definition research.h:158
sanitycheck.h
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
specialist.h
game_was_started
bool game_was_started(void)
Definition srv_main.c:349
server_state
enum server_states server_state(void)
Definition srv_main.c:333
srv_main.h
city
Definition city.h:320
city::task_reqs
struct worker_task_list * task_reqs
Definition city.h:412
city::id
int id
Definition city.h:326
city::capital
enum capital_type capital
Definition city.h:328
city::needs_arrange
enum city_needs_arrange needs_arrange
Definition city.h:441
city::feel
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:333
city::tile
struct tile * tile
Definition city.h:322
city::server
struct city::@17::@19 server
city::units_supported
struct unit_list * units_supported
Definition city.h:406
civ_game::est_connections
struct conn_list * est_connections
Definition game.h:97
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::web_client_connections
struct conn_list * web_client_connections
Definition game.h:99
civ_game::all_connections
struct conn_list * all_connections
Definition game.h:96
civ_game::server
struct civ_game::@31::@35 server
civ_game::max_players
int max_players
Definition game.h:156
civ_game::government_during_revolution
struct government * government_during_revolution
Definition game.h:94
civ_map
Definition map_types.h:71
nation_type::player
struct player * player
Definition nation.h:118
packet_game_info::borders
enum borders_mode borders
Definition packets_gen.h:130
packet_game_info::government_during_revolution_id
Government_type_id government_during_revolution_id
Definition packets_gen.h:171
packet_game_info::turn
int turn
Definition packets_gen.h:241
player_diplstate
Definition player.h:196
player_tile
Definition maphand.h:30
player
Definition player.h:247
player::cities
struct city_list * cities
Definition player.h:279
player::status
bv_pstatus status
Definition player.h:320
player::revolution_finishes
int revolution_finishes
Definition player.h:271
player::team
struct team * team
Definition player.h:259
player::units
struct unit_list * units
Definition player.h:280
player::is_alive
bool is_alive
Definition player.h:266
player::nation
struct nation_type * nation
Definition player.h:258
player::adv
struct adv_data * adv
Definition player.h:332
player::server
struct player::@70::@72 server
server
Definition servers.h:29
team
Definition team.c:40
terrain
Definition terrain.h:182
terrain::mining_time
int mining_time
Definition terrain.h:225
terrain::irrigation_time
int irrigation_time
Definition terrain.h:222
tile
Definition tile.h:50
tile::units
struct unit_list * units
Definition tile.h:58
tile::terrain
struct terrain * terrain
Definition tile.h:57
trade_route
Definition traderoutes.h:83
trade_route::partner
int partner
Definition traderoutes.h:84
unit
Definition unit.h:138
unit::activity
enum unit_activity activity
Definition unit.h:157
unit::moves_left
int moves_left
Definition unit.h:150
unit::id
int id
Definition unit.h:145
unit::hp
int hp
Definition unit.h:151
unit::activity_target
struct extra_type * activity_target
Definition unit.h:164
unit::homecity
int homecity
Definition unit.h:146
world::map
struct civ_map map
Definition world_object.h:38
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
team_count
int team_count(void)
Definition team.c:375
team_index
int team_index(const struct team *pteam)
Definition team.c:383
team_slot_get_team
struct team * team_slot_get_team(const struct team_slot *tslot)
Definition team.c:150
team_slot_index
int team_slot_index(const struct team_slot *tslot)
Definition team.c:138
team_members
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
team_slot_is_used
bool team_slot_is_used(const struct team_slot *tslot)
Definition team.c:162
team_slots_iterate_end
#define team_slots_iterate_end
Definition team.h:77
team_slots_iterate
#define team_slots_iterate(_tslot)
Definition team.h:72
teams_iterate_end
#define teams_iterate_end
Definition team.h:87
teams_iterate
#define teams_iterate(_pteam)
Definition team.h:82
MAX_NUM_TEAM_SLOTS
#define MAX_NUM_TEAM_SLOTS
Definition team.h:27
is_future_tech
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
valid_advance_by_number
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
A_NONE
#define A_NONE
Definition tech.h:43
A_UNSET
#define A_UNSET
Definition tech.h:48
terrain_count
Terrain_type_id terrain_count(void)
Definition terrain.c:118
terrain_index
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:138
terrain.h
is_ocean_tile
#define is_ocean_tile(ptile)
Definition terrain.h:303
terrain_has_flag
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
T_FIRST
#define T_FIRST
Definition terrain.h:60
tile_get_info_text
const char * tile_get_info_text(const struct tile *ptile, bool include_nuisances, int linebreaks)
Definition tile.c:771
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_index
#define tile_index(_pt_)
Definition tile.h:88
tile_worked
#define tile_worked(_tile)
Definition tile.h:114
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:110
TILE_XY
#define TILE_XY(ptile)
Definition tile.h:43
tile_continent
#define tile_continent(_tile)
Definition tile.h:92
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
tile_owner
#define tile_owner(_tile)
Definition tile.h:96
trade_routes_iterate_end
#define trade_routes_iterate_end
Definition traderoutes.h:134
trade_routes_iterate
#define trade_routes_iterate(c, proute)
Definition traderoutes.h:130
get_transporter_occupancy
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1779
unit_transport_check
bool unit_transport_check(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:2475
unit_transport_get
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2437
can_unit_continue_current_activity
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:838
get_activity_text
const char * get_activity_text(enum unit_activity activity)
Definition unit.c:610
get_transporter_capacity
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:299
unit_transported
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2421
unit_transport_cargo
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Definition unit.c:2447
activity_requires_target
bool activity_requires_target(enum unit_activity activity)
Definition unit.c:562
unit.h
unit_tile
#define unit_tile(_pu)
Definition unit.h:390
unit_owner
#define unit_owner(_pu)
Definition unit.h:389
unitlist.h
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
unittools.h
unit_rule_name
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
vision_layer_iterate
#define vision_layer_iterate(v)
Definition vision.h:77
vision_layer_iterate_end
#define vision_layer_iterate_end
Definition vision.h:80
worker_task_is_sane
bool worker_task_is_sane(struct worker_task *ptask)
Definition workertask.c:40
worker_task_list_iterate
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
worker_task_list_iterate_end
#define worker_task_list_iterate_end
Definition workertask.h:35