webperimental: killstack decides stack protects.
[freeciv.git] / server / sanitycheck.c
blob375b91649ba6c365d262f6b1d3214b821528cff9
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "bitvector.h"
20 #include "log.h"
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"
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"
43 #include "sanitycheck.h"
46 #ifdef SANITY_CHECKING
48 #define SANITY_FAIL(format, ...) \
49 fc_assert_fail(file, function, line, NULL, format, ## __VA_ARGS__)
51 #define SANITY_CHECK(check) \
52 fc_assert_full(file, function, line, check, , NOLOGMSG, NOLOGMSG)
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))
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)))
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)
74 static void check_city_feelings(const struct city *pcity, const char *file,
75 const char *function, int line);
77 /**************************************************************************
78 Sanity checking on map (tile) specials.
79 **************************************************************************/
80 static void check_specials(const char *file, const char *function, int line)
82 whole_map_iterate(&(wld.map), ptile) {
83 const struct terrain *pterrain = tile_terrain(ptile);
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;
91 } extra_type_iterate_end;
93 extra_type_by_cause_iterate(EC_MINE, pextra) {
94 if (tile_has_extra(ptile, pextra)) {
95 SANITY_TILE(ptile, pterrain->mining_result == pterrain);
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_result == pterrain);
102 } extra_type_by_cause_iterate_end;
104 SANITY_TILE(ptile, terrain_index(pterrain) >= T_FIRST
105 && terrain_index(pterrain) < terrain_count());
106 } whole_map_iterate_end;
109 /**************************************************************************
110 Sanity checking on fog-of-war (visibility, shared vision, etc.).
111 **************************************************************************/
112 static void check_fow(const char *file, const char *function, int line)
114 if (!game_was_started()) {
115 /* The private map of the players is only allocated at game start. */
116 return;
119 whole_map_iterate(&(wld.map), ptile) {
120 players_iterate(pplayer) {
121 struct player_tile *plr_tile = map_get_player_tile(ptile, pplayer);
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;
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;
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));
143 /**************************************************************************
144 Miscellaneous sanity checks.
145 **************************************************************************/
146 static void check_misc(const char *file, const char *function, int line)
148 int nplayers = 0, nbarbs = 0;
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++;
156 nplayers++;
158 } player_slots_iterate_end;
160 SANITY_CHECK(nplayers == player_count());
161 SANITY_CHECK(nbarbs == server.nbarbarians);
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);
168 /**************************************************************************
169 Sanity checks on the map itself. See also check_specials.
170 **************************************************************************/
171 static void check_map(const char *file, const char *function, int line)
173 whole_map_iterate(&(wld.map), ptile) {
174 struct city *pcity = tile_city(ptile);
175 int cont = tile_continent(ptile);
177 CHECK_INDEX(tile_index(ptile));
179 if (NULL != pcity) {
180 SANITY_TILE(ptile, same_pos(pcity->tile, ptile));
181 if (BORDERS_DISABLED != game.info.borders) {
182 SANITY_TILE(ptile, tile_owner(ptile) != NULL);
186 if (is_ocean_tile(ptile)) {
187 SANITY_TILE(ptile, cont < 0);
188 adjc_iterate(&(wld.map), ptile, tile1) {
189 if (is_ocean_tile(tile1)) {
190 SANITY_TILE(ptile, tile_continent(tile1) == cont);
192 } adjc_iterate_end;
193 } else {
194 SANITY_TILE(ptile, cont > 0);
195 adjc_iterate(&(wld.map), ptile, tile1) {
196 if (!is_ocean_tile(tile1)) {
197 SANITY_TILE(ptile, tile_continent(tile1) == cont);
199 } adjc_iterate_end;
202 unit_list_iterate(ptile->units, punit) {
203 SANITY_TILE(ptile, same_pos(unit_tile(punit), ptile));
205 /* Check diplomatic status of stacked units. */
206 unit_list_iterate(ptile->units, punit2) {
207 SANITY_TILE(ptile, pplayers_allied(unit_owner(punit),
208 unit_owner(punit2)));
209 } unit_list_iterate_end;
210 if (pcity) {
211 SANITY_TILE(ptile, pplayers_allied(unit_owner(punit),
212 city_owner(pcity)));
214 } unit_list_iterate_end;
215 } whole_map_iterate_end;
218 /**************************************************************************
219 Verify that the city itself has sane values.
220 **************************************************************************/
221 static bool check_city_good(struct city *pcity, const char *file,
222 const char *function, int line)
224 struct player *pplayer = city_owner(pcity);
225 struct tile *pcenter = city_tile(pcity);
227 if (NULL == pcenter) {
228 /* Editor! */
229 SANITY_FAIL("(----,----) city has no tile (skipping remaining tests), "
230 "at %s \"%s\"[%d]%s",
231 nation_rule_name(nation_of_player(pplayer)),
232 city_name_get(pcity), city_size_get(pcity),
233 "{city center}");
234 return FALSE;
237 SANITY_CITY(pcity, !terrain_has_flag(tile_terrain(pcenter), TER_NO_CITIES));
239 if (BORDERS_DISABLED != game.info.borders) {
240 SANITY_CITY(pcity, NULL != tile_owner(pcenter));
243 if (NULL != tile_owner(pcenter)) {
244 if (tile_owner(pcenter) != pplayer) {
245 SANITY_FAIL("(%4d,%4d) tile owned by %s, at %s \"%s\"[%d]%s",
246 TILE_XY(pcenter),
247 nation_rule_name(nation_of_player(tile_owner(pcenter))),
248 nation_rule_name(nation_of_player(pplayer)),
249 city_name_get(pcity), city_size_get(pcity),
250 "{city center}");
254 unit_list_iterate(pcity->units_supported, punit) {
255 SANITY_CITY(pcity, punit->homecity == pcity->id);
256 SANITY_CITY(pcity, unit_owner(punit) == pplayer);
257 } unit_list_iterate_end;
259 city_built_iterate(pcity, pimprove) {
260 if (is_small_wonder(pimprove)) {
261 SANITY_CITY(pcity, city_from_small_wonder(pplayer, pimprove) == pcity);
262 } else if (is_great_wonder(pimprove)) {
263 SANITY_CITY(pcity, city_from_great_wonder(pimprove) == pcity);
265 } city_built_iterate_end;
267 trade_routes_iterate(pcity, proute) {
268 struct city *partner = game_city_by_number(proute->partner);
270 if (partner != NULL) {
271 struct trade_route *back_route = NULL;
273 trade_routes_iterate(partner, pback) {
274 if (pback->partner == pcity->id) {
275 back_route = pback;
276 break;
278 } trade_routes_iterate_end;
280 SANITY_CITY(pcity, back_route != NULL);
282 if (back_route != NULL) {
283 switch (back_route->dir) {
284 case RDIR_TO:
285 SANITY_CITY(pcity, proute->dir == RDIR_FROM);
286 break;
287 case RDIR_FROM:
288 SANITY_CITY(pcity, proute->dir == RDIR_TO);
289 break;
290 case RDIR_BIDIRECTIONAL:
291 SANITY_CITY(pcity, proute->dir == RDIR_BIDIRECTIONAL);
292 break;
295 SANITY_CITY(pcity, proute->goods == back_route->goods);
298 } trade_routes_iterate_end;
300 return TRUE;
303 /**************************************************************************
304 Sanity check city size versus worker and specialist counts.
305 **************************************************************************/
306 static void check_city_size(struct city *pcity, const char *file,
307 const char *function, int line)
309 int delta;
310 int citizen_count = 0;
311 struct tile *pcenter = city_tile(pcity);
313 SANITY_CITY(pcity, city_size_get(pcity) >= 1);
315 city_tile_iterate_skip_free_worked(city_map_radius_sq_get(pcity), pcenter,
316 ptile, _index, _x, _y) {
317 if (tile_worked(ptile) == pcity) {
318 citizen_count++;
320 } city_tile_iterate_skip_free_worked_end;
322 citizen_count += city_specialists(pcity);
323 delta = city_size_get(pcity) - citizen_count;
324 if (0 != delta) {
325 SANITY_FAIL("(%4d,%4d) %d citizens not equal [size], "
326 "repairing \"%s\"[%d]", TILE_XY(pcity->tile),
327 citizen_count, city_name_get(pcity), city_size_get(pcity));
329 citylog_map_workers(LOG_DEBUG, pcity);
330 log_debug("[%s (%d)] specialists: %d", city_name_get(pcity), pcity->id,
331 city_specialists(pcity));
333 city_repair_size(pcity, delta);
334 city_refresh_from_main_map(pcity, NULL);
338 /**************************************************************************
339 Verify that the number of people with feelings + specialists equal
340 city size.
341 **************************************************************************/
342 static void check_city_feelings(const struct city *pcity, const char *file,
343 const char *function, int line)
345 int feel;
346 int spe = city_specialists(pcity);
348 for (feel = FEELING_BASE; feel < FEELING_LAST; feel++) {
349 int sum = 0;
350 int ccategory;
352 for (ccategory = CITIZEN_HAPPY; ccategory < CITIZEN_LAST; ccategory++) {
353 sum += pcity->feel[ccategory][feel];
356 /* While loading savegame, we want to check sanity of values read from the
357 * savegame despite the fact that city workers_frozen level of the city
358 * is above zero -> can't limit sanitycheck callpoints by that. Instead
359 * we check even more relevant needs_arrange. */
360 SANITY_CITY(pcity, !pcity->server.needs_arrange);
362 SANITY_CITY(pcity, city_size_get(pcity) - spe == sum);
366 /**************************************************************************
367 Verify that the city has sane values.
368 **************************************************************************/
369 void real_sanity_check_city(struct city *pcity, const char *file,
370 const char *function, int line)
372 if (check_city_good(pcity, file, function, line)) {
373 check_city_size(pcity, file, function, line);
374 check_city_feelings(pcity, file, function, line);
378 /**************************************************************************
379 Sanity checks on all cities in the world.
380 **************************************************************************/
381 static void check_cities(const char *file, const char *function, int line)
383 players_iterate(pplayer) {
384 city_list_iterate(pplayer->cities, pcity) {
385 SANITY_CITY(pcity, city_owner(pcity) == pplayer);
387 real_sanity_check_city(pcity, file, function, line);
388 } city_list_iterate_end;
389 } players_iterate_end;
392 /**************************************************************************
393 Sanity checks on all units in the world.
394 **************************************************************************/
395 static void check_units(const char *file, const char *function, int line)
397 players_iterate(pplayer) {
398 unit_list_iterate(pplayer->units, punit) {
399 struct tile *ptile = unit_tile(punit);
400 struct terrain *pterr = tile_terrain(ptile);
401 struct city *pcity;
402 struct city *phome;
403 struct unit *ptrans = unit_transport_get(punit);
405 SANITY_CHECK(unit_owner(punit) == pplayer);
407 if (IDENTITY_NUMBER_ZERO != punit->homecity) {
408 SANITY_CHECK(phome = player_city_by_number(pplayer,
409 punit->homecity));
410 if (phome) {
411 SANITY_CHECK(city_owner(phome) == pplayer);
415 /* Unit in the correct player list? */
416 SANITY_CHECK(player_unit_by_number(unit_owner(punit),
417 punit->id) != NULL);
419 if (!can_unit_continue_current_activity(punit)) {
420 SANITY_FAIL("(%4d,%4d) %s has activity %s, "
421 "but it can't continue at %s",
422 TILE_XY(ptile), unit_rule_name(punit),
423 get_activity_text(punit->activity),
424 tile_get_info_text(ptile, TRUE, 0));
427 if (activity_requires_target(punit->activity)
428 && (punit->activity != ACTIVITY_IRRIGATE || pterr->irrigation_result == pterr)
429 && (punit->activity != ACTIVITY_MINE || pterr->mining_result == pterr)) {
430 SANITY_CHECK(punit->activity_target != NULL);
433 pcity = tile_city(ptile);
434 if (pcity) {
435 SANITY_CHECK(pplayers_allied(city_owner(pcity), pplayer));
438 SANITY_CHECK(punit->moves_left >= 0);
439 SANITY_CHECK(punit->hp > 0);
441 /* Check for ground units in the ocean. */
442 SANITY_CHECK(can_unit_exist_at_tile(&(wld.map), punit, ptile)
443 || ptrans != NULL);
445 /* Check for over-full transports. */
446 SANITY_CHECK(get_transporter_occupancy(punit)
447 <= get_transporter_capacity(punit));
449 /* Check transporter. This should be last as the pointer ptrans will
450 * be modified. */
451 if (ptrans != NULL) {
452 struct unit *plevel = punit;
453 int level = 0;
455 /* Make sure the transporter is on the tile. */
456 SANITY_CHECK(same_pos(unit_tile(punit), unit_tile(ptrans)));
458 /* Can punit be cargo for its transporter? */
459 SANITY_CHECK(unit_transport_check(punit, ptrans));
461 /* Check that the unit is listed as transported. */
462 SANITY_CHECK(unit_list_search(unit_transport_cargo(ptrans),
463 punit) != NULL);
465 /* Check the depth of the transportation. */
466 while (ptrans) {
467 struct unit_list *pcargos = unit_transport_cargo(ptrans);
469 SANITY_CHECK(pcargos != NULL);
470 SANITY_CHECK(level < GAME_TRANSPORT_MAX_RECURSIVE);
472 /* Check for next level. */
473 plevel = ptrans;
474 ptrans = unit_transport_get(plevel);
475 level++;
478 /* Transporter capacity will be checked when transporter itself
479 * is checked */
482 /* Check that cargo is marked as transported with this unit */
483 unit_list_iterate(unit_transport_cargo(punit), pcargo) {
484 SANITY_CHECK(unit_transport_get(pcargo) == punit);
485 } unit_list_iterate_end;
486 } unit_list_iterate_end;
487 } players_iterate_end;
490 /**************************************************************************
491 Sanity checks on all players.
492 **************************************************************************/
493 static void check_players(const char *file, const char *function, int line)
495 players_iterate(pplayer) {
496 int found_palace = 0;
498 if (!pplayer->is_alive) {
499 /* Dead players' units and cities are disbanded in kill_player(). */
500 SANITY_CHECK(unit_list_size(pplayer->units) == 0);
501 SANITY_CHECK(city_list_size(pplayer->cities) == 0);
503 continue;
506 SANITY_CHECK(pplayer->server.adv != NULL);
507 SANITY_CHECK(!pplayer->nation || pplayer->nation->player == pplayer);
508 SANITY_CHECK(player_list_search(team_members(pplayer->team), pplayer));
510 SANITY_CHECK(!(city_list_size(pplayer->cities) > 0
511 && !pplayer->server.got_first_city));
513 city_list_iterate(pplayer->cities, pcity) {
514 if (is_capital(pcity)) {
515 found_palace++;
517 SANITY_CITY(pcity, found_palace <= 1);
518 } city_list_iterate_end;
520 players_iterate(pplayer2) {
521 struct player_diplstate *state1, *state2;
523 if (pplayer2 == pplayer) {
524 break; /* Do diplomatic sanity check only once per player couple. */
527 state1 = player_diplstate_get(pplayer, pplayer2);
528 state2 = player_diplstate_get(pplayer2, pplayer);
529 SANITY_CHECK(state1->type == state2->type);
530 SANITY_CHECK(state1->max_state == state2->max_state);
531 if (state1->type == DS_CEASEFIRE
532 || state1->type == DS_ARMISTICE) {
533 SANITY_CHECK(state1->turns_left == state2->turns_left);
535 if (state1->type == DS_TEAM) {
536 SANITY_CHECK(players_on_same_team(pplayer, pplayer2));
537 SANITY_CHECK(player_has_real_embassy(pplayer, pplayer2));
538 SANITY_CHECK(player_has_real_embassy(pplayer2, pplayer));
539 SANITY_CHECK(really_gives_vision(pplayer, pplayer2));
540 SANITY_CHECK(really_gives_vision(pplayer2, pplayer));
542 if (pplayer->is_alive
543 && pplayer2->is_alive
544 && pplayers_allied(pplayer, pplayer2)) {
545 enum dipl_reason allied_players_can_be_allied =
546 pplayer_can_make_treaty(pplayer, pplayer2, DS_ALLIANCE);
547 SANITY_CHECK(allied_players_can_be_allied
548 != DIPL_ALLIANCE_PROBLEM_US);
549 SANITY_CHECK(allied_players_can_be_allied
550 != DIPL_ALLIANCE_PROBLEM_THEM);
552 } players_iterate_end;
554 if (pplayer->revolution_finishes == -1) {
555 if (government_of_player(pplayer) == game.government_during_revolution) {
556 SANITY_FAIL("%s government is anarchy, but does not finish!",
557 nation_rule_name(nation_of_player(pplayer)));
559 SANITY_CHECK(government_of_player(pplayer) != game.government_during_revolution);
560 } else if (pplayer->revolution_finishes > game.info.turn) {
561 SANITY_CHECK(government_of_player(pplayer) == game.government_during_revolution);
562 } else {
563 /* Things may vary in this case depending on when the sanity_check
564 * call is made. No better check is possible. */
567 /* Dying players shouldn't be left around. But they are. */
568 SANITY_CHECK(!BV_ISSET(pplayer->server.status, PSTATUS_DYING));
569 } players_iterate_end;
571 nations_iterate(pnation) {
572 SANITY_CHECK(!pnation->player || pnation->player->nation == pnation);
573 } nations_iterate_end;
575 teams_iterate(pteam) {
576 player_list_iterate(team_members(pteam), pplayer) {
577 SANITY_CHECK(pplayer->team == pteam);
578 } player_list_iterate_end;
579 } teams_iterate_end;
582 /****************************************************************************
583 Sanity checking on teams.
584 ****************************************************************************/
585 static void check_teams(const char *file, const char *function, int line)
587 int count[MAX_NUM_TEAM_SLOTS];
589 memset(count, 0, sizeof(count));
590 players_iterate(pplayer) {
591 /* For the moment, all players have teams. */
592 SANITY_CHECK(pplayer->team != NULL);
593 if (pplayer->team) {
594 count[team_index(pplayer->team)]++;
596 } players_iterate_end;
598 team_slots_iterate(tslot) {
599 if (team_slot_is_used(tslot)) {
600 struct team *pteam = team_slot_get_team(tslot);
601 fc_assert_exit(pteam);
602 SANITY_CHECK(player_list_size(team_members(pteam))
603 == count[team_slot_index(tslot)]);
605 } team_slots_iterate_end;
608 /****************************************************************************
609 Sanity checks on all players.
610 ****************************************************************************/
611 static void
612 check_researches(const char *file, const char *function, int line)
614 researches_iterate(presearch) {
615 SANITY_CHECK(S_S_RUNNING != server_state()
616 || A_UNSET == presearch->researching
617 || is_future_tech(presearch->researching)
618 || (A_NONE != presearch->researching
619 && valid_advance_by_number(presearch->researching)));
620 SANITY_CHECK(A_UNSET == presearch->tech_goal
621 || (A_NONE != presearch->tech_goal
622 && valid_advance_by_number(presearch->tech_goal)));
623 } researches_iterate_end;
626 /**************************************************************************
627 Sanity checking on connections.
628 **************************************************************************/
629 static void check_connections(const char *file, const char *function,
630 int line)
632 /* est_connections is a subset of all_connections */
633 SANITY_CHECK(conn_list_size(game.all_connections)
634 >= conn_list_size(game.est_connections));
637 /**************************************************************************
638 Do sanity checks on the server state. Call this once per turn or
639 whenever you feel like it.
641 But be careful, calling it too much would make the server slow down. And
642 at some times the server isn't supposed to be in a sane state so you
643 can't call it in the middle of an operation that is supposed to be
644 atomic.
645 **************************************************************************/
646 void real_sanity_check(const char *file, const char *function, int line)
648 if (!map_is_empty()) {
649 /* Don't sanity-check the map if it hasn't been created yet (this
650 * happens when loading scenarios). */
651 check_specials(file, function, line);
652 check_map(file, function, line);
653 check_cities(file, function, line);
654 check_units(file, function, line);
655 check_fow(file, function, line);
657 check_misc(file, function, line);
658 check_players(file, function, line);
659 check_teams(file, function, line);
660 check_researches(file, function, line);
661 check_connections(file, function, line);
664 /*****************************************************************************
665 Verify that the tile has sane values. This should be called after the
666 terrain is changed.
667 *****************************************************************************/
668 void real_sanity_check_tile(struct tile *ptile, const char *file,
669 const char *function, int line)
671 SANITY_CHECK(ptile != NULL);
672 SANITY_CHECK(ptile->terrain != NULL);
674 unit_list_iterate(ptile->units, punit) {
675 /* Check if the units can survive on the tile (terrain). Here only the
676 * 'easy' test if the unit is transported is done. A complete check is
677 * done by check_units() in real_sanity_check(). */
678 if (!can_unit_exist_at_tile(&(wld.map), punit, ptile)
679 && !unit_transported(punit)) {
680 SANITY_FAIL("(%4d,%4d) %s can't survive on %s", TILE_XY(ptile),
681 unit_rule_name(punit), tile_get_info_text(ptile, TRUE, 0));
683 } unit_list_iterate_end;
686 #endif /* SANITY_CHECKING */