65 #include <fc_config.h>
88 #include "fc_version.h"
148 #ifdef FREECIV_TESTMATIC
149 #define SAVE_DUMMY_TURN_CHANGE_TIME 1
165 #define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath, ...) \
167 char _line[wld.map.xsize + 1]; \
168 int _nat_x, _nat_y; \
170 for (_nat_y = 0; _nat_y < wld.map.ysize; _nat_y++) { \
171 for (_nat_x = 0; _nat_x < wld.map.xsize; _nat_x++) { \
172 struct tile *ptile = \
173 native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
174 fc_assert_action(ptile != nullptr, continue); \
175 _line[_nat_x] = (GET_XY_CHAR); \
176 sg_failure_ret(QChar::isPrint(_line[_nat_x] & 0x7f), \
177 "Trying to write invalid map data at position " \
178 "(%d, %d) for path %s: '%c' (%d)", \
179 _nat_x, _nat_y, secpath, _line[_nat_x], \
182 _line[wld.map.xsize] = '\0'; \
183 secfile_insert_str(secfile, _line, secpath, ##__VA_ARGS__, _nat_y); \
214 #define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath, ...) \
216 int _nat_x, _nat_y; \
217 bool _printed_warning = false; \
218 for (_nat_y = 0; _nat_y < wld.map.ysize; _nat_y++) { \
219 const char *_line = \
220 secfile_lookup_str(secfile, secpath, ##__VA_ARGS__, _nat_y); \
221 if (nullptr == _line) { \
223 fc_snprintf(buf, sizeof(buf), secpath, ##__VA_ARGS__, _nat_y); \
224 qDebug("Line not found='%s'", buf); \
225 _printed_warning = true; \
227 } else if (strlen(_line) != wld.map.xsize) { \
229 fc_snprintf(buf, sizeof(buf), secpath, ##__VA_ARGS__, _nat_y); \
230 qDebug("Line too short (expected %d got %lu)='%s'", wld.map.xsize, \
231 (unsigned long) qstrlen(_line), buf); \
232 _printed_warning = true; \
235 for (_nat_x = 0; _nat_x < wld.map.xsize; _nat_x++) { \
236 const char ch = _line[_nat_x]; \
237 struct tile *ptile = \
238 native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
242 if (_printed_warning) { \
244 log_sg(_("Saved game contains incomplete map data. This can" \
245 " happen with old saved games, or it may indicate an" \
246 " invalid saved game file. Proceed at your own risk.")); \
251 #define halfbyte_iterate_extras(e, num_extras_types) \
254 for (e = 0; 4 * e < (num_extras_types); e++) {
256 #define halfbyte_iterate_extras_end \
272 #define TOKEN_SIZE 10
280 const char *save_reason,
bool scenario);
290 static enum direction8
char2dir(
char dir);
291 static char dir2char(
enum direction8 dir);
294 static char *
quote_block(
const void *
const data,
int length);
295 static int unquote_block(
const char *
const quoted_,
void *dest,
298 const char *path, ...);
300 const struct worklist *pwl,
int max_length,
301 const char *path, ...);
311 const char *path,
int plrno);
361 struct city *pcity,
const char *citystr);
365 const char *citystr);
369 struct unit *punit,
const char *unitstr);
379 const char *citystr);
420 qDebug(
"saving game in new format ...");
424 qCDebug(timers_category,
"Creating secfile in %.3f seconds.",
439 bool was_send_city_suppressed, was_send_tile_suppressed;
492 qCritical(
"Failure loading savegame!");
496 load_rulesets(
nullptr,
nullptr,
false,
nullptr,
true,
false,
true);
504 const char *save_reason,
bool scenario)
550 qCritical(
"Failure saving savegame!");
618 static_cast<savedata *
>(calloc(1,
sizeof(*saving)));
693 static enum direction8
char2dir(
char dir)
698 return DIR8_SOUTHWEST;
702 return DIR8_SOUTHEAST;
708 return DIR8_NORTHWEST;
712 return DIR8_NORTHEAST;
716 return direction8_invalid();
756 case ACTIVITY_POLLUTION:
758 case ACTIVITY_OLD_ROAD:
764 case ACTIVITY_IRRIGATE:
766 case ACTIVITY_CULTIVATE:
768 case ACTIVITY_FORTIFIED:
770 case ACTIVITY_FORTRESS:
772 case ACTIVITY_SENTRY:
774 case ACTIVITY_OLD_RAILROAD:
776 case ACTIVITY_PILLAGE:
780 case ACTIVITY_EXPLORE:
782 case ACTIVITY_TRANSFORM:
784 case ACTIVITY_AIRBASE:
786 case ACTIVITY_FORTIFYING:
788 case ACTIVITY_FALLOUT:
792 case ACTIVITY_GEN_ROAD:
794 case ACTIVITY_CONVERT:
796 case ACTIVITY_UNKNOWN:
797 case ACTIVITY_PATROL_UNUSED:
814 for (a = 0; a < ACTIVITY_LAST; a++) {
817 if (activity == achar) {
818 return static_cast<unit_activity
>(a);
823 return ACTIVITY_LAST;
832 auto bufsize = length * 3 + 10;
833 char *buffer =
new char[bufsize];
837 snprintf(buffer, bufsize,
"%d:", length);
838 offset = qstrlen(buffer);
840 for (i = 0; i < length; i++) {
841 snprintf(buffer + offset, bufsize,
"%02x ", ((
unsigned char *) data)[i]);
855 int i, length, parsed, tmp;
857 const char *quoted = quoted_;
859 parsed = sscanf(quoted,
"%d", &length);
862 if (length > dest_length) {
865 quoted = strchr(quoted,
':');
869 for (i = 0; i < length; i++) {
870 tmp = strtol(quoted, &endptr, 16);
874 (
static_cast<unsigned char *
>(dest))[i] = tmp;
885 const char *path, ...)
903 for (i = 0; i < pwl->
length; i++) {
911 if (pwl->
entries[i].
kind == universals_n_invalid()) {
912 log_sg(
"%s.wl_value%d: unknown \"%s\" \"%s\".", path_str, i, kind,
925 const struct worklist *pwl,
int max_length,
926 const char *path, ...)
940 for (i = 0; i < pwl->
length; i++) {
952 for (i = pwl->
length; i < max_length; i++) {
976 punit->server.ord_city = j++;
1027 const char *pch = strchr(
hex_chars, ch);
1029 if (!pch || ch ==
'\0') {
1030 log_sg(
"Unknown hex value: '%c' (%d)", ch, ch);
1036 for (i = 0; i < 4; i++) {
1039 if (pextra ==
nullptr) {
1042 if ((bin & (1 << i))
1061 for (i = 0; i < 4; i++) {
1093 if (pterrain->identifier_load == ch) {
1099 qFatal(
"Unknown terrain identifier '%c' in savegame.", ch);
1121 const char *path,
int plrno)
1123 char path_with_name[128];
1127 fc_snprintf(path_with_name,
sizeof(path_with_name),
"%s_name", path);
1147 "%s: unknown technology \"%s\".", path_with_name,
name);
1158 char path_with_name[128];
1161 fc_snprintf(path_with_name,
sizeof(path_with_name),
"%s_name", path);
1194 const char *terr_name;
1195 bool ruleset_datafile;
1212 const char *
ruleset, *alt_dir;
1219 if (!strcmp(
"default",
game.
server.rulesetdir)) {
1224 qDebug(
"Savegame specified ruleset '%s'. Really loading '%s'.",
1229 "savefile.ruleset_alt_dir");
1231 if (!
load_rulesets(
nullptr, alt_dir,
false,
nullptr,
true,
false,
1232 ruleset_datafile)) {
1235 _(
"Failed to load either of rulesets '%s' or '%s' "
1236 "needed for savegame."),
1240 _(
"Failed to load ruleset '%s' needed for savegame."),
1245 if (!
load_rulesets(
nullptr,
nullptr,
false,
nullptr,
true,
false,
1246 ruleset_datafile)) {
1258 const char *req_caps;
1261 "scenario.ruleset_caps");
1268 qInfo(
_(
"Scenario requires ruleset capabilities: %s"), req_caps);
1270 qCritical(
_(
"Current ruleset not compatible with the scenario."));
1284 fc_snprintf(testfile,
sizeof(testfile),
"%s.luadata",
1289 if (found.isEmpty()) {
1290 qCritical(
_(
"Can't find scenario luadata file %s.luadata."),
1297 if (secfile ==
nullptr) {
1298 qCritical(
_(
"Failed to load scenario luadata file %s.luadata"),
1312 loading->
file,
false,
"savefile.last_updated_as_year");
1316 loading->
file, 0,
"savefile.improvement_size");
1320 "savefile.improvement_vector");
1327 loading->
file, 0,
"savefile.technology_size");
1331 "savefile.technology_vector");
1338 loading->
file, 0,
"savefile.activities_size");
1342 "savefile.activities_vector");
1352 loading->
file, &loading->
trait.
size,
"savefile.trait_vector");
1361 const char **modname;
1366 "savefile.extras_vector");
1370 "Number of extras defined by the ruleset (= %d) are "
1371 "lower than the number in the savefile (= %d).",
1374 nmod = 4 * ((loading->
extra.
size + 3) / 4);
1376 for (j = 0; j < loading->
extra.
size; j++) {
1380 for (; j < nmod; j++) {
1387 loading->
file, 0,
"savefile.multipliers_size");
1389 const char **modname;
1394 "savefile.multipliers_vector");
1403 qDebug(
"Multiplier \"%s\" in savegame but not in ruleset, "
1413 loading->
file, 0,
"savefile.specialists_size");
1415 const char **modname;
1421 "savefile.specialists_vector");
1426 "Number of specialists defined by the ruleset (= %d) are "
1427 "lower than the number in the savefile (= %d).",
1439 for (; j < nmod; j++) {
1452 const char **modname;
1456 "savefile.action_vector");
1466 log_sg(
"Unknown action \'%s\'", modname[j]);
1476 loading->
file, 0,
"savefile.action_decision_size");
1479 "Failed to load action decision order: %s",
1483 const char **modname;
1487 "savefile.action_decision_vector");
1501 loading->
file, 0,
"savefile.server_side_agent_size");
1504 "Failed to load server side agent order: %s",
1508 const char **modname;
1512 "savefile.server_side_agent_list");
1515 for (j = 0; j < loading->
ssa.
size; j++) {
1528 loading->
file,
nullptr,
"savefile.terrident%d.name", i))
1532 if (pterr !=
nullptr) {
1534 loading->
file,
nullptr,
"savefile.terrident%d.identifier", i);
1538 qCritical(
"Identifier for unknown terrain type %s.", terr_name);
1547 if (pterr != pterr2 && pterr->identifier_load !=
'\0') {
1548 sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1549 "%s and %s share a saved identifier",
1582 "savefile.rulesetdir");
1589 "savefile.rulesetversion");
1594 "savefile.ruleset_alt_dir");
1605 "savefile.improvement_size");
1616 "savefile.improvement_vector");
1623 "savefile.technology_size");
1634 "savefile.technology_vector");
1639 "savefile.activities_size");
1640 if (ACTIVITY_LAST > 0) {
1641 const char **modname;
1646 modname =
new const char *[ACTIVITY_LAST]();
1648 for (j = 0; j < ACTIVITY_LAST; j++) {
1649 modname[i++] = unit_activity_name(
static_cast<unit_activity
>(j));
1653 "savefile.activities_vector");
1659 "savefile.specialists_size");
1661 const char **modname;
1672 "savefile.specialists_vector");
1680 const char **modname;
1684 modname =
new const char *[TRAIT_COUNT]();
1686 for (tr = trait_begin(), j = 0; tr != trait_end();
1687 tr = trait_next(tr), j++) {
1688 modname[j] = trait_name(tr);
1692 "savefile.trait_vector");
1698 "savefile.extras_size");
1700 const char **modname;
1702 modname =
new const char *[
game.
control.num_extra_types]();
1709 "savefile.extras_vector");
1715 "savefile.multipliers_size");
1717 const char **modname;
1728 "savefile.multipliers_vector");
1735 const char **modname;
1739 modname =
new const char *[DS_LAST]();
1741 for (j = 0; j < DS_LAST; j++) {
1742 modname[i++] = diplstate_type_name(
static_cast<diplstate_type
>(j));
1746 "savefile.diplstate_type_vector");
1752 if (CITYO_LAST > 0) {
1753 const char **modname;
1757 modname =
new const char *[CITYO_LAST]();
1759 for (j = 0; j < CITYO_LAST; j++) {
1760 modname[i++] = city_options_name(
static_cast<city_options
>(j));
1764 "savefile.city_options_vector");
1771 const char **modname;
1782 "savefile.action_vector");
1788 "savefile.action_decision_size");
1789 if (ACT_DEC_COUNT > 0) {
1790 const char **modname;
1794 modname =
new const char *[ACT_DEC_COUNT]();
1796 for (j = 0; j < ACT_DEC_COUNT; j++) {
1797 modname[i++] = action_decision_name(
static_cast<action_decision
>(j));
1801 "savefile.action_decision_vector");
1807 "savefile.server_side_agent_size");
1808 if (SSA_COUNT > 0) {
1809 const char **modname;
1813 modname =
new const char *[SSA_COUNT]();
1815 for (j = 0; j < SSA_COUNT; j++) {
1817 server_side_agent_name(
static_cast<server_side_agent
>(j));
1821 "savefile.server_side_agent_list");
1832 "savefile.terrident%d.name", i);
1857 "savefile.options");
1876 loading->
file,
nullptr,
"ruledata.government%d.name", i));
1880 if (gov !=
nullptr) {
1882 loading->
file, 0,
"ruledata.government%d.changes", i);
1901 "game.server_state");
1902 loading->
server_state = server_states_by_name(str, strcmp);
1936 if (
level !=
nullptr) {
1939 game.
info.skill_level = ai_level_invalid();
1942 if (!ai_level_is_valid(
static_cast<ai_level
>(
game.
info.skill_level))) {
1948 if (str !=
nullptr) {
1950 if (!phase_mode_type_is_valid(
game.
info.phase_mode)) {
1951 qCritical(
"Illegal phase mode \"%s\"", str);
1956 qCritical(
"Phase mode missing");
1960 "game.phase_mode_stored");
1961 if (str !=
nullptr) {
1964 if (!phase_mode_type_is_valid(
1965 static_cast<phase_mode_type
>(
game.
server.phase_mode_stored))) {
1966 qCritical(
"Illegal stored phase mode \"%s\"", str);
1970 qCritical(
"Stored phase mode missing");
2012 "game.global_advances");
2013 if (str !=
nullptr) {
2015 "Invalid length of 'game.global_advances' (%lu ~= %lu).",
2016 (
unsigned long) qstrlen(str),
2020 "Undefined value '%c' within 'game.global_advances'.",
2022 if (str[i] ==
'1') {
2026 if (padvance !=
nullptr) {
2038 "game.last_turn_change_time")
2052 fc_snprintf(path,
sizeof(path),
"ruledata.government%d", set_count++);
2066 enum server_states srv_state;
2067 char global_advances[
game.
control.num_tech_types + 1];
2077 srv_state = S_S_INITIAL;
2082 "game.server_state");
2088 "game.phase_seconds");
2092 "game.meta_patches");
2094 "game.meta_server");
2102 ai_level_name(
static_cast<ai_level
>(
game.
info.skill_level)),
2105 phase_mode_type_name(
game.
info.phase_mode),
2108 phase_mode_type_name(
static_cast<phase_mode_type
>(
2110 "game.phase_mode_stored");
2117 "game.timeoutintinc");
2121 "game.timeoutincmult");
2123 "game.timeoutcounter");
2128 "game.year_0_hack");
2131 "game.globalwarming");
2134 "game.warminglevel");
2137 "game.nuclearwinter");
2140 "game.coolinglevel");
2150 for (i = 0; i <
game.
control.num_tech_types; i++) {
2151 global_advances[i] =
game.
info.global_advances[i] ?
'1' :
'0';
2153 global_advances[i] =
'\0';
2164 #ifndef SAVE_DUMMY_TURN_CHANGE_TIME
2166 "game.last_turn_change_time");
2169 "game.last_turn_change_time");
2173 "game.save_players");
2175 if (srv_state != S_S_INITIAL) {
2181 ainames[i] = ait->name;
2204 qWarning().noquote() << QString::fromUtf8(
2205 _(
"Cannot load old random generator state. Seeding a new one."));
2207 }
else if (
auto *state =
2209 std::stringstream ss;
2210 ss.imbue(std::locale::classic());
2214 qWarning().noquote() << QString::fromUtf8(
2215 _(
"Cannot load the random generator state. Seeding a new one."));
2243 std::stringstream ss;
2244 ss.imbue(std::locale::classic());
2246 auto state = ss.str();
2301 sg_failure_ret(29099 <= game_version,
"Saved game is too old, at least "
2302 "version 2.90.99 required.");
2308 "scenario.is_scenario"),
2315 if (buf[0] !=
'\0') {
2320 if (buf[0] !=
'\0') {
2328 if (buf[0] !=
'\0') {
2334 loading->
file,
false,
"scenario.save_random");
2338 loading->
file,
false,
"scenario.startpos_nations");
2340 loading->
file,
false,
"scenario.prevent_new_cities");
2342 loading->
file,
true,
"scenario.lake_flooding");
2346 loading->
file,
false,
"scenario.allow_ai_type_fallback");
2349 loading->
file,
true,
"scenario.ruleset_locked");
2352 if (buf[0] !=
'\0') {
2359 "Invalid scenario definition (server state '%s' and "
2370 struct entry *mod_entry;
2377 MAJOR_VERSION * 1000000 + MINOR_VERSION * 10000 + PATCH_VERSION * 100;
2395 "scenario.authors");
2403 "scenario.description");
2408 "scenario.save_random");
2410 "scenario.players");
2412 "scenario.startpos_nations");
2415 "scenario.prevent_new_cities");
2418 "scenario.lake_flooding");
2421 "scenario.handmade");
2425 "scenario.allow_ai_type_fallback");
2430 "scenario.datafile");
2433 "scenario.ruleset_locked");
2436 "scenario.ruleset_caps");
2548 "map.have_resources");
2593 const char *spec_sprite;
2602 if (
nullptr != ptile->spec_sprite) {
2603 ptile->spec_sprite =
fc_strdup(spec_sprite);
2605 if (label !=
nullptr) {
2630 if (ptile->spec_sprite) {
2634 if (ptile->label !=
nullptr) {
2656 loading->
file,
"map.e%02d_%04d", j);
2695 for (l = 0; l < 4; l++) {
2703 saving->
file,
"map.e%02d_%04d", j);
2717 const char SEPARATOR =
'#';
2718 const char *nation_names;
2721 int i, startpos_count;
2729 if (0 == startpos_count) {
2734 for (i = 0; i < startpos_count; i++) {
2738 log_sg(
"Warning: Undefined coordinates for startpos %d", i);
2743 if (
nullptr == ptile) {
2744 qCritical(
"Start position native coordinates (%d, %d) do not exist "
2745 "in this map. Skipping...",
2751 "map.startpos%d.exclude", i);
2757 if (
nullptr != nation_names &&
'\0' != nation_names[0]) {
2758 const size_t size = qstrlen(nation_names) + 1;
2759 char buf[
size], *start, *end;
2761 memcpy(buf, nation_names,
size);
2762 for (start = buf - 1;
nullptr != start; start = end) {
2764 if ((end = strchr(start, SEPARATOR))) {
2776 qDebug(
"Missing nation \"%s\".", start);
2784 qDebug(
"Number of starts (%d) are lower than rules.max_players "
2785 "(%d), lowering rules.max_players.",
2802 const char SEPARATOR =
'#';
2813 "map.startpos_count");
2827 "map.startpos%d.exclude", i);
2834 nation_names[0] =
'\0';
2835 for (
const auto *pnation : qAsConst(*
nations)) {
2836 if (
'\0' == nation_names[0]) {
2838 sizeof(nation_names));
2840 cat_snprintf(nation_names,
sizeof(nation_names),
"%c%s", SEPARATOR,
2845 "map.startpos%d.nations", i);
2872 const char *buffer1 =
2874 const char *buffer2 =
2876 const char *buffer3 =
2879 loading->
file,
nullptr,
"map.placing%04d", y);
2881 loading->
file,
nullptr,
"map.infra_turns%04d", y);
2882 const char *ptr1 = buffer1;
2883 const char *ptr2 = buffer2;
2884 const char *ptr3 = buffer3;
2885 const char *ptr_placing = buffer_placing;
2886 const char *ptr_turns = buffer_turns;
2898 struct player *owner =
nullptr;
2899 struct player *eowner =
nullptr;
2904 scanin(
const_cast<char **
>(&ptr1), n, token1,
sizeof(token1));
2906 "Map size not correct (map.owner%d).", y);
2907 if (strcmp(token1,
"-") == 0) {
2911 "Got map owner %s in (%d, %d).", token1, x, y);
2914 scanin(
const_cast<char **
>(&ptr2), n, token2,
sizeof(token2));
2916 "Map size not correct (map.source%d).", y);
2917 if (strcmp(token2,
"-") == 0) {
2921 "Got map source %s in (%d, %d).", token2, x, y);
2924 scanin(
const_cast<char **
>(&ptr3), n, token3,
sizeof(token3));
2926 "Map size not correct (map.eowner%d).", y);
2927 if (strcmp(token3,
"-") == 0) {
2931 "Got base owner %s in (%d, %d).", token3, x, y);
2935 if (ptr_placing !=
nullptr) {
2937 scanin(
const_cast<char **
>(&ptr_placing), n, token_placing,
2938 sizeof(token_placing));
2940 "Map size not correct (map.placing%d).", y);
2941 if (strcmp(token_placing,
"-") == 0) {
2945 "Got placing extra %s in (%d, %d).", token_placing,
2953 if (ptr_turns !=
nullptr) {
2955 scanin(
const_cast<char **
>(&ptr_turns), n, token_turns,
2956 sizeof(token_turns));
2958 "Map size not correct (map.infra_turns%d).", y);
2960 "Got infra_turns %s in (%d, %d).", token_turns, x, y);
3001 qstrcpy(token,
"-");
3006 strcat(line, token);
3022 if (ptile->
claimer ==
nullptr) {
3023 qstrcpy(token,
"-");
3027 strcat(line, token);
3044 qstrcpy(token,
"-");
3049 strcat(line, token);
3065 if (ptile->
placing ==
nullptr) {
3066 qstrcpy(token,
"-");
3071 strcat(line, token);
3087 if (ptile->
placing !=
nullptr) {
3092 strcat(line, token);
3112 "City worked map not loaded!");
3117 const char *buffer =
3119 const char *ptr = buffer;
3122 "Savegame corrupt - map line %d not found.", y);
3128 scanin(
const_cast<char **
>(&ptr), n, token,
sizeof(token));
3130 "Savegame corrupt - map size not correct.");
3131 if (strcmp(token,
"-") == 0) {
3135 "Savegame corrupt - got tile worked by city "
3136 "id=%s in (%d, %d).",
3170 if (pcity ==
nullptr) {
3171 qstrcpy(token,
"-");
3175 strcat(line, token);
3204 for (l = 0; l <
lines; l++) {
3205 for (j = 0; j < 8; j++) {
3206 for (i = 0; i < 4; i++) {
3214 loading->
file,
"map.k%02d_%04d", l * 8 + j);
3234 & (1u << (p % 32))) {
3264 QScopedArrayPointer<unsigned int> known(
3285 for (l = 0; l <
lines; l++) {
3286 for (j = 0; j < 8; j++) {
3287 for (i = 0; i < 4; i++) {
3297 saving->
file,
"map.k%02d_%04d", l * 8 + j);
3322 bool shuffle_loaded =
true;
3336 "Invalid length for 'players.destroyed_wonders' "
3338 (
unsigned long) qstrlen(str),
3342 "Undefined value '%c' within "
3343 "'players.destroyed_wonders'.",
3346 if (str[k] ==
'1') {
3357 loading->
file,
server.identity_number,
"players.identity_number_used");
3367 struct rgbcolor *prgbcolor =
nullptr;
3384 log_sg(
"Game has started, yet player %d has no color defined.",
3388 qDebug(
"No color defined for player %d.", pslot_id);
3397 sg_failure_ret(pplayer !=
nullptr,
"Invalid AI type: '%s'!", str);
3422 "player%d.multiplier%d.val",
3430 qDebug(
"Player %d had illegal value for multiplier \"%s\": "
3431 "was %d, clamped to %d",
3445 qDebug(
"Player %d had illegal value for multiplier_target "
3446 " \"%s\": was %d, clamped to %d",
3455 loading->
file,
false,
"player%d.border_vision",
3464 "The value of players.nplayers "
3465 "(%d) from the loaded game does not match the number of "
3466 "players present (%d).",
3479 "Invalid team definition for player %s (nb %d).",
3495 "players.shuffled_player_%d", 0)
3505 shuffled_player_set[plrid] =
false;
3508 shuffled_players[plrid] = -1;
3515 loading->
file, -1,
"players.shuffled_player_%d", i);
3517 if (shuffle == -1) {
3518 log_sg(
"Missing player shuffle information (index %d) "
3519 "- reshuffle player list!",
3521 shuffle_loaded =
false;
3523 }
else if (shuffled_player_set[shuffle]) {
3524 log_sg(
"Player shuffle %d used two times "
3525 "- reshuffle player list!",
3527 shuffle_loaded =
false;
3531 shuffled_player_set[shuffle] =
true;
3534 shuffled_players[i] = shuffle;
3537 if (shuffle_loaded) {
3542 if (!shuffled_player_set[i]) {
3543 shuffled_players[shuffle_index] = i;
3549 "Invalid player shuffle data!");
3552 #ifdef FREECIV_DEBUG
3557 log_debug(
"[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
3558 plrid, shuffled_players[plrid], plrid,
3559 shuffled_player_set[plrid] ?
"is used" :
"-");
3569 if (!shuffle_loaded) {
3600 if (
is_ai(pplayer)) {
3601 qInfo(
_(
"%s has been added as %s level AI-controlled player "
3604 ai_level_translated_name(pplayer->ai_common.skill_level),
3607 qInfo(
_(
"%s has been added as human player."),
player_name(pplayer));
3632 pplayer,
pick_a_nation(
nullptr,
false,
true, NOT_A_BARBARIAN));
3634 log_sg(
_(
"%s had invalid nation; changing to %s."),
3652 log_sg(
"Illegal alliance structure detected: "
3653 "%s alliance to %s reduced to peace treaty.",
3671 pcity,
nullptr,
nullptr, &(pcity->illness_trade),
nullptr);
3705 BV_CLR_ALL(pplayer->server.really_gives_vision);
3717 loading->
file,
false,
3718 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
3738 log_sg(
"Unit doing illegal activity in savegame!");
3740 "Activity: %s, Target: %s", unit_activity_name(punit->activity),
3743 punit->activity = ACTIVITY_IDLE;
3784 char destroyed[
B_LAST + 1];
3800 "players.identity_number_used");
3808 "players.shuffled_player_%d", i);
3839 const char *barb_str;
3852 "player%d.username", plrno));
3854 "player%d.unassigned_user", plrno),
3858 "player%d.orig_username", plrno));
3861 "player%d.ranked_username", plrno));
3863 "player%d.unassigned_ranked", plrno),
3866 "player%d.delegation_username", plrno);
3876 for (i = 0; i < nval; i++) {
3877 const char *sval = slist[i];
3878 enum plr_flag_id fid = plr_flag_id_by_name(sval,
fc_strcasecmp);
3887 if (plr->
nation !=
nullptr) {
3894 sg_failure_ret(gov !=
nullptr,
"Player%d: unsupported government \"%s\".",
3901 if (str !=
nullptr) {
3907 loading->
file, -1,
"player%d.revolution_finishes", plrno);
3910 &plr->
server.got_first_city,
3911 "player%d.got_first_city", plrno),
3924 fc_snprintf(buf,
sizeof(buf),
"player%d.diplstate%d", plrno, i);
3927 loading->
file, DS_WAR, diplstate_type,
"%s.current", buf));
3929 loading->
file, DS_WAR, diplstate_type,
"%s.closest", buf));
3931 loading->
file, 0,
"%s.first_contact_turn", buf);
3935 loading->
file, 0,
"%s.has_reason_to_cancel", buf);
3937 loading->
file, 0,
"%s.contact_turns_left", buf);
3953 fc_snprintf(buf,
sizeof(buf),
"player%d.ai%d", plrno,
3971 "player%d.ai.level", plrno);
3972 if (
level !=
nullptr) {
3988 "player%d.ai.skill_level", plrno));
3992 "player%d.ai.barb_type", plrno);
3997 log_sg(
"Player%d: Invalid barbarian type \"%s\". "
3998 "Changed to \"None\".",
4020 if (style ==
nullptr) {
4022 log_sg(
"Player%d: unsupported city_style_name \"%s\". "
4023 "Changed to \"%s\".",
4030 "player%d.idle_turns", plrno),
4033 plr->
is_male = strcmp(
"male", kind) == 0;
4035 "player%d.is_alive", plrno),
4038 "player%d.turns_alive", plrno),
4041 "player%d.last_war", plrno),
4044 loading->
file,
false,
"player%d.phase_done", plrno);
4046 "player%d.gold", plrno),
4049 "player%d.rates.tax", plrno),
4052 "player%d.rates.science", plrno),
4055 "player%d.rates.luxury", plrno),
4058 loading->
file, 0,
"player%d.research.bulbs_last_turn", plrno);
4062 for (i = 0; i < loading->
trait.
size; i++) {
4065 if (trait_is_valid(tr)) {
4069 "player%d.trait%d.val", plrno, i),
4074 "player%d.trait%d.mod", plrno, i),
4086 "player%d.achievement_count", plrno);
4089 for (i = 0; i < count; i++) {
4095 "player%d.achievement%d.name", plrno, i);
4101 "player%d.achievement%d.first",
4107 "Multiple players listed as first to get achievement \"%s\".",
4147 loading->
file, 0,
"score%d.landarea", plrno);
4149 loading->
file, 0,
"score%d.settledarea", plrno);
4151 loading->
file, 0,
"score%d.population", plrno);
4157 loading->
file, 0,
"score%d.pollution", plrno);
4159 loading->
file, 0,
"score%d.literacy", plrno);
4165 loading->
file, 0,
"score%d.spaceship", plrno);
4167 loading->
file, 0,
"score%d.units_built", plrno);
4169 loading->
file, 0,
"score%d.units_killed", plrno);
4171 loading->
file, 0,
"score%d.units_lost", plrno);
4184 fc_snprintf(prefix,
sizeof(prefix),
"player%d.spaceship", plrno);
4193 "%s.structurals", prefix),
4196 "%s.components", prefix),
4199 "%s.modules", prefix),
4205 "%s.propulsion", prefix),
4208 "%s.habitation", prefix),
4211 "%s.life_support", prefix),
4214 "%s.solar_panels", prefix),
4219 st !=
nullptr,
"%s",
4223 "Undefined value '%c' within '%s.structure'.", st[i],
4226 if (!(st[i] ==
'0'))
4233 "%s.launch_year", prefix),
4243 if (str !=
nullptr) {
4246 "Invalid length for 'player%d.lost_wonders' "
4248 plrno, (
unsigned long) qstrlen(str),
4252 "Undefined value '%c' within "
4253 "'player%d.lost_wonders'.",
4256 if (str[k] ==
'1') {
4267 "player%d.history", plrno);
4269 "player%d.hut_count", plrno);
4279 const char *flag_names[PLRF_COUNT];
4286 for (i = 0; i < PLRF_COUNT; i++) {
4288 flag_names[set_count++] =
4289 plr_flag_id_name(
static_cast<plr_flag_id
>(i));
4294 "player%d.flags", plrno);
4302 "player%d.unassigned_user", plrno);
4303 if (plr->
rgb !=
nullptr) {
4308 log_sg(
"Game has started, yet player %d has no color defined.", plrno);
4312 "player%d.ranked_username", plrno);
4314 "player%d.unassigned_ranked", plrno);
4316 "player%d.orig_username", plrno);
4320 "player%d.delegation_username", plrno);
4322 "player%d.nation", plrno);
4324 "player%d.team_no", plrno);
4328 "player%d.government_name", plrno);
4333 "player%d.target_government_name", plrno);
4337 "player%d.style_by_name", plrno);
4363 fc_snprintf(buf,
sizeof(buf),
"player%d.diplstate%d", plrno, i);
4370 "%s.first_contact_turn", buf);
4373 "%s.has_reason_to_cancel", buf);
4375 "%s.contact_turns_left", buf);
4379 "%s.gives_shared_vision", buf);
4388 "player%d.ai%d.love", plrno, i);
4399 for (k = 0; k < i; k++) {
4401 "player%d.multiplier%d.val", plrno, k);
4403 "player%d.multiplier%d.target", plrno, k);
4407 "player%d.ai.level", plrno);
4410 "player%d.ai.barb_type", plrno);
4416 "player%d.rates.science", plrno);
4418 "player%d.rates.luxury", plrno);
4420 "player%d.research.bulbs_last_turn", plrno);
4427 for (tr = trait_begin(), j = 0; tr != trait_end();
4428 tr = trait_next(tr), j++) {
4430 "player%d.trait%d.val", plrno, j);
4432 "player%d.trait%d.mod", plrno, j);
4444 "player%d.achievement%d.name", plrno, j);
4445 if (pach->first == plr) {
4447 "player%d.achievement%d.first", plrno, j);
4450 "player%d.achievement%d.first", plrno, j);
4462 "player%d.got_first_city", plrno);
4464 "player%d.revolution_finishes", plrno);
4476 "score%d.specialists%d", plrno, sp);
4487 "score%d.settledarea", plrno);
4489 "score%d.population", plrno);
4502 "score%d.units_built", plrno);
4504 "score%d.units_killed", plrno);
4506 "score%d.units_lost", plrno);
4519 fc_snprintf(buf,
sizeof(buf),
"player%d.spaceship", plrno);
4566 "player%d.border_vision", plrno);
4585 if (!plr->
is_alive && ncities > 0) {
4586 log_sg(
"'player%d.ncities' = %d for dead player!", plrno, ncities);
4590 if (!plr->
server.got_first_city && ncities > 0) {
4592 plr->
server.got_first_city =
true;
4596 for (i = 0; i < ncities; i++) {
4600 fc_snprintf(buf,
sizeof(buf),
"player%d.c%d", plrno, i);
4608 sg_failure_ret(
false,
"Error loading city %d of player %d.", i, plrno);
4628 city_list_append(plr->
cities, pcity);
4631 tasks_handled =
false;
4632 for (i = 0; !tasks_handled; i++) {
4634 struct city *pcity =
nullptr;
4637 "player%d.task%d.city", plrno, i);
4639 if (city_id != -1) {
4643 if (pcity !=
nullptr) {
4649 "player%d.task%d.x", plrno, i);
4651 "player%d.task%d.y", plrno, i);
4660 "Unknown workertask activity %s", str);
4665 if (strcmp(
"-", str)) {
4671 ptask->
tgt =
nullptr;
4673 if (ptask->
act == ACTIVITY_IRRIGATE) {
4674 ptask->
act = ACTIVITY_CULTIVATE;
4675 }
else if (ptask->
act == ACTIVITY_MINE) {
4676 ptask->
act = ACTIVITY_MINE;
4681 loading->
file, 1,
"player%d.task%d.want", plrno, i);
4683 worker_task_list_append(pcity->
task_reqs, ptask);
4685 tasks_handled =
true;
4694 struct city *pcity,
const char *citystr)
4697 const char *kind, *
name, *str;
4698 int id, i, repair, sp_count = 0, workers = 0, value;
4701 const char *stylename;
4710 "%s has invalid center tile (%d, %d)", citystr,
nat_x,
4713 "%s duplicates city (%d, %d)", citystr,
nat_x,
nat_y);
4717 "%s.name", citystr));
4724 "%s.original", citystr);
4726 if (
nullptr != past) {
4735 "Invalid city size: %d, set to %d", value,
size);
4747 for (i = 0; partner != 0; i++) {
4754 const char *good_str;
4758 trade_route_list_append(pcity->
routes, proute);
4764 "No traderoute direction found for %s", citystr);
4767 "Illegal route direction %s",
dir);
4779 "%s.food_stock", citystr),
4782 "%s.shield_stock", citystr),
4790 "%s.was_happy", citystr);
4793 "%s.turn_plague", citystr);
4796 "%s.anarchy", citystr),
4804 "%s.turn_founded", citystr),
4807 "%s.did_buy", citystr),
4811 loading->
file, 0,
"%s.bought_shields", citystr);
4813 "%s.did_sell", citystr),
4817 "%s.turn_last_built", citystr),
4826 "%s.currently_building: unknown \"%s\" \"%s\".", citystr,
4833 "%s.changed_from: unknown \"%s\" \"%s\".", citystr, kind,
4838 "%s.before_change_shields", citystr);
4840 loading->
file, 0,
"%s.caravan_shields", citystr);
4842 loading->
file, 0,
"%s.disbanded_shields", citystr);
4844 loading->
file, 0,
"%s.last_turns_shield_surplus", citystr);
4848 if (stylename !=
nullptr) {
4853 if (pcity->
style < 0) {
4857 pcity->
server.synced =
false;
4868 "Invalid length of '%s.improvements' (%lu ~= %lu).",
4869 citystr, (
unsigned long) qstrlen(str),
4873 "Undefined value '%c' within '%s.improvements'.", str[i],
4887 "No worked tiles map defined.");
4895 "%s.city_radius_sq", citystr);
4904 #ifdef FREECIV_DEBUG
4916 if (
nullptr != pwork) {
4917 log_sg(
"[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
4918 "(%d,%d) [%d]; repairing ",
4927 log_sg(
"[%s] city center of '%s' (%d,%d) [%d] is empty; repairing ",
4940 log_sg(
"[%s] size mismatch for '%s' (%d,%d): size [%d] != "
4941 "(workers [%d] - 1 + specialists [%d]",
4954 for (i = 0; i < CITYO_LAST; i++) {
4964 "%s.rally_point_length", citystr);
4969 const char *rally_orders, *rally_dirs, *rally_activities;
4973 loading->
file,
false,
"%s.rally_point_persistent", citystr);
4975 loading->
file,
false,
"%s.rally_point_vigilant", citystr);
4978 loading->
file,
"",
"%s.rally_point_orders", citystr);
4980 loading->
file,
"",
"%s.rally_point_dirs", citystr);
4982 loading->
file,
"",
"%s.rally_point_activities", citystr);
4984 for (i = 0; i <
len; i++) {
4987 if (rally_orders[i] ==
'\0' || rally_dirs[i] ==
'\0'
4988 || rally_activities[i] ==
'\0') {
4989 log_sg(
"Invalid rally point.");
5003 if (unconverted >= 0 && unconverted < loading->
action.size) {
5008 log_sg(
"Invalid action id in order for city rally point %d",
5016 loading->
file,
NO_TARGET,
"%s.rally_point_tgt_vec,%d", citystr,
5019 loading->
file, -1,
"%s.rally_point_sub_tgt_vec,%d", citystr, i);
5039 "%s.rally_point_sub_tgt_vec", citystr);
5046 "%s.cma_enabled", citystr);
5050 for (i = 0; i <
O_LAST; i++) {
5052 loading->
file, 0,
"%s.cma_minimal_surplus,%d", citystr, i);
5054 loading->
file, 0,
"%s.factor,%d", citystr, i);
5057 loading->
file,
false,
"%s.max_growth", citystr);
5059 loading->
file,
false,
"%s.require_happy", citystr);
5061 loading->
file,
false,
"%s.allow_disorder", citystr);
5063 loading->
file,
false,
"%s.allow_specialists", citystr);
5065 loading->
file, 0,
"%s.happy_factor", citystr);
5069 for (i = 0; i <
O_LAST; i++) {
5071 "%s.cma_minimal_surplus,%d", citystr, i);
5098 const char *citystr)
5100 if (
game.
info.citizen_nationality) {
5112 log_sg(
"Citizens of an invalid nation for %s (player slot %d)!",
5119 "Invalid value for citizens of player %d in %s: %d.",
5133 log_sg(
"City size and number of citizens does not match in %s "
5134 "(%d != %d)! Repairing ...",
5148 int wlist_max_length = 0, rally_point_max_length = 0;
5157 "player%d.ncities", plrno);
5159 if (
game.
info.citizen_nationality) {
5176 if (pcity->worklist.length > wlist_max_length) {
5177 wlist_max_length = pcity->worklist.length;
5180 if (pcity->rally_point.length > rally_point_max_length) {
5181 rally_point_max_length = pcity->rally_point.length;
5184 if (
game.
info.citizen_nationality) {
5201 char impr_buf[
B_LAST + 1];
5205 fc_snprintf(buf,
sizeof(buf),
"player%d.c%d", plrno, i);
5214 "%s.original", buf);
5231 "%s.route_direction%d", buf, j);
5233 "%s.route_good%d", buf, j);
5242 route_direction_name(RDIR_BIDIRECTIONAL),
5243 "%s.route_direction%d", buf, j);
5245 "%s.route_good%d", buf, j);
5267 "%s.turn_last_built", buf);
5274 "%s.currently_building_kind", buf);
5276 "%s.currently_building_name", buf);
5280 "%s.changed_from_kind", buf);
5283 "%s.changed_from_name", buf);
5286 "%s.before_change_shields", buf);
5288 "%s.bought_shields", buf);
5290 "%s.caravan_shields", buf);
5292 "%s.disbanded_shields", buf);
5294 "%s.last_turns_shield_surplus", buf);
5302 "player%d.c%d.city_radius_sq", plrno, i);
5317 qstrlen(impr_buf) <
sizeof(impr_buf),
5318 "Invalid size of the improvement vector (%s.improvements: "
5320 buf, (
long unsigned int) qstrlen(impr_buf),
5321 (
long unsigned int)
sizeof(impr_buf));
5327 for (j = 0; j < CITYO_LAST; j++) {
5329 "%s.option%d", buf, j);
5334 if (
game.
info.citizen_nationality) {
5348 "%s.rally_point_length", buf);
5349 if (pcity->rally_point.length) {
5350 int len = pcity->rally_point.length;
5351 char orders[
len + 1], dirs[
len + 1], activities[
len + 1];
5354 int sub_targets[
len];
5357 "%s.rally_point_persistent", buf);
5359 "%s.rally_point_vigilant", buf);
5361 for (j = 0; j <
len; j++) {
5362 orders[j] =
order2char(pcity->rally_point.orders[j].order);
5364 activities[j] =
'?';
5368 switch (pcity->rally_point.orders[j].order) {
5371 dirs[j] =
dir2char(pcity->rally_point.orders[j].dir);
5374 sub_targets[j] = pcity->rally_point.orders[j].sub_target;
5379 actions[j] = pcity->rally_point.orders[j].action;
5380 targets[j] = pcity->rally_point.orders[j].target;
5381 sub_targets[j] = pcity->rally_point.orders[j].sub_target;
5388 orders[
len] = dirs[
len] = activities[
len] =
'\0';
5393 "%s.rally_point_activities", buf);
5396 "%s.rally_point_action_vec", buf);
5399 for (j =
len; j < rally_point_max_length; j++) {
5405 "%s.rally_point_tgt_vec", buf);
5408 for (j =
len; j < rally_point_max_length; j++) {
5410 "%s.rally_point_tgt_vec,%d", buf, j);
5414 "%s.rally_point_sub_tgt_vec", buf);
5417 for (j =
len; j < rally_point_max_length; j++) {
5439 for (j = 1; j < rally_point_max_length; j++) {
5447 for (j = 1; j < rally_point_max_length; j++) {
5449 "%s.rally_point_tgt_vec,%d", buf, j);
5455 for (j = 1; j < rally_point_max_length; j++) {
5462 "%s.cma_enabled", buf);
5463 if (pcity->cm_parameter) {
5465 pcity->cm_parameter->minimal_surplus,
O_LAST,
5466 "%s.cma_minimal_surplus", buf);
5468 O_LAST,
"%s.cma_factor", buf);
5470 "%s.max_growth", buf);
5472 "%s.require_happy", buf);
5474 "%s.allow_disorder", buf);
5476 pcity->cm_parameter->allow_specialists,
5477 "%s.allow_specialists", buf);
5479 "%s.happy_factor", buf);
5483 memset(zeros, 0,
sizeof(zeros));
5485 "%s.cma_minimal_surplus", buf);
5512 "player%d.task%d.activity", plrno, i);
5513 if (ptask->tgt !=
nullptr) {
5515 "player%d.task%d.target", plrno, i);
5544 if (!plr->
is_alive && nunits > 0) {
5545 log_sg(
"'player%d.nunits' = %d for dead player!", plrno, nunits);
5549 for (i = 0; i < nunits; i++) {
5557 fc_snprintf(buf,
sizeof(buf),
"player%d.u%d", plrno, i);
5561 sg_failure_ret(type !=
nullptr,
"%s: unknown unit type \"%s\".", buf,
5568 sg_failure_ret(
false,
"Error loading unit %d of player %d.", i, plrno);
5590 unit_list_append(plr->
units, punit);
5606 struct unit *punit,
const char *unitstr)
5609 enum unit_activity activity;
5615 const char *facing_str;
5636 if (facing_str[0] !=
'x') {
5640 enum direction8 facing =
char2dir(facing_str[0]);
5642 if (direction8_is_valid(facing)) {
5645 qCritical(
"Illegal unit orientation '%s'", facing_str);
5652 "%s.nationality", unitstr);
5660 "%s.homecity", unitstr),
5665 punit->
name = QString::fromUtf8(
name);
5669 "%s.moves", unitstr),
5683 if (activity == ACTIVITY_PATROL_UNUSED) {
5691 activity = ACTIVITY_IDLE;
5697 if (extra_id != -2) {
5698 if (extra_id >= 0 && extra_id < loading->extra.size) {
5701 }
else if (activity == ACTIVITY_IRRIGATE) {
5704 if (tgt !=
nullptr) {
5709 }
else if (activity == ACTIVITY_MINE) {
5712 if (tgt !=
nullptr) {
5725 "%s.activity_count", unitstr),
5730 loading->
file, ACTIVITY_IDLE,
"%s.changed_from", unitstr));
5733 "%s.changed_from_tgt", unitstr);
5735 if (extra_id != -2) {
5736 if (extra_id >= 0 && extra_id < loading->extra.size) {
5745 loading->
file,
S_LAST,
"%s.changed_from_target", unitstr));
5756 if (tgt !=
nullptr) {
5764 if (tgt !=
nullptr) {
5769 }
else if (punit->
changed_from == ACTIVITY_POLLUTION) {
5772 if (tgt !=
nullptr) {
5780 if (tgt !=
nullptr) {
5789 loading->
file, 0,
"%s.changed_from_count", unitstr);
5796 if (activity == ACTIVITY_SENTRY) {
5809 if (punit->
veteran >= levels) {
5815 loading->
file, (punit->
moves_left == 0),
"%s.done_moving", unitstr);
5843 "%s.server_side_agent", unitstr);
5844 if (unconverted >= 0 && unconverted < loading->ssa.size) {
5848 log_sg(
"Invalid server side agent %d for unit %d", unconverted,
5865 loading->
file,
false,
"%s.paradropped", unitstr);
5868 if (str[0] !=
'\0') {
5889 "%s.action_decision", unitstr),
5892 if (unconverted >= 0 && unconverted < loading->act_dec.size) {
5897 log_sg(
"Invalid action decision want for unit %d", punit->
id);
5907 "%s.action_decision_tile_x", unitstr)
5909 "%s.action_decision_tile_y", unitstr)) {
5915 log_sg(
"Bad action_decision_tile for unit %d", punit->
id);
5931 "%s.orders_length", unitstr);
5933 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
5938 loading->
file, 0,
"%s.orders_index", unitstr);
5940 loading->
file,
false,
"%s.orders_repeat", unitstr);
5942 loading->
file,
false,
"%s.orders_vigilant", unitstr);
5945 "%s.orders_list", unitstr);
5947 "%s.dir_list", unitstr);
5949 "%s.activity_list", unitstr);
5952 for (j = 0; j <
len; j++) {
5954 bool action_wants_extra =
false;
5957 if (orders_unitstr[j] ==
'\0' || dir_unitstr[j] ==
'\0'
5958 || act_unitstr[j] ==
'\0') {
5959 log_sg(
"Invalid unit orders.");
5970 if (unconverted >= 0 && unconverted < loading->
action.size) {
5975 log_sg(
"Invalid action id in order for unit %d", punit->
id);
5983 && !direction8_is_valid(
order->dir))
5985 && !direction8_is_valid(
order->dir))
5989 &&
order->activity == ACTIVITY_LAST)) {
6000 loading->
file, -1,
"%s.sub_tgt_vec,%d", unitstr, j);
6010 "Cannot find building %d for %s to %s", order_sub_tgt,
6015 order->sub_target = order_sub_tgt;
6020 if (order_sub_tgt ==
A_NONE
6024 log_sg(
"Cannot find tech %d for %s to steal", order_sub_tgt,
6028 order->sub_target = order_sub_tgt;
6032 case ASTK_EXTRA_NOT_THERE:
6034 action_wants_extra =
true;
6039 "Specified sub target for action %d unsupported.",
6045 "Bad action action %d.",
order->action);
6051 enum unit_activity act;
6053 if (order_sub_tgt < 0 || order_sub_tgt >= loading->
extra.
size) {
6055 log_sg(
"Cannot find extra %d for %s to build", order_sub_tgt,
6061 order->sub_target = order_sub_tgt;
6065 if (action_wants_extra) {
6068 act =
order->activity;
6071 if (unit_activity_is_valid(act)
6081 if (order_sub_tgt != -1) {
6083 "Unexpected sub_target %d (expected %d) for order type %d",
6084 order_sub_tgt, -1,
order->order);
6127 if (!plr->
is_alive && nunits > 0) {
6128 log_sg(
"'player%d.nunits' = %d for dead player!", plrno, nunits);
6132 for (i = 0; i < nunits; i++) {
6133 int id_unit, id_trans;
6134 struct unit *punit, *ptrans;
6137 "player%d.u%d.id", plrno, i);
6142 loading->
file, -1,
"player%d.u%d.transported_by", plrno, i);
6143 if (id_trans == -1) {
6165 int longest_order = 0;
6177 if (punit->has_orders) {
6178 if (longest_order < punit->
orders.length) {
6179 longest_order = punit->orders.length;
6188 char dirbuf[2] =
" ";
6193 dirbuf[0] =
dir2char(punit->facing);
6201 if (
game.
info.citizen_nationality) {
6204 "%s.nationality", buf);
6212 "%s.type_by_name", buf);
6216 "%s.activity_count", buf);
6217 if (punit->activity_target ==
nullptr) {
6221 "%s.activity_tgt", buf);
6227 "%s.changed_from_count", buf);
6228 if (punit->changed_from_target ==
nullptr) {
6233 "%s.changed_from_tgt", buf);
6245 if (punit->goto_tile) {
6258 "%s.server_side_agent", buf);
6273 "%s.transported_by", buf);
6274 if (punit->carrying !=
nullptr) {
6276 "%s.carrying", buf);
6282 "%s.action_decision", buf);
6286 if (punit->action_decision_tile) {
6301 if (punit->has_orders) {
6302 int len = punit->orders.length;
6303 char orders_buf[
len + 1], dir_buf[
len + 1];
6304 char act_buf[
len + 1];
6305 int action_buf[
len];
6307 int sub_tgt_vec[
len];
6313 "%s.orders_index", buf);
6315 "%s.orders_repeat", buf);
6317 "%s.orders_vigilant", buf);
6319 for (j = 0; j <
len; j++) {
6320 orders_buf[j] =
order2char(punit->orders.list[j].order);
6324 sub_tgt_vec[j] = -1;
6326 switch (punit->orders.list[j].order) {
6329 dir_buf[j] =
dir2char(punit->orders.list[j].dir);
6332 sub_tgt_vec[j] = punit->orders.list[j].sub_target;
6336 action_buf[j] = punit->orders.list[j].action;
6337 tgt_vec[j] = punit->orders.list[j].target;
6338 sub_tgt_vec[j] = punit->orders.list[j].sub_target;
6345 orders_buf[
len] = dir_buf[
len] = act_buf[
len] =
'\0';
6355 for (j = last_order; j < longest_order; j++) {
6362 for (j = last_order; j < longest_order; j++) {
6367 "%s.sub_tgt_vec", buf);
6370 for (j = last_order; j < longest_order; j++) {
6390 for (j = 1; j < longest_order; j++) {
6396 for (j = 1; j < longest_order; j++) {
6402 for (j = 1; j < longest_order; j++) {
6428 loading->
file, 0,
"player%d.attribute_v2_block_length", plrno);
6431 log_sg(
"player%d.attribute_v2_block_length=%d too small", plrno,
length);
6433 log_sg(
"player%d.attribute_v2_block_length=%d too big (max %d)", plrno,
6437 size_t actual_length;
6442 loading->
file, "ed_length,
6443 "player%d.attribute_v2_block_length_quoted", plrno),
6446 "player%d.attribute_v2_block_parts",
6450 quoted =
new char[quoted_length + 1];
6453 for (part_nr = 0; part_nr <
parts; part_nr++) {
6455 loading->
file,
"player%d.attribute_v2_block_data.part%d", plrno,
6458 log_sg(
"attribute_v2_block_parts=%d actual=%d",
parts, part_nr);
6461 log_debug(
"attribute_v2_block_length_quoted=%lu have=%lu part=%lu",
6462 (
unsigned long) quoted_length,
6463 (
unsigned long) qstrlen(quoted),
6464 (
unsigned long) qstrlen(current));
6465 fc_assert(strlen(quoted) + qstrlen(current) <= quoted_length);
6466 strcat(quoted, current);
6469 "attribute_v2_block_length_quoted=%lu actual=%lu",
6470 (
unsigned long) quoted_length,
6471 (
unsigned long) qstrlen(quoted));
6496 #define PART_SIZE (3 * 256)
6497 #define PART_ADJUST (3)
6501 int current_part_nr;
6504 char *quoted_at = strchr(quoted,
':');
6505 size_t bytes_left = qstrlen(quoted);
6506 size_t bytes_at_colon = 1 + (quoted_at - quoted);
6507 size_t bytes_adjust = bytes_at_colon %
PART_ADJUST;
6510 "player%d.attribute_v2_block_length", plrno);
6512 "player%d.attribute_v2_block_length_quoted", plrno);
6517 if ((bytes_left - bytes_adjust) >
PART_SIZE) {
6525 "player%d.attribute_v2_block_parts", plrno);
6528 size_t size_of_current_part =
PART_SIZE + bytes_adjust;
6531 memcpy(part, quoted, size_of_current_part);
6532 part[size_of_current_part] =
'\0';
6534 "player%d.attribute_v2_block_data.part%d", plrno,
6536 bytes_left -= size_of_current_part;
6537 quoted_at = "ed[size_of_current_part];
6538 current_part_nr = 1;
6541 current_part_nr = 0;
6544 for (; current_part_nr <
parts; current_part_nr++) {
6545 size_t size_of_current_part =
MIN(bytes_left,
PART_SIZE);
6547 memcpy(part, quoted_at, size_of_current_part);
6548 part[size_of_current_part] =
'\0';
6550 "player%d.attribute_v2_block_data.part%d", plrno,
6552 bytes_left -= size_of_current_part;
6553 quoted_at = "ed_at[size_of_current_part];
6570 "player%d.dc_total", plrno);
6572 bool someone_alive =
false;
6577 if (
game.
server.revealmap & REVEAL_MAP_DEAD) {
6580 if (pteam_member->is_alive) {
6581 someone_alive =
true;
6587 if (!someone_alive) {
6593 if (-1 == total_ncities || !
game.
info.fogofwar
6595 "game.save_private_map")) {
6611 if (
nullptr != pcity) {
6625 loading->
file,
"player%d.map_t%04d", plrno);
6633 loading->
file,
"player%d.map_e%02d_%04d", plrno, j);
6658 loading->
file,
"player%d.map_owner%04d", plrno, y);
6660 loading->
file,
"player%d.extras_owner%04d", plrno, y);
6661 const char *ptr = buffer;
6662 const char *ptr2 = buffer2;
6665 "Savegame corrupt - map line %d not found.", y);
6672 scanin(
const_cast<char **
>(&ptr), n, token,
sizeof(token));
6674 "Savegame corrupt - map size not correct.");
6675 if (strcmp(token,
"-") == 0) {
6679 "Savegame corrupt - got tile owner=%s in (%d, %d).",
6683 scanin(
const_cast<char **
>(&ptr2), n, token2,
sizeof(token2));
6685 "Savegame corrupt - map size not correct.");
6686 if (strcmp(token2,
"-") == 0) {
6691 "Savegame corrupt - got extras owner=%s in (%d, %d).", token,
6701 for (i = 0; i < 4; i++) {
6707 loading->
file,
"player%d.map_u%02d_%04d", plrno, i);
6712 loading->
file,
"player%d.map_u%02d_%04d", plrno, i);
6717 for (i = 0; i < total_ncities; i++) {
6720 fc_snprintf(buf,
sizeof(buf),
"player%d.dc%d", plrno, i);
6729 log_sg(
"Skipping seen city %d for player %d.", i, plrno);
6743 if (
nullptr != pcity) {
6762 const char *citystr)
6768 const char *stylename;
6769 enum capital_type cap;
6777 "%s invalid tile (%d,%d)", citystr,
nat_x,
nat_y);
6784 "%s has invalid owner (%d); skipping.", citystr,
id);
6790 "%s has invalid id (%d); skipping.", citystr,
id);
6797 "Invalid city size: %d; set to %d.",
size, city_size);
6805 "Invalid length of '%s.improvements' (%lu ~= %lu).",
6806 citystr, (
unsigned long) qstrlen(str),
6810 "Undefined value '%c' within '%s.improvements'.", str[i],
6825 "%s.name", citystr));
6828 "%s.occupied", citystr);
6834 "%s.unhappy", citystr);
6837 if (stylename !=
nullptr) {
6842 if (pdcity->
style < 0) {
6847 "%s.city_image", citystr);
6851 "%s.capital", citystr),
6854 if (capital_type_is_valid(cap)) {
6857 pdcity->
capital = CAPITAL_NOT;
6882 saving->
file,
"player%d.map_t%04d", plrno);
6897 if (plrtile ==
nullptr || plrtile->
owner ==
nullptr) {
6898 qstrcpy(token,
"-");
6903 strcat(line, token);
6921 if (plrtile ==
nullptr || plrtile->
extras_owner ==
nullptr) {
6922 qstrcpy(token,
"-");
6927 strcat(line, token);
6943 for (l = 0; l < 4; l++) {
6955 saving->
file,
"player%d.map_e%02d_%04d", plrno, j);
6960 for (i = 0; i < 4; i++) {
6965 saving->
file,
"player%d.map_u%02d_%04d", plrno, i);
6973 char impr_buf[
B_LAST + 1];
6976 fc_snprintf(buf,
sizeof(buf),
"player%d.dc%d", plrno, i);
7016 qstrlen(impr_buf) <
sizeof(impr_buf),
7017 "Invalid size of the improvement vector (%s.improvements: "
7019 buf, (
long unsigned int) qstrlen(impr_buf),
7020 (
long unsigned int)
sizeof(impr_buf));
7046 int *vlist_research;
7049 vlist_research =
nullptr;
7062 for (i = 0; i < count; i++) {
7068 "Invalid research number %d in 'research.r%d.number'",
7075 "research.r%d.techs", i),
7078 "research.r%d.futuretech", i),
7082 "research.r%d.bulbs", i),
7086 "research.r%d.bulbs_before", i),
7093 "research.r%d.got_tech", i),
7099 "Invalid length of 'research.r%d.done' (%lu ~= %lu).", i,
7100 (
unsigned long) qstrlen(str),
7104 "Undefined value '%c' within 'research.r%d.done'.",
7107 if (str[j] ==
'1') {
7120 "research.r%d.vbs", i);
7127 delete[] vlist_research;
7128 vlist_research =
nullptr;
7148 int *vlist_research;
7150 vlist_research =
nullptr;
7158 "research.r%d.number", i);
7160 presearch.tech_goal);
7162 "research.r%d.techs", i);
7164 "research.r%d.futuretech", i);
7166 "research.r%d.bulbs_before", i);
7168 vlist_research =
new int[
game.
control.num_tech_types]();
7172 presearch.inventions[j].bulbs_researched_saved;
7177 "research.r%d.vbs", i);
7178 delete[] vlist_research;
7179 vlist_research =
nullptr;
7182 presearch.researching_saved);
7184 "research.r%d.bulbs", i);
7186 presearch.researching);
7188 "research.r%d.got_tech", i);
7256 "treaty%d.plr0", tidx))
7269 if (p0 ==
nullptr || p1 ==
nullptr) {
7270 qCritical(
"Treaty between unknown players %s and %s", plr0, plr1);
7275 treaty_list_prepend(
treaties, ptreaty);
7278 loading->
file,
nullptr,
"treaty%d.clause%d.type",
7282 enum clause_type type = clause_type_by_name(ct,
fc_strcasecmp);
7285 if (!clause_type_is_valid(type)) {
7286 qCritical(
"Invalid clause type \"%s\"", ct);
7288 struct player *pgiver =
nullptr;
7298 qCritical(
"Clause giver %s is not participant of the treaty"
7299 "between %s and %s",
7303 if (pgiver !=
nullptr) {
7307 loading->
file, 0,
"treaty%d.clause%d.value", tidx, cidx);
7316 loading->
file,
false,
"treaty%d.accept0", tidx);
7318 loading->
file,
false,
"treaty%d.accept1", tidx);
7337 fc_snprintf(tpath,
sizeof(tpath),
"treaty%d", tidx++);
7350 fc_snprintf(cpath,
sizeof(cpath),
"%s.clause%d", tpath, cidx++);
7417 int mapdef_count, i;
7429 qDebug(
"Saved map image definitions: %d.", mapdef_count);
7431 if (0 >= mapdef_count) {
7435 for (i = 0; i < mapdef_count; i++) {
7440 qDebug(
"[Mapimg %4d] Missing definition.", i);
7445 qCritical(
"Invalid map image definition %4d: %s.", i, p);
7448 qDebug(
"Mapimg %4d loaded.", i);
7496 qDebug(
"Max players lower than current players, fixing");
7507 log_sg(
"Removing %s unferried %s in %s at (%d, %d)",
7535 bool saved_ai_control =
is_ai(pplayer);
7546 if (saved_ai_control) {
7553 #ifdef FREECIV_DEBUG
7559 qCritical(
"[city id: %d] Unused worked tile at (%d, %d).",
7570 if (presearch.researching !=
A_UNSET
7574 != TECH_PREREQS_KNOWN))) {
7575 log_sg(
_(
"%s had invalid researching technology."),
7577 presearch.researching =
A_UNSET;
7579 if (presearch.tech_goal !=
A_UNSET
7583 presearch.tech_goal)
7586 log_sg(
_(
"%s had invalid technology goal."),
7588 presearch.tech_goal =
A_UNSET;
7596 int unique_count[
U_LAST];
7598 memset(unique_count, 0,
sizeof(unique_count));
7610 log_sg(
_(
"%s has multiple units of type %s though it should be "
7612 "to have only one."),
7625 punit->orders.list)) {
7626 log_sg(
"Invalid unit orders for unit %d.", punit->id);
7634 if (0 == qstrlen(
server.game_identifier)
7638 sizeof(
server.game_identifier));
bool achievement_player_has(const struct achievement *pach, const struct player *pplayer)
Has the given player got the achievement?
const char * achievement_rule_name(struct achievement *pach)
Return untranslated name of this achievement type.
struct achievement * achievement_by_rule_name(const char *name)
Returns achievement matching rule name or nullptr if there is no achievement with such name.
#define achievements_iterate_end
#define achievements_iterate(_ach_)
static struct action * actions[MAX_NUM_ACTIONS]
struct action * action_by_rule_name(const char *name)
Return the action with the given name.
const QString action_id_name_translation(action_id act_id)
Get the action name used when displaying the action in the UI.
bool action_id_exists(const action_id act_id)
Returns TRUE iff the specified action ID refers to a valid action.
const char * action_id_rule_name(action_id act_id)
Get the rule name of the action.
#define action_id_get_sub_target_kind(act_id)
#define action_id_get_activity(act_id)
void building_advisor(struct player *pplayer)
Prime pcity->server.adv.building_want[].
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Make and cache lots of calculations needed for other functions.
void adv_data_phase_done(struct player *pplayer)
Clean up our mess.
const char * ai_name(const struct ai_type *ai)
Return the name of the ai type.
int ai_type_get_count()
Return number of ai types.
#define CALL_FUNC_EACH_AI(_func,...)
#define CALL_PLR_AI_FUNC(_func, _player,...)
#define ai_type_iterate_end
#define ai_type_iterate(NAME_ai)
void ai_traits_init(struct player *pplayer)
Initialize ai traits for player.
bool BV_ISSET(const BV &bv, int bit)
bool has_capabilities(const char *us, const char *them)
This routine returns true if all the mandatory capabilities in us appear in them.
citizens citizens_nation_get(const struct city *pcity, const struct player_slot *pslot)
Get the number of citizens with the given nationality.
void citizens_nation_set(struct city *pcity, const struct player_slot *pslot, citizens count)
Set the number of citizens with the given nationality.
citizens citizens_count(const struct city *pcity)
Return the number of citizens in a city.
void citizens_init(struct city *pcity)
Initialise citizens data.
void citizens_update(struct city *pcity, struct player *plr)
void city_map_radius_sq_set(struct city *pcity, int radius_sq)
Returns the current squared radius of the city.
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_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Calculate city's illness in tenth of percent:
void city_size_set(struct city *pcity, citizens size)
Set the city size.
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Adds an improvement (and its effects) to a city.
void destroy_city_virtual(struct city *pcity)
Removes the virtual skeleton of a city.
const char * city_style_rule_name(const int style)
Return the (untranslated) rule name of the city style.
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Create virtual skeleton for a city.
citizens city_size_get(const struct city *pcity)
Get the city size.
int city_style_by_rule_name(const char *s)
Returns the city style that has the given (untranslated) rule name.
#define cities_iterate_end
#define city_list_iterate(citylist, pcity)
#define cities_iterate(pcity)
#define city_tile_iterate(_radius_sq, _city_tile, _tile)
#define output_type_iterate(output)
#define city_list_iterate_end
#define city_tile_iterate_end
#define output_type_iterate_end
void auto_arrange_workers(struct city *pcity)
Call sync_cities() to send the affected cities to the clients.
void city_repair_size(struct city *pcity, int change)
Repair the city population without affecting city size.
bool city_refresh(struct city *pcity)
Updates unit upkeeps and city internal cached data.
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Set an AI level and related quantities, with no feedback.
static struct treaty_list * treaties
struct treaty_list * get_all_treaties()
Get treaty list.
#define treaty_list_iterate(list, p)
#define treaty_list_iterate_end
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val)
Add clause to treaty.
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Initialize treaty structure between two players.
#define clause_list_iterate_end
#define clause_list_iterate(clauselist, pclause)
#define MAX_NUM_PLAYER_SLOTS
enum output_type_id Output_type_id
#define IDENTITY_NUMBER_ZERO
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
void initialize_globals()
Initialize wonder information.
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
#define GAME_DEFAULT_TIMEOUTINTINC
#define GAME_DEFAULT_SCORETURN
#define GAME_DEFAULT_TIMEOUTINT
#define GAME_DEFAULT_TIMEOUTINCMULT
#define GAME_DEFAULT_TIMEOUTINC
#define GAME_DEFAULT_RULESETDIR
#define GAME_DEFAULT_TIMEOUTCOUNTER
#define GAME_DEFAULT_PHASE_MODE
#define GAME_HARDCODED_DEFAULT_SKILL_LEVEL
struct government * government_of_player(const struct player *pplayer)
Return the government of a player.
const char * government_rule_name(const struct government *pgovern)
Return the (untranslated) rule name of the government.
struct government * government_by_rule_name(const char *name)
Returns the government that has the given (untranslated) rule name.
std::vector< government > governments
void idex_register_unit(struct world *iworld, struct unit *punit)
Register a unit into idex, with current punit->id.
void idex_register_city(struct world *iworld, struct city *pcity)
Register a city into idex, with current pcity->id.
Impr_type_id improvement_count()
Return the number of improvements.
const char * improvement_rule_name(const struct impr_type *pimprove)
Return the (untranslated) rule name of the improvement.
struct impr_type * improvement_by_rule_name(const char *name)
Does a linear search of improvement_types[].name.vernacular Returns nullptr when none match.
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
Returns whether this wonder has been destroyed.
bool wonder_is_lost(const struct player *pplayer, const struct impr_type *pimprove)
Returns whether the player has lost this wonder after having owned it (small or great).
struct impr_type * improvement_by_number(const Impr_type_id id)
Returns the improvement type for the given index/ID.
Impr_type_id improvement_index(const struct impr_type *pimprove)
Return the improvement index.
bool is_wonder(const struct impr_type *pimprove)
Returns whether improvement is some kind of wonder.
bool is_great_wonder(const struct impr_type *pimprove)
Is this building a great wonder?
#define improvement_iterate_end
#define improvement_iterate(_p)
void adv_city_free(struct city *pcity)
Free advisors related city data.
void adv_city_alloc(struct city *pcity)
Allocate advisors related city data.
#define fc_assert_msg(condition, message,...)
#define fc_assert_ret(condition)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define fc_assert_action(condition, action)
#define log_debug(message,...)
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Disallow the nation to start at the start position.
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 startpos_allows_all(const struct startpos *psp)
Returns TRUE if any nation can start here.
int map_startpos_count()
Is there start positions set for map.
struct startpos * map_startpos_new(struct tile *ptile)
Create a new start position at the given tile and return it.
struct tile * startpos_tile(const struct startpos *psp)
Returns the tile where this start position is located.
QSet< const struct nation_type * > * startpos_raw_nations(const struct startpos *psp)
Return a the nations hash, used for the property editor.
void map_init_topology()
map_init_topology needs to be called after map.topology_id is changed.
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Return the tile for the given native position.
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
void main_map_allocate()
Allocate main map and related global structures.
bool startpos_is_excluding(const struct startpos *psp)
Returns TRUE if the nations returned by startpos_raw_nations() are actually excluded from the nations...
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Allow the nation to start at the start position.
#define whole_map_iterate(_map, _tile)
#define index_to_native_pos(pnat_x, pnat_y, mindex)
#define whole_map_iterate_end
void assign_continent_numbers()
Assigns continent and ocean numbers to all tiles, and set map.num_continents and map....
void player_map_init(struct player *pplayer)
Allocate space for map, and initialise the tiles.
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Remember that tile was last seen this year.
void map_calculate_borders()
Update borders for all sources.
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Claim ownership of a single tile.
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Return whether the player knows the tile.
bool send_tile_suppression(bool now)
Suppress send_tile_info() during game_load()
void map_know_and_see_all(struct player *pplayer)
Call this function to unfog all tiles.
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Give pplayer the correct knowledge about tile; return TRUE iff knowledge changed.
void tile_claim_bases(struct tile *ptile, struct player *powner)
Claim ownership of bases on single tile.
void map_set_known(struct tile *ptile, struct player *pplayer)
Set known status of the tile.
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Returns whether the layer 'vlayer' of the tile 'ptile' is known and seen by the player 'pplayer'.
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Changes site information for player tile.
void give_shared_vision(struct player *pfrom, struct player *pto)
Starts shared vision between two players.
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...
struct vision_site * map_get_player_city(const struct tile *ptile, const struct player *pplayer)
Returns city located at given tile from player map.
bool mapimg_id2str(int id, char *str, size_t str_len)
Return the map image definition 'id' as a mapdef string.
int mapimg_count()
Return the number of map image definitions.
bool mapimg_define(const char *maparg, bool check)
Define on map image.
bool mapimg_delete(int id)
Delete a map image definition.
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 * multiplier_rule_name(const struct multiplier *pmul)
Return the (untranslated) rule name of the multiplier.
Multiplier_type_id multiplier_count()
Return number of loaded multipliers in the ruleset.
struct multiplier * multiplier_by_rule_name(const char *name)
Returns multiplier matching rule name, or nullptr if there is no multiplier with such a name.
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Returns multiplier index.
#define multipliers_iterate(_mul_)
#define multipliers_iterate_end
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
const char * nation_plural_for_player(const struct player *pplayer)
Return the (translated) plural noun of the given nation of a player.
struct nation_type * nation_by_rule_name(const char *name)
Returns the nation that has the given (untranslated) rule name (adjective).
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
#define NO_NATION_SELECTED
void event_cache_load(struct section_file *file, const char *section)
Load the event cache from a savefile.
void event_cache_save(struct section_file *file, const char *section)
Save the event cache into the savegame.
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.
struct player_slot * player_slot_by_number(int player_id)
Return the possibly unused and uninitialized player slot.
bool player_slot_is_used(const struct player_slot *pslot)
Returns TRUE is this slot is "used" i.e.
struct player * player_by_name(const char *name)
Find player by given name.
struct player * player_by_number(const int player_id)
Return struct player pointer for the given player index.
int player_number(const struct player *pplayer)
Return the player index/number/id.
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.
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players can attack each other.
int player_slot_index(const struct player_slot *pslot)
Returns the index of the player slot.
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Check if player has given flag.
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,...
int player_slot_max_used_number()
Return the highest used player slot index.
int player_index(const struct player *pplayer)
Return the player index.
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.
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Set the player's nation to the given nation (may be nullptr).
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
bool gives_shared_vision(const struct player *me, const struct player *them)
Return TRUE iff the player me gives shared vision to player them.
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 MAX_ATTRIBUTE_BLOCK
#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 set_as_human(plr)
#define players_iterate_alive_end
#define player_slots_iterate_end
#define players_iterate_alive(_pplayer)
void server_player_set_name(struct player *pplayer, const char *name)
Try to set the player name to 'name'.
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Creates a new, uninitialized, used player slot.
void assign_player_colors()
Permanently assign colors to any players that don't already have them.
void set_shuffled_players(int *shuffled_players)
Initialize the shuffled players list (as from a loaded savegame).
void player_delegation_set(struct player *pplayer, const char *username)
Define a delegation.
void fit_nationset_to_players()
Try to select a nation set that fits the current players' nations, or failing that,...
struct nation_type * pick_a_nation(const struct nation_list *choices, bool ignore_conflicts, bool needs_startpos, enum barbarian_type barb_type)
This function returns a random-ish nation that is suitable for 'barb_type' and is usable (not already...
void server_remove_player(struct player *pplayer)
This function does not close any connections attached to this player.
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Initialize ANY newly-created player on the server.
int normal_player_count()
Return the number of non-barbarian players.
void shuffle_players()
Shuffle or reshuffle the player order, storing in static variables above.
const char * player_delegation_get(const struct player *pplayer)
Returns the username that control of the player is delegated to, if any.
#define shuffled_players_iterate_end
#define shuffled_players_iterate(NAME_pplayer)
std::mt19937 & fc_rand_state()
Returns a reference to the current random generator state; eg for save/restore.
void fc_rand_set_state(const std::mt19937 &state)
Replace current rand_state with user-supplied; eg for save/restore.
void fc_rand_seed(std::mt19937 &gen)
Seeds the given generator with a random value.
struct section_file * secfile_load(const QString &filename, bool allow_duplicates)
Create a section file from a file.
const char * secfile_error()
Returns the last error which occurred in a string.
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
Lookup a integer value in the secfile.
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
Returns the entry at "fullpath" or nullptr if not matched.
int * secfile_lookup_int_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Lookup a integer vector in the secfile.
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Lookup a string value in the secfile.
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Lookup a string vector in the secfile.
bool entry_str_set_gt_marking(struct entry *pentry, bool gt_marking)
Sets if the string should get gettext marking.
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Lookup a boolean value in the secfile.
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Lookup a string value in the secfile.
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
Returns the entry by the name or nullptr if not matched.
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Lookup a integer value in the secfile.
struct section * secfile_section_lookup(const struct section_file *secfile, const char *path,...)
Find a section by path.
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
Lookup a boolean value in the secfile.
#define secfile_insert_int(secfile, value, path,...)
#define secfile_insert_enum(secfile, enumerator, specenum_type, path,...)
#define secfile_insert_int_vec(secfile, values, dim, path,...)
#define secfile_insert_str_vec(secfile, strings, dim, path,...)
#define secfile_insert_str(secfile, string, path,...)
#define secfile_lookup_enum_default(secfile, defval, specenum_type, path, ...)
#define secfile_insert_bool(secfile, value, path,...)
#define secfile_replace_str(secfile, string, path,...)
struct history_report * history_report_get()
Return current history report.
const char * universal_type_rule_name(const struct universal *psource)
Return untranslated name of the universal source name.
const char * universal_rule_name(const struct universal *psource)
Return the (untranslated) rule name of the universal.
struct universal universal_by_rule_name(const char *kind, const char *value)
Parse requirement type (kind) and value strings into a universal structure.
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Returns TRUE iff the given tech is ever reachable via research by the players sharing the research by...
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Set research knowledge about tech to given state.
const char * research_name_translation(const struct research *presearch)
Returns the name of the research owner: a player name or a team name.
int research_number(const research *presearch)
Returns the index of the research in the array.
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
struct research * research_by_number(int number)
Returns the research for the given index.
bool research_is_valid(const struct research &presearch)
Checks whether the research object is valid in the current game.
void research_update(struct research *presearch)
Mark as TECH_PREREQS_KNOWN each tech which is available, not known and which has all requirements ful...
std::vector< research > research_array
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Free rgbcolor structure.
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, const char *path,...)
Lookup an RGB color definition ([colorpath].red, [colorpath].green and [colorpath]....
void rgbcolor_save(struct section_file *file, const struct rgbcolor *prgbcolor, const char *path,...)
Save an RGB color definition ([colorpath].red, [colorpath].green and [colorpath].blue).
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Loads the rulesets.
#define sanity_check_city(x)
struct extra_type * special_extra_get(int spe)
Get extra of the given special.
char bin2ascii_hex(int value, int halfbyte_wanted)
This returns an ascii hex value of the given half-byte of the binary integer.
void sg_load_compat(struct loaddata *loading, enum sgf_version format_class)
Compatibility functions for loaded game.
enum ai_level ai_level_convert(int old_level)
Translate savegame secfile data from earlier development version format to current one.
int ascii_hex2bin(char ch, int halfbyte)
This returns a binary integer value of the ascii hex char, offset by the given number of half-bytes.
void sg_load_post_load_compat(struct loaddata *loading, enum sgf_version format_class)
Compatibility functions for loaded game that needs game state.
int current_compat_ver()
Return current compatibility version.
#define sg_check_ret(...)
#define sg_warn(condition, message,...)
#define sg_failure_ret_val(condition, _val, message,...)
#define sg_failure_ret(condition, message,...)
#define sg_warn_ret_val(condition, _val, message,...)
void savegame3_save(struct section_file *sfile, const char *save_reason, bool scenario)
Main entry point for saving a game in savegame3 format.
static void sg_save_history(struct savedata *saving)
Save '[history]'.
static void sg_load_players_basic(struct loaddata *loading)
Load '[player]' (basic data).
static struct loaddata * loaddata_new(struct section_file *file)
Create new loaddata item for given section file.
static void worklist_save(struct section_file *file, const struct worklist *pwl, int max_length, const char *path,...)
Save the worklist elements specified by path from the worklist pointed to by 'pwl'.
static void sg_load_map_known(struct loaddata *loading)
Load tile known status.
static void sg_load_map_owner(struct loaddata *loading)
Load tile owner information.
static void sg_extras_set(bv_extras *extras, char ch, struct extra_type **idx)
Helper function for loading extras from a savegame.
static void unit_ordering_calc()
Assign values to ord_city and ord_map for each unit, so the values can be saved.
static char * quote_block(const void *const data, int length)
Quote the memory block denoted by data and length so it consists only of " a-f0-9:".
#define halfbyte_iterate_extras_end
#define halfbyte_iterate_extras(e, num_extras_types)
static void sg_load_map(struct loaddata *loading)
Load '[map'].
static enum unit_orders char2order(char order)
Returns an order for a character identifier.
static int unquote_block(const char *const quoted_, void *dest, int dest_length)
Unquote a string.
static void sg_save_map_tiles_extras(struct savedata *saving)
Save information about extras on map.
static void sg_save_map_worked(struct savedata *saving)
Save worked tiles information.
static void sg_save_players(struct savedata *saving)
Save '[player]'.
#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath,...)
static void sg_save_player_cities(struct savedata *saving, struct player *plr)
Save cities data.
static void sg_load_player_city_citizens(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr)
Load nationality data for one city.
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Load city data.
static void sg_load_map_tiles(struct loaddata *loading)
Load tiles of the map.
static char activity2char(enum unit_activity activity)
Returns a character identifier for an activity.
static struct savedata * savedata_new(struct section_file *file, const char *save_reason, bool scenario)
Create new savedata item for given file.
static void sg_load_savefile(struct loaddata *loading)
Load '[savefile]'.
static enum unit_activity char2activity(char activity)
Returns an activity for a character identifier.
static bool sg_load_player_unit(struct loaddata *loading, struct player *plr, struct unit *punit, const char *unitstr)
Load one unit.
static void sg_load_settings(struct loaddata *loading)
Load '[settings]'.
static void sg_load_player_units(struct loaddata *loading, struct player *plr)
Load unit data.
static char terrain2char(const struct terrain *pterrain)
References the terrain character.
static void sg_save_random(struct savedata *saving)
Save '[random]'.
static void sg_save_map_startpos(struct savedata *saving)
Save the map start positions.
static void sg_load_researches(struct loaddata *loading)
Load '[research]'.
static void sg_load_map_worked(struct loaddata *loading)
Load worked tiles information.
#define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath,...)
static void sg_save_savefile_options(struct savedata *saving, const char *option)
Save options for this savegame.
static void sg_load_random(struct loaddata *loading)
Load '[random]'.
static void sg_save_savefile(struct savedata *saving)
Save '[savefile]'.
static void sg_load_player_units_transport(struct loaddata *loading, struct player *plr)
Load the transport status of all units.
static void sg_load_history(struct loaddata *loading)
Load '[history]'.
static void sg_save_treaties(struct savedata *saving)
Save '[treaty_xxx]'.
static void sg_save_map_owner(struct savedata *saving)
Save tile owner information.
static void sg_save_researches(struct savedata *saving)
Save '[research]'.
static void savegame3_save_real(struct section_file *file, const char *save_reason, bool scenario)
Really save the game to a file.
static void sg_load_script(struct loaddata *loading)
Load '[script]'.
static void sg_load_scenario(struct loaddata *loading)
Load '[scenario]'.
static void sg_load_game(struct loaddata *loading)
Load '[game]'.
static void savedata_destroy(struct savedata *saving)
Free resources allocated for savedata item.
static void sg_load_player_main(struct loaddata *loading, struct player *plr)
Main player data loading function.
static char order2char(enum unit_orders order)
Returns a character identifier for an order.
static void sg_load_treaties(struct loaddata *loading)
Load '[treaty_xxx]'.
static void sg_save_scenario(struct savedata *saving)
Save '[scenario]'.
static void sg_save_player_units(struct savedata *saving, struct player *plr)
Save unit data.
static void sg_save_ruledata(struct savedata *saving)
Save '[ruledata]'.
static Tech_type_id technology_load(struct section_file *file, const char *path, int plrno)
Load technology from path_name and if doesn't exist (because savegame is too old) load from path.
static void sg_save_player_vision(struct savedata *saving, struct player *plr)
Save vision data.
static void unit_ordering_apply()
For each city and tile, sort unit lists according to ord_city and ord_map values.
static enum direction8 char2dir(char dir)
Returns a direction for a character identifier.
static bool sg_load_player_city(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr)
Load data for one city.
static struct terrain * char2terrain(char ch)
Dereferences the terrain character.
static char sg_extras_get(bv_extras extras, struct extra_type *presource, const int *idx)
Helper function for saving extras into a savegame.
static void sg_save_sanitycheck(struct savedata *saving)
Sanity check for saved game.
static void sg_load_mapimg(struct loaddata *loading)
Load '[mapimg]'.
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Load player (client) attributes data.
static void sg_save_player_attributes(struct savedata *saving, struct player *plr)
Save player (client) attributes data.
static void sg_load_ruledata(struct loaddata *loading)
Load '[ruledata]'.
static void worklist_load(struct section_file *file, struct worklist *pwl, const char *path,...)
Load the worklist elements specified by path to the worklist pointed to by 'pwl'.
static void sg_save_map(struct savedata *saving)
Save 'map'.
static void sg_load_player_vision(struct loaddata *loading, struct player *plr)
Load vision data.
static void sg_save_map_tiles(struct savedata *saving)
Save all map tiles.
static void sg_save_mapimg(struct savedata *saving)
Save '[mapimg]'.
static const char savefile_options_default[]
static char dir2char(enum direction8 dir)
Returns a character identifier for a direction.
static bool sg_load_player_vision_city(struct loaddata *loading, struct player *plr, struct vision_site *pdcity, const char *citystr)
Load data for one seen city.
static void sg_load_map_startpos(struct loaddata *loading)
Load starting positions for the players from a savegame file.
static void loaddata_destroy(struct loaddata *loading)
Free resources allocated for loaddata item.
static void sg_load_players(struct loaddata *loading)
Load '[player]'.
static void technology_save(struct section_file *file, const char *path, int plrno, Tech_type_id tech)
Save technology in secfile entry called path_name.
static void sg_save_event_cache(struct savedata *saving)
Save '[event_cache]'.
static void sg_load_map_tiles_extras(struct loaddata *loading)
Load extras to map.
static void sg_load_sanitycheck(struct loaddata *loading)
Sanity check for loaded game.
static void sg_load_event_cache(struct loaddata *loading)
Load '[event_cache]'.
void savegame3_load(struct section_file *file)
Really loading the savegame.
static void sg_save_game(struct savedata *saving)
Save '[game]'.
static void sg_save_player_main(struct savedata *saving, struct player *plr)
Main player data saving function.
static void sg_save_script(struct savedata *saving)
Save '[script]'.
static void sg_save_settings(struct savedata *saving)
Save [settings].
static void sg_save_map_known(struct savedata *saving)
Save tile known status for whole map and all players.
void script_server_state_save(struct section_file *file)
Save the scripting state to file.
void script_server_state_load(struct section_file *file)
Load the scripting state from file.
void settings_game_load(struct section_file *file, const char *section)
Restore all settings from a savegame.
void settings_game_save(struct section_file *file, const char *section)
Save game settings.
struct setting_list * level[OLEVELS_NUM]
bool str_to_int(const char *str, int *pint)
Convert 'str' to it's int reprentation if possible.
char scanin(char **buf, char *delimiters, char *dest, int size)
Scan in a word or set of words from start to but not including any of the given delimiters.
bool is_base64url(const char *s)
Check for valid base64url.
QString fileinfoname(const QStringList &dirs, const QString &filename)
Returns a filename to access the specified file from a directory by searching all specified directori...
void randomize_base64url_string(char *s, size_t n)
generate a random string meeting criteria such as is_ascii_name(), is_base64url(),...
const QStringList & get_scenario_dirs()
Returns a list of scenario directory paths, in the order in which they should be searched.
#define CLIP(lower, current, upper)
void spaceship_calc_derived(struct player_spaceship *ship)
Calculate and fill in the derived quantities about the spaceship.
void spaceship_init(struct player_spaceship *ship)
Initialize spaceship struct; could also be used to "cancel" a spaceship (eg, if/when capital-capture ...
#define NUM_SS_STRUCTURALS
struct specialist * specialist_by_rule_name(const char *name)
Return the specialist type with the given (untranslated!) rule name.
const char * specialist_rule_name(const struct specialist *sp)
Return the (untranslated) rule name of the specialist type.
Specialist_type_id specialist_index(const struct specialist *sp)
Return the specialist index.
struct specialist * specialist_by_number(const Specialist_type_id id)
Return the specialist pointer for the given number.
Specialist_type_id specialist_count()
Return the number of specialist_types.
#define specialist_type_iterate_end
#define specialist_type_iterate(sp)
#define DEFAULT_SPECIALIST
void server_game_init(bool keep_ruleset_value)
Initialize game data for the server (corresponds to server_game_free).
const char * aifill(int amount)
Fill or remove players to meet the given aifill.
void server_game_free()
Free game data that we reinitialize as part of a server soft restart.
void identity_number_reserve(int id)
Mark identity number allocated.
struct server_arguments srvarg
void init_game_seed()
Initialize the game seed.
bool game_was_started()
Returns iff the game was started once upon a time.
enum server_states server_state()
Return current server state.
void update_nations_with_startpos()
Update information about which nations have start positions on the map.
struct worker_task_list * task_reqs
struct city::@14 rally_point
struct built_status built[B_LAST]
int last_turns_shield_surplus
bv_city_options city_options
struct trade_route_list * routes
struct universal production
struct unit_order * orders
char name[MAX_LEN_CITYNAME]
int before_change_shields
struct city::@15::@17 server
citizens specialists[SP_MAX]
struct cm_parameter * cm_parameter
struct universal changed_from
struct unit_list * units_supported
struct civ_game::@28::@32 server
struct packet_scenario_description scenario_desc
struct packet_ruleset_control control
struct packet_game_info info
struct packet_scenario_info scenario
char * ruleset_capabilities
QHash< struct tile *, struct startpos * > * startpos_table
struct civ_map::@39::@41 server
int minimal_surplus[O_LAST]
char title[REPORT_TITLESIZE]
char body[REPORT_BODYSIZE]
struct loaddata::@96 trait
const char * secfile_options
struct loaddata::@98 multiplier
struct loaddata::@97 extra
struct loaddata::@105 act_dec
struct loaddata::@93 improvement
struct loaddata::@106 ssa
enum server_states server_state
struct loaddata::@94 technology
struct loaddata::@104 action
struct loaddata::@95 activities
struct loaddata::@102 specialist
struct section_file * file
The base class for options.
enum ai_level skill_level
std::vector< ai_trait > traits
enum barbarian_type barbarian_type
int love[MAX_NUM_PLAYER_SLOTS]
enum diplstate_type max_state
bv_spaceship_structure structure
enum spaceship_state state
struct player * extras_owner
struct extra_type * resource
struct city_list * cities
QByteArray attribute_block
struct player_ai ai_common
struct government * target_government
char username[MAX_LEN_NAME]
struct player::@65::@67 server
struct government * government
const struct ai_type * ai
char ranked_username[MAX_LEN_NAME]
struct player_economic economic
struct player_spaceship spaceship
struct player_score score
int multipliers[MAX_NUM_MULTIPLIERS]
struct nation_type * nation
struct nation_style * style
int multipliers_target[MAX_NUM_MULTIPLIERS]
int bulbs_researched_saved
int bulbs_researching_saved
Tech_type_id researching_saved
struct research::research_invention inventions[A_LAST]
struct section_file * file
char secfile_options[512]
struct extra_type * placing
struct goods_type * goods
enum action_decision action_decision_want
struct extra_type * changed_from_target
struct unit::@76::@79 server
enum unit_activity changed_from
struct player * nationality
struct goods_type * carrying
struct tile * action_decision_tile
enum server_side_agent ssa_controller
enum capital_type capital
struct universal entries[MAX_LEN_WORKLIST]
int city_style(struct city *pcity)
Return citystyle of the city.
struct nation_style * style_by_rule_name(const char *name)
Returns style matching rule name or nullptr if there is no style with such name.
const char * style_rule_name(const struct nation_style *pstyle)
Return the (untranslated) rule name of the style.
struct nation_style * style_by_number(int id)
Return style of given id.
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
int cat_snprintf(char *str, size_t n, const char *format,...)
cat_snprintf is like a combination of fc_snprintf and fc_strlcat; it does snprintf to the end of an e...
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
#define sz_strlcpy(dest, src)
#define sz_strlcat(dest, src)
int team_index(const struct team *pteam)
Return the team index.
void team_add_player(struct player *pplayer, struct team *pteam)
Set a player to a team.
const struct player_list * team_members(const struct team *pteam)
Returns the member list of the team.
struct team * team_new(struct team_slot *tslot)
Creates a new team for the slot.
struct team_slot * team_slot_by_number(int team_id)
Return the possibly unused and uninitialized team slot.
bool is_future_tech(Tech_type_id tech)
Is the given tech a future tech.
struct advance * advance_by_rule_name(const char *name)
Does a linear search of advances[].name.vernacular Returns nullptr when none match.
const char * advance_rule_name(const struct advance *padvance)
Return the (untranslated) rule name of the advance/technology.
struct advance * advance_by_number(const Tech_type_id atype)
Return the advance for the given advance index.
struct advance * valid_advance_by_number(const Tech_type_id id)
Returns pointer when the advance "exists" in this game, returns nullptr otherwise.
Tech_type_id advance_index(const struct advance *padvance)
Return the advance index.
Tech_type_id advance_number(const struct advance *padvance)
Return the advance index.
#define advance_index_iterate_end
#define advance_iterate(_start, _p)
#define advance_iterate_end
#define advance_index_iterate(_start, _index)
char terrain_identifier(const struct terrain *pterrain)
Return the terrain identifier.
const char * terrain_rule_name(const struct terrain *pterrain)
Return the (untranslated) rule name of the terrain.
struct terrain * terrain_by_rule_name(const char *name)
Return the terrain type matching the name, or T_UNKNOWN if none matches.
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Check for resource in terrain resources list.
#define terrain_type_iterate(_p)
#define TERRAIN_UNKNOWN_IDENTIFIER
#define terrain_type_iterate_end
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Check if tile contains base providing effect for unit.
bool tile_set_label(struct tile *ptile, const char *label)
Sets label for tile.
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Set the given resource at the specified tile.
void tile_set_worked(struct tile *ptile, struct city *pcity)
Set the city/worker on the tile (may be nullptr).
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_has_extra(ptile, pextra)
#define tile_owner(_tile)
void timer_destroy(civtimer *t)
Deletes timer.
double timer_read_seconds(civtimer *t)
Read value from timer.
civtimer * timer_new(enum timer_timetype type, enum timer_use use)
Allocate a new timer with specified "type" and "use".
void timer_start(civtimer *t)
Start timing, adding to previous accumulated time if timer has not been cleared.
void timer_stop(civtimer *t)
Stop timing, and accumulate time so far.
struct goods_type * goods_by_number(Goods_type_id id)
Return goods type of given id.
const char * goods_rule_name(struct goods_type *pgood)
Return untranslated name of this goods type.
struct goods_type * goods_by_rule_name(const char *name)
Returns goods type matching rule name or nullptr if there is no goods type with such name.
#define trade_routes_iterate_end
#define trade_routes_iterate(c, proute)
void free_unit_orders(struct unit *punit)
Free and reset the unit's goto route (punit->pgr).
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Load pcargo onto ptrans.
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Assign a new untargeted task to a unit.
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.
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
assign a new targeted task to a unit.
void unit_virtual_destroy(struct unit *punit)
Free the memory used by virtual unit.
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Create a virtual unit skeleton.
void unit_tile_set(struct unit *punit, struct tile *ptile)
Set the tile location of the unit.
struct player * unit_nationality(const struct unit *punit)
Return the nationality of the unit.
void unit_list_sort_ord_map(struct unit_list *punitlist)
Sorts the unit list by punit->server.ord_map values.
void unit_list_sort_ord_city(struct unit_list *punitlist)
Sorts the unit list by punit->server.ord_city values.
#define unit_list_iterate(unitlist, punit)
#define unit_list_iterate_safe(unitlist, _unit)
#define unit_list_iterate_end
#define unit_list_iterate_safe_end
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Returns the upkeep of a unit of this type under the given government.
int utype_veteran_levels(const struct unit_type *punittype)
Return veteran levels of the given unit type.
const char * utype_name_translation(const struct unit_type *punittype)
Return the (translated) name of the unit type.
struct unit_type * unit_type_by_rule_name(const char *name)
Returns the unit type that has the given (untranslated) rule name.
Unit_type_id utype_index(const struct unit_type *punittype)
Return the unit type index.
static bool utype_has_flag(const struct unit_type *punittype, int flag)
#define unit_type_iterate(_p)
#define unit_type_iterate_end
const char * freeciv21_version()
Returns the raw version string.
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Create a new vision source.
void vision_site_size_set(struct vision_site *psite, citizens size)
Set the city size.
citizens vision_site_size_get(const struct vision_site *psite)
Get the city size.
bool vision_reveal_tiles(struct vision *vision, bool reveal_tiles)
Sets the can_reveal_tiles flag.
struct vision_site * vision_site_new(int identity, struct tile *location, struct player *owner)
Returns the basic structure.
#define vision_site_owner(v)
#define worker_task_list_iterate(tasklist, ptask)
#define worker_task_list_iterate_end
void worklist_init(struct worklist *pwl)
Initialize a worklist to be empty.