Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/sanitycheck.c Source File

Freeciv-3.1

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