41 #ifdef SANITY_CHECKING
43 #define SANITY_FAIL(format, ...) fc_assert_msg(false, format, ##__VA_ARGS__)
45 #define SANITY_CHECK(check) fc_assert(check)
47 #define SANITY_CITY(_city, check) \
48 fc_assert_msg(check, "(%4d, %4d) in \"%s\"[%d]", TILE_XY((_city)->tile), \
49 city_name_get(_city), city_size_get(_city))
51 #define SANITY_TERRAIN(_tile, check) \
52 fc_assert_msg(check, "(%4d, %4d) at \"%s\"", TILE_XY(_tile), \
53 terrain_rule_name(tile_terrain(_tile)))
55 #define SANITY_TILE(_tile, check) \
57 struct city *_tile##_city = tile_city(_tile); \
58 if (nullptr != _tile##_city) { \
59 SANITY_CITY(_tile##_city, check); \
61 SANITY_TERRAIN(_tile, check); \
65 static void check_city_feelings(
const struct city *pcity,
const char *file,
66 const char *
function,
int line);
71 static void check_specials(
const char *file,
const char *
function,
int line)
113 static void check_fow(
const char *file,
const char *
function,
int line)
129 SANITY_TILE(ptile, plr_tile->
seen_count[v] < 30000);
130 SANITY_TILE(ptile, plr_tile->
own_seen[v] < 30000);
136 SANITY_TILE(ptile, plr_tile->
seen_count[V_INVIS]
154 static void check_misc(
const char *file,
const char *
function,
int line)
156 int nplayers = 0, nbarbs = 0;
171 SANITY_CHECK(nbarbs ==
server.nbarbarians);
181 static void check_map(
const char *file,
const char *
function,
int line)
190 if (
nullptr != pcity) {
192 SANITY_TILE(ptile,
tile_owner(ptile) !=
nullptr);
197 SANITY_TILE(ptile,
tile_owner(ptile) ==
nullptr);
201 SANITY_TILE(ptile, cont < 0);
210 SANITY_TILE(ptile, cont > 0);
244 static bool check_city_good(
struct city *pcity,
const char *file,
245 const char *
function,
int line)
250 if (
nullptr == pcenter) {
252 SANITY_FAIL(
"(----,----) city has no tile (skipping remaining tests), "
253 "at %s \"%s\"[%d]%s",
262 SANITY_CITY(pcity,
nullptr !=
tile_owner(pcenter));
268 "(%4d,%4d) tile owned by %s, at %s \"%s\"[%d]%s",
TILE_XY(pcenter),
277 SANITY_CITY(pcity, punit->homecity == pcity->
id);
278 SANITY_CITY(pcity,
unit_owner(punit) == pplayer);
296 if (partner !=
nullptr) {
301 if (pback->partner == pcity->
id) {
308 SANITY_CITY(pcity, back_route !=
nullptr);
310 if (back_route !=
nullptr) {
311 switch (back_route->
dir) {
313 SANITY_CITY(pcity, proute->dir == RDIR_FROM);
316 SANITY_CITY(pcity, proute->dir == RDIR_TO);
318 case RDIR_BIDIRECTIONAL:
319 SANITY_CITY(pcity, proute->dir == RDIR_BIDIRECTIONAL);
323 SANITY_CITY(pcity, proute->goods == back_route->
goods);
335 static void check_city_size(
struct city *pcity,
const char *file,
336 const char *
function,
int line)
339 int citizen_count = 0;
345 ptile, _index, _x, _y)
356 SANITY_FAIL(
"(%4d,%4d) %d citizens not equal [size], "
357 "repairing \"%s\"[%d]",
375 static void check_city_feelings(
const struct city *pcity,
const char *file,
376 const char *
function,
int line)
386 sum += pcity->
feel[ccategory][feel];
393 SANITY_CITY(pcity, !pcity->
server.needs_arrange);
402 void real_sanity_check_city(
struct city *pcity,
const char *file,
403 const char *
function,
int line)
405 if (check_city_good(pcity, file,
function, line)) {
406 check_city_size(pcity, file,
function, line);
407 check_city_feelings(pcity, file,
function, line);
414 static void check_cities(
const char *file,
const char *
function,
int line)
420 SANITY_CITY(pcity,
city_owner(pcity) == pplayer);
422 real_sanity_check_city(pcity, file,
function, line);
432 static void check_units(
const char *file,
const char *
function,
int line)
459 SANITY_FAIL(
"(%4d,%4d) %s has activity %s, "
460 "but it can't continue at %s",
467 && (punit->activity != ACTIVITY_IRRIGATE
469 && (punit->activity != ACTIVITY_MINE
471 SANITY_CHECK(punit->activity_target !=
nullptr);
479 SANITY_CHECK(punit->moves_left >= 0);
480 SANITY_CHECK(punit->hp > 0);
484 || ptrans !=
nullptr);
492 if (ptrans !=
nullptr) {
493 struct unit *plevel = punit;
510 SANITY_CHECK(pcargos !=
nullptr);
538 static void check_players(
const char *file,
const char *
function,
int line)
542 int found_primary_capital = 0;
546 SANITY_CHECK(unit_list_size(pplayer->
units) == 0);
547 SANITY_CHECK(city_list_size(pplayer->
cities) == 0);
552 SANITY_CHECK(pplayer->
server.adv !=
nullptr);
556 SANITY_CHECK(!(city_list_size(pplayer->
cities) > 0
557 && !pplayer->
server.got_first_city));
561 if (pcity->
capital == CAPITAL_PRIMARY) {
562 found_primary_capital++;
564 SANITY_CITY(pcity, found_primary_capital <= 1);
572 if (pplayer2 == pplayer) {
578 SANITY_CHECK(state1->
type == state2->
type);
580 if (state1->
type == DS_CEASEFIRE || state1->
type == DS_ARMISTICE) {
583 if (state1->
type == DS_TEAM) {
587 if (pplayer->
is_alive && pplayer2->is_alive) {
592 if (pplayer->
is_alive && pplayer2->is_alive
596 SANITY_CHECK(allied_players_can_be_allied
598 SANITY_CHECK(allied_players_can_be_allied
607 SANITY_FAIL(
"%s government is anarchy, but does not finish!",
625 for (
const auto &pnation :
nations) {
626 SANITY_CHECK(!pnation.player || pnation.player->nation == &pnation);
633 SANITY_CHECK(pplayer->
team == pteam);
643 static void check_teams(
const char *file,
const char *
function,
int line)
647 memset(count, 0,
sizeof(count));
651 SANITY_CHECK(pplayer->
team !=
nullptr);
673 static void check_researches(
const char *file,
const char *
function,
679 ||
A_UNSET == presearch.researching
681 || (
A_NONE != presearch.researching
683 SANITY_CHECK(
A_UNSET == presearch.tech_goal
684 || (
A_NONE != presearch.tech_goal
693 static void check_connections(
const char *file,
const char *
function,
710 void real_sanity_check(
const char *file,
const char *
function,
int line)
715 check_specials(file,
function, line);
716 check_map(file,
function, line);
717 check_cities(file,
function, line);
718 check_units(file,
function, line);
719 check_fow(file,
function, line);
721 check_misc(file,
function, line);
722 check_players(file,
function, line);
723 check_teams(file,
function, line);
724 check_researches(file,
function, line);
725 check_connections(file,
function, line);
732 void real_sanity_check_tile(
struct tile *ptile,
const char *file,
733 const char *
function,
int line)
735 SANITY_CHECK(ptile !=
nullptr);
736 SANITY_CHECK(ptile->
terrain !=
nullptr);
745 SANITY_FAIL(
"(%4d,%4d) %s can't survive on %s",
TILE_XY(ptile),
bool BV_ISSET(const BV &bv, int bit)
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
void citylog_map_workers(QtMsgType level, struct city *pcity)
Display the location of the workers within the city map of pcity.
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
const char * city_name_get(const struct city *pcity)
Return the name of the city.
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
citizens city_specialists(const struct city *pcity)
Give the number of specialists in a city.
void city_refresh_from_main_map(struct city *pcity, bool *workers_map, const std::vector< city * > &gov_centers, const std::array< cached_waste, O_LAST > *pcwaste, const std::vector< std::array< int, O_LAST >> *pcsoutputs)
Refreshes the internal cached data in the city structure.
citizens city_size_get(const struct city *pcity)
Get the city size.
#define city_list_iterate(citylist, pcity)
#define city_list_iterate_end
#define city_tile_iterate_skip_center_end
#define city_tile_iterate_skip_center(_radius_sq, _city_tile, _tile, _index, _x, _y)
#define city_built_iterate(_pcity, _p)
#define city_built_iterate_end
void city_repair_size(struct city *pcity, int change)
Repair the city population without affecting city size.
#define MAX_NUM_PLAYER_SLOTS
#define IDENTITY_NUMBER_ZERO
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
#define GAME_TRANSPORT_MAX_RECURSIVE
struct government * government_of_player(const struct player *pplayer)
Return the government of a player.
struct government * government_by_number(const Government_type_id gov)
Return the government with the given index.
struct city * city_from_great_wonder(const struct impr_type *pimprove)
Get the world city with this great wonder.
struct city * city_from_small_wonder(const struct player *pplayer, const struct impr_type *pimprove)
Get the player city with this small wonder.
bool is_great_wonder(const struct impr_type *pimprove)
Is this building a great wonder?
bool is_small_wonder(const struct impr_type *pimprove)
Is this building a small wonder?
#define log_debug(message,...)
#define fc_assert_exit(condition)
bool map_is_empty()
Returns TRUE if we are at a stage of the game where the map has not yet been generated/loaded.
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Are (x1,y1) and (x2,y2) really the same when adjusted? This function might be necessary ALOT of place...
#define CHECK_INDEX(mindex)
#define adjc_iterate(nmap, center_tile, itr_tile)
#define whole_map_iterate(_map, _tile)
#define whole_map_iterate_end
bool really_gives_vision(struct player *me, struct player *them)
Return TRUE iff the player me really gives shared vision to player them.
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Players' information of tiles is tracked so that fogged area can be kept consistent even when the cli...
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "exist" at this location.
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
std::vector< nation_type > nations
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
If the specified player owns the unit with the specified id, return pointer to the unit struct.
bool player_slot_is_used(const struct player_slot *pslot)
Returns TRUE is this slot is "used" i.e.
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Return TRUE if players are in the same team.
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Returns true iff p1 can make given treaty with p2.
int player_count()
Return the number of players.
std::vector< city * > player_gov_centers(const struct player *pplayer)
Locate the player's government centers.
bool player_has_real_embassy(const struct player *pplayer, const struct player *pplayer2)
Returns whether pplayer has a real embassy with pplayer2, established from a diplomat,...
struct city * player_city_by_number(const struct player *pplayer, int city_id)
If the specified player owns the city with the specified id, return pointer to the city struct.
struct player * player_slot_get_player(const struct player_slot *pslot)
Returns the team corresponding to the slot.
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
#define players_iterate_end
@ DIPL_ALLIANCE_PROBLEM_THEM
@ DIPL_ALLIANCE_PROBLEM_US
#define players_iterate(_pplayer)
#define player_list_iterate(playerlist, pplayer)
static bool is_barbarian(const struct player *pplayer)
#define player_slots_iterate(_pslot)
#define player_list_iterate_end
#define player_slots_iterate_end
int normal_player_count()
Return the number of non-barbarian players.
bool research_is_valid(const struct research &presearch)
Checks whether the research object is valid in the current game.
std::vector< research > research_array
struct setting_list * level[OLEVELS_NUM]
bool game_was_started()
Returns iff the game was started once upon a time.
enum server_states server_state()
Return current server state.
enum capital_type capital
struct city::@15::@17 server
citizens feel[CITIZEN_LAST][FEELING_LAST]
struct unit_list * units_supported
struct civ_game::@28::@32 server
struct conn_list * est_connections
struct packet_game_info info
struct conn_list * all_connections
struct government * government_during_revolution
enum diplstate_type max_state
struct city_list * cities
struct player::@65::@67 server
struct nation_type * nation
struct terrain * irrigation_result
struct terrain * mining_result
struct goods_type * goods
int team_index(const struct team *pteam)
Return the team index.
int team_count()
Return the current number of teams.
struct team * team_slot_get_team(const struct team_slot *tslot)
Returns the team corresponding to the slot.
const struct player_list * team_members(const struct team *pteam)
Returns the member list of the team.
int team_slot_index(const struct team_slot *tslot)
Returns the index of the team slots.
bool team_slot_is_used(const struct team_slot *tslot)
Returns TRUE is this slot is "used" i.e.
#define team_slots_iterate_end
#define team_slots_iterate(_tslot)
#define teams_iterate_end
#define teams_iterate(_pteam)
#define MAX_NUM_TEAM_SLOTS
bool is_future_tech(Tech_type_id tech)
Is the given tech a future tech.
struct advance * valid_advance_by_number(const Tech_type_id id)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Terrain_type_id terrain_count()
Return the number of terrains.
Terrain_type_id terrain_index(const struct terrain *pterrain)
Return the terrain index.
#define is_ocean_tile(ptile)
#define terrain_has_flag(terr, flag)
const char * tile_get_info_text(const struct tile *ptile, bool include_nuisances, int linebreaks)
Return a (static) string with tile name describing terrain and extras of some categories.
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
#define tile_worked(_tile)
#define tile_terrain(_tile)
#define tile_continent(_tile)
#define tile_has_extra(ptile, pextra)
#define tile_owner(_tile)
#define trade_routes_iterate_end
#define trade_routes_iterate(c, proute)
int get_transporter_occupancy(const struct unit *ptrans)
Return how many units are in the transport.
bool unit_transport_check(const struct unit *pcargo, const struct unit *ptrans)
Returns whether 'pcargo' in 'ptrans' is a valid transport.
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
bool can_unit_continue_current_activity(struct unit *punit)
Check if the unit's current activity is actually legal.
struct unit_list * unit_transport_cargo(const struct unit *ptrans)
Returns the list of cargo units.
int get_transporter_capacity(const struct unit *punit)
Return the number of units the transporter can hold (or 0).
const char * get_activity_text(enum unit_activity activity)
Return the name of the activity in a static buffer.
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
bool activity_requires_target(enum unit_activity activity)
Return TRUE if activity requires some sort of target to be specified.
#define unit_list_iterate(unitlist, punit)
#define unit_list_iterate_end
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
#define vision_layer_iterate(v)
#define vision_layer_iterate_end