Freeciv-3.4
Loading...
Searching...
No Matches
savegame2.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/*
15 This file includes the definition of a new savegame format introduced with
16 2.3.0. It is defined by the mandatory option '+version2'. The main load
17 function checks if this option is present. If not, the old (pre-2.3.0)
18 loading routines are used.
19 The format version is also saved in the settings section of the savefile, as an
20 integer (savefile.version). The integer is used to determine the version
21 of the savefile.
22
23 Structure of this file:
24
25 - The real work is done by savegame2_load().
26 This function call all submodules (settings, players, etc.)
27
28 - The remaining part of this file is split into several sections:
29 * helper functions
30 * load functions for all submodules (and their subsubmodules)
31
32 - If possible, all functions for load submodules should exit in
33 pairs named sg_load_<submodule>. If one is not
34 needed please add a comment why.
35
36 - The submodules can be further divided as:
37 sg_load_<submodule>_<subsubmodule>
38
39 - If needed (due to static variables in the *.c files) these functions
40 can be located in the corresponding source files (as done for the settings
41 and the event_cache).
42
43 Loading a savegame:
44
45 - The status of the process is saved within the static variable
46 'sg_success'. This variable is set to TRUE within savegame2_load().
47 If you encounter an error use sg_failure_*() to set it to FALSE and
48 return an error message. Furthermore, sg_check_* should be used at the
49 start of each (submodule) function to return if previous functions failed.
50
51 - While the loading process dependencies between different modules exits.
52 They can be handled within the struct loaddata *loading which is used as
53 first argument for all sg_load_*() function. Please indicate the
54 dependencies within the definition of this struct.
55
56*/
57
58#ifdef HAVE_CONFIG_H
59#include <fc_config.h>
60#endif
61
62#include <ctype.h>
63#include <stdarg.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67
68/* utility */
69#include "bitvector.h"
70#include "fcintl.h"
71#include "idex.h"
72#include "log.h"
73#include "mem.h"
74#include "rand.h"
75#include "registry.h"
76#include "shared.h"
77#include "support.h" /* bool type */
78#include "timing.h"
79
80/* common */
81#include "achievements.h"
82#include "ai.h"
83#include "bitvector.h"
84#include "capability.h"
85#include "citizens.h"
86#include "city.h"
87#include "game.h"
88#include "government.h"
89#include "map.h"
90#include "mapimg.h"
91#include "movement.h"
92#include "multipliers.h"
93#include "packets.h"
94#include "research.h"
95#include "rgbcolor.h"
96#include "specialist.h"
97#include "unit.h"
98#include "unitlist.h"
99#include "version.h"
100
101/* server */
102#include "barbarian.h"
103#include "citizenshand.h"
104#include "citytools.h"
105#include "cityturn.h"
106#include "diplhand.h"
107#include "maphand.h"
108#include "meta.h"
109#include "notify.h"
110#include "plrhand.h"
111#include "report.h"
112#include "ruleload.h"
113#include "sanitycheck.h"
114#include "score.h"
115#include "settings.h"
116#include "spacerace.h"
117#include "srv_main.h"
118#include "stdinhand.h"
119#include "techtools.h"
120#include "unittools.h"
121
122/* server/advisors */
123#include "advdata.h"
124#include "advbuilding.h"
125#include "infracache.h"
126
127/* server/generator */
128#include "mapgen.h"
129#include "mapgen_utils.h"
130
131/* server/scripting */
132#include "script_server.h"
133
134/* server/savegame */
135#include "savecompat.h"
136#include "savemain.h"
137
138/* ai */
139#include "aitraits.h"
140#include "difficulty.h"
141
142#include "savegame2.h"
143
144extern bool sg_success;
145
146#define ACTIVITY_OLD_ROAD (ACTIVITY_LAST + 1)
147#define ACTIVITY_OLD_RAILROAD (ACTIVITY_LAST + 2)
148#define ACTIVITY_OLD_POLLUTION_SG2 (ACTIVITY_OLD_RAILROAD + 1)
149#define ACTIVITY_OLD_FALLOUT_SG2 (ACTIVITY_OLD_POLLUTION_SG2 + 1)
150#define ACTIVITY_LAST_SAVEGAME2 (ACTIVITY_OLD_FALLOUT_SG2 + 1)
151
152/*
153 * This loops over the entire map to save data. It collects all the data of
154 * a line using GET_XY_CHAR and then executes the macro SECFILE_INSERT_LINE.
155 *
156 * Parameters:
157 * ptile: current tile within the line (used by GET_XY_CHAR)
158 * GET_XY_CHAR: macro returning the map character for each position
159 * secfile: a secfile struct
160 * secpath, ...: path as used for sprintf() with arguments; the last item
161 * will be the y coordinate
162 * Example:
163 * SAVE_MAP_CHAR(ptile, terrain2char(ptile->terrain), file, "map.t%04d");
164 */
165#define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath, ...) \
166{ \
167 char _line[MAP_NATIVE_WIDTH + 1]; \
168 int _nat_x, _nat_y; \
169 \
170 for (_nat_y = 0; _nat_y < MAP_NATIVE_HEIGHT; _nat_y++) { \
171 for (_nat_x = 0; _nat_x < MAP_NATIVE_WIDTH; _nat_x++) { \
172 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
173 \
174 fc_assert_action(ptile != nullptr, continue); \
175 \
176 _line[_nat_x] = (GET_XY_CHAR); \
177 sg_failure_ret(fc_isprint(_line[_nat_x] & 0x7f), \
178 "Trying to write invalid map data at position " \
179 "(%d, %d) for path %s: '%c' (%d)", _nat_x, _nat_y, \
180 secpath, _line[_nat_x], _line[_nat_x]); \
181 } \
182 _line[MAP_NATIVE_WIDTH] = '\0'; \
183 secfile_insert_str(secfile, _line, secpath, ## __VA_ARGS__, _nat_y); \
184 } \
185}
186
187/*
188 * This loops over the entire map to load data. It inputs a line of data
189 * using the macro SECFILE_LOOKUP_LINE and then loops using the macro
190 * SET_XY_CHAR to load each char into the map at (map_x, map_y). Internal
191 * variables ch, map_x, map_y, nat_x, and nat_y are allocated within the
192 * macro but definable by the caller.
193 *
194 * Parameters:
195 * ch: a variable to hold a char (data for a single position,
196 * used by SET_XY_CHAR)
197 * ptile: current tile within the line (used by SET_XY_CHAR)
198 * SET_XY_CHAR: macro to load the map character at each (map_x, map_y)
199 * secfile: a secfile struct
200 * secpath, ...: path as used for sprintf() with arguments; the last item
201 * will be the y coordinate
202 * Example:
203 * LOAD_MAP_CHAR(ch, ptile,
204 * map_get_player_tile(ptile, plr)->terrain
205 * = char2terrain(ch), file, "player%d.map_t%04d", plrno);
206 *
207 * Note: some (but not all) of the code this is replacing used to skip over
208 * lines that did not exist. This allowed for backward-compatibility.
209 * We could add another parameter that specified whether it was OK to
210 * skip the data, but there's not really much advantage to exiting
211 * early in this case. Instead, we let any map data type to be empty,
212 * and just print an informative warning message about it.
213 */
214#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath, ...) \
215{ \
216 int _nat_x, _nat_y; \
217 bool _printed_warning = FALSE; \
218 for (_nat_y = 0; _nat_y < MAP_NATIVE_HEIGHT; _nat_y++) { \
219 const char *_line = secfile_lookup_str(secfile, secpath, \
220 ## __VA_ARGS__, _nat_y); \
221 if (_line == nullptr) { \
222 char buf[64]; \
223 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
224 log_verbose("Line not found='%s'", buf); \
225 _printed_warning = TRUE; \
226 continue; \
227 } else if (strlen(_line) != MAP_NATIVE_WIDTH) { \
228 char buf[64]; \
229 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
230 log_verbose("Line too short (expected %d got " SIZE_T_PRINTF \
231 ")='%s'", MAP_NATIVE_WIDTH, strlen(_line), buf); \
232 _printed_warning = TRUE; \
233 continue; \
234 } \
235 for (_nat_x = 0; _nat_x < MAP_NATIVE_WIDTH; _nat_x++) { \
236 const char ch = _line[_nat_x]; \
237 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
238 (SET_XY_CHAR); \
239 } \
240 } \
241 if (_printed_warning) { \
242 /* TRANS: Minor error message. */ \
243 log_sg(_("Saved game contains incomplete map data. This can" \
244 " happen with old saved games, or it may indicate an" \
245 " invalid saved game file. Proceed at your own risk.")); \
246 } \
247}
248
249/* Iterate on the extras half-bytes */
250#define halfbyte_iterate_extras(e, num_extras_types) \
251{ \
252 int e; \
253 for (e = 0; 4 * e < (num_extras_types); e++) {
254
255#define halfbyte_iterate_extras_end \
256 } \
257}
258
259/* Iterate on the specials half-bytes */
260#define halfbyte_iterate_special(s, num_specials_types) \
261{ \
262 enum tile_special_type s; \
263 for (s = 0; 4 * s < (num_specials_types); s++) {
264
265#define halfbyte_iterate_special_end \
266 } \
267}
268
269/* Iterate on the bases half-bytes */
270#define halfbyte_iterate_bases(b, num_bases_types) \
271{ \
272 int b; \
273 for (b = 0; 4 * b < (num_bases_types); b++) {
274
275#define halfbyte_iterate_bases_end \
276 } \
277}
278
279/* Iterate on the roads half-bytes */
280#define halfbyte_iterate_roads(r, num_roads_types) \
281{ \
282 int r; \
283 for (r = 0; 4 * r < (num_roads_types); r++) {
284
285#define halfbyte_iterate_roads_end \
286 } \
287}
288
289#define TOKEN_SIZE 10
290
291#define ORDER_OLD_BUILD_CITY (-1)
292#define ORDER_OLD_DISBAND (-2)
293#define ORDER_OLD_BUILD_WONDER (-3)
294#define ORDER_OLD_TRADE_ROUTE (-4)
295#define ORDER_OLD_HOMECITY (-5)
296
297static struct loaddata *loaddata_new(struct section_file *file);
298static void loaddata_destroy(struct loaddata *loading);
299
300static enum unit_orders char2order(char order);
301static enum direction8 char2dir(char dir);
302static char activity2char(int activity);
303static int char2activity(char activity);
304static int unquote_block(const char *const quoted_, void *dest,
305 int dest_length);
306static void worklist_load(struct section_file *file, int wlist_max_length,
307 struct worklist *pwl,
308 const char *path, ...);
309static void unit_ordering_apply(void);
310static void sg_extras_set_dbv(struct dbv *extras, char ch,
311 struct extra_type **idx);
312static void sg_extras_set_bv(bv_extras *extras, char ch,
313 struct extra_type **idx);
314static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch,
315 const enum tile_special_type *idx,
316 bool rivers_overlay);
317static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch,
318 const enum tile_special_type *idx,
319 bool rivers_overlay);
320static void sg_bases_set_dbv(struct dbv *extras, char ch, struct base_type **idx);
321static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx);
322static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx);
323static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx);
324static struct extra_type *char2resource(char c);
325static struct terrain *char2terrain(char ch);
326static Tech_type_id technology_load(struct section_file *file,
327 const char *path, int plrno);
328
329static void sg_load_ruleset(struct loaddata *loading);
330static void sg_load_savefile(struct loaddata *loading);
331
332static void sg_load_game(struct loaddata *loading);
333
334static void sg_load_ruledata(struct loaddata *loading);
335
336static void sg_load_random(struct loaddata *loading);
337
338static void sg_load_script(struct loaddata *loading);
339
340static void sg_load_scenario(struct loaddata *loading);
341
342static void sg_load_settings(struct loaddata *loading);
343
344static void sg_load_map(struct loaddata *loading);
345static void sg_load_map_tiles(struct loaddata *loading);
346static void sg_load_map_tiles_extras(struct loaddata *loading);
347static void sg_load_map_tiles_bases(struct loaddata *loading);
348static void sg_load_map_tiles_roads(struct loaddata *loading);
350 bool rivers_overlay);
351static void sg_load_map_tiles_resources(struct loaddata *loading);
352
353static void sg_load_map_startpos(struct loaddata *loading);
354static void sg_load_map_owner(struct loaddata *loading);
355static void sg_load_map_worked(struct loaddata *loading);
356static void sg_load_map_known(struct loaddata *loading);
357
358static void sg_load_players_basic(struct loaddata *loading);
359static void sg_load_players(struct loaddata *loading);
360static void sg_load_player_main(struct loaddata *loading,
361 struct player *plr);
362static void sg_load_player_cities(struct loaddata *loading,
363 struct player *plr);
364static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
365 struct city *pcity, const char *citystr,
366 int wlist_max_length);
368 struct player *plr,
369 struct city *pcity,
370 const char *citystr);
371static void sg_load_player_units(struct loaddata *loading,
372 struct player *plr);
373static bool sg_load_player_unit(struct loaddata *loading,
374 struct player *plr, struct unit *punit,
375 const char *unitstr);
377 struct player *plr);
378static void sg_load_player_attributes(struct loaddata *loading,
379 struct player *plr);
380static void sg_load_player_vision(struct loaddata *loading,
381 struct player *plr);
383 struct player *plr,
384 struct vision_site *pdcity,
385 const char *citystr);
386
387static void sg_load_researches(struct loaddata *loading);
388
389static void sg_load_event_cache(struct loaddata *loading);
390
391static void sg_load_treaties(struct loaddata *loading);
392
393static void sg_load_history(struct loaddata *loading);
394
395static void sg_load_mapimg(struct loaddata *loading);
396
397static void sg_load_sanitycheck(struct loaddata *loading);
398
399
400/* =======================================================================
401 * Basic load / save functions.
402 * ======================================================================= */
403
404/************************************************************************/
407void savegame2_load(struct section_file *file)
408{
409 struct loaddata *loading;
411
412 /* initialise loading */
417
418 /* Load the savegame data. */
419 /* Set up correct ruleset */
421 /* [compat] */
423 /* [savefile] */
425 /* [game] */
427 /* [scenario] */
429 /* [random] */
431 /* [settings] */
433 /* [ruledata] */
435 /* [players] (basic data) */
437 /* [map]; needs width and height loaded by [settings] */
439 /* [research] */
441 /* [player<i>] */
443 /* [event_cache] */
445 /* [treaties] */
447 /* [history] */
449 /* [mapimg] */
451 /* [script] -- must come last as may reference game objects */
453 /* [post_load_compat]; needs the game loaded by [savefile] */
455
456 /* Sanity checks for the loaded game. */
458
459 /* deinitialise loading */
463
464 if (!sg_success) {
465 log_error("Failure loading savegame!");
467 }
468}
469
470/************************************************************************/
473static struct loaddata *loaddata_new(struct section_file *file)
474{
475 struct loaddata *loading = calloc(1, sizeof(*loading));
476 loading->file = file;
477 loading->secfile_options = nullptr;
478
479 loading->improvement.order = nullptr;
480 loading->improvement.size = -1;
481 loading->technology.order = nullptr;
482 loading->technology.size = -1;
483 loading->activities.order = nullptr;
484 loading->activities.size = -1;
485 loading->trait.order = nullptr;
486 loading->trait.size = -1;
487 loading->extra.order = nullptr;
488 loading->extra.size = -1;
489 loading->multiplier.order = nullptr;
490 loading->multiplier.size = -1;
491 loading->special.order = nullptr;
492 loading->special.size = -1;
493 loading->base.order = nullptr;
494 loading->base.size = -1;
495 loading->road.order = nullptr;
496 loading->road.size = -1;
497 loading->specialist.order = nullptr;
498 loading->specialist.size = -1;
499 loading->ds_t.order = nullptr;
500 loading->ds_t.size = -1;
501 loading->coptions.order = nullptr;
502 loading->coptions.size = -1;
503
504 loading->server_state = S_S_INITIAL;
505 loading->rstate = fc_rand_state();
506 loading->worked_tiles = nullptr;
507
508 return loading;
509}
510
511/************************************************************************/
515{
516 if (loading->improvement.order != nullptr) {
517 free(loading->improvement.order);
518 }
519
520 if (loading->technology.order != nullptr) {
521 free(loading->technology.order);
522 }
523
524 if (loading->activities.order != nullptr) {
525 free(loading->activities.order);
526 }
527
528 if (loading->trait.order != nullptr) {
529 free(loading->trait.order);
530 }
531
532 if (loading->extra.order != nullptr) {
533 free(loading->extra.order);
534 }
535
536 if (loading->multiplier.order != nullptr) {
537 free(loading->multiplier.order);
538 }
539
540 if (loading->special.order != nullptr) {
541 free(loading->special.order);
542 }
543
544 if (loading->base.order != nullptr) {
545 free(loading->base.order);
546 }
547
548 if (loading->road.order != nullptr) {
549 free(loading->road.order);
550 }
551
552 if (loading->specialist.order != nullptr) {
553 free(loading->specialist.order);
554 }
555
556 if (loading->ds_t.order != nullptr) {
557 free(loading->ds_t.order);
558 }
559
560 if (loading->coptions.order != nullptr) {
561 free(loading->coptions.order);
562 }
563
564 if (loading->worked_tiles != nullptr) {
565 free(loading->worked_tiles);
566 }
567
568 free(loading);
569}
570
571
572/************************************************************************/
582
583/************************************************************************/
593
594/* =======================================================================
595 * Helper functions.
596 * ======================================================================= */
597
598/************************************************************************/
601static enum unit_orders char2order(char order)
602{
603 switch (order) {
604 case 'm':
605 case 'M':
606 return ORDER_MOVE;
607 case 'w':
608 case 'W':
609 return ORDER_FULL_MP;
610 case 'b':
611 case 'B':
613 case 'a':
614 case 'A':
615 return ORDER_ACTIVITY;
616 case 'd':
617 case 'D':
618 return ORDER_OLD_DISBAND;
619 case 'u':
620 case 'U':
622 case 't':
623 case 'T':
625 case 'h':
626 case 'H':
627 return ORDER_OLD_HOMECITY;
628 case 'x':
629 case 'X':
630 return ORDER_ACTION_MOVE;
631 }
632
633 /* This can happen if the savegame is invalid. */
634 return ORDER_LAST;
635}
636
637/************************************************************************/
640static enum direction8 char2dir(char dir)
641{
642 /* Numberpad values for the directions. */
643 switch (dir) {
644 case '1':
645 return DIR8_SOUTHWEST;
646 case '2':
647 return DIR8_SOUTH;
648 case '3':
649 return DIR8_SOUTHEAST;
650 case '4':
651 return DIR8_WEST;
652 case '6':
653 return DIR8_EAST;
654 case '7':
655 return DIR8_NORTHWEST;
656 case '8':
657 return DIR8_NORTH;
658 case '9':
659 return DIR8_NORTHEAST;
660 }
661
662 /* This can happen if the savegame is invalid. */
663 return direction8_invalid();
664}
665
666/************************************************************************/
669static char activity2char(int activity)
670{
671 switch (activity) {
672 case ACTIVITY_IDLE:
673 return 'w';
674 case ACTIVITY_CLEAN:
675 return 'C';
677 return 'p';
679 return 'r';
680 case ACTIVITY_MINE:
681 return 'm';
683 return 'i';
685 return 'f';
686 case ACTIVITY_SENTRY:
687 return 's';
689 return 'l';
690 case ACTIVITY_PILLAGE:
691 return 'e';
692 case ACTIVITY_GOTO:
693 return 'g';
694 case ACTIVITY_EXPLORE:
695 return 'x';
697 return 'o';
699 return 'y';
701 return 'u';
702 case ACTIVITY_BASE:
703 return 'b';
705 return 'R';
706 case ACTIVITY_CONVERT:
707 return 'c';
709 case ACTIVITY_PLANT:
710 return '?';
711 case ACTIVITY_LAST:
712 break;
713 }
714
716
717 return '?';
718}
719
720/************************************************************************/
723static int char2activity(char activity)
724{
725 int a;
726
727 for (a = 0; a < ACTIVITY_LAST_SAVEGAME2; a++) {
728 char achar = activity2char(a);
729
730 if (activity == achar) {
731 return a;
732 }
733 }
734
735 /* This can happen if the savegame is invalid. */
736 return ACTIVITY_LAST;
737}
738
739/************************************************************************/
744static int unquote_block(const char *const quoted_, void *dest,
745 int dest_length)
746{
747 int i, length, parsed, tmp;
748 char *endptr;
749 const char *quoted = quoted_;
750
751 parsed = sscanf(quoted, "%d", &length);
752
753 if (parsed != 1) {
754 log_error(_("Syntax error in attribute block."));
755 return 0;
756 }
757
758 if (length > dest_length) {
759 return 0;
760 }
761
762 quoted = strchr(quoted, ':');
763
764 if (quoted == nullptr) {
765 log_error(_("Syntax error in attribute block."));
766 return 0;
767 }
768
769 quoted++;
770
771 for (i = 0; i < length; i++) {
772 tmp = strtol(quoted, &endptr, 16);
773
774 if ((endptr - quoted) != 2
775 || *endptr != ' '
776 || (tmp & 0xff) != tmp) {
777 log_error(_("Syntax error in attribute block."));
778 return 0;
779 }
780
781 ((unsigned char *) dest)[i] = tmp;
782 quoted += 3;
783 }
784
785 return length;
786}
787
788/************************************************************************/
793 struct worklist *pwl, const char *path, ...)
794{
795 int i;
796 const char *kind;
797 const char *name;
798 char path_str[1024];
799 va_list ap;
800
801 /* The first part of the registry path is taken from the varargs to the
802 * function. */
803 va_start(ap, path);
804 fc_vsnprintf(path_str, sizeof(path_str), path, ap);
805 va_end(ap);
806
809 "%s.wl_length", path_str);
810 if (pwl->length > MAX_LEN_WORKLIST) {
811 log_sg("worklist length %d, while MAX_LEN_WORKLIST %d.",
812 pwl->length, MAX_LEN_WORKLIST);
813 pwl->length = MAX_LEN_WORKLIST;
814 } else if (pwl->length > wlist_max_length) {
815 log_sg("worklist length %d, while player's max worklist length %d.",
816 pwl->length, wlist_max_length);
817 }
818
819 for (i = 0; i < pwl->length; i++) {
820 kind = secfile_lookup_str(file, "%s.wl_kind%d", path_str, i);
821
822 /* We lookup the production value by name. An invalid entry isn't a
823 * fatal error; we just truncate the worklist. */
824 name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
825 path_str, i);
826 pwl->entries[i] = universal_by_rule_name(kind, name);
827 if (pwl->entries[i].kind == universals_n_invalid()) {
828 log_sg("%s.wl_value%d: unknown \"%s\" \"%s\".", path_str, i, kind,
829 name);
830 pwl->length = i;
831 break;
832 }
833 }
834
835 /* Padding entries */
836 for (; i < wlist_max_length; i++) {
837 secfile_entry_ignore(file, "%s.wl_kind%d", path_str, i);
838 secfile_entry_ignore(file, "%s.wl_value%d", path_str, i);
839 }
840}
841
842/************************************************************************/
846static void unit_ordering_apply(void)
847{
848 players_iterate(pplayer) {
849 city_list_iterate(pplayer->cities, pcity) {
850 unit_list_sort_ord_city(pcity->units_supported);
851 }
854
855 whole_map_iterate(&(wld.map), ptile) {
856 unit_list_sort_ord_map(ptile->units);
858}
859
860/************************************************************************/
867static void sg_extras_set_dbv(struct dbv *extras, char ch,
868 struct extra_type **idx)
869{
870 int i, bin;
871 const char *pch = strchr(hex_chars, ch);
872
873 if (!pch || ch == '\0') {
874 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
875 bin = 0;
876 } else {
877 bin = pch - hex_chars;
878 }
879
880 for (i = 0; i < 4; i++) {
881 struct extra_type *pextra = idx[i];
882
883 if (pextra == nullptr) {
884 continue;
885 }
886 if ((bin & (1 << i))
887 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
888 dbv_set(extras, extra_index(pextra));
889 }
890 }
891}
892
893/************************************************************************/
901 struct extra_type **idx)
902{
903 int i, bin;
904 const char *pch = strchr(hex_chars, ch);
905
906 if (!pch || ch == '\0') {
907 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
908 bin = 0;
909 } else {
910 bin = pch - hex_chars;
911 }
912
913 for (i = 0; i < 4; i++) {
914 struct extra_type *pextra = idx[i];
915
916 if (pextra == nullptr) {
917 continue;
918 }
919 if ((bin & (1 << i))
920 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
921 BV_SET(*extras, extra_index(pextra));
922 }
923 }
924}
925
926/************************************************************************/
933static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch,
934 const enum tile_special_type *idx,
935 bool rivers_overlay)
936{
937 int i, bin;
938 const char *pch = strchr(hex_chars, ch);
939
940 if (!pch || ch == '\0') {
941 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
942 bin = 0;
943 } else {
944 bin = pch - hex_chars;
945 }
946
947 for (i = 0; i < 4; i++) {
948 enum tile_special_type sp = idx[i];
949
950 if (sp == S_LAST) {
951 continue;
952 }
953 if (rivers_overlay && sp != S_OLD_RIVER) {
954 continue;
955 }
956
957 if (sp == S_HUT && !wld.map.server.have_huts) {
958 /* It would be logical to have this in the saving side -
959 * really not saving the huts in the first place, BUT
960 * 1) They have been saved by older versions, so we
961 * have to deal with such savegames.
962 * 2) This makes scenario author less likely to lose
963 * one's work completely after carefully placing huts
964 * and then saving with 'have_huts' disabled. */
965 continue;
966 }
967
968 if (bin & (1 << i)) {
969 if (sp == S_OLD_ROAD) {
970 struct road_type *proad;
971
973 if (proad) {
975 }
976 } else if (sp == S_OLD_RAILROAD) {
977 struct road_type *proad;
978
980 if (proad) {
982 }
983 } else if (sp == S_OLD_RIVER) {
984 struct road_type *proad;
985
987 if (proad) {
989 }
990 } else {
991 struct extra_type *pextra = nullptr;
992 enum extra_cause cause = EC_COUNT;
993
994 /* Converting from old hardcoded specials to as sensible extra as we can */
995 switch (sp) {
996 case S_IRRIGATION:
997 case S_FARMLAND:
998 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
999 * gets applied twice, which hopefully has the correct result. */
1000 cause = EC_IRRIGATION;
1001 break;
1002 case S_MINE:
1003 cause = EC_MINE;
1004 break;
1005 case S_POLLUTION:
1006 cause = EC_POLLUTION;
1007 break;
1008 case S_HUT:
1009 cause = EC_HUT;
1010 break;
1011 case S_FALLOUT:
1012 cause = EC_FALLOUT;
1013 break;
1014 default:
1016 break;
1017 }
1018
1019 if (cause != EC_COUNT) {
1020 struct tile *vtile = tile_virtual_new(ptile);
1021 struct terrain *pterr = tile_terrain(vtile);
1022 const struct req_context tile_ctxt = { .tile = vtile };
1023
1024 /* Do not let the extras already set to the real tile mess with setup
1025 * of the player tiles if that's what we're doing. */
1026 dbv_to_bv(vtile->extras.vec, extras);
1027
1028 /* It's ok not to know which player or which unit originally built the extra -
1029 * in the rules used when specials were saved these could not have made any
1030 * difference. */
1031 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
1032
1033 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
1034 && (cause != EC_MINE || pterr->mining_time != 0)
1035 && (cause != EC_BASE || pterr->base_time != 0)
1036 && (cause != EC_ROAD || pterr->road_time != 0)) {
1040 || tile_city(vtile) != nullptr
1041 || extra_base_get(candidate)->border_sq <= 0)
1043 &(const struct req_context) {
1044 .player = tile_owner(vtile),
1045 },
1046 &candidate->reqs,
1047 RPT_POSSIBLE)) {
1048 pextra = candidate;
1049 break;
1050 }
1051 }
1053 }
1054
1056 }
1057
1058 if (pextra) {
1059 dbv_set(extras, extra_index(pextra));
1060 }
1061 }
1062 }
1063 }
1064}
1065
1066/************************************************************************/
1073static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch,
1074 const enum tile_special_type *idx,
1075 bool rivers_overlay)
1076{
1077 int i, bin;
1078 const char *pch = strchr(hex_chars, ch);
1079
1080 if (!pch || ch == '\0') {
1081 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1082 bin = 0;
1083 } else {
1084 bin = pch - hex_chars;
1085 }
1086
1087 for (i = 0; i < 4; i++) {
1088 enum tile_special_type sp = idx[i];
1089
1090 if (sp == S_LAST) {
1091 continue;
1092 }
1093 if (rivers_overlay && sp != S_OLD_RIVER) {
1094 continue;
1095 }
1096
1097 if (sp == S_HUT && !wld.map.server.have_huts) {
1098 /* It would be logical to have this in the saving side -
1099 * really not saving the huts in the first place, BUT
1100 * 1) They have been saved by older versions, so we
1101 * have to deal with such savegames.
1102 * 2) This makes scenario author less likely to lose
1103 * one's work completely after carefully placing huts
1104 * and then saving with 'have_huts' disabled. */
1105 continue;
1106 }
1107
1108 if (bin & (1 << i)) {
1109 if (sp == S_OLD_ROAD) {
1110 struct road_type *proad;
1111
1113 if (proad) {
1115 }
1116 } else if (sp == S_OLD_RAILROAD) {
1117 struct road_type *proad;
1118
1120 if (proad) {
1122 }
1123 } else if (sp == S_OLD_RIVER) {
1124 struct road_type *proad;
1125
1127 if (proad) {
1129 }
1130 } else {
1131 struct extra_type *pextra = nullptr;
1132 enum extra_cause cause = EC_COUNT;
1133
1134 /* Converting from old hardcoded specials to as sensible extra as we can */
1135 switch (sp) {
1136 case S_IRRIGATION:
1137 case S_FARMLAND:
1138 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
1139 * gets applied twice, which hopefully has the correct result. */
1140 cause = EC_IRRIGATION;
1141 break;
1142 case S_MINE:
1143 cause = EC_MINE;
1144 break;
1145 case S_POLLUTION:
1146 cause = EC_POLLUTION;
1147 break;
1148 case S_HUT:
1149 cause = EC_HUT;
1150 break;
1151 case S_FALLOUT:
1152 cause = EC_FALLOUT;
1153 break;
1154 default:
1156 break;
1157 }
1158
1159 if (cause != EC_COUNT) {
1160 struct tile *vtile = tile_virtual_new(ptile);
1161 struct terrain *pterr = tile_terrain(vtile);
1162 const struct req_context tile_ctxt = { .tile = vtile };
1163
1164 /* Do not let the extras already set to the real tile mess with setup
1165 * of the player tiles if that's what we're doing. */
1166 vtile->extras = *extras;
1167
1168 /* It's ok not to know which player or which unit originally built the extra -
1169 * in the rules used when specials were saved these could not have made any
1170 * difference. */
1171 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
1172
1173 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
1174 && (cause != EC_MINE || pterr->mining_time != 0)
1175 && (cause != EC_BASE || pterr->base_time != 0)
1176 && (cause != EC_ROAD || pterr->road_time != 0)) {
1180 || tile_city(vtile) != nullptr
1181 || extra_base_get(candidate)->border_sq <= 0)
1183 &(const struct req_context) {
1184 .player = tile_owner(vtile),
1185 },
1186 &candidate->reqs,
1187 RPT_POSSIBLE)) {
1188 pextra = candidate;
1189 break;
1190 }
1191 }
1193 }
1194
1196 }
1197
1198 if (pextra) {
1199 BV_SET(*extras, extra_index(pextra));
1200 }
1201 }
1202 }
1203 }
1204}
1205
1206/************************************************************************/
1213static void sg_bases_set_dbv(struct dbv *extras, char ch,
1214 struct base_type **idx)
1215{
1216 int i, bin;
1217 const char *pch = strchr(hex_chars, ch);
1218
1219 if (!pch || ch == '\0') {
1220 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1221 bin = 0;
1222 } else {
1223 bin = pch - hex_chars;
1224 }
1225
1226 for (i = 0; i < 4; i++) {
1227 struct base_type *pbase = idx[i];
1228
1229 if (pbase == nullptr) {
1230 continue;
1231 }
1232 if (bin & (1 << i)) {
1234 }
1235 }
1236}
1237
1238/************************************************************************/
1245static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx)
1246{
1247 int i, bin;
1248 const char *pch = strchr(hex_chars, ch);
1249
1250 if (!pch || ch == '\0') {
1251 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1252 bin = 0;
1253 } else {
1254 bin = pch - hex_chars;
1255 }
1256
1257 for (i = 0; i < 4; i++) {
1258 struct base_type *pbase = idx[i];
1259
1260 if (pbase == nullptr) {
1261 continue;
1262 }
1263 if (bin & (1 << i)) {
1265 }
1266 }
1267}
1268
1269/************************************************************************/
1276static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx)
1277{
1278 int i, bin;
1279 const char *pch = strchr(hex_chars, ch);
1280
1281 if (!pch || ch == '\0') {
1282 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1283 bin = 0;
1284 } else {
1285 bin = pch - hex_chars;
1286 }
1287
1288 for (i = 0; i < 4; i++) {
1289 struct road_type *proad = idx[i];
1290
1291 if (proad == nullptr) {
1292 continue;
1293 }
1294 if (bin & (1 << i)) {
1296 }
1297 }
1298}
1299
1300/************************************************************************/
1307static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx)
1308{
1309 int i, bin;
1310 const char *pch = strchr(hex_chars, ch);
1311
1312 if (!pch || ch == '\0') {
1313 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1314 bin = 0;
1315 } else {
1316 bin = pch - hex_chars;
1317 }
1318
1319 for (i = 0; i < 4; i++) {
1320 struct road_type *proad = idx[i];
1321
1322 if (proad == nullptr) {
1323 continue;
1324 }
1325 if (bin & (1 << i)) {
1327 }
1328 }
1329}
1330
1331/************************************************************************/
1334static struct extra_type *char2resource(char c)
1335{
1336 /* Speed common values */
1338 || c == RESOURCE_NONE_IDENTIFIER) {
1339 return nullptr;
1340 }
1341
1342 return resource_by_identifier(c);
1343}
1344
1345/************************************************************************/
1349static struct terrain *char2terrain(char ch)
1350{
1351 /* terrain_by_identifier plus fatal error */
1353 return T_UNKNOWN;
1354 }
1355 terrain_type_iterate(pterrain) {
1356 if (pterrain->identifier == ch) {
1357 return pterrain;
1358 }
1360
1361 log_fatal("Unknown terrain identifier '%c' in savegame.", ch);
1362
1364
1365 RETURN_VALUE_AFTER_EXIT(nullptr);
1366}
1367
1368/************************************************************************/
1372 const char *path, int plrno)
1373{
1374 char path_with_name[128];
1375 const char *name;
1376 struct advance *padvance;
1377
1379 "%s_name", path);
1380
1382
1383 if (!name || name[0] == '\0') {
1384 /* Used by researching_saved */
1385 return A_UNKNOWN;
1386 }
1387 if (fc_strcasecmp(name, "A_FUTURE") == 0) {
1388 return A_FUTURE;
1389 }
1390 if (fc_strcasecmp(name, "A_NONE") == 0) {
1391 return A_NONE;
1392 }
1393 if (fc_strcasecmp(name, "A_UNSET") == 0) {
1394 return A_UNSET;
1395 }
1396
1399 "%s: unknown technology \"%s\".", path_with_name, name);
1400
1401 return advance_number(padvance);
1402}
1403
1404/* =======================================================================
1405 * Load savefile data.
1406 * ======================================================================= */
1407
1408/************************************************************************/
1412{
1413 const char *ruleset = secfile_lookup_str_default(loading->file,
1415 "savefile.rulesetdir");
1416
1417 /* Load ruleset. */
1419 if (!strcmp("default", game.server.rulesetdir)) {
1420 int version;
1421
1422 version = secfile_lookup_int_default(loading->file, -1, "savefile.version");
1423 if (version >= 30) {
1424 /* Here 'default' really means current default.
1425 * Saving happens with real ruleset name, so savegames containing this
1426 * are special scenarios. */
1428 } else {
1429 /* 'default' is the old name of the classic ruleset */
1430 sz_strlcpy(game.server.rulesetdir, "classic");
1431 }
1432 log_verbose("Savegame specified ruleset '%s'. Really loading '%s'.",
1434 }
1435 if (!load_rulesets(nullptr, nullptr, FALSE, nullptr, TRUE, FALSE, TRUE)) {
1436 /* Failed to load correct ruleset */
1437 sg_failure_ret(FALSE, _("Failed to load ruleset '%s' needed for savegame."),
1438 ruleset);
1439 }
1440}
1441
1442/************************************************************************/
1446{
1447 int i;
1448 const char *terr_name;
1449 const char *str;
1450
1451 /* Check status and return if not OK (sg_success FALSE). */
1452 sg_check_ret();
1453
1454 /* Load savefile options. */
1455 loading->secfile_options
1456 = secfile_lookup_str(loading->file, "savefile.options");
1457
1458 /* We don't need these entries, but read them anyway to avoid
1459 * warnings about unread secfile entries. */
1460 secfile_entry_ignore_by_path(loading->file, "savefile.reason");
1461 secfile_entry_ignore_by_path(loading->file, "savefile.revision");
1462
1463 str = secfile_lookup_str(loading->file, "savefile.orig_version");
1465
1466 /* In case of savegame2.c saves, missing entry means savegame older than support
1467 * for saving last_updated by turn. So this must default to TRUE. */
1469 "savefile.last_updated_as_year");
1470
1471 /* Load improvements. */
1472 loading->improvement.size
1474 "savefile.improvement_size");
1475 if (loading->improvement.size) {
1476 loading->improvement.order
1477 = secfile_lookup_str_vec(loading->file, &loading->improvement.size,
1478 "savefile.improvement_vector");
1479 sg_failure_ret(loading->improvement.size != 0,
1480 "Failed to load improvement order: %s",
1481 secfile_error());
1482 }
1483
1484 /* Load technologies. */
1485 loading->technology.size
1487 "savefile.technology_size");
1488 if (loading->technology.size) {
1489 loading->technology.order
1490 = secfile_lookup_str_vec(loading->file, &loading->technology.size,
1491 "savefile.technology_vector");
1492 sg_failure_ret(loading->technology.size != 0,
1493 "Failed to load technology order: %s",
1494 secfile_error());
1495 }
1496
1497 /* Load Activities. */
1498 loading->activities.size
1500 "savefile.activities_size");
1501 if (loading->activities.size) {
1502 loading->activities.order
1503 = secfile_lookup_str_vec(loading->file, &loading->activities.size,
1504 "savefile.activities_vector");
1505 sg_failure_ret(loading->activities.size != 0,
1506 "Failed to load activity order: %s",
1507 secfile_error());
1508 }
1509
1510 /* Load traits. */
1511 loading->trait.size
1513 "savefile.trait_size");
1514 if (loading->trait.size) {
1515 loading->trait.order
1516 = secfile_lookup_str_vec(loading->file, &loading->trait.size,
1517 "savefile.trait_vector");
1518 sg_failure_ret(loading->trait.size != 0,
1519 "Failed to load trait order: %s",
1520 secfile_error());
1521 }
1522
1523 /* Load extras. */
1524 loading->extra.size
1526 "savefile.extras_size");
1527 if (loading->extra.size) {
1528 const char **modname;
1529 size_t nmod;
1530 int j;
1531
1532 modname = secfile_lookup_str_vec(loading->file, &loading->extra.size,
1533 "savefile.extras_vector");
1534 sg_failure_ret(loading->extra.size != 0,
1535 "Failed to load extras order: %s",
1536 secfile_error());
1538 "Number of extras defined by the ruleset (= %d) are "
1539 "lower than the number in the savefile (= %d).",
1540 game.control.num_extra_types, (int)loading->extra.size);
1541 /* Make sure that the size of the array is divisible by 4 */
1542 nmod = 4 * ((loading->extra.size + 3) / 4);
1543 loading->extra.order = fc_calloc(nmod, sizeof(*loading->extra.order));
1544 for (j = 0; j < loading->extra.size; j++) {
1545 loading->extra.order[j] = extra_type_by_rule_name(modname[j]);
1546 }
1547 free(modname);
1548 for (; j < nmod; j++) {
1549 loading->extra.order[j] = nullptr;
1550 }
1551 }
1552
1553 /* Load multipliers. */
1554 loading->multiplier.size
1556 "savefile.multipliers_size");
1557 if (loading->multiplier.size) {
1558 const char **modname;
1559 int j;
1560
1561 modname = secfile_lookup_str_vec(loading->file, &loading->multiplier.size,
1562 "savefile.multipliers_vector");
1563 sg_failure_ret(loading->multiplier.size != 0,
1564 "Failed to load multipliers order: %s",
1565 secfile_error());
1566 /* It's OK for the set of multipliers in the savefile to differ
1567 * from those in the ruleset. */
1568 loading->multiplier.order = fc_calloc(loading->multiplier.size,
1569 sizeof(*loading->multiplier.order));
1570 for (j = 0; j < loading->multiplier.size; j++) {
1571 loading->multiplier.order[j] = multiplier_by_rule_name(modname[j]);
1572 if (!loading->multiplier.order[j]) {
1573 log_verbose("Multiplier \"%s\" in savegame but not in ruleset, "
1574 "discarding", modname[j]);
1575 }
1576 }
1577 free(modname);
1578 }
1579
1580 /* Load specials. */
1581 loading->special.size
1583 "savefile.specials_size");
1584 if (loading->special.size) {
1585 const char **modname;
1586 size_t nmod;
1587 enum tile_special_type j;
1588
1589 modname = secfile_lookup_str_vec(loading->file, &loading->special.size,
1590 "savefile.specials_vector");
1591 sg_failure_ret(loading->special.size != 0,
1592 "Failed to load specials order: %s",
1593 secfile_error());
1594 /* make sure that the size of the array is divisible by 4 */
1595 /* Allocating extra 4 slots, just a couple of bytes,
1596 * in case of special.size being divisible by 4 already is intentional.
1597 * Added complexity would cost those couple of bytes in code size alone,
1598 * and we actually need at least one slot immediately after last valid
1599 * one. That's where S_LAST is (or was in version that saved the game)
1600 * and in some cases S_LAST gets written to savegame, at least as
1601 * activity target special when activity targets some base or road
1602 * instead. By having current S_LAST in that index allows us to map
1603 * that old S_LAST to current S_LAST, just like any real special within
1604 * special.size gets mapped. */
1605 nmod = loading->special.size + (4 - (loading->special.size % 4));
1606 loading->special.order = fc_calloc(nmod,
1607 sizeof(*loading->special.order));
1608 for (j = 0; j < loading->special.size; j++) {
1609 if (!fc_strcasecmp("Road", modname[j])) {
1610 loading->special.order[j] = S_OLD_ROAD;
1611 } else if (!fc_strcasecmp("Railroad", modname[j])) {
1612 loading->special.order[j] = S_OLD_RAILROAD;
1613 } else if (!fc_strcasecmp("River", modname[j])) {
1614 loading->special.order[j] = S_OLD_RIVER;
1615 } else {
1616 loading->special.order[j] = special_by_rule_name(modname[j]);
1617 }
1618 }
1619 free(modname);
1620 for (; j < nmod; j++) {
1621 loading->special.order[j] = S_LAST;
1622 }
1623 }
1624
1625 /* Load bases. */
1626 loading->base.size
1628 "savefile.bases_size");
1629 if (loading->base.size) {
1630 const char **modname;
1631 size_t nmod;
1632 int j;
1633
1634 modname = secfile_lookup_str_vec(loading->file, &loading->base.size,
1635 "savefile.bases_vector");
1636 sg_failure_ret(loading->base.size != 0,
1637 "Failed to load bases order: %s",
1638 secfile_error());
1639 /* make sure that the size of the array is divisible by 4 */
1640 nmod = 4 * ((loading->base.size + 3) / 4);
1641 loading->base.order = fc_calloc(nmod, sizeof(*loading->base.order));
1642 for (j = 0; j < loading->base.size; j++) {
1643 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1644
1645 sg_failure_ret(pextra != nullptr
1646 || game.control.num_base_types >= loading->base.size,
1647 "Unknown base type %s in savefile.",
1648 modname[j]);
1649
1650 if (pextra != nullptr) {
1651 loading->base.order[j] = extra_base_get(pextra);
1652 } else {
1653 loading->base.order[j] = nullptr;
1654 }
1655 }
1656 free(modname);
1657 for (; j < nmod; j++) {
1658 loading->base.order[j] = nullptr;
1659 }
1660 }
1661
1662 /* Load roads. */
1663 loading->road.size
1665 "savefile.roads_size");
1666 if (loading->road.size) {
1667 const char **modname;
1668 size_t nmod;
1669 int j;
1670
1671 modname = secfile_lookup_str_vec(loading->file, &loading->road.size,
1672 "savefile.roads_vector");
1673 sg_failure_ret(loading->road.size != 0,
1674 "Failed to load roads order: %s",
1675 secfile_error());
1677 "Number of roads defined by the ruleset (= %d) are "
1678 "lower than the number in the savefile (= %d).",
1679 game.control.num_road_types, (int)loading->road.size);
1680 /* Make sure that the size of the array is divisible by 4 */
1681 nmod = 4 * ((loading->road.size + 3) / 4);
1682 loading->road.order = fc_calloc(nmod, sizeof(*loading->road.order));
1683 for (j = 0; j < loading->road.size; j++) {
1684 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1685
1686 if (pextra != nullptr) {
1687 loading->road.order[j] = extra_road_get(pextra);
1688 } else {
1689 loading->road.order[j] = nullptr;
1690 }
1691 }
1692 free(modname);
1693 for (; j < nmod; j++) {
1694 loading->road.order[j] = nullptr;
1695 }
1696 }
1697
1698 /* Load specialists. */
1699 loading->specialist.size
1701 "savefile.specialists_size");
1702 if (loading->specialist.size) {
1703 const char **modname;
1704 size_t nmod;
1705 int j;
1706
1707 modname = secfile_lookup_str_vec(loading->file, &loading->specialist.size,
1708 "savefile.specialists_vector");
1709 sg_failure_ret(loading->specialist.size != 0,
1710 "Failed to load specialists order: %s",
1711 secfile_error());
1713 "Number of specialists defined by the ruleset (= %d) are "
1714 "lower than the number in the savefile (= %d).",
1715 game.control.num_specialist_types, (int)loading->specialist.size);
1716 /* Make sure that the size of the array is divisible by 4 */
1717 /* That's not really needed with specialists at the moment, but done this way
1718 * for consistency with other types, and to be prepared for the time it needs
1719 * to be this way. */
1720 nmod = 4 * ((loading->specialist.size + 3) / 4);
1721 loading->specialist.order = fc_calloc(nmod, sizeof(*loading->specialist.order));
1722 for (j = 0; j < loading->specialist.size; j++) {
1723 loading->specialist.order[j] = specialist_by_rule_name(modname[j]);
1724 }
1725 free(modname);
1726 for (; j < nmod; j++) {
1727 loading->specialist.order[j] = nullptr;
1728 }
1729 }
1730
1731 /* Load diplomatic state type order. */
1732 loading->ds_t.size
1734 "savefile.diplstate_type_size");
1735
1736 sg_failure_ret(loading->ds_t.size > 0,
1737 "Failed to load diplomatic state type order: %s",
1738 secfile_error());
1739
1740 if (loading->ds_t.size) {
1741 const char **modname;
1742 int j;
1743
1744 modname = secfile_lookup_str_vec(loading->file, &loading->ds_t.size,
1745 "savefile.diplstate_type_vector");
1746
1747 loading->ds_t.order = fc_calloc(loading->ds_t.size,
1748 sizeof(*loading->ds_t.order));
1749
1750 for (j = 0; j < loading->ds_t.size; j++) {
1751 loading->ds_t.order[j] = diplstate_type_by_name(modname[j],
1753 }
1754
1755 free(modname);
1756 }
1757
1758 /* Load city options order. */
1759 loading->coptions.size
1761 "savefile.city_options_size");
1762
1763 {
1764 const char *modname_old[] = { "Disband", "Sci_Specialists", "Tax_Specialists" };
1765 const char **modname;
1766 int j;
1767 bool compat;
1768
1769 if (loading->coptions.size > 0) {
1770 modname = secfile_lookup_str_vec(loading->file, &loading->coptions.size,
1771 "savefile.city_options_vector");
1772 compat = FALSE;
1773 } else {
1775 loading->coptions.size = 3;
1776 compat = TRUE;
1777 }
1778
1779 loading->coptions.order = fc_calloc(loading->coptions.size,
1780 sizeof(*loading->coptions.order));
1781
1782 for (j = 0; j < loading->coptions.size; j++) {
1783 loading->coptions.order[j] = city_options_by_name(modname[j],
1785 }
1786
1787 if (!compat) {
1788 free(modname);
1789 }
1790 }
1791
1792 /* Terrain identifiers */
1794 pterr->identifier_load = '\0';
1796
1797 i = 0;
1798 while ((terr_name = secfile_lookup_str_default(loading->file, nullptr,
1799 "savefile.terrident%d.name", i))
1800 != nullptr) {
1802
1803 if (pterr != nullptr) {
1804 const char *iptr
1805 = secfile_lookup_str_default(loading->file, nullptr,
1806 "savefile.terrident%d.identifier", i);
1807
1808 pterr->identifier_load = *iptr;
1809 } else {
1810 log_error("Identifier for unknown terrain type %s.", terr_name);
1811 }
1812 i++;
1813 }
1814
1817 if (pterr != pterr2 && pterr->identifier_load != '\0') {
1818 sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1819 "%s and %s share a saved identifier",
1821 }
1824}
1825
1826/* =======================================================================
1827 * Load game status.
1828 * ======================================================================= */
1829
1830/************************************************************************/
1834{
1835 int i;
1836 const char *name;
1837
1838 /* Check status and return if not OK (sg_success FALSE). */
1839 sg_check_ret();
1840
1841 for (i = 0;
1842 (name = secfile_lookup_str_default(loading->file, nullptr,
1843 "ruledata.government%d.name", i));
1844 i++) {
1846
1847 if (gov != nullptr) {
1848 gov->changed_to_times
1850 "ruledata.government%d.changes", i);
1851 }
1852 }
1853}
1854
1855/************************************************************************/
1858static void sg_load_game(struct loaddata *loading)
1859{
1860 int game_version;
1861 const char *str;
1862 int i;
1863
1864 /* Check status and return if not OK (sg_success FALSE). */
1865 sg_check_ret();
1866
1867 /* Load version. */
1869 = secfile_lookup_int_default(loading->file, 0, "game.version");
1870 /* We require at least version 2.2.99 */
1871 sg_failure_ret(20299 <= game_version, "Saved game is too old, at least "
1872 "version 2.2.99 required.");
1873
1874 loading->full_version = game_version;
1875
1876 secfile_entry_ignore(loading->file, "scenario.game_version");
1877
1878 /* Load server state. */
1879 str = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
1880 "game.server_state");
1881 loading->server_state = server_states_by_name(str, strcmp);
1882 if (!server_states_is_valid(loading->server_state)) {
1883 /* Don't take any risk! */
1884 loading->server_state = S_S_INITIAL;
1885 }
1886
1889 "game.meta_patches");
1891
1893 /* Do not overwrite this if the user requested a specific metaserver
1894 * from the command line (option --Metaserver). */
1898 "game.meta_server"));
1899 }
1900
1901 if ('\0' == srvarg.serverid[0]) {
1902 /* Do not overwrite this if the user requested a specific metaserver
1903 * from the command line (option --serverid). */
1906 "game.serverid"));
1907 }
1908 sz_strlcpy(server.game_identifier,
1909 secfile_lookup_str_default(loading->file, "", "game.id"));
1910 /* We are not checking game_identifier legality just yet.
1911 * That's done when we are sure that rand seed has been initialized,
1912 * so that we can generate new game_identifier, if needed.
1913 * See sq_load_sanitycheck(). */
1914
1917 "game.phase_mode");
1920 "game.phase_mode_stored");
1923 "game.phase");
1927 "game.scoreturn");
1928
1931 "game.timeoutint");
1934 "game.timeoutintinc");
1937 "game.timeoutinc");
1940 "game.timeoutincmult");
1943 "game.timeoutcounter");
1944
1945 game.info.turn
1946 = secfile_lookup_int_default(loading->file, 0, "game.turn");
1948 "game.year"), "%s", secfile_error());
1951 = secfile_lookup_bool_default(loading->file, FALSE, "game.year_0_hack");
1952
1954 = secfile_lookup_int_default(loading->file, 0, "game.globalwarming");
1956 = secfile_lookup_int_default(loading->file, 0, "game.heating");
1958 = secfile_lookup_int_default(loading->file, 0, "game.warminglevel");
1959
1961 = secfile_lookup_int_default(loading->file, 0, "game.nuclearwinter");
1963 = secfile_lookup_int_default(loading->file, 0, "game.cooling");
1965 = secfile_lookup_int_default(loading->file, 0, "game.coolinglevel");
1966
1967 /* Savegame may have stored random_seed for documentation purposes only,
1968 * but we want to keep it for resaving. */
1969 game.server.seed = secfile_lookup_int_default(loading->file, 0, "game.random_seed");
1970
1971 /* Global advances. */
1972 str = secfile_lookup_str_default(loading->file, nullptr,
1973 "game.global_advances");
1974 if (str != nullptr) {
1975 sg_failure_ret(strlen(str) == loading->technology.size,
1976 "Invalid length of 'game.global_advances' ("
1977 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
1978 strlen(str), loading->technology.size);
1979 for (i = 0; i < loading->technology.size; i++) {
1980 sg_failure_ret(str[i] == '1' || str[i] == '0',
1981 "Undefined value '%c' within 'game.global_advances'.",
1982 str[i]);
1983 if (str[i] == '1') {
1984 struct advance *padvance =
1985 advance_by_rule_name(loading->technology.order[i]);
1986
1987 if (padvance != nullptr) {
1989 }
1990 }
1991 }
1992 }
1993
1995 = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
1996
1998 = secfile_lookup_float_default(loading->file, 0, "game.last_turn_change_time");
1999}
2000
2001/* =======================================================================
2002 * Load random status.
2003 * ======================================================================= */
2004
2005/************************************************************************/
2008static void sg_load_random(struct loaddata *loading)
2009{
2010 /* Check status and return if not OK (sg_success FALSE). */
2011 sg_check_ret();
2012
2013 if (secfile_lookup_bool_default(loading->file, FALSE, "random.saved")) {
2014 const char *str;
2015 int i;
2016
2017 /* Since random state was previously saved, save it also when resaving.
2018 * This affects only pre-2.6 scenarios where scenario.save_random
2019 * is not defined.
2020 * - If this is 2.6 or later scenario -> it would have saved random.saved = TRUE
2021 * only if scenario.save_random is already TRUE
2022 *
2023 * Do NOT touch this in case of regular savegame. They always have random.saved
2024 * set, but if one starts to make scenario based on a savegame, we want
2025 * default scenario settings in the beginning (default save_random = FALSE).
2026 */
2029 }
2030
2032 "random.index_J"), "%s", secfile_error());
2034 "random.index_K"), "%s", secfile_error());
2036 "random.index_X"), "%s", secfile_error());
2037
2038 for (i = 0; i < 8; i++) {
2039 str = secfile_lookup_str(loading->file, "random.table%d",i);
2040 sg_failure_ret(str != nullptr, "%s", secfile_error());
2041 sscanf(str, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
2042 &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
2043 &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
2044 &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
2045 }
2046 loading->rstate.is_init = TRUE;
2047 fc_rand_set_state(loading->rstate);
2048 } else {
2049 /* No random values - mark the setting. */
2050 secfile_entry_ignore_by_path(loading->file, "random.saved");
2051
2052 /* We're loading a game without a seed (which is okay, if it's a scenario).
2053 * We need to generate the game seed now because it will be needed later
2054 * during the load. */
2056 loading->rstate = fc_rand_state();
2057 }
2058}
2059
2060/* =======================================================================
2061 * Load lua script data.
2062 * ======================================================================= */
2063
2064/************************************************************************/
2067static void sg_load_script(struct loaddata *loading)
2068{
2069 /* Check status and return if not OK (sg_success FALSE). */
2070 sg_check_ret();
2071
2073}
2074
2075/* =======================================================================
2076 * Load scenario data.
2077 * ======================================================================= */
2078
2079/************************************************************************/
2083{
2084 const char *buf;
2085 bool lake_flood_default;
2086
2087 /* Check status and return if not OK (sg_success FALSE). */
2088 sg_check_ret();
2089
2090 if (secfile_section_lookup(loading->file, "scenario") == nullptr) {
2092
2093 return;
2094 }
2095
2096 /* Default is that when there's scenario section (which we already checked)
2097 * this is a scenario. Only if it explicitly says that it's not, we consider
2098 * this regular savegame */
2099 game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
2100
2101 if (!game.scenario.is_scenario) {
2102 return;
2103 }
2104
2105 buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
2106 if (buf[0] != '\0') {
2108 }
2109
2111 "scenario.authors");
2112 if (buf[0] != '\0') {
2114 } else {
2115 game.scenario.authors[0] = '\0';
2116 }
2117
2119 "scenario.description");
2120 if (buf[0] != '\0') {
2122 } else {
2123 game.scenario_desc.description[0] = '\0';
2124 }
2125
2127 = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
2129 = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
2132 "scenario.startpos_nations");
2133
2136 "scenario.prevent_new_cities");
2137 if (loading->version < 20599) {
2138 /* Lake flooding may break some old scenarios where rivers made out of
2139 * lake terrains, so play safe there */
2141 } else {
2142 /* If lake flooding is a problem for a newer scenario, it could explicitly
2143 * disable it. */
2145 }
2148 "scenario.lake_flooding");
2151 "scenario.handmade");
2154 "scenario.allow_ai_type_fallback");
2156
2157 sg_failure_ret(loading->server_state == S_S_INITIAL
2158 || (loading->server_state == S_S_RUNNING
2159 && game.scenario.players),
2160 "Invalid scenario definition (server state '%s' and "
2161 "players are %s).",
2162 server_states_name(loading->server_state),
2163 game.scenario.players ? "saved" : "not saved");
2164
2165 /* Remove all defined players. They are recreated with the skill level
2166 * defined by the scenario. */
2167 (void) aifill(0);
2168}
2169
2170/* =======================================================================
2171 * Load game settings.
2172 * ======================================================================= */
2173
2174/************************************************************************/
2178{
2179 /* Check status and return if not OK (sg_success FALSE). */
2180 sg_check_ret();
2181
2182 settings_game_load(loading->file, "settings");
2183
2184 /* Save current status of fogofwar. */
2186
2187 /* Add all compatibility settings here. */
2188}
2189
2190/* =======================================================================
2191 * Load the main map.
2192 * ======================================================================= */
2193
2194/************************************************************************/
2197static void sg_load_map(struct loaddata *loading)
2198{
2199 /* Check status and return if not OK (sg_success FALSE). */
2200 sg_check_ret();
2201
2202 /* This defaults to TRUE even if map has not been generated. Also,
2203 * old versions have also explicitly saved TRUE even in pre-game.
2204 * We rely on that
2205 * 1) scenario maps have it explicitly right.
2206 * 2) when map is actually generated, it re-initialize this to FALSE. */
2208 = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
2209
2211
2212 /* Savegame may have stored random_seed for documentation purposes only,
2213 * but we want to keep it for resaving. */
2215 = secfile_lookup_int_default(loading->file, 0, "map.random_seed");
2216
2217 if (S_S_INITIAL == loading->server_state
2219 /* Generator MAPGEN_SCENARIO is used;
2220 * this map was done with the map editor. */
2221
2222 /* Load tiles. */
2225
2226 if (loading->version >= 30) {
2227 /* 2.6.0 or newer */
2229 } else {
2231 if (loading->version >= 20) {
2232 /* 2.5.0 or newer */
2234 }
2235 if (has_capability("specials", loading->secfile_options)) {
2236 /* Load specials. */
2238 }
2239 }
2240
2241 /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
2243 if (has_capability("specials", loading->secfile_options)) {
2244 /* Load resources. */
2246 } else if (has_capability("riversoverlay", loading->secfile_options)) {
2247 /* Load only rivers overlay. */
2249 }
2250
2251 /* Nothing more needed for a scenario. */
2252 secfile_entry_ignore(loading->file, "game.save_known");
2253
2254 return;
2255 }
2256
2257 if (S_S_INITIAL == loading->server_state) {
2258 /* Nothing more to do if it is not a scenario but in initial state. */
2259 return;
2260 }
2261
2264 if (loading->version >= 30) {
2265 /* 2.6.0 or newer */
2267 } else {
2269 if (loading->version >= 20) {
2270 /* 2.5.0 or newer */
2272 }
2274 }
2279}
2280
2281/************************************************************************/
2285{
2286 /* Check status and return if not OK (sg_success FALSE). */
2287 sg_check_ret();
2288
2289 /* Initialize the map for the current topology. 'map.xsize' and
2290 * 'map.ysize' must be set. */
2292
2293 /* Allocate map. */
2295
2296 /* get the terrain type */
2297 LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
2298 "map.t%04d");
2300
2301 /* Check for special tile sprites. */
2302 whole_map_iterate(&(wld.map), ptile) {
2303 const char *spec_sprite;
2304 const char *label;
2305 int nat_x, nat_y;
2306
2308 spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
2309 nat_x, nat_y);
2310 label = secfile_lookup_str_default(loading->file, nullptr,
2311 "map.label_%d_%d",
2312 nat_x, nat_y);
2313 if (ptile->spec_sprite != nullptr) {
2314 ptile->spec_sprite = fc_strdup(spec_sprite);
2315 }
2316 if (label != nullptr) {
2317 tile_set_label(ptile, label);
2318 }
2320}
2321
2322/************************************************************************/
2326{
2327 /* Check status and return if not OK (sg_success FALSE). */
2328 sg_check_ret();
2329
2330 /* Load extras. */
2331 halfbyte_iterate_extras(j, loading->extra.size) {
2332 LOAD_MAP_CHAR(ch, ptile, sg_extras_set_bv(&ptile->extras,
2333 ch, loading->extra.order + 4 * j),
2334 loading->file, "map.e%02d_%04d", j);
2336}
2337
2338/************************************************************************/
2342{
2343 /* Check status and return if not OK (sg_success FALSE). */
2344 sg_check_ret();
2345
2346 /* Load bases. */
2347 halfbyte_iterate_bases(j, loading->base.size) {
2348 LOAD_MAP_CHAR(ch, ptile, sg_bases_set_bv(&ptile->extras, ch,
2349 loading->base.order + 4 * j),
2350 loading->file, "map.b%02d_%04d", j);
2352}
2353
2354/************************************************************************/
2358{
2359 /* Check status and return if not OK (sg_success FALSE). */
2360 sg_check_ret();
2361
2362 /* Load roads. */
2363 halfbyte_iterate_roads(j, loading->road.size) {
2364 LOAD_MAP_CHAR(ch, ptile, sg_roads_set_bv(&ptile->extras, ch,
2365 loading->road.order + 4 * j),
2366 loading->file, "map.r%02d_%04d", j);
2368}
2369
2370/************************************************************************/
2374 bool rivers_overlay)
2375{
2376 /* Check status and return if not OK (sg_success FALSE). */
2377 sg_check_ret();
2378
2379 /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
2380 * from the savegame file.
2381 *
2382 * A scenario may define the terrain of the map but not list the specials
2383 * on it (thus allowing users to control the placement of specials).
2384 * However rivers are a special case and must be included in the map along
2385 * with the scenario. Thus in those cases this function should be called
2386 * to load the river information separate from any other special data.
2387 *
2388 * This does not need to be called from map_load(), because map_load()
2389 * loads the rivers overlay along with the rest of the specials. Call this
2390 * only if you've already called map_load_tiles(), and want to load only
2391 * the rivers overlay but no other specials. Scenarios that encode things
2392 * this way should have the "riversoverlay" capability. */
2393 halfbyte_iterate_special(j, loading->special.size) {
2394 LOAD_MAP_CHAR(ch, ptile, sg_special_set_bv(ptile, &ptile->extras, ch,
2395 loading->special.order + 4 * j,
2397 loading->file, "map.spe%02d_%04d", j);
2399}
2400
2401/************************************************************************/
2405{
2406 /* Check status and return if not OK (sg_success FALSE). */
2407 sg_check_ret();
2408
2410 loading->file, "map.res%04d");
2411
2412 /* After the resources are loaded, indicate those currently valid. */
2413 whole_map_iterate(&(wld.map), ptile) {
2414 if (ptile->resource == nullptr) {
2415 continue;
2416 }
2417
2418 if (ptile->terrain == nullptr
2419 || !terrain_has_resource(ptile->terrain, ptile->resource)) {
2420 BV_CLR(ptile->extras, extra_index(ptile->resource));
2421 }
2423
2426}
2427
2428/************************************************************************/
2433{
2434 struct nation_type *pnation;
2435 struct startpos *psp;
2436 struct tile *ptile;
2437 const char SEPARATOR = '#';
2438 const char *nation_names;
2439 int nat_x, nat_y;
2440 bool exclude;
2441 int i, startpos_count;
2442
2443 /* Check status and return if not OK (sg_success FALSE). */
2444 sg_check_ret();
2445
2447 = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
2448
2449 if (0 == startpos_count) {
2450 /* Nothing to do. */
2451 return;
2452 }
2453
2454 for (i = 0; i < startpos_count; i++) {
2455 if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
2456 || !secfile_lookup_int(loading->file, &nat_y,
2457 "map.startpos%d.y", i)) {
2458 log_sg("Warning: Undefined coordinates for startpos %d", i);
2459 continue;
2460 }
2461
2462 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
2463 if (ptile == nullptr) {
2464 log_error("Start position native coordinates (%d, %d) do not exist "
2465 "in this map. Skipping...", nat_x, nat_y);
2466 continue;
2467 }
2468
2469 exclude = secfile_lookup_bool_default(loading->file, FALSE,
2470 "map.startpos%d.exclude", i);
2471
2472 psp = map_startpos_new(ptile);
2473
2475 "map.startpos%d.nations", i);
2476 if (nation_names != nullptr && '\0' != nation_names[0]) {
2477 const size_t size = strlen(nation_names) + 1;
2478 char buf[size], *start, *end;
2479
2481 for (start = buf - 1; start != nullptr; start = end) {
2482 start++;
2483 if ((end = strchr(start, SEPARATOR))) {
2484 *end = '\0';
2485 }
2486
2487 pnation = nation_by_rule_name(start);
2488 if (NO_NATION_SELECTED != pnation) {
2489 if (exclude) {
2490 startpos_disallow(psp, pnation);
2491 } else {
2492 startpos_allow(psp, pnation);
2493 }
2494 } else {
2495 log_verbose("Missing nation \"%s\".", start);
2496 }
2497 }
2498 }
2499 }
2500
2501 if (0 < map_startpos_count()
2502 && loading->server_state == S_S_INITIAL
2504 log_verbose("Number of starts (%d) are lower than rules.max_players "
2505 "(%d), lowering rules.max_players.",
2508 }
2509
2510 /* Re-initialize nation availability in light of start positions.
2511 * This has to be after loading [scenario] and [map].startpos and
2512 * before we seek nations for players. */
2514}
2515
2516/************************************************************************/
2520{
2521 int x, y;
2522 struct player *owner = nullptr;
2523 struct tile *claimer = nullptr;
2524 struct player *eowner = nullptr;
2525
2526 /* Check status and return if not OK (sg_success FALSE). */
2527 sg_check_ret();
2528
2529 if (game.info.is_new_game) {
2530 /* No owner/source information for a new game / scenario. */
2531 return;
2532 }
2533
2534 /* Owner and ownership source are stored as plain numbers */
2535 for (y = 0; y < MAP_NATIVE_HEIGHT; y++) {
2536 const char *buffer1 = secfile_lookup_str(loading->file,
2537 "map.owner%04d", y);
2538 const char *buffer2 = secfile_lookup_str(loading->file,
2539 "map.source%04d", y);
2540 const char *buffer3 = secfile_lookup_str(loading->file,
2541 "map.eowner%04d", y);
2542 const char *ptr1 = buffer1;
2543 const char *ptr2 = buffer2;
2544 const char *ptr3 = buffer3;
2545
2546 sg_failure_ret(buffer1 != nullptr, "%s", secfile_error());
2547 sg_failure_ret(buffer2 != nullptr, "%s", secfile_error());
2548 if (loading->version >= 30) {
2549 sg_failure_ret(buffer3 != nullptr, "%s", secfile_error());
2550 }
2551
2552 for (x = 0; x < MAP_NATIVE_WIDTH; x++) {
2553 char token1[TOKEN_SIZE];
2554 char token2[TOKEN_SIZE];
2555 char token3[TOKEN_SIZE];
2556 int number;
2557 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2558
2559 scanin(&ptr1, ",", token1, sizeof(token1));
2560 sg_failure_ret(token1[0] != '\0',
2561 "Map size not correct (map.owner%d).", y);
2562 if (strcmp(token1, "-") == 0) {
2563 owner = nullptr;
2564 } else {
2566 "Got map owner %s in (%d, %d).", token1, x, y);
2567 owner = player_by_number(number);
2568 }
2569
2570 scanin(&ptr2, ",", token2, sizeof(token2));
2571 sg_failure_ret(token2[0] != '\0',
2572 "Map size not correct (map.source%d).", y);
2573 if (strcmp(token2, "-") == 0) {
2574 claimer = nullptr;
2575 } else {
2577 "Got map source %s in (%d, %d).", token2, x, y);
2578 claimer = index_to_tile(&(wld.map), number);
2579 }
2580
2581 if (loading->version >= 30) {
2582 scanin(&ptr3, ",", token3, sizeof(token3));
2583 sg_failure_ret(token3[0] != '\0',
2584 "Map size not correct (map.eowner%d).", y);
2585 if (strcmp(token3, "-") == 0) {
2586 eowner = nullptr;
2587 } else {
2589 "Got base owner %s in (%d, %d).", token3, x, y);
2590 eowner = player_by_number(number);
2591 }
2592 } else {
2593 eowner = owner;
2594 }
2595
2597 tile_claim_bases(ptile, eowner);
2598 log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
2599 }
2600 }
2601}
2602
2603/************************************************************************/
2607{
2608 int x, y;
2609
2610 /* Check status and return if not OK (sg_success FALSE). */
2611 sg_check_ret();
2612
2613 sg_failure_ret(loading->worked_tiles == nullptr,
2614 "City worked map not loaded!");
2615
2616 loading->worked_tiles = fc_malloc(MAP_INDEX_SIZE *
2617 sizeof(*loading->worked_tiles));
2618
2619 for (y = 0; y < MAP_NATIVE_HEIGHT; y++) {
2620 const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
2621 y);
2622 const char *ptr = buffer;
2623
2624 sg_failure_ret(buffer != nullptr,
2625 "Savegame corrupt - map line %d not found.", y);
2626 for (x = 0; x < MAP_NATIVE_WIDTH; x++) {
2627 char token[TOKEN_SIZE];
2628 int number;
2629 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2630
2631 scanin(&ptr, ",", token, sizeof(token));
2632 sg_failure_ret('\0' != token[0],
2633 "Savegame corrupt - map size not correct.");
2634 if (strcmp(token, "-") == 0) {
2635 number = -1;
2636 } else {
2637 sg_failure_ret(str_to_int(token, &number) && 0 < number,
2638 "Savegame corrupt - got tile worked by city "
2639 "id=%s in (%d, %d).", token, x, y);
2640 }
2641
2642 loading->worked_tiles[ptile->index] = number;
2643 }
2644 }
2645}
2646
2647/************************************************************************/
2651{
2652 /* Check status and return if not OK (sg_success FALSE). */
2653 sg_check_ret();
2654
2655 players_iterate(pplayer) {
2656 /* Allocate player private map here; it is needed in different modules
2657 * besides this one ((i.e. sg_load_player_*()). */
2658 player_map_init(pplayer);
2660
2662 "game.save_known")) {
2663 int lines = player_slot_max_used_number() / 32 + 1;
2664 int j, p, l, i;
2665 unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
2666
2667 for (l = 0; l < lines; l++) {
2668 for (j = 0; j < 8; j++) {
2669 for (i = 0; i < 4; i++) {
2670 /* Only bother trying to load the map for this halfbyte if at least
2671 * one of the corresponding player slots is in use. */
2672 if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
2673 LOAD_MAP_CHAR(ch, ptile,
2674 known[l * MAP_INDEX_SIZE + tile_index(ptile)]
2675 |= ascii_hex2bin(ch, j),
2676 loading->file, "map.k%02d_%04d", l * 8 + j);
2677 break;
2678 }
2679 }
2680 }
2681 }
2682
2683 players_iterate(pplayer) {
2684 dbv_clr_all(&pplayer->tile_known);
2686
2687 /* HACK: we read the known data from hex into 32-bit integers, and
2688 * now we convert it to the known tile data of each player. */
2689 whole_map_iterate(&(wld.map), ptile) {
2690 players_iterate(pplayer) {
2691 p = player_index(pplayer);
2692 l = player_index(pplayer) / 32;
2693
2694 if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
2695 map_set_known(ptile, pplayer);
2696 }
2699
2700 FC_FREE(known);
2701 }
2702}
2703
2704/* =======================================================================
2705 * Load player data.
2706 *
2707 * This is split into two parts as some data can only be loaded if the
2708 * number of players is known and the corresponding player slots are
2709 * defined.
2710 * ======================================================================= */
2711
2712/************************************************************************/
2716{
2717 int i, k, nplayers;
2718 const char *str;
2719 bool shuffle_loaded = TRUE;
2720
2721 /* Check status and return if not OK (sg_success FALSE). */
2722 sg_check_ret();
2723
2724 if (S_S_INITIAL == loading->server_state
2725 || game.info.is_new_game) {
2726 /* Nothing more to do. */
2727 return;
2728 }
2729
2730 /* Load destroyed wonders: */
2732 "players.destroyed_wonders");
2733 sg_failure_ret(str != nullptr, "%s", secfile_error());
2734 sg_failure_ret(strlen(str) == loading->improvement.size,
2735 "Invalid length for 'players.destroyed_wonders' ("
2736 SIZE_T_PRINTF" ~= " SIZE_T_PRINTF ")",
2737 strlen(str), loading->improvement.size);
2738 for (k = 0; k < loading->improvement.size; k++) {
2739 sg_failure_ret(str[k] == '1' || str[k] == '0',
2740 "Undefined value '%c' within "
2741 "'players.destroyed_wonders'.", str[k]);
2742
2743 if (str[k] == '1') {
2744 struct impr_type *pimprove =
2745 improvement_by_rule_name(loading->improvement.order[k]);
2746
2747 if (pimprove) {
2750 }
2751 }
2752 }
2753
2754 server.identity_number
2755 = secfile_lookup_int_default(loading->file, server.identity_number,
2756 "players.identity_number_used");
2757
2758 /* First remove all defined players. */
2759 players_iterate(pplayer) {
2760 server_remove_player(pplayer);
2762
2763 /* Now, load the players from the savefile. */
2764 player_slots_iterate(pslot) {
2765 struct player *pplayer;
2766 struct rgbcolor *prgbcolor = nullptr;
2767 int pslot_id = player_slot_index(pslot);
2768
2769 if (secfile_section_lookup(loading->file, "player%d",
2770 pslot_id) == nullptr) {
2771 continue;
2772 }
2773
2774 /* Get player AI type. */
2775 str = secfile_lookup_str(loading->file, "player%d.ai_type",
2776 player_slot_index(pslot));
2777 sg_failure_ret(str != nullptr, "%s", secfile_error());
2778
2779 /* Get player color */
2780 if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
2781 pslot_id)) {
2782 if (loading->version >= 10 && game_was_started()) {
2783 /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
2784 * as they predate the introduction of configurable player colors. */
2785 log_sg("Game has started, yet player %d has no color defined.",
2786 pslot_id);
2787 /* This will be fixed up later */
2788 } else {
2789 log_verbose("No color defined for player %d.", pslot_id);
2790 /* Colors will be assigned on game start, or at end of savefile
2791 * loading if game has already started */
2792 }
2793 }
2794
2795 /* Create player. */
2796 pplayer = server_create_player(player_slot_index(pslot), str,
2797 prgbcolor,
2800 sg_failure_ret(pplayer != nullptr, "Invalid AI type: '%s'!", str);
2801
2802 server_player_init(pplayer, FALSE, FALSE);
2803
2804 /* Free the color definition. */
2806
2807 /* Multipliers (policies) */
2808
2809 /* First initialise player values with ruleset defaults; this will
2810 * cover any in the ruleset not known when the savefile was created. */
2811 multipliers_iterate(pmul) {
2812 pplayer->multipliers[multiplier_index(pmul)].value
2813 = pplayer->multipliers[multiplier_index(pmul)].target = pmul->def;
2815
2816 /* Now override with any values from the savefile. */
2817 for (k = 0; k < loading->multiplier.size; k++) {
2818 const struct multiplier *pmul = loading->multiplier.order[k];
2819
2820 if (pmul) {
2822 int val =
2824 "player%d.multiplier%d.val",
2825 player_slot_index(pslot), k);
2826 int rval = (((CLIP(pmul->start, val, pmul->stop)
2827 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2828
2829 if (rval != val) {
2830 log_verbose("Player %d had illegal value for multiplier \"%s\": "
2831 "was %d, clamped to %d", pslot_id,
2832 multiplier_rule_name(pmul), val, rval);
2833 }
2834 pplayer->multipliers[idx].value = rval;
2835
2836 val =
2838 pplayer->multipliers[idx].value,
2839 "player%d.multiplier%d.target",
2840 player_slot_index(pslot), k);
2841 rval = (((CLIP(pmul->start, val, pmul->stop)
2842 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2843
2844 if (rval != val) {
2845 log_verbose("Player %d had illegal value for multiplier_target "
2846 "\"%s\": was %d, clamped to %d", pslot_id,
2847 multiplier_rule_name(pmul), val, rval);
2848 }
2849 pplayer->multipliers[idx].target = rval;
2850
2851 /* Never present in savegame2 format */
2852 pplayer->multipliers[idx].changed = 0;
2853 } /* else silently discard multiplier not in current ruleset */
2854 }
2855
2856 /* Just in case savecompat starts adding it in the future. */
2857 pplayer->server.border_vision =
2859 "player%d.border_vision",
2860 player_slot_index(pslot));
2862
2863 /* check number of players */
2864 nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
2865 sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
2866 "(%d) from the loaded game does not match the number of "
2867 "players present (%d).", nplayers, player_count());
2868
2869 /* Load team information. */
2870 players_iterate(pplayer) {
2871 int team;
2872 struct team_slot *tslot = nullptr;
2873
2875 "player%d.team_no",
2876 player_number(pplayer))
2878 "Invalid team definition for player %s (nb %d).",
2879 player_name(pplayer), player_number(pplayer));
2880 /* Should never fail when slot given is not nullptr */
2881 team_add_player(pplayer, team_new(tslot));
2883
2884 /* Loading the shuffle list is quite complex. At the time of saving the
2885 * shuffle data is saved as
2886 * shuffled_player_<number> = player_slot_id
2887 * where number is an increasing number and player_slot_id is a number
2888 * between 0 and the maximum number of player slots. Now we have to create
2889 * a list
2890 * shuffler_players[number] = player_slot_id
2891 * where all player slot IDs are used exactly one time. The code below
2892 * handles this ... */
2893 if (secfile_lookup_int_default(loading->file, -1,
2894 "players.shuffled_player_%d", 0) >= 0) {
2895 int slots = player_slot_count();
2896 int plrcount = player_count();
2899
2900 for (i = 0; i < slots; i++) {
2901 /* Array to save used numbers. */
2903 /* List of all player IDs (needed for set_shuffled_players()). It is
2904 * initialised with the value -1 to indicate that no value is set. */
2905 shuffled_players[i] = -1;
2906 }
2907
2908 /* Load shuffled player list. */
2909 for (i = 0; i < plrcount; i++) {
2910 int shuffle
2912 "players.shuffled_player_%d", i);
2913
2914 if (shuffle == -1) {
2915 log_sg("Missing player shuffle information (index %d) "
2916 "- reshuffle player list!", i);
2918 break;
2919 } else if (shuffled_player_set[shuffle]) {
2920 log_sg("Player shuffle %d used two times "
2921 "- reshuffle player list!", shuffle);
2923 break;
2924 }
2925 /* Set this ID as used. */
2927
2928 /* Save the player ID in the shuffle list. */
2930 }
2931
2932 if (shuffle_loaded) {
2933 /* Insert missing numbers. */
2934 int shuffle_index = plrcount;
2935
2936 for (i = 0; i < slots; i++) {
2937 if (!shuffled_player_set[i]) {
2939 }
2940
2941 /* shuffle_index must not grow higher than size of shuffled_players. */
2943 "Invalid player shuffle data!");
2944 }
2945
2946#ifdef FREECIV_DEBUG
2947 log_debug("[load shuffle] player_count() = %d", player_count());
2948 player_slots_iterate(pslot) {
2949 int plrid = player_slot_index(pslot);
2950
2951 log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
2953 shuffled_player_set[plrid] ? "is used" : "-");
2955#endif /* FREECIV_DEBUG */
2956
2957 /* Set shuffle list from savegame. */
2959 }
2960 }
2961
2962 if (!shuffle_loaded) {
2963 /* No shuffled players included or error loading them, so shuffle them
2964 * (this may include scenarios). */
2966 }
2967}
2968
2969/************************************************************************/
2973{
2974 /* Check status and return if not OK (sg_success FALSE). */
2975 sg_check_ret();
2976
2977 if (game.info.is_new_game) {
2978 /* Nothing to do. */
2979 return;
2980 }
2981
2982 players_iterate(pplayer) {
2983 sg_load_player_main(loading, pplayer);
2985 sg_load_player_units(loading, pplayer);
2987
2988 /* Check the success of the functions above. */
2989 sg_check_ret();
2990
2991 /* Print out some information */
2992 if (is_ai(pplayer)) {
2993 log_normal(_("%s has been added as %s level AI-controlled player "
2994 "(%s)."), player_name(pplayer),
2995 ai_level_translated_name(pplayer->ai_common.skill_level),
2996 ai_name(pplayer->ai));
2997 } else {
2998 log_normal(_("%s has been added as human player."),
2999 player_name(pplayer));
3000 }
3002
3003 /* Also load the transport status of the units here. It must be a special
3004 * case as all units must be known (unit on an allied transporter). */
3005 players_iterate(pplayer) {
3006 /* Load unit transport status. */
3009
3010 /* Savegame may contain nation assignments that are incompatible with the
3011 * current nationset -- for instance, if it predates the introduction of
3012 * nationsets. Ensure they are compatible, one way or another. */
3014
3015 /* Some players may have invalid nations in the ruleset. Once all players
3016 * are loaded, pick one of the remaining nations for them. */
3017 players_iterate(pplayer) {
3018 if (pplayer->nation == NO_NATION_SELECTED) {
3019 player_set_nation(pplayer, pick_a_nation(nullptr, FALSE, TRUE,
3021 /* TRANS: Minor error message: <Leader> ... <Poles>. */
3022 log_sg(_("%s had invalid nation; changing to %s."),
3023 player_name(pplayer), nation_plural_for_player(pplayer));
3024
3025 ai_traits_init(pplayer);
3026 }
3028
3029 /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
3032 if (pplayers_allied(plr, aplayer)) {
3034 DS_ALLIANCE);
3035
3038 log_sg("Illegal alliance structure detected: "
3039 "%s alliance to %s reduced to peace treaty.",
3044 }
3045 }
3048
3049 /* Update cached city illness. This can depend on trade routes,
3050 * so can't be calculated until all players have been loaded. */
3051 if (game.info.illness_on) {
3053 pcity->server.illness
3054 = city_illness_calc(pcity, nullptr, nullptr,
3055 &(pcity->illness_trade), nullptr);
3057 }
3058
3059 /* Update all city information. This must come after all cities are
3060 * loaded (in player_load) but before player (dumb) cities are loaded
3061 * in player_load_vision(). */
3062 players_iterate(plr) {
3063 city_list_iterate(plr->cities, pcity) {
3066 CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
3069
3070 /* Since the cities must be placed on the map to put them on the
3071 player map we do this afterwards */
3072 players_iterate(pplayer) {
3074 /* Check the success of the function above. */
3075 sg_check_ret();
3077
3078 /* Check shared vision. Shared tiles are never given in savegame2 save */
3079 players_iterate(pplayer) {
3080 BV_CLR_ALL(pplayer->gives_shared_vision);
3081 BV_CLR_ALL(pplayer->gives_shared_tiles);
3082 BV_CLR_ALL(pplayer->server.really_gives_vision);
3084
3085 /* Set up shared vision... */
3086 players_iterate(pplayer) {
3087 int plr1 = player_index(pplayer);
3088
3090 int plr2 = player_index(pplayer2);
3091
3093 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
3094 give_shared_vision(pplayer, pplayer2);
3095 }
3098
3099 /* ...and check it */
3102 /* TODO: Is there a good reason player is not marked as
3103 * giving shared vision to themselves -> really_gives_vision()
3104 * returning FALSE when pplayer1 == pplayer2 */
3105 if (pplayer1 != pplayer2
3108 sg_regr(3000900,
3109 _("%s did not give shared vision to team member %s."),
3112 }
3114 sg_regr(3000900,
3115 _("%s did not give shared vision to team member %s."),
3118 }
3119 }
3122
3125
3126 /* All vision is ready; this calls city_thaw_workers_queue(). */
3128
3129 /* Make sure everything is consistent. */
3130 players_iterate(pplayer) {
3131 unit_list_iterate(pplayer->units, punit) {
3133 struct tile *ptile = unit_tile(punit);
3134
3135 log_sg("%s doing illegal activity in savegame!",
3137 log_sg("Activity: %s, Target: %s, Tile: (%d, %d), Terrain: %s",
3141 : "missing",
3142 TILE_XY(ptile), terrain_rule_name(tile_terrain(ptile)));
3144 }
3147
3150 city_thaw_workers(pcity); /* may auto_arrange_workers() */
3152
3153 /* Player colors are always needed once game has started. Pre-2.4 savegames
3154 * lack them. This cannot be in compatibility conversion layer as we need
3155 * all the player data available to be able to assign best colors. */
3156 if (game_was_started()) {
3158 }
3159}
3160
3161/************************************************************************/
3165 struct player *plr)
3166{
3167 const char **slist;
3168 int i, plrno = player_number(plr);
3169 const char *str;
3170 struct government *gov;
3171 const char *level;
3172 const char *barb_str;
3173 size_t nval;
3174
3175 /* Check status and return if not OK (sg_success FALSE). */
3176 sg_check_ret();
3177
3178 /* Basic player data. */
3179 str = secfile_lookup_str(loading->file, "player%d.name", plrno);
3180 sg_failure_ret(str != nullptr, "%s", secfile_error());
3182 sz_strlcpy(plr->username,
3184 "player%d.username", plrno));
3186 "player%d.unassigned_user", plrno),
3187 "%s", secfile_error());
3190 "player%d.orig_username",
3191 plrno));
3194 "player%d.ranked_username",
3195 plrno));
3197 "player%d.unassigned_ranked", plrno),
3198 "%s", secfile_error());
3200 "player%d.delegation_username",
3201 plrno);
3202 /* Defaults to no delegation. */
3203 if (strlen(str)) {
3205 }
3206
3207 /* Player flags */
3208 BV_CLR_ALL(plr->flags);
3209 slist = secfile_lookup_str_vec(loading->file, &nval, "player%d.flags", plrno);
3210 for (i = 0; i < nval; i++) {
3211 const char *sval = slist[i];
3213
3214 sg_failure_ret(plr_flag_id_is_valid(fid), "Invalid player flag \"%s\".", sval);
3215
3216 BV_SET(plr->flags, fid);
3217 }
3218 free(slist);
3219
3220 /* Nation */
3221 str = secfile_lookup_str(loading->file, "player%d.nation", plrno);
3223 if (plr->nation != nullptr) {
3224 ai_traits_init(plr);
3225 }
3226
3227 /* Government */
3228 str = secfile_lookup_str(loading->file, "player%d.government_name",
3229 plrno);
3231 sg_failure_ret(gov != nullptr, "Player%d: unsupported government \"%s\".",
3232 plrno, str);
3233 plr->government = gov;
3234
3235 /* Target government */
3237 "player%d.target_government_name", plrno);
3238 if (str != nullptr) {
3240 } else {
3241 plr->target_government = nullptr;
3242 }
3245 "player%d.revolution_finishes", plrno);
3246
3247 /* Load diplomatic data (diplstate + embassy + vision).
3248 * Shared vision is loaded in sg_load_players(). */
3250 players_iterate(pplayer) {
3251 char buf[32];
3252 int unconverted;
3253 struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
3254 i = player_index(pplayer);
3255
3256 /* load diplomatic status */
3257 fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
3258
3259 unconverted =
3260 secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
3261 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
3262 /* Look up what state the unconverted number represents. */
3263 ds->type = loading->ds_t.order[unconverted];
3264 } else {
3265 log_sg("No valid diplomatic state type between players %d and %d",
3266 plrno, i);
3267
3268 ds->type = DS_WAR;
3269 }
3270
3271 unconverted =
3272 secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
3273 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
3274 /* Look up what state the unconverted number represents. */
3275 ds->max_state = loading->ds_t.order[unconverted];
3276 } else {
3277 log_sg("No valid diplomatic max_state between players %d and %d",
3278 plrno, i);
3279
3280 ds->max_state = DS_WAR;
3281 }
3282
3283 /* FIXME: If either party is barbarian, we cannot enforce below check */
3284#if 0
3285 if (ds->type == DS_WAR && ds->first_contact_turn <= 0) {
3286 sg_regr(3020000,
3287 "Player%d: War with player %d who has never been met. "
3288 "Reverted to No Contact state.", plrno, i);
3289 ds->type = DS_NO_CONTACT;
3290 }
3291#endif
3292
3293 if (valid_dst_closest(ds) != ds->max_state) {
3294 sg_regr(3020000,
3295 "Player%d: closest diplstate to player %d less than current. "
3296 "Updated.", plrno, i);
3297 ds->max_state = ds->type;
3298 }
3299
3300 ds->first_contact_turn =
3302 "%s.first_contact_turn", buf);
3303 ds->turns_left =
3304 secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
3305 ds->has_reason_to_cancel =
3307 "%s.has_reason_to_cancel", buf);
3308 ds->contact_turns_left =
3310 "%s.contact_turns_left", buf);
3311
3312 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
3313 buf)) {
3314 BV_SET(plr->real_embassy, i);
3315 }
3316 /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
3317 * must be known. */
3319
3320 /* load ai data */
3322 char buf[32];
3323
3324 fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
3326
3328 secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
3329 CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
3331
3332 CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
3333
3334 /* Some sane defaults */
3335 plr->ai_common.fuzzy = 0;
3336 plr->ai_common.expand = 100;
3337 plr->ai_common.science_cost = 100;
3338
3339
3340 level = secfile_lookup_str_default(loading->file, nullptr,
3341 "player%d.ai.level", plrno);
3342 if (level != nullptr) {
3343 if (!fc_strcasecmp("Handicapped", level)) {
3344 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
3346 } else {
3348 }
3349 } else {
3351 }
3352
3357 "player%d.ai.skill_level",
3358 plrno));
3359 }
3360
3362 "player%d.ai.barb_type", plrno);
3364
3366 log_sg("Player%d: Invalid barbarian type \"%s\". "
3367 "Changed to \"None\".", plrno, barb_str);
3369 }
3370
3371 if (is_barbarian(plr)) {
3372 server.nbarbarians++;
3373 }
3374
3375 if (is_ai(plr)) {
3377 CALL_PLR_AI_FUNC(gained_control, plr, plr);
3378 }
3379
3380 /* Load nation style. */
3381 {
3382 struct nation_style *style;
3383
3384 str = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
3385
3386 /* Handle pre-2.6 savegames */
3387 if (str == nullptr) {
3388 str = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
3389 plrno);
3390 }
3391
3392 sg_failure_ret(str != nullptr, "%s", secfile_error());
3393 style = style_by_rule_name(str);
3394 if (style == nullptr) {
3395 style = style_by_number(0);
3396 log_sg("Player%d: unsupported city_style_name \"%s\". "
3397 "Changed to \"%s\".", plrno, str, style_rule_name(style));
3398 }
3399 plr->style = style;
3400 }
3401
3403 "player%d.idle_turns", plrno),
3404 "%s", secfile_error());
3406 "player%d.is_male", plrno);
3408 "player%d.is_alive", plrno),
3409 "%s", secfile_error());
3411 "player%d.turns_alive", plrno),
3412 "%s", secfile_error());
3414 "player%d.last_war", plrno),
3415 "%s", secfile_error());
3417 "player%d.phase_done", plrno);
3419 "player%d.gold", plrno),
3420 "%s", secfile_error());
3422 "player%d.rates.tax", plrno),
3423 "%s", secfile_error());
3425 "player%d.rates.science", plrno),
3426 "%s", secfile_error());
3428 "player%d.rates.luxury", plrno),
3429 "%s", secfile_error());
3430 plr->server.bulbs_last_turn =
3432 "player%d.research.bulbs_last_turn", plrno);
3433
3434 /* Traits */
3435 if (plr->nation) {
3436 for (i = 0; i < loading->trait.size; i++) {
3437 enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
3438
3439 if (trait_is_valid(tr)) {
3440 int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
3441 plrno, i);
3442
3443 if (val != -1) {
3444 plr->ai_common.traits[tr].val = val;
3445 }
3446
3448 "player%d.trait%d.mod", plrno, i),
3449 "%s", secfile_error());
3450 plr->ai_common.traits[tr].mod = val;
3451 }
3452 }
3453 }
3454
3455 /* Achievements */
3456 {
3457 int count;
3458
3459 count = secfile_lookup_int_default(loading->file, -1,
3460 "player%d.achievement_count", plrno);
3461
3462 if (count > 0) {
3463 for (i = 0; i < count; i++) {
3464 const char *name;
3465 struct achievement *pach;
3466 bool first;
3467
3469 "player%d.achievement%d.name", plrno, i);
3471
3472 sg_failure_ret(pach != nullptr,
3473 "Unknown achievement \"%s\".", name);
3474
3476 "player%d.achievement%d.first",
3477 plrno, i),
3478 "achievement error: %s", secfile_error());
3479
3480 sg_failure_ret(pach->first == nullptr || !first,
3481 "Multiple players listed as first to get achievement \"%s\".",
3482 name);
3483
3484 BV_SET(pach->achievers, player_index(plr));
3485
3486 if (first) {
3487 pach->first = plr;
3488 }
3489 }
3490 }
3491 }
3492
3493 /* Player score. */
3494 plr->score.happy =
3496 "score%d.happy", plrno);
3497 plr->score.content =
3499 "score%d.content", plrno);
3500 plr->score.unhappy =
3502 "score%d.unhappy", plrno);
3503 plr->score.angry =
3505 "score%d.angry", plrno);
3506
3507 /* Make sure that the score about specialists in current ruleset that
3508 * were not present at saving time are set to zero. */
3510 plr->score.specialists[sp] = 0;
3512
3513 for (i = 0; i < loading->specialist.size; i++) {
3514 plr->score.specialists[specialist_index(loading->specialist.order[i])]
3516 "score%d.specialists%d", plrno, i);
3517 }
3518
3519 plr->score.wonders =
3521 "score%d.wonders", plrno);
3522 plr->score.techs =
3524 "score%d.techs", plrno);
3525 plr->score.techout =
3527 "score%d.techout", plrno);
3528 plr->score.landarea =
3530 "score%d.landarea", plrno);
3531 plr->score.settledarea =
3533 "score%d.settledarea", plrno);
3534 plr->score.population =
3536 "score%d.population", plrno);
3537 plr->score.cities =
3539 "score%d.cities", plrno);
3540 plr->score.units =
3542 "score%d.units", plrno);
3543 plr->score.pollution =
3545 "score%d.pollution", plrno);
3546 plr->score.literacy =
3548 "score%d.literacy", plrno);
3549 plr->score.bnp =
3551 "score%d.bnp", plrno);
3552 plr->score.mfg =
3554 "score%d.mfg", plrno);
3555 plr->score.spaceship =
3557 "score%d.spaceship", plrno);
3558 plr->score.units_built =
3560 "score%d.units_built", plrno);
3561 plr->score.units_killed =
3563 "score%d.units_killed", plrno);
3564 plr->score.units_lost =
3566 "score%d.units_lost", plrno);
3567 plr->score.units_used = 0; /* Was never saved to savegame2.c saves */
3568 plr->score.culture =
3570 "score%d.culture", plrno);
3571 plr->score.game =
3573 "score%d.total", plrno);
3574
3575 /* Load space ship data. */
3576 {
3577 struct player_spaceship *ship = &plr->spaceship;
3578 char prefix[32];
3579 const char *st;
3580 int ei;
3581
3582 fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
3585 &ei,
3586 "%s.state", prefix),
3587 "%s", secfile_error());
3588 ship->state = ei;
3589
3590 if (ship->state != SSHIP_NONE) {
3591 sg_failure_ret(secfile_lookup_int(loading->file, &ship->structurals,
3592 "%s.structurals", prefix),
3593 "%s", secfile_error());
3594 sg_failure_ret(secfile_lookup_int(loading->file, &ship->components,
3595 "%s.components", prefix),
3596 "%s", secfile_error());
3598 "%s.modules", prefix),
3599 "%s", secfile_error());
3601 "%s.fuel", prefix),
3602 "%s", secfile_error());
3603 sg_failure_ret(secfile_lookup_int(loading->file, &ship->propulsion,
3604 "%s.propulsion", prefix),
3605 "%s", secfile_error());
3606 sg_failure_ret(secfile_lookup_int(loading->file, &ship->habitation,
3607 "%s.habitation", prefix),
3608 "%s", secfile_error());
3609 sg_failure_ret(secfile_lookup_int(loading->file, &ship->life_support,
3610 "%s.life_support", prefix),
3611 "%s", secfile_error());
3612 sg_failure_ret(secfile_lookup_int(loading->file, &ship->solar_panels,
3613 "%s.solar_panels", prefix),
3614 "%s", secfile_error());
3615
3616 st = secfile_lookup_str(loading->file, "%s.structure", prefix);
3617 sg_failure_ret(st != nullptr, "%s", secfile_error())
3618 for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
3619 sg_failure_ret(st[i] == '1' || st[i] == '0',
3620 "Undefined value '%c' within '%s.structure'.", st[i],
3621 prefix)
3622
3623 if (!(st[i] == '0')) {
3624 BV_SET(ship->structure, i);
3625 }
3626 }
3627 if (ship->state >= SSHIP_LAUNCHED) {
3628 sg_failure_ret(secfile_lookup_int(loading->file, &ship->launch_year,
3629 "%s.launch_year", prefix),
3630 "%s", secfile_error());
3631 }
3633 }
3634 }
3635
3636 /* Load lost wonder data. */
3637 str = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
3638 /* If not present, probably an old savegame; nothing to be done */
3639 if (str != nullptr) {
3640 int k;
3641
3642 sg_failure_ret(strlen(str) == loading->improvement.size,
3643 "Invalid length for 'player%d.lost_wonders' ("
3644 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ")",
3645 plrno, strlen(str), loading->improvement.size);
3646 for (k = 0; k < loading->improvement.size; k++) {
3647 sg_failure_ret(str[k] == '1' || str[k] == '0',
3648 "Undefined value '%c' within "
3649 "'player%d.lost_wonders'.", plrno, str[k]);
3650
3651 if (str[k] == '1') {
3652 struct impr_type *pimprove =
3653 improvement_by_rule_name(loading->improvement.order[k]);
3654
3655 if (pimprove) {
3656 plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
3657 }
3658 }
3659 }
3660 }
3661
3662 plr->history =
3663 secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
3664 plr->server.huts =
3665 secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
3666}
3667
3668/************************************************************************/
3672 struct player *plr)
3673{
3674 int ncities, i, plrno = player_number(plr);
3675 bool tasks_handled;
3676 int wlist_max_length;
3677
3678 /* Check status and return if not OK (sg_success FALSE). */
3679 sg_check_ret();
3680
3682 "player%d.ncities", plrno),
3683 "%s", secfile_error());
3684
3685 if (!plr->is_alive && ncities > 0) {
3686 log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
3687 ncities = 0;
3688 }
3689
3690 if (!player_has_flag(plr, PLRF_FIRST_CITY) && ncities > 0) {
3691 /* Probably barbarians in an old savegame; fix up */
3693 }
3694
3696 "player%d.wl_max_length",
3697 plrno);
3699 log_sg("wlist_max_length %d over MAX_LEN_WORKLIST (%d)",
3701 }
3702
3703 /* Load all cities of the player. */
3704 for (i = 0; i < ncities; i++) {
3705 char buf[32];
3706 struct city *pcity;
3707
3708 fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
3709
3710 /* Create a dummy city. */
3711 pcity = create_city_virtual(plr, nullptr, buf);
3716 sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
3717 }
3718
3721
3722 /* Load the information about the nationality of citizens. This is done
3723 * here because the city sanity check called by citizens_update() requires
3724 * that the city is registered. */
3726
3727 /* After everything is loaded, but before vision. */
3729
3730 /* adding the city contribution to fog-of-war */
3734
3736 }
3737
3739 for (i = 0; !tasks_handled; i++) {
3740 int city_id;
3741 struct city *pcity = nullptr;
3742
3743 city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
3744 plrno, i);
3745
3746 if (city_id != -1) {
3747 pcity = player_city_by_number(plr, city_id);
3748 }
3749
3750 if (pcity != nullptr) {
3751 const char *str;
3752 int nat_x, nat_y;
3753 struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
3754
3755 nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
3756 nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
3757
3758 ptask->ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3759
3760 str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
3762
3764 "Unknown workertask activity %s", str);
3765
3766 str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
3767
3768 if (strcmp("-", str)) {
3770
3771 sg_failure_ret(ptask->tgt != nullptr,
3772 "Unknown workertask target %s", str);
3773 } else {
3774 ptask->tgt = nullptr;
3775 }
3776
3777 ptask->want = secfile_lookup_int_default(loading->file, 1,
3778 "player%d.task%d.want", plrno, i);
3779
3780 worker_task_list_append(pcity->task_reqs, ptask);
3781 } else {
3783 }
3784 }
3785}
3786
3787/************************************************************************/
3790static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
3791 struct city *pcity, const char *citystr,
3792 int wlist_max_length)
3793{
3794 struct player *past;
3795 const char *kind, *name, *str;
3796 int id, i, repair, sp_count = 0, workers = 0, value;
3797 int nat_x, nat_y;
3798 citizens size;
3799 const char *stylename;
3800 const struct civ_map *nmap = &(wld.map);
3801
3803 FALSE, "%s", secfile_error());
3805 FALSE, "%s", secfile_error());
3807 sg_warn_ret_val(pcity->tile != nullptr, FALSE,
3808 "%s has invalid center tile (%d, %d)",
3809 citystr, nat_x, nat_y);
3811 "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
3812
3813 /* Instead of dying, use 'citystr' string for damaged name. */
3815 "%s.name", citystr));
3816
3818 citystr), FALSE, "%s", secfile_error());
3819
3821 "%s.original", citystr);
3822 past = player_by_number(id);
3823 if (past != nullptr) {
3824 pcity->original = past;
3825 }
3826
3827 /* savegame2 saves never had this information. Guess. */
3828 if (pcity->original != plr) {
3829 pcity->acquire_t = CACQ_CONQUEST;
3830 } else {
3831 pcity->acquire_t = CACQ_FOUNDED;
3832 }
3833
3834 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
3835 citystr), FALSE, "%s", secfile_error());
3836 size = (citizens)value; /* Set the correct type */
3837 sg_warn_ret_val(value == (int)size, FALSE,
3838 "Invalid city size: %d, set to %d", value, size);
3840
3841 for (i = 0; i < loading->specialist.size; i++) {
3842 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
3843 citystr, i),
3844 FALSE, "%s", secfile_error());
3845 pcity->specialists[specialist_index(loading->specialist.order[i])]
3846 = (citizens)value;
3847 sp_count += value;
3848 }
3849
3850 /* savegame2.c saves were ever saved with MAX_TRADE_ROUTES_OLD routes max */
3851 for (i = 0; i < MAX_TRADE_ROUTES_OLD; i++) {
3852 int partner = secfile_lookup_int_default(loading->file, 0,
3853 "%s.traderoute%d", citystr, i);
3854
3855 if (partner != 0) {
3856 struct trade_route *proute = fc_malloc(sizeof(struct trade_route));
3857
3858 proute->partner = partner;
3860 proute->goods = goods_by_number(0); /* First good */
3861
3863 }
3864 }
3865
3866 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->food_stock,
3867 "%s.food_stock", citystr),
3868 FALSE, "%s", secfile_error());
3869 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->shield_stock,
3870 "%s.shield_stock", citystr),
3871 FALSE, "%s", secfile_error());
3872 pcity->history =
3873 secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
3874
3875 pcity->airlift =
3876 secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
3877 pcity->was_happy =
3878 secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
3879 citystr);
3880 pcity->had_famine = FALSE;
3881
3882 pcity->turn_plague =
3883 secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
3884
3886 "%s.anarchy", citystr),
3887 FALSE, "%s", secfile_error());
3888 pcity->rapture =
3889 secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
3890 pcity->steal =
3891 secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
3892
3893 /* Before did_buy for undocumented hack */
3894 pcity->turn_founded =
3895 secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
3896 citystr);
3897 sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
3898 citystr), FALSE, "%s", secfile_error());
3899 pcity->did_buy = (i != 0);
3900 if (i == -1 && pcity->turn_founded == -2) {
3901 /* Undocumented hack */
3902 pcity->turn_founded = game.info.turn;
3903 }
3904
3905 pcity->did_sell
3906 = secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
3907
3908 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->turn_last_built,
3909 "%s.turn_last_built", citystr),
3910 FALSE, "%s", secfile_error());
3911
3912 kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
3913 citystr);
3914 name = secfile_lookup_str(loading->file, "%s.currently_building_name",
3915 citystr);
3916 pcity->production = universal_by_rule_name(kind, name);
3917 sg_warn_ret_val(pcity->production.kind != universals_n_invalid(), FALSE,
3918 "%s.currently_building: unknown \"%s\" \"%s\".",
3919 citystr, kind, name);
3920
3921 kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
3922 citystr);
3923 name = secfile_lookup_str(loading->file, "%s.changed_from_name",
3924 citystr);
3927 "%s.changed_from: unknown \"%s\" \"%s\".",
3928 citystr, kind, name);
3929
3930 pcity->before_change_shields =
3931 secfile_lookup_int_default(loading->file, pcity->shield_stock,
3932 "%s.before_change_shields", citystr);
3933 pcity->caravan_shields =
3935 "%s.caravan_shields", citystr);
3936 pcity->disbanded_shields =
3938 "%s.disbanded_shields", citystr);
3939 pcity->last_turns_shield_surplus =
3941 "%s.last_turns_shield_surplus",
3942 citystr);
3943
3945 "%s.style", citystr);
3946 if (stylename != nullptr) {
3948 } else {
3949 pcity->style = 0;
3950 }
3951 if (pcity->style < 0) {
3952 pcity->style = city_style(pcity);
3953 }
3954
3955 pcity->server.synced = FALSE; /* Must re-sync with clients */
3956
3957 /* Initialise list of city improvements. */
3958 for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
3959 pcity->built[i].turn = I_NEVER;
3960 }
3961
3962 /* Load city improvements. */
3963 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
3964 sg_warn_ret_val(str != nullptr, FALSE, "%s", secfile_error());
3965 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
3966 "Invalid length of '%s.improvements' ("
3967 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
3968 citystr, strlen(str), loading->improvement.size);
3969 for (i = 0; i < loading->improvement.size; i++) {
3970 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
3971 "Undefined value '%c' within '%s.improvements'.",
3972 str[i], citystr)
3973
3974 if (str[i] == '1') {
3975 struct impr_type *pimprove =
3976 improvement_by_rule_name(loading->improvement.order[i]);
3977
3978 if (pimprove) {
3979 city_add_improvement(pcity, pimprove);
3980 }
3981 }
3982 }
3983
3984 sg_failure_ret_val(loading->worked_tiles != nullptr, FALSE,
3985 "No worked tiles map defined.");
3986
3988
3989 /* Load new savegame with variable (squared) city radius and worked
3990 * tiles map */
3991
3992 int radius_sq
3993 = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
3994 citystr);
3995 city_map_radius_sq_set(pcity, radius_sq);
3996
3998 if (loading->worked_tiles[ptile->index] == pcity->id) {
3999 if (sq_map_distance(ptile, pcity->tile) > radius_sq) {
4000 log_sg("[%s] '%s' (%d, %d) has worker outside current radius "
4001 "at (%d, %d); repairing", citystr, city_name_get(pcity),
4002 TILE_XY(pcity->tile), TILE_XY(ptile));
4003 pcity->specialists[DEFAULT_SPECIALIST]++;
4004 sp_count++;
4005 } else {
4006 tile_set_worked(ptile, pcity);
4007 workers++;
4008 }
4009
4010#ifdef FREECIV_DEBUG
4011 /* Set this tile to unused; a check for not reset tiles is
4012 * included in game_load_internal() */
4013 loading->worked_tiles[ptile->index] = -1;
4014#endif /* FREECIV_DEBUG */
4015 }
4017
4018 if (tile_worked(city_tile(pcity)) != pcity) {
4019 struct city *pwork = tile_worked(city_tile(pcity));
4020
4021 if (pwork != nullptr) {
4022 log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
4023 "(%d,%d) [%d]; repairing", citystr, city_name_get(pcity),
4026
4027 tile_set_worked(city_tile(pcity), nullptr); /* Remove tile from pwork */
4028 pwork->specialists[DEFAULT_SPECIALIST]++;
4030 } else {
4031 log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing",
4034 }
4035
4036 /* repair pcity */
4039 }
4040
4042 if (0 != repair) {
4043 log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
4044 "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
4046 workers, FREE_WORKED_TILES, sp_count);
4047
4048 /* repair pcity */
4050 }
4051
4052 /* worklist_init() done in create_city_virtual() */
4053 worklist_load(loading->file, wlist_max_length, &pcity->worklist, "%s", citystr);
4054
4055 /* Load city options. */
4056 BV_CLR_ALL(pcity->city_options);
4057 for (i = 0; i < loading->coptions.size; i++) {
4058 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
4059 citystr, i)) {
4060 BV_SET(pcity->city_options, loading->coptions.order[i]);
4061 }
4062 }
4063 /* Was never stored to savegame2 saves */
4064 pcity->wlcb = WLCB_SMART;
4065
4066 CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
4067
4068 return TRUE;
4069}
4070
4071/************************************************************************/
4075 struct player *plr,
4076 struct city *pcity,
4077 const char *citystr)
4078{
4080 citizens size;
4081
4083 player_slots_iterate(pslot) {
4084 int nationality;
4085
4087 "%s.citizen%d", citystr,
4088 player_slot_index(pslot));
4089 if (nationality > 0 && !player_slot_is_used(pslot)) {
4090 log_sg("Citizens of an invalid nation for %s (player slot %d)!",
4092 continue;
4093 }
4094
4095 if (nationality != -1 && player_slot_is_used(pslot)) {
4097 "Invalid value for citizens of player %d in %s: %d.",
4100 }
4102 /* Sanity check. */
4104 if (size != city_size_get(pcity)) {
4105 if (size != 0) {
4106 /* size == 0 can be result from the fact that ruleset had no
4107 * nationality enabled at saving time, so no citizens at all
4108 * were saved. But something more serious must be going on if
4109 * citizens have been saved partially - if some of them are there. */
4110 log_sg("City size and number of citizens does not match in %s "
4111 "(%d != %d)! Repairing ...", city_name_get(pcity),
4113 }
4114 citizens_update(pcity, nullptr);
4115 }
4116 }
4117}
4118
4119/************************************************************************/
4123 struct player *plr)
4124{
4125 int nunits, i, plrno = player_number(plr);
4126
4127 /* Check status and return if not OK (sg_success FALSE). */
4128 sg_check_ret();
4129
4131 "player%d.nunits", plrno),
4132 "%s", secfile_error());
4133 if (!plr->is_alive && nunits > 0) {
4134 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4135 nunits = 0; /* Some old savegames may be buggy. */
4136 }
4137
4138 for (i = 0; i < nunits; i++) {
4139 struct unit *punit;
4140 struct city *pcity;
4141 const char *name;
4142 char buf[32];
4143 struct unit_type *type;
4144 struct tile *ptile;
4145
4146 fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
4147
4148 name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
4150 sg_failure_ret(type != nullptr, "%s: unknown unit type \"%s\".", buf, name);
4151
4152 /* Create a dummy unit. */
4153 punit = unit_virtual_create(plr, nullptr, type, 0);
4154 if (!sg_load_player_unit(loading, plr, punit, buf)) {
4156 sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
4157 }
4158
4161
4163 unit_list_prepend(pcity->units_supported, punit);
4164 } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
4165 log_sg("%s: bad home city %d.", buf, punit->homecity);
4167 }
4168
4169 ptile = unit_tile(punit);
4170
4171 /* Allocate the unit's contribution to fog of war */
4174 /* NOTE: There used to be some map_set_known calls here. These were
4175 * unneeded since unfogging the tile when the unit sees it will
4176 * automatically reveal that tile. */
4177
4180
4181 /* Claim ownership of fortress? */
4182 if ((extra_owner(ptile) == nullptr
4183 || pplayers_at_war(extra_owner(ptile), plr))
4185 tile_claim_bases(ptile, plr);
4186 }
4187 }
4188}
4189
4190/************************************************************************/
4200static int sg_order_to_action(int order, struct unit *act_unit,
4201 struct tile *tgt_tile)
4202{
4203 switch (order) {
4205 if (tile_city(tgt_tile)
4207 /* The player's cities are loaded right before their units. It wasn't
4208 * possible for rulesets to allow joining foreign cities before 3.0.
4209 * This means that a converted build city order only can be a Join
4210 * City order if it targets a domestic city. */
4211 return ACTION_JOIN_CITY;
4212 } else {
4213 /* Assume that the intention was to found a new city. */
4214 return ACTION_FOUND_CITY;
4215 }
4217 /* Maps one to one with each other. */
4218 return ACTION_HELP_WONDER;
4220 /* Maps one to one with each other. */
4221 return ACTION_TRADE_ROUTE;
4222 case ORDER_OLD_DISBAND:
4223 /* Added to the order system in the same commit as Help Wonder. Assume
4224 * that anyone that intended to order Help Wonder used Help Wonder. */
4225 /* Could in theory be intended as an order to disband in the field. Why
4226 * would the player give a unit an order to go to a non city location
4227 * and disband there? Assume the intention was to recover production
4228 * until a non recovering disband order is found. */
4230 case ORDER_OLD_HOMECITY:
4231 return ACTION_HOME_CITY;
4232 }
4233
4234 /* The order hasn't been replaced by an action. */
4235 return ACTION_NONE;
4236}
4237
4238/************************************************************************/
4242 struct player *plr, struct unit *punit,
4243 const char *unitstr)
4244{
4245 int activity;
4246 int nat_x, nat_y;
4247 enum tile_special_type target;
4248 struct extra_type *pextra = nullptr;
4249 struct base_type *pbase = nullptr;
4250 struct road_type *proad = nullptr;
4251 struct tile *ptile;
4252 int extra_id;
4253 int base_id;
4254 int road_id;
4255 int ei;
4256 const char *facing_str;
4258 int natnbr;
4259 bool ai_controlled;
4260
4262 unitstr), FALSE, "%s", secfile_error());
4264 FALSE, "%s", secfile_error());
4266 FALSE, "%s", secfile_error());
4267
4268 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
4269 sg_warn_ret_val(ptile != nullptr, FALSE, "%s invalid tile (%d, %d)",
4270 unitstr, nat_x, nat_y);
4271 unit_tile_set(punit, ptile);
4272
4275 "%s.facing", unitstr);
4276 if (facing_str[0] != 'x') {
4277 /* We don't touch punit->facing if savegame does not contain that
4278 * information. Initial orientation set by unit_virtual_create()
4279 * is as good as any. */
4280 enum direction8 facing = char2dir(facing_str[0]);
4281
4282 if (direction8_is_valid(facing)) {
4283 punit->facing = facing;
4284 } else {
4285 log_error("Illegal unit orientation '%s'", facing_str);
4286 }
4287 }
4288
4289 /* If savegame has unit nationality, it doesn't hurt to
4290 * internally set it even if nationality rules are disabled. */
4292 player_number(plr),
4293 "%s.nationality", unitstr);
4294
4296 if (punit->nationality == nullptr) {
4297 punit->nationality = plr;
4298 }
4299
4301 "%s.homecity", unitstr), FALSE,
4302 "%s", secfile_error());
4304 "%s.moves", unitstr), FALSE,
4305 "%s", secfile_error());
4307 "%s.fuel", unitstr), FALSE,
4308 "%s", secfile_error());
4309
4311 "%s.activity", unitstr), FALSE,
4312 "%s", secfile_error());
4313 if (ei >= 0 && ei < loading->activities.size) {
4314 activity = unit_activity_by_name(loading->activities.order[ei],
4316 } else {
4317 log_sg("Invalid activity id for unit %d", punit->id);
4318 activity = ACTIVITY_IDLE;
4319 }
4320
4323 "%s.born", unitstr);
4325
4327 "%s.activity_tgt", unitstr);
4328
4329 if (extra_id != -2) {
4330 if (extra_id >= 0 && extra_id < loading->extra.size) {
4331 pextra = loading->extra.order[extra_id];
4332 set_unit_activity_targeted(punit, activity, pextra,
4333 activity_default_action(activity));
4334 } else if (activity == ACTIVITY_IRRIGATE) {
4338 punit);
4339 if (tgt != nullptr) {
4342 } else {
4345 }
4346 } else if (activity == ACTIVITY_MINE) {
4348 EC_MINE,
4350 punit);
4351 if (tgt != nullptr) {
4354 } else {
4357 }
4358 } else {
4359 set_unit_activity(punit, activity,
4360 activity_default_action(activity));
4361 }
4362 } else {
4363 /* extra_id == -2 -> activity_tgt not set */
4365 "%s.activity_base", unitstr);
4366 if (base_id >= 0 && base_id < loading->base.size) {
4367 pbase = loading->base.order[base_id];
4368 }
4370 "%s.activity_road", unitstr);
4371 if (road_id >= 0 && road_id < loading->road.size) {
4372 proad = loading->road.order[road_id];
4373 }
4374
4375 {
4377 loading->special.size /* S_LAST */,
4378 "%s.activity_target", unitstr);
4379 if (tgt_no >= 0 && tgt_no < loading->special.size) {
4380 target = loading->special.order[tgt_no];
4381 } else {
4382 target = S_LAST;
4383 }
4384 }
4385
4386 if (target == S_OLD_ROAD) {
4387 target = S_LAST;
4389 } else if (target == S_OLD_RAILROAD) {
4390 target = S_LAST;
4392 }
4393
4394 if (activity == ACTIVITY_OLD_ROAD) {
4395 activity = ACTIVITY_GEN_ROAD;
4397 } else if (activity == ACTIVITY_OLD_RAILROAD) {
4398 activity = ACTIVITY_GEN_ROAD;
4400 }
4401
4402 /* We need changed_from == ACTIVITY_IDLE by now so that
4403 * set_unit_activity() and friends don't spuriously restore activity
4404 * points -- unit should have been created this way */
4406
4407 if (activity == ACTIVITY_BASE) {
4408 if (pbase) {
4410 } else {
4411 log_sg("Cannot find base %d for %s to build",
4415 }
4416 } else if (activity == ACTIVITY_GEN_ROAD) {
4417 if (proad) {
4419 } else {
4420 log_sg("Cannot find road %d for %s to build",
4424 }
4425 } else if (activity == ACTIVITY_PILLAGE) {
4426 struct extra_type *a_target;
4427
4428 if (target != S_LAST) {
4429 a_target = special_extra_get(target);
4430 } else if (pbase != nullptr) {
4432 } else if (proad != nullptr) {
4434 } else {
4435 a_target = nullptr;
4436 }
4437 /* An out-of-range base number is seen with old savegames. We take
4438 * it as indicating undirected pillaging. We will assign pillage
4439 * targets before play starts. */
4441 activity_default_action(activity));
4442 } else if (activity == ACTIVITY_IRRIGATE) {
4446 punit);
4447 if (tgt != nullptr) {
4450 } else {
4453 }
4454 } else if (activity == ACTIVITY_MINE) {
4456 EC_MINE,
4458 punit);
4459 if (tgt != nullptr) {
4462 } else {
4465 }
4466 } else if (activity == ACTIVITY_OLD_POLLUTION_SG2
4467 || activity == ACTIVITY_OLD_FALLOUT_SG2) {
4469 ERM_CLEAN,
4471 punit);
4472 if (tgt != nullptr) {
4475 } else {
4478 }
4479 } else {
4480 set_unit_activity_targeted(punit, activity, nullptr,
4481 activity_default_action(activity));
4482 }
4483 } /* activity_tgt == nullptr */
4484
4486 "%s.activity_count", unitstr), FALSE,
4487 "%s", secfile_error());
4488
4491 "%s.changed_from", unitstr);
4492
4494 "%s.changed_from_tgt", unitstr);
4495
4496 if (extra_id != -2) {
4497 if (extra_id >= 0 && extra_id < loading->extra.size) {
4498 punit->changed_from_target = loading->extra.order[extra_id];
4499 } else {
4500 punit->changed_from_target = nullptr;
4501 }
4502 } else {
4503 /* extra_id == -2 -> changed_from_tgt not set */
4504
4505 cfspe =
4507 "%s.changed_from_target", unitstr);
4508 base_id =
4510 "%s.changed_from_base", unitstr);
4511 road_id =
4513 "%s.changed_from_road", unitstr);
4514
4515 if (road_id == -1) {
4516 if (cfspe == S_OLD_ROAD) {
4518 if (proad) {
4520 }
4521 } else if (cfspe == S_OLD_RAILROAD) {
4523 if (proad) {
4525 }
4526 }
4527 }
4528
4529 if (base_id >= 0 && base_id < loading->base.size) {
4531 } else if (road_id >= 0 && road_id < loading->road.size) {
4533 } else if (cfspe != S_LAST) {
4535 } else {
4536 punit->changed_from_target = nullptr;
4537 }
4538
4543 punit);
4544 if (tgt != nullptr) {
4546 } else {
4547 punit->changed_from_target = nullptr;
4548 }
4549 } else if (punit->changed_from == ACTIVITY_MINE) {
4551 EC_MINE,
4553 punit);
4554
4555 if (tgt != nullptr) {
4557 } else {
4558 punit->changed_from_target = nullptr;
4559 }
4563 ERM_CLEAN,
4565 punit);
4566
4567 if (tgt != nullptr) {
4569 } else {
4570 punit->changed_from_target = nullptr;
4571 }
4572 }
4573 }
4574
4577 "%s.changed_from_count", unitstr);
4578
4579 /* Special case: for a long time, we accidentally incremented
4580 * activity_count while a unit was sentried, so it could increase
4581 * without bound (bug #20641) and be saved in old savefiles.
4582 * We zero it to prevent potential trouble overflowing the range
4583 * in network packets, etc. */
4584 if (activity == ACTIVITY_SENTRY) {
4585 punit->activity_count = 0;
4586 }
4589 }
4590
4591 punit->veteran
4592 = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
4593 {
4594 /* Protect against change in veteran system in ruleset */
4595 const int levels = utype_veteran_levels(unit_type_get(punit));
4596 if (punit->veteran >= levels) {
4597 fc_assert(levels >= 1);
4598 punit->veteran = levels - 1;
4599 }
4600 }
4603 "%s.done_moving", unitstr);
4606 "%s.battlegroup", unitstr);
4607
4609 "%s.go", unitstr)) {
4610 int gnat_x, gnat_y;
4611
4613 "%s.goto_x", unitstr), FALSE,
4614 "%s", secfile_error());
4616 "%s.goto_y", unitstr), FALSE,
4617 "%s", secfile_error());
4618
4620 } else {
4621 punit->goto_tile = nullptr;
4622
4623 if (punit->activity == ACTIVITY_GOTO) {
4624 /* goto_tile should never be nullptr with ACTIVITY_GOTO */
4625 log_sg("Unit %d on goto without goto_tile. Aborting goto.",
4626 punit->id);
4628 }
4629
4630 /* These variables are not used but needed for saving the unit table.
4631 * Load them to prevent unused variables errors. */
4632 secfile_entry_ignore(loading->file, "%s.goto_x", unitstr);
4633 secfile_entry_ignore(loading->file, "%s.goto_y", unitstr);
4634 }
4635
4636 /* Load AI data of the unit. */
4637 CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
4638
4641 "%s.ai", unitstr), FALSE,
4642 "%s", secfile_error());
4643 if (ai_controlled) {
4644 /* Autoworker and Autoexplore are separated by
4645 * compat_post_load_030100() when set to SSA_AUTOWORKER */
4647 } else {
4649 }
4651 "%s.hp", unitstr), FALSE,
4652 "%s", secfile_error());
4653
4655 = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
4657 = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
4658 punit->moved
4659 = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
4662 "%s.paradropped", unitstr);
4663
4664 /* The transport status (punit->transported_by) is loaded in
4665 * sg_player_units_transport(). */
4666
4667 /* Initialize upkeep values: these are hopefully initialized
4668 * elsewhere before use (specifically, in city_support(); but
4669 * fixme: check whether always correctly initialized?).
4670 * Below is mainly for units which don't have homecity --
4671 * otherwise these don't get initialized (and AI calculations
4672 * etc may use junk values). */
4676
4680 "%s.action_decision_want", unitstr);
4681
4683 /* Load the tile to act against. */
4684 int adwt_x, adwt_y;
4685
4686 if (secfile_lookup_int(loading->file, &adwt_x,
4687 "%s.action_decision_tile_x", unitstr)
4689 "%s.action_decision_tile_y", unitstr)) {
4691 adwt_x, adwt_y);
4692 } else {
4694 punit->action_decision_tile = nullptr;
4695 log_sg("Bad action_decision_tile for unit %d", punit->id);
4696 }
4697 } else {
4698 secfile_entry_ignore(loading->file, "%s.action_decision_tile_x", unitstr);
4699 secfile_entry_ignore(loading->file, "%s.action_decision_tile_y", unitstr);
4700
4701 punit->action_decision_tile = nullptr;
4702 }
4703
4704 /* Load the unit orders */
4705 {
4706 int len = secfile_lookup_int_default(loading->file, 0,
4707 "%s.orders_length", unitstr);
4708
4709 if (len > 0) {
4710 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
4711 const char *tgt_unitstr;
4712 const char *base_unitstr = nullptr;
4713 const char *road_unitstr = nullptr;
4716 int j;
4717
4718 punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
4722 "%s.orders_index", unitstr);
4725 "%s.orders_repeat", unitstr);
4728 "%s.orders_vigilant", unitstr);
4729
4732 "%s.orders_list", unitstr);
4735 "%s.dir_list", unitstr);
4738 "%s.activity_list", unitstr);
4740 = secfile_lookup_str_default(loading->file, nullptr,
4741 "%s.tgt_list", unitstr);
4742
4743 if (tgt_unitstr == nullptr) {
4745 = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
4747 = secfile_lookup_str_default(loading->file, nullptr,
4748 "%s.road_list", unitstr);
4749 }
4750
4752
4753 for (j = 0; j < len; j++) {
4754 struct unit_order *order = &punit->orders.list[j];
4755
4756 if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
4757 || act_unitstr[j] == '\0') {
4758 log_sg("Invalid unit orders.");
4760 break;
4761 }
4762 order->order = char2order(orders_unitstr[j]);
4763 order->dir = char2dir(dir_unitstr[j]);
4764 order->activity = char2activity(act_unitstr[j]);
4765 /* Target, if needed, is set in compat_post_load_030100() */
4766 order->target = NO_TARGET;
4767 order->sub_target = NO_TARGET;
4768
4769 if (order->order == ORDER_LAST
4770 || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
4771 || (order->order == ORDER_ACTION_MOVE
4772 && !direction8_is_valid(order->dir))
4773 || (order->order == ORDER_ACTIVITY
4774 && order->activity == ACTIVITY_LAST)) {
4775 /* An invalid order. Just drop the orders for this unit. */
4777 punit->orders.list = nullptr;
4778 punit->orders.length = 0;
4780 punit->goto_tile = nullptr;
4781 break;
4782 }
4783
4784 /* The order may have been replaced by the perform action order */
4785 order->action = sg_order_to_action(order->order, punit,
4786 punit->goto_tile);
4787 if (order->action != ACTION_NONE) {
4788 /* The order was converted by sg_order_to_action() */
4789 order->order = ORDER_PERFORM_ACTION;
4790 }
4791
4792 if (tgt_unitstr) {
4793 if (tgt_unitstr[j] != '?') {
4795
4796 if (extra_id < 0 || extra_id >= loading->extra.size) {
4797 log_sg("Cannot find extra %d for %s to build",
4799 order->sub_target = EXTRA_NONE;
4800 } else {
4801 order->sub_target = extra_id;
4802 }
4803 } else {
4804 order->sub_target = EXTRA_NONE;
4805 }
4806 } else {
4807 /* In pre-2.6 savegames, base_list and road_list were only saved
4808 * for those activities (and not e.g. pillaging) */
4809 if (base_unitstr && base_unitstr[j] != '?'
4810 && order->activity == ACTIVITY_BASE) {
4812
4813 if (base_id < 0 || base_id >= loading->base.size) {
4814 log_sg("Cannot find base %d for %s to build",
4817 nullptr, nullptr));
4818 }
4819
4820 order->sub_target
4822 } else if (road_unitstr && road_unitstr[j] != '?'
4823 && order->activity == ACTIVITY_GEN_ROAD) {
4825
4826 if (road_id < 0 || road_id >= loading->road.size) {
4827 log_sg("Cannot find road %d for %s to build",
4829 road_id = 0;
4830 }
4831
4832 order->sub_target
4834 } else {
4835 order->sub_target = EXTRA_NONE;
4836 }
4837
4838 if (order->activity == ACTIVITY_OLD_ROAD) {
4839 order->activity = ACTIVITY_GEN_ROAD;
4840 order->sub_target
4842 } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
4843 order->activity = ACTIVITY_GEN_ROAD;
4844 order->sub_target
4846 }
4847 }
4848 }
4849 } else {
4850 /* Never nullify goto_tile for a unit that is in active goto. */
4851 if (punit->activity != ACTIVITY_GOTO) {
4852 punit->goto_tile = nullptr;
4853 }
4854
4856 punit->orders.list = nullptr;
4857 punit->orders.length = 0;
4858
4859 secfile_entry_ignore(loading->file, "%s.orders_index", unitstr);
4860 secfile_entry_ignore(loading->file, "%s.orders_repeat", unitstr);
4861 secfile_entry_ignore(loading->file, "%s.orders_vigilant", unitstr);
4862 secfile_entry_ignore(loading->file, "%s.orders_list", unitstr);
4863 secfile_entry_ignore(loading->file, "%s.dir_list", unitstr);
4864 secfile_entry_ignore(loading->file, "%s.activity_list", unitstr);
4865 secfile_entry_ignore(loading->file, "%s.tgt_list", unitstr);
4866 }
4867 }
4868
4869 return TRUE;
4870}
4871
4872/************************************************************************/
4877 struct player *plr)
4878{
4879 int nunits, i, plrno = player_number(plr);
4880
4881 /* Check status and return if not OK (sg_success FALSE). */
4882 sg_check_ret();
4883
4884 /* Recheck the number of units for the player. This is a copied from
4885 * sg_load_player_units(). */
4887 "player%d.nunits", plrno),
4888 "%s", secfile_error());
4889 if (!plr->is_alive && nunits > 0) {
4890 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4891 nunits = 0; /* Some old savegames may be buggy. */
4892 }
4893
4894 for (i = 0; i < nunits; i++) {
4895 int id_unit, id_trans;
4896 struct unit *punit, *ptrans;
4897
4899 "player%d.u%d.id",
4900 plrno, i);
4902 fc_assert_action(punit != nullptr, continue);
4903
4905 "player%d.u%d.transported_by",
4906 plrno, i);
4907 if (id_trans == -1) {
4908 /* Not transported. */
4909 continue;
4910 }
4911
4913 fc_assert_action(id_trans == -1 || ptrans != nullptr, continue);
4914
4915 if (ptrans) {
4916#ifndef FREECIV_NDEBUG
4917 bool load_success =
4918#endif
4920
4921 fc_assert_action(load_success, continue);
4922 }
4923 }
4924}
4925
4926/************************************************************************/
4930 struct player *plr)
4931{
4932 int plrno = player_number(plr);
4933
4934 /* Check status and return if not OK (sg_success FALSE). */
4935 sg_check_ret();
4936
4937 /* Toss any existing attribute_block (should not exist) */
4938 if (plr->attribute_block.data) {
4940 plr->attribute_block.data = nullptr;
4941 }
4942
4943 /* This is a big heap of opaque data for the client, check everything! */
4945 loading->file, 0, "player%d.attribute_v2_block_length", plrno);
4946
4947 if (0 > plr->attribute_block.length) {
4948 log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
4949 plr->attribute_block.length);
4950 plr->attribute_block.length = 0;
4951 } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
4952 log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
4954 plr->attribute_block.length = 0;
4955 } else if (0 < plr->attribute_block.length) {
4956 int part_nr, parts;
4957 int quoted_length;
4958 char *quoted;
4959#ifndef FREECIV_NDEBUG
4960 size_t actual_length;
4961#endif
4962
4965 "player%d.attribute_v2_block_length_quoted",
4966 plrno), "%s", secfile_error());
4969 "player%d.attribute_v2_block_parts", plrno),
4970 "%s", secfile_error());
4971
4973 quoted[0] = '\0';
4975 for (part_nr = 0; part_nr < parts; part_nr++) {
4976 const char *current =
4978 "player%d.attribute_v2_block_data.part%d",
4979 plrno, part_nr);
4980 if (!current) {
4981 log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
4982 break;
4983 }
4984 log_debug("attribute_v2_block_length_quoted=%d"
4985 " have=" SIZE_T_PRINTF " part=" SIZE_T_PRINTF,
4986 quoted_length, strlen(quoted), strlen(current));
4987 fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
4988 strcat(quoted, current);
4989 }
4991 "attribute_v2_block_length_quoted=%d"
4992 " actual=" SIZE_T_PRINTF,
4994
4995#ifndef FREECIV_NDEBUG
4997#endif
4999 plr->attribute_block.data,
5000 plr->attribute_block.length);
5002 free(quoted);
5003 }
5004}
5005
5006/************************************************************************/
5010 struct player *plr)
5011{
5012 int plrno = player_number(plr);
5013 int total_ncities =
5015 "player%d.dc_total", plrno);
5016 int i;
5017 bool someone_alive = FALSE;
5018
5019 /* Check status and return if not OK (sg_success FALSE). */
5020 sg_check_ret();
5021
5024 if (pteam_member->is_alive) {
5026 break;
5027 }
5029
5030 if (!someone_alive) {
5031 /* Reveal all for completely dead teams. */
5033 }
5034 }
5035
5036 if (!plr->is_alive
5037 || -1 == total_ncities
5038 || !game.info.fogofwar
5040 "game.save_private_map")) {
5041 /* We have:
5042 * - a dead player;
5043 * - fogged cities are not saved for any reason;
5044 * - a savegame with fog of war turned off;
5045 * - or game.save_private_map is not set to FALSE in the scenario /
5046 * savegame. The players private knowledge is set to be what they could
5047 * see without fog of war. */
5048 whole_map_iterate(&(wld.map), ptile) {
5049 if (map_is_known(ptile, plr)) {
5050 struct city *pcity = tile_city(ptile);
5051
5052 update_player_tile_last_seen(plr, ptile);
5053 update_player_tile_knowledge(plr, ptile);
5054
5055 if (pcity != nullptr) {
5056 update_dumb_city(plr, pcity);
5057 }
5058 }
5060
5061 /* Nothing more to do; */
5062 return;
5063 }
5064
5065 /* Load player map (terrain). */
5066 LOAD_MAP_CHAR(ch, ptile,
5067 map_get_player_tile(ptile, plr)->terrain
5068 = char2terrain(ch), loading->file,
5069 "player%d.map_t%04d", plrno);
5070
5071 /* Load player map (resources). */
5072 LOAD_MAP_CHAR(ch, ptile,
5073 map_get_player_tile(ptile, plr)->resource
5074 = char2resource(ch), loading->file,
5075 "player%d.map_res%04d", plrno);
5076
5077 if (loading->version >= 30) {
5078 /* 2.6.0 or newer */
5079
5080 /* Load player map (extras). */
5081 halfbyte_iterate_extras(j, loading->extra.size) {
5082 LOAD_MAP_CHAR(ch, ptile,
5084 ch, loading->extra.order + 4 * j),
5085 loading->file, "player%d.map_e%02d_%04d", plrno, j);
5087 } else {
5088 /* Load player map (specials). */
5089 halfbyte_iterate_special(j, loading->special.size) {
5090 LOAD_MAP_CHAR(ch, ptile,
5091 sg_special_set_dbv(ptile,
5092 &(map_get_player_tile(ptile, plr)->extras),
5093 ch, loading->special.order + 4 * j, FALSE),
5094 loading->file, "player%d.map_spe%02d_%04d", plrno, j);
5096
5097 /* Load player map (bases). */
5098 halfbyte_iterate_bases(j, loading->base.size) {
5099 LOAD_MAP_CHAR(ch, ptile,
5101 ch, loading->base.order + 4 * j),
5102 loading->file, "player%d.map_b%02d_%04d", plrno, j);
5104
5105 /* Load player map (roads). */
5106 if (loading->version >= 20) {
5107 /* 2.5.0 or newer */
5108 halfbyte_iterate_roads(j, loading->road.size) {
5109 LOAD_MAP_CHAR(ch, ptile,
5111 ch, loading->road.order + 4 * j),
5112 loading->file, "player%d.map_r%02d_%04d", plrno, j);
5114 }
5115 }
5116
5118 /* Load player map (border). */
5119 int x, y;
5120
5121 for (y = 0; y < MAP_NATIVE_HEIGHT; y++) {
5122 const char *buffer
5123 = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
5124 plrno, y);
5125 const char *buffer2
5126 = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
5127 plrno, y);
5128 const char *ptr = buffer;
5129 const char *ptr2 = buffer2;
5130
5131 sg_failure_ret(buffer != nullptr,
5132 "Savegame corrupt - map line %d not found.", y);
5133 for (x = 0; x < MAP_NATIVE_WIDTH; x++) {
5134 char token[TOKEN_SIZE];
5135 char token2[TOKEN_SIZE];
5136 int number;
5137 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
5138
5139 scanin(&ptr, ",", token, sizeof(token));
5140 sg_failure_ret('\0' != token[0],
5141 "Savegame corrupt - map size not correct.");
5142 if (strcmp(token, "-") == 0) {
5143 map_get_player_tile(ptile, plr)->owner = nullptr;
5144 } else {
5145 sg_failure_ret(str_to_int(token, &number),
5146 "Savegame corrupt - got tile owner=%s in (%d, %d).",
5147 token, x, y);
5148 map_get_player_tile(ptile, plr)->owner = player_by_number(number);
5149 }
5150
5151 if (loading->version >= 30) {
5152 scanin(&ptr2, ",", token2, sizeof(token2));
5153 sg_failure_ret('\0' != token2[0],
5154 "Savegame corrupt - map size not correct.");
5155 if (strcmp(token2, "-") == 0) {
5156 map_get_player_tile(ptile, plr)->extras_owner = nullptr;
5157 } else {
5159 "Savegame corrupt - got extras owner=%s in (%d, %d).",
5160 token, x, y);
5161 map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
5162 }
5163 } else {
5165 = map_get_player_tile(ptile, plr)->owner;
5166 }
5167 }
5168 }
5169 }
5170
5171 /* Load player map (update time). */
5172 for (i = 0; i < 4; i++) {
5173 /* put 4-bit segments of 16-bit "updated" field */
5174 if (i == 0) {
5175 LOAD_MAP_CHAR(ch, ptile,
5176 map_get_player_tile(ptile, plr)->last_updated
5177 = ascii_hex2bin(ch, i),
5178 loading->file, "player%d.map_u%02d_%04d", plrno, i);
5179 } else {
5180 LOAD_MAP_CHAR(ch, ptile,
5181 map_get_player_tile(ptile, plr)->last_updated
5182 |= ascii_hex2bin(ch, i),
5183 loading->file, "player%d.map_u%02d_%04d", plrno, i);
5184 }
5185 }
5186
5187 /* Load player map known cities. */
5188 for (i = 0; i < total_ncities; i++) {
5189 struct vision_site *pdcity;
5190 char buf[32];
5191 fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
5192
5193 pdcity = vision_site_new(0, nullptr, nullptr);
5196 pdcity);
5198 } else {
5199 /* Error loading the data. */
5200 log_sg("Skipping seen city %d for player %d.", i, plrno);
5201 if (pdcity != nullptr) {
5203 }
5204 }
5205 }
5206
5207 /* Repair inconsistent player maps. */
5208 whole_map_iterate(&(wld.map), ptile) {
5209 if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
5210 struct city *pcity = tile_city(ptile);
5211
5212 update_player_tile_knowledge(plr, ptile);
5213 reality_check_city(plr, ptile);
5214
5215 if (pcity != nullptr) {
5216 update_dumb_city(plr, pcity);
5217 }
5218 } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
5219 /* Non fogged borders aren't loaded. See hrm Bug #879084 */
5220 struct player_tile *plrtile = map_get_player_tile(ptile, plr);
5221
5222 plrtile->owner = tile_owner(ptile);
5223 }
5225}
5226
5227/************************************************************************/
5231 struct player *plr,
5232 struct vision_site *pdcity,
5233 const char *citystr)
5234{
5235 const char *str;
5236 int i, id, size;
5237 citizens city_size;
5238 int nat_x, nat_y;
5239 const char *stylename;
5240 const char *vname;
5241
5243 citystr),
5244 FALSE, "%s", secfile_error());
5246 citystr),
5247 FALSE, "%s", secfile_error());
5248 pdcity->location = native_pos_to_tile(&(wld.map), nat_x, nat_y);
5249 sg_warn_ret_val(pdcity->location != nullptr, FALSE,
5250 "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
5251
5252 sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
5253 citystr),
5254 FALSE, "%s", secfile_error());
5255 pdcity->owner = player_by_number(id);
5256 sg_warn_ret_val(pdcity->owner != nullptr, FALSE,
5257 "%s has invalid owner (%d); skipping.", citystr, id);
5258
5260 "%s.id", citystr),
5261 FALSE, "%s", secfile_error());
5263 "%s has invalid id (%d); skipping.", citystr, id);
5264
5266 "%s.size", citystr),
5267 FALSE, "%s", secfile_error());
5268 city_size = (citizens)size; /* set the correct type */
5269 sg_warn_ret_val(size == (int)city_size, FALSE,
5270 "Invalid city size: %d; set to %d.", size, city_size);
5271 vision_site_size_set(pdcity, city_size);
5272
5273 /* Initialise list of improvements */
5274 BV_CLR_ALL(pdcity->improvements);
5275 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
5276 sg_warn_ret_val(str != nullptr, FALSE, "%s", secfile_error());
5277 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
5278 "Invalid length of '%s.improvements' ("
5279 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5280 citystr, strlen(str), loading->improvement.size);
5281 for (i = 0; i < loading->improvement.size; i++) {
5282 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
5283 "Undefined value '%c' within '%s.improvements'.",
5284 str[i], citystr)
5285
5286 if (str[i] == '1') {
5287 struct impr_type *pimprove =
5288 improvement_by_rule_name(loading->improvement.order[i]);
5289
5290 if (pimprove) {
5291 BV_SET(pdcity->improvements, improvement_index(pimprove));
5292 }
5293 }
5294 }
5295
5296 vname = secfile_lookup_str_default(loading->file, nullptr,
5297 "%s.name", citystr);
5298
5299 if (vname != nullptr) {
5300 pdcity->name = fc_strdup(vname);
5301 }
5302
5304 "%s.occupied", citystr);
5306 "%s.walls", citystr);
5308 "%s.happy", citystr);
5310 "%s.unhappy", citystr);
5312 "%s.style", citystr);
5313 if (stylename != nullptr) {
5315 } else {
5316 pdcity->style = 0;
5317 }
5318 if (pdcity->style < 0) {
5319 pdcity->style = 0;
5320 }
5321
5322 pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
5323 "%s.city_image", citystr);
5324
5325 pdcity->capital = CAPITAL_NOT;
5326
5327 return TRUE;
5328}
5329
5330/* =======================================================================
5331 * Load the researches.
5332 * ======================================================================= */
5333
5334/************************************************************************/
5338{
5339 struct research *presearch;
5340 int count;
5341 int number;
5342 const char *str;
5343 int i, j;
5344 bool got_tech;
5345
5346 /* Check status and return if not OK (sg_success FALSE). */
5347 sg_check_ret();
5348
5349 /* Initialize all researches. */
5353
5354 /* May be unsaved (e.g. scenario case). */
5355 count = secfile_lookup_int_default(loading->file, 0, "research.count");
5356 for (i = 0; i < count; i++) {
5358 "research.r%d.number", i),
5359 "%s", secfile_error());
5360 presearch = research_by_number(number);
5361 sg_failure_ret(presearch != nullptr,
5362 "Invalid research number %d in 'research.r%d.number'",
5363 number, i);
5364
5365 presearch->tech_goal = technology_load(loading->file,
5366 "research.r%d.goal", i);
5368 &presearch->future_tech,
5369 "research.r%d.futuretech", i),
5370 "%s", secfile_error());
5372 &presearch->bulbs_researched,
5373 "research.r%d.bulbs", i),
5374 "%s", secfile_error());
5376 &presearch->bulbs_researching_saved,
5377 "research.r%d.bulbs_before", i),
5378 "%s", secfile_error());
5379 presearch->researching_saved = technology_load(loading->file,
5380 "research.r%d.saved", i);
5381 presearch->researching = technology_load(loading->file,
5382 "research.r%d.now", i);
5384 &got_tech,
5385 "research.r%d.got_tech", i),
5386 "%s", secfile_error());
5387 if (got_tech) {
5388 presearch->free_bulbs = presearch->bulbs_researched;
5389 }
5390
5391 str = secfile_lookup_str(loading->file, "research.r%d.done", i);
5392 sg_failure_ret(str != nullptr, "%s", secfile_error());
5393 sg_failure_ret(strlen(str) == loading->technology.size,
5394 "Invalid length of 'research.r%d.done' ("
5395 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5396 i, strlen(str), loading->technology.size);
5397 for (j = 0; j < loading->technology.size; j++) {
5398 sg_failure_ret(str[j] == '1' || str[j] == '0',
5399 "Undefined value '%c' within 'research.r%d.done'.",
5400 str[j], i);
5401
5402 if (str[j] == '1') {
5403 struct advance *padvance =
5404 advance_by_rule_name(loading->technology.order[j]);
5405
5406 if (padvance) {
5408 TECH_KNOWN);
5409 }
5410 }
5411 }
5412 }
5413
5414 /* In case of tech_leakage, we can update research only after all the
5415 * researches have been loaded */
5419}
5420
5421/* =======================================================================
5422 * Load the event cache. Should be the last thing to do.
5423 * ======================================================================= */
5424
5425/************************************************************************/
5429{
5430 /* Check status and return if not OK (sg_success FALSE). */
5431 sg_check_ret();
5432
5433 event_cache_load(loading->file, "event_cache");
5434}
5435
5436/* =======================================================================
5437 * Load the open treaties
5438 * ======================================================================= */
5439
5440/************************************************************************/
5444{
5445 int tidx;
5446 const char *plr0;
5447
5448 /* Check status and return if not OK (sg_success FALSE). */
5449 sg_check_ret();
5450
5451 for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, nullptr,
5452 "treaty%d.plr0", tidx)) != nullptr ;
5453 tidx++) {
5454 const char *plr1;
5455 const char *ct;
5456 int cidx;
5457 struct player *p0, *p1;
5458
5459 plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
5460
5461 p0 = player_by_name(plr0);
5462 p1 = player_by_name(plr1);
5463
5464 if (p0 == nullptr || p1 == nullptr) {
5465 log_error("Treaty between unknown players %s and %s", plr0, plr1);
5466 } else {
5467 struct treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
5468
5471
5472 for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, nullptr,
5473 "treaty%d.clause%d.type",
5474 tidx, cidx)) != nullptr ;
5475 cidx++ ) {
5477 const char *plrx;
5478
5479 if (!clause_type_is_valid(type)) {
5480 log_error("Invalid clause type \"%s\"", ct);
5481 } else {
5482 struct player *pgiver = nullptr;
5483
5484 plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
5485 tidx, cidx);
5486
5487 if (!fc_strcasecmp(plrx, plr0)) {
5488 pgiver = p0;
5489 } else if (!fc_strcasecmp(plrx, plr1)) {
5490 pgiver = p1;
5491 } else {
5492 log_error("Clause giver %s is not participant of the treaty"
5493 "between %s and %s", plrx, plr0, plr1);
5494 }
5495
5496 if (pgiver != nullptr) {
5497 int value;
5498
5499 value = secfile_lookup_int_default(loading->file, 0,
5500 "treaty%d.clause%d.value",
5501 tidx, cidx);
5502
5503 add_clause(ptreaty, pgiver, type, value, nullptr);
5504 }
5505 }
5506 }
5507
5508 /* These must be after clauses have been added so that acceptance
5509 * does not get cleared by what seems like changes to the treaty. */
5511 "treaty%d.accept0", tidx);
5513 "treaty%d.accept1", tidx);
5514 }
5515 }
5516}
5517
5518/* =======================================================================
5519 * Load the history report
5520 * ======================================================================= */
5521
5522/************************************************************************/
5526{
5528 int turn;
5529
5530 /* Check status and return if not OK (sg_success FALSE). */
5531 sg_check_ret();
5532
5533 turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
5534
5535 if (turn != -2) {
5536 hist->turn = turn;
5537 }
5538
5539 if (turn + 1 >= game.info.turn) {
5540 const char *str;
5541
5542 str = secfile_lookup_str(loading->file, "history.title");
5543 sg_failure_ret(str != nullptr, "%s", secfile_error());
5544 sz_strlcpy(hist->title, str);
5545 str = secfile_lookup_str(loading->file, "history.body");
5546 sg_failure_ret(str != nullptr, "%s", secfile_error());
5547 sz_strlcpy(hist->body, str);
5548 }
5549}
5550
5551/* =======================================================================
5552 * Load the mapimg definitions.
5553 * ======================================================================= */
5554
5555/************************************************************************/
5558static void sg_load_mapimg(struct loaddata *loading)
5559{
5560 int mapdef_count, i;
5561
5562 /* Check status and return if not OK (sg_success FALSE). */
5563 sg_check_ret();
5564
5565 /* Clear all defined map images. */
5566 while (mapimg_count() > 0) {
5567 mapimg_delete(0);
5568 }
5569
5571 "mapimg.count");
5572 log_verbose("Saved map image definitions: %d.", mapdef_count);
5573
5574 if (0 >= mapdef_count) {
5575 return;
5576 }
5577
5578 for (i = 0; i < mapdef_count; i++) {
5579 const char *p;
5580
5581 p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
5582 if (p == nullptr) {
5583 log_verbose("[Mapimg %4d] Missing definition.", i);
5584 continue;
5585 }
5586
5587 if (!mapimg_define(p, FALSE)) {
5588 log_error("Invalid map image definition %4d: %s.", i, p);
5589 }
5590
5591 log_verbose("Mapimg %4d loaded.", i);
5592 }
5593}
5594
5595/* =======================================================================
5596 * Sanity checks for loading a game.
5597 * ======================================================================= */
5598
5599/************************************************************************/
5603{
5604 int players;
5605
5606 /* Check status and return if not OK (sg_success FALSE). */
5607 sg_check_ret();
5608
5609 if (game.info.is_new_game) {
5610 /* Nothing to do for new games (or not started scenarios). */
5611 return;
5612 }
5613
5614 /* Old savegames may have maxplayers lower than current player count,
5615 * fix. */
5616 players = normal_player_count();
5617 if (game.server.max_players < players) {
5618 log_verbose("Max players lower than current players, fixing");
5619 game.server.max_players = players;
5620 }
5621
5622 /* Fix ferrying sanity */
5623 players_iterate(pplayer) {
5624 unit_list_iterate_safe(pplayer->units, punit) {
5627 log_sg("Removing %s unferried %s in %s at (%d, %d)",
5633 }
5636
5637 /* Fix stacking issues. We don't rely on the savegame preserving
5638 * alliance invariants (old savegames often did not) so if there are any
5639 * unallied units on the same tile we just bounce them. */
5640 players_iterate(pplayer) {
5642 resolve_unit_stacks(pplayer, aplayer, TRUE);
5645
5646 /* Recalculate the potential buildings for each city. Has caused some
5647 * problems with game random state.
5648 * This also changes the game state if you save the game directly after
5649 * loading it and compare the results. */
5650 players_iterate(pplayer) {
5651 /* Building advisor needs data phase open in order to work */
5652 adv_data_phase_init(pplayer, FALSE);
5653 building_advisor(pplayer);
5654 /* Close data phase again so it can be opened again when game starts. */
5655 adv_data_phase_done(pplayer);
5657
5658 /* Prevent a buggy or intentionally crafted save game from crashing
5659 * Freeciv. See hrm Bug #887748 */
5660 players_iterate(pplayer) {
5661 city_list_iterate(pplayer->cities, pcity) {
5662 worker_task_list_iterate(pcity->task_reqs, ptask) {
5663 if (!worker_task_is_sane(ptask)) {
5664 log_error("[city id: %d] Bad worker task %d.",
5665 pcity->id, ptask->act);
5666 worker_task_list_remove(pcity->task_reqs, ptask);
5667 free(ptask);
5668 ptask = nullptr;
5669 }
5673
5674 /* Check worked tiles map */
5675#ifdef FREECIV_DEBUG
5676 if (loading->worked_tiles != nullptr) {
5677 /* Check the entire map for unused worked tiles */
5678 whole_map_iterate(&(wld.map), ptile) {
5679 if (loading->worked_tiles[ptile->index] != -1) {
5680 log_error("[city id: %d] Unused worked tile at (%d, %d).",
5681 loading->worked_tiles[ptile->index], TILE_XY(ptile));
5682 }
5684 }
5685#endif /* FREECIV_DEBUG */
5686
5687 /* Check researching technologies and goals. */
5689 if (presearch->researching != A_UNSET
5690 && !is_future_tech(presearch->researching)
5691 && (valid_advance_by_number(presearch->researching) == nullptr
5693 != TECH_PREREQS_KNOWN))) {
5694 log_sg(_("%s had invalid researching technology."),
5696 presearch->researching = A_UNSET;
5697 }
5698 if (presearch->tech_goal != A_UNSET
5699 && !is_future_tech(presearch->tech_goal)
5700 && (valid_advance_by_number(presearch->tech_goal) == nullptr
5703 == TECH_KNOWN))) {
5704 log_sg(_("%s had invalid technology goal."),
5706 presearch->tech_goal = A_UNSET;
5707 }
5708
5711
5712 players_iterate(pplayer) {
5713 unit_list_iterate_safe(pplayer->units, punit) {
5714 if (punit->has_orders
5716 punit->orders.list)) {
5717 log_sg("Invalid unit orders for unit %d.", punit->id);
5719 }
5722
5723 /* Check max rates (rules may have changed since saving) */
5724 players_iterate(pplayer) {
5727
5728 /* Check initial city sanity */
5729 players_iterate(pplayer) {
5730 if (!player_has_flag(pplayer, PLRF_FIRST_CITY)
5731 && city_list_size(pplayer->cities) > 0) {
5732 log_sg(_("%s inconsistency: Has never had their first city, "
5733 "but has cities this very moment. Fixing."),
5734 player_name(pplayer));
5735 BV_SET(pplayer->flags, PLRF_FIRST_CITY);
5736 }
5738
5739 if (0 == strlen(server.game_identifier)
5740 || !is_base64url(server.game_identifier)) {
5741 /* This uses fc_rand(), so random state has to be initialized before. */
5742 randomize_base64url_string(server.game_identifier,
5743 sizeof(server.game_identifier));
5744 }
5745
5746 /* Check if some player has more than one of some UTYF_UNIQUE unit type */
5747 players_iterate(pplayer) {
5748 int unique_count[U_LAST];
5749
5750 memset(unique_count, 0, sizeof(unique_count));
5751
5752 unit_list_iterate(pplayer->units, punit) {
5755
5758 log_sg(_("%s has multiple units of type %s though it should be possible "
5759 "to have only one."),
5761 }
5764
5765 /* Restore game random state, just in case various initialization code
5766 * inexplicably altered the previously existing state. */
5767 if (!game.info.is_new_game) {
5768 fc_rand_set_state(loading->rstate);
5769
5770 if (loading->version < 30) {
5771 /* For older savegames we have to recalculate the score with current data,
5772 * instead of using beginning-of-turn saved scores. */
5773 players_iterate(pplayer) {
5774 calc_civ_score(pplayer);
5776 }
5777 }
5778
5779 /* At the end do the default sanity checks. */
5780 sanity_check();
5781}
struct achievement * achievement_by_rule_name(const char *name)
#define ACTION_NONE
Definition actions.h:59
void building_advisor(struct player *pplayer)
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Definition advdata.c:270
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:574
const char * ai_name(const struct ai_type *ai)
Definition ai.c:335
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:390
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:380
void ai_traits_init(struct player *pplayer)
Definition aitraits.c:33
#define str
Definition astring.c:76
Base_type_id base_number(const struct base_type *pbase)
Definition base.c:96
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:106
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:144
struct base_type * base_by_number(const Base_type_id id)
Definition base.c:80
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c:142
void dbv_clr_all(struct dbv *pdbv)
Definition bitvector.c:174
void dbv_to_bv(unsigned char *dest, const struct dbv *src)
Definition bitvector.c:227
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_CLR(bv, bit)
Definition bitvector.h:94
bool has_capability(const char *cap, const char *capstr)
Definition capability.c:79
void citizens_nation_set(struct city *pcity, const struct player_slot *pslot, citizens count)
Definition citizens.c:145
citizens citizens_count(const struct city *pcity)
Definition citizens.c:162
void citizens_init(struct city *pcity)
Definition citizens.c:32
void citizens_update(struct city *pcity, struct player *plr)
void city_map_radius_sq_set(struct city *pcity, int radius_sq)
Definition city.c:148
void city_name_set(struct city *pcity, const char *new_name)
Definition city.c:1197
const char * city_name_get(const struct city *pcity)
Definition city.c:1157
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3538
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2938
void city_size_set(struct city *pcity, citizens size)
Definition city.c:1232
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3465
void destroy_city_virtual(struct city *pcity)
Definition city.c:3628
int city_style_by_rule_name(const char *s)
Definition city.c:1791
#define cities_iterate_end
Definition city.h:517
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:565
#define cities_iterate(pcity)
Definition city.h:512
#define CITY_MAP_MAX_RADIUS_SQ
Definition city.h:84
static citizens city_size_get(const struct city *pcity)
Definition city.h:570
#define output_type_iterate(output)
Definition city.h:853
#define city_owner(_pcity_)
Definition city.h:564
#define FREE_WORKED_TILES
Definition city.h:890
#define MAX_CITY_SIZE
Definition city.h:104
#define city_list_iterate_end
Definition city.h:510
#define I_NEVER
Definition city.h:245
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:228
#define city_tile_iterate_end
Definition city.h:236
#define output_type_iterate_end
Definition city.h:859
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2787
bool send_city_suppression(bool now)
Definition citytools.c:2176
static void void city_freeze_workers(struct city *pcity)
Definition citytools.c:136
void city_thaw_workers(struct city *pcity)
Definition citytools.c:146
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2858
void city_refresh_vision(struct city *pcity)
Definition citytools.c:3460
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:853
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
char * incite_cost
Definition comments.c:77
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:3189
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:3210
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:77
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Definition difficulty.c:39
enum diplstate_type valid_dst_closest(struct player_diplstate *dst)
Definition diplhand.c:108
struct treaty * ptreaty
Definition diplodlg_g.h:28
void treaty_add(struct treaty *ptreaty)
Definition diptreaty.c:377
void init_treaty(struct treaty *ptreaty, struct player *plr0, struct player *plr1)
Definition diptreaty.c:99
bool add_clause(struct treaty *ptreaty, struct player *pfrom, enum clause_type type, int val, struct player *client_player)
Definition diptreaty.c:145
int int id
Definition editgui_g.h:28
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:779
struct extra_type * extra_type_by_rule_name(const char *name)
Definition extras.c:212
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
int extra_number(const struct extra_type *pextra)
Definition extras.c:161
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:804
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define EXTRA_NONE
Definition extras.h:85
#define extra_base_get(_e_)
Definition extras.h:190
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
static char * ruleset
Definition fc_manual.c:160
#define NO_TARGET
Definition fc_types.h:215
int Road_type_id
Definition fc_types.h:245
@ ROCO_RAILROAD
Definition fc_types.h:948
@ ROCO_RIVER
Definition fc_types.h:948
@ ROCO_ROAD
Definition fc_types.h:948
int Tech_type_id
Definition fc_types.h:238
unsigned char citizens
Definition fc_types.h:249
@ RPT_POSSIBLE
Definition fc_types.h:515
int Base_type_id
Definition fc_types.h:244
int Multiplier_type_id
Definition fc_types.h:247
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:94
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:115
void initialize_globals(void)
Definition game.c:692
struct city * game_city_by_number(int id)
Definition game.c:106
#define GAME_DEFAULT_TIMEOUTINTINC
Definition game.h:603
#define GAME_DEFAULT_SCORETURN
Definition game.h:587
#define GAME_DEFAULT_TIMEOUTINT
Definition game.h:602
#define GAME_DEFAULT_TIMEOUTINCMULT
Definition game.h:605
#define GAME_DEFAULT_TIMEOUTINC
Definition game.h:604
#define GAME_DEFAULT_RULESETDIR
Definition game.h:681
#define GAME_DEFAULT_TIMEOUTCOUNTER
Definition game.h:607
#define GAME_DEFAULT_PHASE_MODE
Definition game.h:622
struct government * government_by_rule_name(const char *name)
Definition government.c:57
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
void idex_register_unit(struct world *iworld, struct unit *punit)
Definition idex.c:82
void idex_register_city(struct world *iworld, struct city *pcity)
Definition idex.c:67
Impr_type_id improvement_index(const struct impr_type *pimprove)
struct impr_type * improvement_by_rule_name(const char *name)
#define WONDER_DESTROYED
#define WONDER_LOST
void adv_city_free(struct city *pcity)
Definition infracache.c:502
void adv_city_alloc(struct city *pcity)
Definition infracache.c:489
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:182
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define log_fatal(message,...)
Definition log.h:101
#define fc_assert_action(condition, action)
Definition log.h:188
#define log_debug(message,...)
Definition log.h:116
#define log_normal(message,...)
Definition log.h:108
#define log_error(message,...)
Definition log.h:104
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1813
#define nat_x
#define nat_y
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:686
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:2030
void map_init_topology(struct civ_map *nmap)
Definition map.c:315
void main_map_allocate(void)
Definition map.c:534
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:471
int map_startpos_count(void)
Definition map.c:2017
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:458
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1796
#define whole_map_iterate(_map, _tile)
Definition map.h:582
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:161
#define whole_map_iterate_end
Definition map.h:591
@ MAPGEN_SCENARIO
Definition map_types.h:47
void assign_continent_numbers(void)
void player_map_init(struct player *pplayer)
Definition maphand.c:1228
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1475
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2174
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:901
bool send_tile_suppression(bool now)
Definition maphand.c:474
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:344
void map_know_and_see_all(struct player *pplayer)
Definition maphand.c:1203
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1406
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2187
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1185
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:927
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1166
void map_calculate_borders(void)
Definition maphand.c:2332
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1640
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1390
bool mapimg_define(const char *maparg, bool check)
Definition mapimg.c:769
bool mapimg_delete(int id)
Definition mapimg.c:1205
int mapimg_count(void)
Definition mapimg.c:573
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
void set_meta_patches_string(const char *string)
Definition meta.c:172
const char * default_meta_patches_string(void)
Definition meta.c:83
#define DEFAULT_META_SERVER_ADDR
Definition meta.h:21
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
const char * multiplier_rule_name(const struct multiplier *pmul)
struct multiplier * multiplier_by_rule_name(const char *name)
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Definition multipliers.c:80
#define multipliers_iterate(_mul_)
Definition multipliers.h:61
#define multipliers_iterate_end
Definition multipliers.h:67
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
struct nation_type * nation_by_rule_name(const char *name)
Definition nation.c:121
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
#define NO_NATION_SELECTED
Definition nation.h:30
void event_cache_load(struct section_file *file, const char *section)
Definition notify.c:783
int parts
Definition packhand.c:134
char * lines
Definition packhand.c:133
int len
Definition packhand.c:129
bool player_slot_is_used(const struct player_slot *pslot)
Definition player.c:441
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1217
struct player * player_by_number(const int player_id)
Definition player.c:837
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1468
int player_count(void)
Definition player.c:806
int player_slot_count(void)
Definition player.c:415
struct player_slot * player_slot_by_number(int player_id)
Definition player.c:454
int player_number(const struct player *pplayer)
Definition player.c:826
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Definition player.c:164
const char * player_name(const struct player *pplayer)
Definition player.c:885
int player_slot_max_used_number(void)
Definition player.c:467
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1376
int player_slot_index(const struct player_slot *pslot)
Definition player.c:423
struct player * player_by_name(const char *name)
Definition player.c:871
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1979
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1191
int player_index(const struct player *pplayer)
Definition player.c:818
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Definition player.c:849
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:325
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1397
struct player_slot * slots
Definition player.c:51
#define players_iterate_end
Definition player.h:552
dipl_reason
Definition player.h:192
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition player.h:194
@ DIPL_ALLIANCE_PROBLEM_US
Definition player.h:194
#define players_iterate(_pplayer)
Definition player.h:547
#define MAX_ATTRIBUTE_BLOCK
Definition player.h:223
#define player_list_iterate(playerlist, pplayer)
Definition player.h:570
static bool is_barbarian(const struct player *pplayer)
Definition player.h:499
#define player_slots_iterate(_pslot)
Definition player.h:538
#define is_ai(plr)
Definition player.h:232
#define player_list_iterate_end
Definition player.h:572
#define players_iterate_alive_end
Definition player.h:562
#define player_slots_iterate_end
Definition player.h:542
#define players_iterate_alive(_pplayer)
Definition player.h:557
void server_player_set_name(struct player *pplayer, const char *name)
Definition plrhand.c:2270
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Definition plrhand.c:1896
int normal_player_count(void)
Definition plrhand.c:3217
void player_limit_to_max_rates(struct player *pplayer)
Definition plrhand.c:2059
struct nation_type * pick_a_nation(const struct nation_list *choices, bool ignore_conflicts, bool needs_startpos, enum barbarian_type barb_type)
Definition plrhand.c:2466
void set_shuffled_players(int *shuffled_players)
Definition plrhand.c:2416
void player_delegation_set(struct player *pplayer, const char *username)
Definition plrhand.c:3263
void shuffle_players(void)
Definition plrhand.c:2391
void server_remove_player(struct player *pplayer)
Definition plrhand.c:1945
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Definition plrhand.c:1620
void assign_player_colors(void)
Definition plrhand.c:1736
void fit_nationset_to_players(void)
Definition plrhand.c:2672
RANDOM_STATE fc_rand_state(void)
Definition rand.c:208
void fc_rand_set_state(RANDOM_STATE state)
Definition rand.c:229
const char * secfile_error(void)
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
float secfile_lookup_float_default(const struct section_file *secfile, float def, const char *path,...)
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
struct section * secfile_section_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
#define secfile_lookup_enum_default(secfile, defval, specenum_type, path,...)
#define secfile_entry_ignore(_sfile_, _fmt_,...)
#define secfile_entry_ignore_by_path(_sfile_, _path_)
struct history_report * history_report_get(void)
Definition report.c:1859
bool are_reqs_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
struct universal universal_by_rule_name(const char *kind, const char *value)
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c:671
const char * research_name_translation(const struct research *presearch)
Definition research.c:158
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:640
struct research * research_by_number(int number)
Definition research.c:119
int recalculate_techs_researched(const struct research *presearch)
Definition research.c:1357
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:622
void research_update(struct research *presearch)
Definition research.c:504
#define researches_iterate(_presearch)
Definition research.h:155
#define researches_iterate_end
Definition research.h:158
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Definition rgbcolor.c:70
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, char *path,...)
Definition rgbcolor.c:86
struct extra_type * road_extra_get(const struct road_type *proad)
Definition road.c:42
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
struct road_type * road_by_number(Road_type_id id)
Definition road.c:58
struct road_type * road_by_compat_special(enum road_compat compat)
Definition road.c:160
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Definition ruleload.c:9489
#define sanity_check()
Definition sanitycheck.h:44
#define sanity_check_city(x)
Definition sanitycheck.h:42
struct extra_type * resource_by_identifier(const char identifier)
Definition savecompat.c:335
static struct compatibility compat[]
Definition savecompat.c:117
int char2num(char ch)
Definition savecompat.c:279
void sg_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:154
enum ai_level ai_level_convert(int old_level)
int ascii_hex2bin(char ch, int halfbyte)
Definition savecompat.c:255
struct extra_type * special_extra_get(int spe)
Definition savecompat.c:320
enum tile_special_type special_by_rule_name(const char *name)
Definition savecompat.c:294
void sg_load_post_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:205
const char * special_rule_name(enum tile_special_type type)
Definition savecompat.c:310
#define sg_check_ret(...)
Definition savecompat.h:148
#define sg_warn(condition, message,...)
Definition savecompat.h:158
tile_special_type
Definition savecompat.h:29
@ S_MINE
Definition savecompat.h:31
@ S_HUT
Definition savecompat.h:33
@ S_FALLOUT
Definition savecompat.h:35
@ S_POLLUTION
Definition savecompat.h:32
@ S_OLD_RIVER
Definition savecompat.h:42
@ S_FARMLAND
Definition savecompat.h:34
@ S_OLD_ROAD
Definition savecompat.h:40
@ S_LAST
Definition savecompat.h:38
@ S_IRRIGATION
Definition savecompat.h:30
@ S_OLD_RAILROAD
Definition savecompat.h:41
#define hex_chars
Definition savecompat.h:203
#define sg_failure_ret_val(condition, _val, message,...)
Definition savecompat.h:182
#define sg_failure_ret(condition, message,...)
Definition savecompat.h:175
#define MAX_TRADE_ROUTES_OLD
Definition savecompat.h:220
#define sg_regr(fixversion, message,...)
Definition savecompat.h:191
@ SAVEGAME_2
Definition savecompat.h:27
#define log_sg
Definition savecompat.h:144
#define sg_warn_ret_val(condition, _val, message,...)
Definition savecompat.h:169
static void unit_ordering_apply(void)
Definition savegame2.c:846
static void sg_load_players_basic(struct loaddata *loading)
Definition savegame2.c:2715
static struct loaddata * loaddata_new(struct section_file *file)
Definition savegame2.c:473
#define ACTIVITY_OLD_POLLUTION_SG2
Definition savegame2.c:148
static void sg_load_map_known(struct loaddata *loading)
Definition savegame2.c:2650
#define halfbyte_iterate_roads_end
Definition savegame2.c:285
static struct extra_type * char2resource(char c)
Definition savegame2.c:1334
static void sg_load_map_owner(struct loaddata *loading)
Definition savegame2.c:2519
bool sg_success
Definition savecompat.c:35
#define halfbyte_iterate_extras_end
Definition savegame2.c:255
static void sg_load_map_tiles_roads(struct loaddata *loading)
Definition savegame2.c:2357
#define halfbyte_iterate_extras(e, num_extras_types)
Definition savegame2.c:250
static void sg_load_map(struct loaddata *loading)
Definition savegame2.c:2197
static enum unit_orders char2order(char order)
Definition savegame2.c:601
static int unquote_block(const char *const quoted_, void *dest, int dest_length)
Definition savegame2.c:744
static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx)
Definition savegame2.c:1245
#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath,...)
Definition savegame2.c:214
#define ACTIVITY_OLD_RAILROAD
Definition savegame2.c:147
static void sg_load_player_city_citizens(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr)
Definition savegame2.c:4074
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3671
static void sg_load_map_tiles(struct loaddata *loading)
Definition savegame2.c:2284
static char activity2char(int activity)
Definition savegame2.c:669
static void sg_load_savefile(struct loaddata *loading)
Definition savegame2.c:1445
#define ACTIVITY_OLD_FALLOUT_SG2
Definition savegame2.c:149
static bool sg_load_player_unit(struct loaddata *loading, struct player *plr, struct unit *punit, const char *unitstr)
Definition savegame2.c:4241
static void set_unit_activity_base(struct unit *punit, Base_type_id base)
Definition savegame2.c:575
static bool sg_load_player_city(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr, int wlist_max_length)
Definition savegame2.c:3790
static void sg_load_settings(struct loaddata *loading)
Definition savegame2.c:2177
static void sg_bases_set_dbv(struct dbv *extras, char ch, struct base_type **idx)
Definition savegame2.c:1213
static void sg_load_player_units(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4122
#define halfbyte_iterate_special(s, num_specials_types)
Definition savegame2.c:260
void savegame2_load(struct section_file *file)
Definition savegame2.c:407
static void sg_load_researches(struct loaddata *loading)
Definition savegame2.c:5337
#define halfbyte_iterate_bases_end
Definition savegame2.c:275
static void sg_load_map_worked(struct loaddata *loading)
Definition savegame2.c:2606
static void sg_load_random(struct loaddata *loading)
Definition savegame2.c:2008
#define halfbyte_iterate_special_end
Definition savegame2.c:265
#define halfbyte_iterate_bases(b, num_bases_types)
Definition savegame2.c:270
static void sg_load_player_units_transport(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4876
static void sg_load_history(struct loaddata *loading)
Definition savegame2.c:5525
static int char2activity(char activity)
Definition savegame2.c:723
#define ORDER_OLD_BUILD_WONDER
Definition savegame2.c:293
static void sg_load_map_tiles_specials(struct loaddata *loading, bool rivers_overlay)
Definition savegame2.c:2373
#define TOKEN_SIZE
Definition savegame2.c:289
static void sg_load_script(struct loaddata *loading)
Definition savegame2.c:2067
static void sg_load_scenario(struct loaddata *loading)
Definition savegame2.c:2082
static void sg_load_ruleset(struct loaddata *loading)
Definition savegame2.c:1411
static void sg_load_game(struct loaddata *loading)
Definition savegame2.c:1858
static void sg_load_player_main(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3164
#define ACTIVITY_OLD_ROAD
Definition savegame2.c:146
static void sg_load_treaties(struct loaddata *loading)
Definition savegame2.c:5443
static void sg_extras_set_bv(bv_extras *extras, char ch, struct extra_type **idx)
Definition savegame2.c:900
static void set_unit_activity_road(struct unit *punit, Road_type_id road)
Definition savegame2.c:586
static Tech_type_id technology_load(struct section_file *file, const char *path, int plrno)
Definition savegame2.c:1371
static enum direction8 char2dir(char dir)
Definition savegame2.c:640
static void sg_load_map_tiles_resources(struct loaddata *loading)
Definition savegame2.c:2404
#define ORDER_OLD_BUILD_CITY
Definition savegame2.c:291
static struct terrain * char2terrain(char ch)
Definition savegame2.c:1349
#define ORDER_OLD_DISBAND
Definition savegame2.c:292
static void sg_load_mapimg(struct loaddata *loading)
Definition savegame2.c:5558
#define ORDER_OLD_HOMECITY
Definition savegame2.c:295
static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch, const enum tile_special_type *idx, bool rivers_overlay)
Definition savegame2.c:1073
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4929
static void sg_load_ruledata(struct loaddata *loading)
Definition savegame2.c:1833
static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch, const enum tile_special_type *idx, bool rivers_overlay)
Definition savegame2.c:933
static void sg_load_player_vision(struct loaddata *loading, struct player *plr)
Definition savegame2.c:5009
static void worklist_load(struct section_file *file, int wlist_max_length, struct worklist *pwl, const char *path,...)
Definition savegame2.c:792
static bool sg_load_player_vision_city(struct loaddata *loading, struct player *plr, struct vision_site *pdcity, const char *citystr)
Definition savegame2.c:5230
static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx)
Definition savegame2.c:1307
static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx)
Definition savegame2.c:1276
static void sg_load_map_startpos(struct loaddata *loading)
Definition savegame2.c:2432
static void loaddata_destroy(struct loaddata *loading)
Definition savegame2.c:514
static void sg_load_players(struct loaddata *loading)
Definition savegame2.c:2972
#define ORDER_OLD_TRADE_ROUTE
Definition savegame2.c:294
static void sg_load_map_tiles_extras(struct loaddata *loading)
Definition savegame2.c:2325
static void sg_load_sanitycheck(struct loaddata *loading)
Definition savegame2.c:5602
static void sg_load_event_cache(struct loaddata *loading)
Definition savegame2.c:5428
static void sg_load_map_tiles_bases(struct loaddata *loading)
Definition savegame2.c:2341
static void sg_extras_set_dbv(struct dbv *extras, char ch, struct extra_type **idx)
Definition savegame2.c:867
#define ACTIVITY_LAST_SAVEGAME2
Definition savegame2.c:150
static int sg_order_to_action(int order, struct unit *act_unit, struct tile *tgt_tile)
Definition savegame2.c:4200
#define halfbyte_iterate_roads(r, num_roads_types)
Definition savegame2.c:280
void save_restore_sane_state(void)
Definition savemain.c:347
void calc_civ_score(struct player *pplayer)
Definition score.c:251
void script_server_state_load(struct section_file *file)
void settings_game_load(struct section_file *file, const char *section)
Definition settings.c:4958
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
bool str_to_int(const char *str, int *pint)
Definition shared.c:515
bool is_base64url(const char *s)
Definition shared.c:321
char scanin(const char **buf, char *delimiters, char *dest, int size)
Definition shared.c:1923
void randomize_base64url_string(char *s, size_t n)
Definition shared.c:343
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
void spaceship_calc_derived(struct player_spaceship *ship)
Definition spacerace.c:46
void spaceship_init(struct player_spaceship *ship)
Definition spaceship.c:96
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
@ SSHIP_LAUNCHED
Definition spaceship.h:85
@ SSHIP_NONE
Definition spaceship.h:84
struct specialist * specialist_by_rule_name(const char *name)
Definition specialist.c:123
Specialist_type_id specialist_index(const struct specialist *sp)
Definition specialist.c:90
#define specialist_type_iterate_end
Definition specialist.h:85
#define specialist_type_iterate(sp)
Definition specialist.h:79
#define DEFAULT_SPECIALIST
Definition specialist.h:43
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
const char * aifill(int amount)
Definition srv_main.c:2556
bool game_was_started(void)
Definition srv_main.c:357
void identity_number_reserve(int id)
Definition srv_main.c:2083
struct server_arguments srvarg
Definition srv_main.c:182
void init_game_seed(void)
Definition srv_main.c:209
void update_nations_with_startpos(void)
Definition srv_main.c:2361
struct player * first
int val
Definition traits.h:38
int mod
Definition traits.h:39
Definition city.h:318
citizens * nationality
Definition city.h:339
bool last_updated_year
Definition game.h:243
int world_peace_start
Definition game.h:245
float turn_change_time
Definition game.h:225
bool vision_reveal_tiles
Definition game.h:207
struct packet_scenario_description scenario_desc
Definition game.h:88
struct packet_ruleset_control control
Definition game.h:83
bool fogofwar_old
Definition game.h:241
struct packet_game_info info
Definition game.h:89
int timeoutcounter
Definition game.h:214
char rulesetdir[MAX_LEN_NAME]
Definition game.h:246
int scoreturn
Definition game.h:232
randseed seed
Definition game.h:234
struct packet_scenario_info scenario
Definition game.h:87
int timeoutint
Definition game.h:210
unsigned revealmap
Definition game.h:184
char orig_game_version[MAX_LEN_NAME]
Definition game.h:228
bool foggedborders
Definition game.h:154
int timeoutincmult
Definition game.h:212
struct civ_game::@32::@36 server
int timeoutinc
Definition game.h:211
int phase_mode_stored
Definition game.h:223
int max_players
Definition game.h:163
int timeoutintinc
Definition game.h:213
randseed seed
Definition map_types.h:105
bool have_resources
Definition map_types.h:121
bool altitude_info
Definition map_types.h:74
struct civ_map::@44::@46 server
bool have_huts
Definition map_types.h:120
enum map_generator generator
Definition map_types.h:111
int changed_to_times
Definition government.h:66
const char ** order
Definition savecompat.h:52
struct section_file * file
Definition savecompat.h:46
bool global_advances[A_LAST]
int great_wonder_owners[B_LAST]
enum ai_level skill_level
enum phase_mode_type phase_mode
char description[MAX_LEN_CONTENT]
char authors[MAX_LEN_PACKET/3]
enum ai_level skill_level
Definition player.h:116
struct ai_trait * traits
Definition player.h:126
enum barbarian_type barbarian_type
Definition player.h:122
int science_cost
Definition player.h:119
int love[MAX_NUM_PLAYER_SLOTS]
Definition player.h:124
int expand
Definition player.h:118
int fuzzy
Definition player.h:117
enum diplstate_type type
Definition player.h:199
int units_killed
Definition player.h:105
int landarea
Definition player.h:94
int population
Definition player.h:96
int pollution
Definition player.h:99
int wonders
Definition player.h:91
int settledarea
Definition player.h:95
int units_used
Definition player.h:108
int specialists[SP_MAX]
Definition player.h:90
int units_lost
Definition player.h:106
int angry
Definition player.h:89
int techout
Definition player.h:93
int units
Definition player.h:98
int units_built
Definition player.h:104
int content
Definition player.h:87
int happy
Definition player.h:86
int spaceship
Definition player.h:103
int culture
Definition player.h:109
int unhappy
Definition player.h:88
int cities
Definition player.h:97
int literacy
Definition player.h:100
int techs
Definition player.h:92
struct player * extras_owner
Definition maphand.h:35
struct player * owner
Definition maphand.h:34
struct city_list * cities
Definition player.h:281
int bulbs_last_turn
Definition player.h:351
struct player_ai ai_common
Definition player.h:288
bv_plr_flags flags
Definition player.h:292
bool is_male
Definition player.h:257
int wonders[B_LAST]
Definition player.h:305
bool unassigned_ranked
Definition player.h:255
struct government * target_government
Definition player.h:259
char username[MAX_LEN_NAME]
Definition player.h:252
int revolution_finishes
Definition player.h:273
int nturns_idle
Definition player.h:265
struct government * government
Definition player.h:258
struct team * team
Definition player.h:261
int turns_alive
Definition player.h:266
struct unit_list * units
Definition player.h:282
char ranked_username[MAX_LEN_NAME]
Definition player.h:254
int huts
Definition player.h:349
bool is_alive
Definition player.h:268
bv_player real_embassy
Definition player.h:277
struct player::@73::@75 server
struct player_economic economic
Definition player.h:284
struct player_spaceship spaceship
Definition player.h:286
struct attribute_block_s attribute_block
Definition player.h:307
struct player_score score
Definition player.h:283
struct multiplier_value multipliers[MAX_NUM_MULTIPLIERS]
Definition player.h:314
struct nation_type * nation
Definition player.h:260
struct nation_style * style
Definition player.h:279
bool border_vision
Definition player.h:327
bool phase_done
Definition player.h:263
int history
Definition player.h:316
char orig_username[MAX_LEN_NAME]
Definition player.h:347
int last_war_action
Definition player.h:270
bool unassigned_user
Definition player.h:253
const struct tile * tile
char metaserver_addr[256]
Definition srv_main.h:29
char serverid[256]
Definition srv_main.h:49
Definition map.c:40
Definition team.c:40
Definition tile.h:50
int index
Definition tile.h:51
bv_extras extras
Definition tile.h:55
struct unit_list * units
Definition tile.h:58
struct tile * claimer
Definition tile.h:64
bool accept1
Definition diptreaty.h:83
bool accept0
Definition diptreaty.h:83
enum unit_orders order
Definition unit.h:93
Definition unit.h:139
int length
Definition unit.h:197
int upkeep[O_LAST]
Definition unit.h:149
bool has_orders
Definition unit.h:195
enum action_decision action_decision_want
Definition unit.h:204
int battlegroup
Definition unit.h:193
enum unit_activity activity
Definition unit.h:158
int moves_left
Definition unit.h:151
int id
Definition unit.h:146
int ord_city
Definition unit.h:244
struct unit::@83 orders
bool moved
Definition unit.h:175
int ord_map
Definition unit.h:243
int index
Definition unit.h:197
struct vision * vision
Definition unit.h:246
bool vigilant
Definition unit.h:199
int hp
Definition unit.h:152
int fuel
Definition unit.h:154
struct extra_type * changed_from_target
Definition unit.h:172
int current_form_turn
Definition unit.h:210
enum direction8 facing
Definition unit.h:143
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:141
struct extra_type * activity_target
Definition unit.h:166
int activity_count
Definition unit.h:164
struct unit_order * list
Definition unit.h:200
enum unit_activity changed_from
Definition unit.h:170
struct player * nationality
Definition unit.h:145
bool repeat
Definition unit.h:198
int homecity
Definition unit.h:147
bool paradropped
Definition unit.h:176
bool done_moving
Definition unit.h:183
int birth_turn
Definition unit.h:209
struct tile * goto_tile
Definition unit.h:156
struct tile * action_decision_tile
Definition unit.h:205
int veteran
Definition unit.h:153
int changed_from_count
Definition unit.h:171
enum server_side_agent ssa_controller
Definition unit.h:174
struct civ_map map
int city_style(struct city *pcity)
Definition style.c:235
struct nation_style * style_by_rule_name(const char *name)
Definition style.c:113
struct nation_style * style_by_number(int id)
Definition style.c:84
const char * style_rule_name(const struct nation_style *pstyle)
Definition style.c:104
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:925
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:851
#define sz_strlcpy(dest, src)
Definition support.h:195
#define RETURN_VALUE_AFTER_EXIT(_val_)
Definition support.h:146
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:173
bool team_add_player(struct player *pplayer, struct team *pteam)
Definition team.c:452
struct team * team_new(struct team_slot *tslot)
Definition team.c:309
const struct player_list * team_members(const struct team *pteam)
Definition team.c:443
bool is_future_tech(Tech_type_id tech)
Definition tech.c:286
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:181
struct advance * advance_by_rule_name(const char *name)
Definition tech.c:205
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:100
#define A_FUTURE
Definition tech.h:46
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
#define A_UNKNOWN
Definition tech.h:49
void init_tech(struct research *research, bool update)
Definition techtools.c:1168
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:188
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:249
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Definition terrain.c:257
#define terrain_type_iterate(_p)
Definition terrain.h:267
#define T_UNKNOWN
Definition terrain.h:62
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:88
#define terrain_type_iterate_end
Definition terrain.h:273
#define RESOURCE_NONE_IDENTIFIER
Definition terrain.h:52
#define RESOURCE_NULL_IDENTIFIER
Definition terrain.h:51
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:216
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1036
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:982
bool tile_set_label(struct tile *ptile, const char *label)
Definition tile.c:1098
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Definition tile.c:350
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
void tile_set_worked(struct tile *ptile, struct city *pcity)
Definition tile.c:107
#define tile_index(_pt_)
Definition tile.h:89
#define tile_worked(_tile)
Definition tile.h:119
#define tile_terrain(_tile)
Definition tile.h:115
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_has_extra(ptile, pextra)
Definition tile.h:152
#define tile_owner(_tile)
Definition tile.h:97
struct goods_type * goods_by_number(Goods_type_id id)
void free_unit_orders(struct unit *punit)
Definition unit.c:1827
int unit_upkeep_cost(const struct unit *punit, Output_type_id otype)
Definition unit.c:2973
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2462
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2526
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:882
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2943
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1682
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2731
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target, enum gen_action trigger_action)
Definition unit.c:1157
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1787
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1308
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1139
#define unit_tile(_pu)
Definition unit.h:408
#define BATTLEGROUP_NONE
Definition unit.h:192
unit_orders
Definition unit.h:37
@ ORDER_ACTION_MOVE
Definition unit.h:45
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_FULL_MP
Definition unit.h:43
@ ORDER_MOVE
Definition unit.h:39
@ ORDER_LAST
Definition unit.h:49
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_owner(_pu)
Definition unit.h:407
void unit_list_sort_ord_map(struct unit_list *punitlist)
Definition unitlist.c:73
void unit_list_sort_ord_city(struct unit_list *punitlist)
Definition unitlist.c:85
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void resolve_unit_stacks(struct player *pplayer, struct player *aplayer, bool verbose)
Definition unittools.c:1414
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:5029
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1238
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:126
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1794
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1613
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2662
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:93
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1586
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_type_iterate(_p)
Definition unittype.h:865
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:872
void vision_site_size_set(struct vision_site *psite, citizens size)
Definition vision.c:180
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Definition vision.c:33
bool vision_reveal_tiles(struct vision *vision, bool reveal_tiles)
Definition vision.c:62
struct vision_site * vision_site_new(int identity, struct tile *location, struct player *owner)
Definition vision.c:86
void vision_site_destroy(struct vision_site *psite)
Definition vision.c:74
bool worker_task_is_sane(struct worker_task *ptask)
Definition workertask.c:40
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
#define MAX_LEN_WORKLIST
Definition worklist.h:24
#define MAP_NATIVE_WIDTH
#define MAP_INDEX_SIZE
#define MAP_NATIVE_HEIGHT