Freeciv-3.2
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 "ruleset.h"
113#include "sanitycheck.h"
114#include "savecompat.h"
115#include "score.h"
116#include "settings.h"
117#include "spacerace.h"
118#include "srv_main.h"
119#include "stdinhand.h"
120#include "techtools.h"
121#include "unittools.h"
122
123/* server/advisors */
124#include "advdata.h"
125#include "advbuilding.h"
126#include "infracache.h"
127
128/* server/generator */
129#include "mapgen.h"
130#include "mapgen_utils.h"
131
132/* server/scripting */
133#include "script_server.h"
134
135/* ai */
136#include "aitraits.h"
137#include "difficulty.h"
138
139#include "savegame2.h"
140
141extern bool sg_success;
142
143#define ACTIVITY_OLD_ROAD (ACTIVITY_LAST + 1)
144#define ACTIVITY_OLD_RAILROAD (ACTIVITY_LAST + 2)
145#define ACTIVITY_OLD_POLLUTION_SG2 (ACTIVITY_OLD_RAILROAD + 1)
146#define ACTIVITY_OLD_FALLOUT_SG2 (ACTIVITY_OLD_POLLUTION_SG2 + 1)
147#define ACTIVITY_LAST_SAVEGAME2 (ACTIVITY_OLD_FALLOUT_SG2 + 1)
148
149/*
150 * This loops over the entire map to save data. It collects all the data of
151 * a line using GET_XY_CHAR and then executes the macro SECFILE_INSERT_LINE.
152 *
153 * Parameters:
154 * ptile: current tile within the line (used by GET_XY_CHAR)
155 * GET_XY_CHAR: macro returning the map character for each position
156 * secfile: a secfile struct
157 * secpath, ...: path as used for sprintf() with arguments; the last item
158 * will be the y coordinate
159 * Example:
160 * SAVE_MAP_CHAR(ptile, terrain2char(ptile->terrain), file, "map.t%04d");
161 */
162#define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath, ...) \
163{ \
164 char _line[wld.map.xsize + 1]; \
165 int _nat_x, _nat_y; \
166 \
167 for (_nat_y = 0; _nat_y < wld.map.ysize; _nat_y++) { \
168 for (_nat_x = 0; _nat_x < wld.map.xsize; _nat_x++) { \
169 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
170 fc_assert_action(ptile != NULL, continue); \
171 _line[_nat_x] = (GET_XY_CHAR); \
172 sg_failure_ret(fc_isprint(_line[_nat_x] & 0x7f), \
173 "Trying to write invalid map data at position " \
174 "(%d, %d) for path %s: '%c' (%d)", _nat_x, _nat_y, \
175 secpath, _line[_nat_x], _line[_nat_x]); \
176 } \
177 _line[wld.map.xsize] = '\0'; \
178 secfile_insert_str(secfile, _line, secpath, ## __VA_ARGS__, _nat_y); \
179 } \
180}
181
182/*
183 * This loops over the entire map to load data. It inputs a line of data
184 * using the macro SECFILE_LOOKUP_LINE and then loops using the macro
185 * SET_XY_CHAR to load each char into the map at (map_x, map_y). Internal
186 * variables ch, map_x, map_y, nat_x, and nat_y are allocated within the
187 * macro but definable by the caller.
188 *
189 * Parameters:
190 * ch: a variable to hold a char (data for a single position,
191 * used by SET_XY_CHAR)
192 * ptile: current tile within the line (used by SET_XY_CHAR)
193 * SET_XY_CHAR: macro to load the map character at each (map_x, map_y)
194 * secfile: a secfile struct
195 * secpath, ...: path as used for sprintf() with arguments; the last item
196 * will be the y coordinate
197 * Example:
198 * LOAD_MAP_CHAR(ch, ptile,
199 * map_get_player_tile(ptile, plr)->terrain
200 * = char2terrain(ch), file, "player%d.map_t%04d", plrno);
201 *
202 * Note: some (but not all) of the code this is replacing used to skip over
203 * lines that did not exist. This allowed for backward-compatibility.
204 * We could add another parameter that specified whether it was OK to
205 * skip the data, but there's not really much advantage to exiting
206 * early in this case. Instead, we let any map data type to be empty,
207 * and just print an informative warning message about it.
208 */
209#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath, ...) \
210{ \
211 int _nat_x, _nat_y; \
212 bool _printed_warning = FALSE; \
213 for (_nat_y = 0; _nat_y < wld.map.ysize; _nat_y++) { \
214 const char *_line = secfile_lookup_str(secfile, secpath, \
215 ## __VA_ARGS__, _nat_y); \
216 if (NULL == _line) { \
217 char buf[64]; \
218 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
219 log_verbose("Line not found='%s'", buf); \
220 _printed_warning = TRUE; \
221 continue; \
222 } else if (strlen(_line) != wld.map.xsize) { \
223 char buf[64]; \
224 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
225 log_verbose("Line too short (expected %d got " SIZE_T_PRINTF \
226 ")='%s'", wld.map.xsize, strlen(_line), buf); \
227 _printed_warning = TRUE; \
228 continue; \
229 } \
230 for (_nat_x = 0; _nat_x < wld.map.xsize; _nat_x++) { \
231 const char ch = _line[_nat_x]; \
232 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
233 (SET_XY_CHAR); \
234 } \
235 } \
236 if (_printed_warning) { \
237 /* TRANS: Minor error message. */ \
238 log_sg(_("Saved game contains incomplete map data. This can" \
239 " happen with old saved games, or it may indicate an" \
240 " invalid saved game file. Proceed at your own risk.")); \
241 } \
242}
243
244/* Iterate on the extras half-bytes */
245#define halfbyte_iterate_extras(e, num_extras_types) \
246{ \
247 int e; \
248 for (e = 0; 4 * e < (num_extras_types); e++) {
249
250#define halfbyte_iterate_extras_end \
251 } \
252}
253
254/* Iterate on the specials half-bytes */
255#define halfbyte_iterate_special(s, num_specials_types) \
256{ \
257 enum tile_special_type s; \
258 for (s = 0; 4 * s < (num_specials_types); s++) {
259
260#define halfbyte_iterate_special_end \
261 } \
262}
263
264/* Iterate on the bases half-bytes */
265#define halfbyte_iterate_bases(b, num_bases_types) \
266{ \
267 int b; \
268 for (b = 0; 4 * b < (num_bases_types); b++) {
269
270#define halfbyte_iterate_bases_end \
271 } \
272}
273
274/* Iterate on the roads half-bytes */
275#define halfbyte_iterate_roads(r, num_roads_types) \
276{ \
277 int r; \
278 for (r = 0; 4 * r < (num_roads_types); r++) {
279
280#define halfbyte_iterate_roads_end \
281 } \
282}
283
284#define TOKEN_SIZE 10
285
286#define ORDER_OLD_BUILD_CITY (-1)
287#define ORDER_OLD_DISBAND (-2)
288#define ORDER_OLD_BUILD_WONDER (-3)
289#define ORDER_OLD_TRADE_ROUTE (-4)
290#define ORDER_OLD_HOMECITY (-5)
291
292static struct loaddata *loaddata_new(struct section_file *file);
293static void loaddata_destroy(struct loaddata *loading);
294
295static enum unit_orders char2order(char order);
296static enum direction8 char2dir(char dir);
297static char activity2char(int activity);
298static int char2activity(char activity);
299static int unquote_block(const char *const quoted_, void *dest,
300 int dest_length);
301static void worklist_load(struct section_file *file, int wlist_max_length,
302 struct worklist *pwl,
303 const char *path, ...);
304static void unit_ordering_apply(void);
305static void sg_extras_set_dbv(struct dbv *extras, char ch,
306 struct extra_type **idx);
307static void sg_extras_set_bv(bv_extras *extras, char ch,
308 struct extra_type **idx);
309static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch,
310 const enum tile_special_type *idx,
311 bool rivers_overlay);
312static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch,
313 const enum tile_special_type *idx,
314 bool rivers_overlay);
315static void sg_bases_set_dbv(struct dbv *extras, char ch, struct base_type **idx);
316static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx);
317static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx);
318static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx);
319static struct extra_type *char2resource(char c);
320static struct terrain *char2terrain(char ch);
321static Tech_type_id technology_load(struct section_file *file,
322 const char *path, int plrno);
323
324static void sg_load_ruleset(struct loaddata *loading);
325static void sg_load_savefile(struct loaddata *loading);
326
327static void sg_load_game(struct loaddata *loading);
328
329static void sg_load_ruledata(struct loaddata *loading);
330
331static void sg_load_random(struct loaddata *loading);
332
333static void sg_load_script(struct loaddata *loading);
334
335static void sg_load_scenario(struct loaddata *loading);
336
337static void sg_load_settings(struct loaddata *loading);
338
339static void sg_load_map(struct loaddata *loading);
340static void sg_load_map_tiles(struct loaddata *loading);
341static void sg_load_map_tiles_extras(struct loaddata *loading);
342static void sg_load_map_tiles_bases(struct loaddata *loading);
343static void sg_load_map_tiles_roads(struct loaddata *loading);
345 bool rivers_overlay);
346static void sg_load_map_tiles_resources(struct loaddata *loading);
347
348static void sg_load_map_startpos(struct loaddata *loading);
349static void sg_load_map_owner(struct loaddata *loading);
350static void sg_load_map_worked(struct loaddata *loading);
351static void sg_load_map_known(struct loaddata *loading);
352
353static void sg_load_players_basic(struct loaddata *loading);
354static void sg_load_players(struct loaddata *loading);
355static void sg_load_player_main(struct loaddata *loading,
356 struct player *plr);
357static void sg_load_player_cities(struct loaddata *loading,
358 struct player *plr);
359static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
360 struct city *pcity, const char *citystr,
361 int wlist_max_length);
363 struct player *plr,
364 struct city *pcity,
365 const char *citystr);
366static void sg_load_player_units(struct loaddata *loading,
367 struct player *plr);
368static bool sg_load_player_unit(struct loaddata *loading,
369 struct player *plr, struct unit *punit,
370 const char *unitstr);
372 struct player *plr);
373static void sg_load_player_attributes(struct loaddata *loading,
374 struct player *plr);
375static void sg_load_player_vision(struct loaddata *loading,
376 struct player *plr);
378 struct player *plr,
379 struct vision_site *pdcity,
380 const char *citystr);
381
382static void sg_load_researches(struct loaddata *loading);
383
384static void sg_load_event_cache(struct loaddata *loading);
385
386static void sg_load_treaties(struct loaddata *loading);
387
388static void sg_load_history(struct loaddata *loading);
389
390static void sg_load_mapimg(struct loaddata *loading);
391
392static void sg_load_sanitycheck(struct loaddata *loading);
393
394
395/* =======================================================================
396 * Basic load / save functions.
397 * ======================================================================= */
398
399/************************************************************************/
402void savegame2_load(struct section_file *file)
403{
404 struct loaddata *loading;
406
407 /* initialise loading */
412
413 /* Load the savegame data. */
414 /* Set up correct ruleset */
416 /* [compat] */
418 /* [savefile] */
420 /* [game] */
422 /* [scenario] */
424 /* [random] */
426 /* [settings] */
428 /* [ruledata] */
430 /* [players] (basic data) */
432 /* [map]; needs width and height loaded by [settings] */
434 /* [research] */
436 /* [player<i>] */
438 /* [event_cache] */
440 /* [treaties] */
442 /* [history] */
444 /* [mapimg] */
446 /* [script] -- must come last as may reference game objects */
448 /* [post_load_compat]; needs the game loaded by [savefile] */
450
451 /* Sanity checks for the loaded game. */
453
454 /* deinitialise loading */
458
459 if (!sg_success) {
460 log_error("Failure loading savegame!");
461 /* Try to get the server back to a vaguely sane state */
465 }
466}
467
468/************************************************************************/
471static struct loaddata *loaddata_new(struct section_file *file)
472{
473 struct loaddata *loading = calloc(1, sizeof(*loading));
474 loading->file = file;
475 loading->secfile_options = NULL;
476
477 loading->improvement.order = NULL;
478 loading->improvement.size = -1;
479 loading->technology.order = NULL;
480 loading->technology.size = -1;
481 loading->activities.order = NULL;
482 loading->activities.size = -1;
483 loading->trait.order = NULL;
484 loading->trait.size = -1;
485 loading->extra.order = NULL;
486 loading->extra.size = -1;
487 loading->multiplier.order = NULL;
488 loading->multiplier.size = -1;
489 loading->special.order = NULL;
490 loading->special.size = -1;
491 loading->base.order = NULL;
492 loading->base.size = -1;
493 loading->road.order = NULL;
494 loading->road.size = -1;
495 loading->specialist.order = NULL;
496 loading->specialist.size = -1;
497 loading->ds_t.order = NULL;
498 loading->ds_t.size = -1;
499 loading->coptions.order = NULL;
500 loading->coptions.size = -1;
501
502 loading->server_state = S_S_INITIAL;
503 loading->rstate = fc_rand_state();
504 loading->worked_tiles = NULL;
505
506 return loading;
507}
508
509/************************************************************************/
513{
514 if (loading->improvement.order != NULL) {
515 free(loading->improvement.order);
516 }
517
518 if (loading->technology.order != NULL) {
519 free(loading->technology.order);
520 }
521
522 if (loading->activities.order != NULL) {
523 free(loading->activities.order);
524 }
525
526 if (loading->trait.order != NULL) {
527 free(loading->trait.order);
528 }
529
530 if (loading->extra.order != NULL) {
531 free(loading->extra.order);
532 }
533
534 if (loading->multiplier.order != NULL) {
535 free(loading->multiplier.order);
536 }
537
538 if (loading->special.order != NULL) {
539 free(loading->special.order);
540 }
541
542 if (loading->base.order != NULL) {
543 free(loading->base.order);
544 }
545
546 if (loading->road.order != NULL) {
547 free(loading->road.order);
548 }
549
550 if (loading->specialist.order != NULL) {
551 free(loading->specialist.order);
552 }
553
554 if (loading->ds_t.order != NULL) {
555 free(loading->ds_t.order);
556 }
557
558 if (loading->coptions.order != NULL) {
559 free(loading->coptions.order);
560 }
561
562 if (loading->worked_tiles != NULL) {
563 free(loading->worked_tiles);
564 }
565
566 free(loading);
567}
568
569
570/************************************************************************/
579
580/************************************************************************/
589
590/* =======================================================================
591 * Helper functions.
592 * ======================================================================= */
593
594/************************************************************************/
597static enum unit_orders char2order(char order)
598{
599 switch (order) {
600 case 'm':
601 case 'M':
602 return ORDER_MOVE;
603 case 'w':
604 case 'W':
605 return ORDER_FULL_MP;
606 case 'b':
607 case 'B':
609 case 'a':
610 case 'A':
611 return ORDER_ACTIVITY;
612 case 'd':
613 case 'D':
614 return ORDER_OLD_DISBAND;
615 case 'u':
616 case 'U':
618 case 't':
619 case 'T':
621 case 'h':
622 case 'H':
623 return ORDER_OLD_HOMECITY;
624 case 'x':
625 case 'X':
626 return ORDER_ACTION_MOVE;
627 }
628
629 /* This can happen if the savegame is invalid. */
630 return ORDER_LAST;
631}
632
633/************************************************************************/
636static enum direction8 char2dir(char dir)
637{
638 /* Numberpad values for the directions. */
639 switch (dir) {
640 case '1':
641 return DIR8_SOUTHWEST;
642 case '2':
643 return DIR8_SOUTH;
644 case '3':
645 return DIR8_SOUTHEAST;
646 case '4':
647 return DIR8_WEST;
648 case '6':
649 return DIR8_EAST;
650 case '7':
651 return DIR8_NORTHWEST;
652 case '8':
653 return DIR8_NORTH;
654 case '9':
655 return DIR8_NORTHEAST;
656 }
657
658 /* This can happen if the savegame is invalid. */
659 return direction8_invalid();
660}
661
662/************************************************************************/
665static char activity2char(int activity)
666{
667 switch (activity) {
668 case ACTIVITY_IDLE:
669 return 'w';
670 case ACTIVITY_CLEAN:
671 return 'C';
673 return 'p';
675 return 'r';
676 case ACTIVITY_MINE:
677 return 'm';
679 return 'i';
681 return 'f';
682 case ACTIVITY_SENTRY:
683 return 's';
685 return 'l';
686 case ACTIVITY_PILLAGE:
687 return 'e';
688 case ACTIVITY_GOTO:
689 return 'g';
690 case ACTIVITY_EXPLORE:
691 return 'x';
693 return 'o';
695 return 'y';
697 return 'u';
698 case ACTIVITY_BASE:
699 return 'b';
701 return 'R';
702 case ACTIVITY_CONVERT:
703 return 'c';
705 case ACTIVITY_PLANT:
706 return '?';
707 case ACTIVITY_LAST:
708 break;
709 }
710
712
713 return '?';
714}
715
716/************************************************************************/
719static int char2activity(char activity)
720{
721 int a;
722
723 for (a = 0; a < ACTIVITY_LAST_SAVEGAME2; a++) {
724 char achar = activity2char(a);
725
726 if (activity == achar) {
727 return a;
728 }
729 }
730
731 /* This can happen if the savegame is invalid. */
732 return ACTIVITY_LAST;
733}
734
735/************************************************************************/
740static int unquote_block(const char *const quoted_, void *dest,
741 int dest_length)
742{
743 int i, length, parsed, tmp;
744 char *endptr;
745 const char *quoted = quoted_;
746
747 parsed = sscanf(quoted, "%d", &length);
748
749 if (parsed != 1) {
750 log_error(_("Syntax error in attribute block."));
751 return 0;
752 }
753
754 if (length > dest_length) {
755 return 0;
756 }
757
758 quoted = strchr(quoted, ':');
759
760 if (quoted == NULL) {
761 log_error(_("Syntax error in attribute block."));
762 return 0;
763 }
764
765 quoted++;
766
767 for (i = 0; i < length; i++) {
768 tmp = strtol(quoted, &endptr, 16);
769
770 if ((endptr - quoted) != 2
771 || *endptr != ' '
772 || (tmp & 0xff) != tmp) {
773 log_error(_("Syntax error in attribute block."));
774 return 0;
775 }
776
777 ((unsigned char *) dest)[i] = tmp;
778 quoted += 3;
779 }
780
781 return length;
782}
783
784/************************************************************************/
789 struct worklist *pwl, const char *path, ...)
790{
791 int i;
792 const char *kind;
793 const char *name;
794 char path_str[1024];
795 va_list ap;
796
797 /* The first part of the registry path is taken from the varargs to the
798 * function. */
799 va_start(ap, path);
800 fc_vsnprintf(path_str, sizeof(path_str), path, ap);
801 va_end(ap);
802
805 "%s.wl_length", path_str);
806
807 for (i = 0; i < pwl->length; i++) {
808 kind = secfile_lookup_str(file, "%s.wl_kind%d", path_str, i);
809
810 /* We lookup the production value by name. An invalid entry isn't a
811 * fatal error; we just truncate the worklist. */
812 name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
813 path_str, i);
814 pwl->entries[i] = universal_by_rule_name(kind, name);
815 if (pwl->entries[i].kind == universals_n_invalid()) {
816 log_sg("%s.wl_value%d: unknown \"%s\" \"%s\".", path_str, i, kind,
817 name);
818 pwl->length = i;
819 break;
820 }
821 }
822
823 /* Padding entries */
824 for (; i < wlist_max_length; i++) {
825 (void) secfile_entry_lookup(file, "%s.wl_kind%d", path_str, i);
826 (void) secfile_entry_lookup(file, "%s.wl_value%d", path_str, i);
827 }
828}
829
830/************************************************************************/
834static void unit_ordering_apply(void)
835{
836 players_iterate(pplayer) {
837 city_list_iterate(pplayer->cities, pcity) {
838 unit_list_sort_ord_city(pcity->units_supported);
839 }
842
843 whole_map_iterate(&(wld.map), ptile) {
844 unit_list_sort_ord_map(ptile->units);
846}
847
848/************************************************************************/
855static void sg_extras_set_dbv(struct dbv *extras, char ch,
856 struct extra_type **idx)
857{
858 int i, bin;
859 const char *pch = strchr(hex_chars, ch);
860
861 if (!pch || ch == '\0') {
862 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
863 bin = 0;
864 } else {
865 bin = pch - hex_chars;
866 }
867
868 for (i = 0; i < 4; i++) {
869 struct extra_type *pextra = idx[i];
870
871 if (pextra == NULL) {
872 continue;
873 }
874 if ((bin & (1 << i))
875 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
876 dbv_set(extras, extra_index(pextra));
877 }
878 }
879}
880
881/************************************************************************/
889 struct extra_type **idx)
890{
891 int i, bin;
892 const char *pch = strchr(hex_chars, ch);
893
894 if (!pch || ch == '\0') {
895 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
896 bin = 0;
897 } else {
898 bin = pch - hex_chars;
899 }
900
901 for (i = 0; i < 4; i++) {
902 struct extra_type *pextra = idx[i];
903
904 if (pextra == NULL) {
905 continue;
906 }
907 if ((bin & (1 << i))
908 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
909 BV_SET(*extras, extra_index(pextra));
910 }
911 }
912}
913
914/************************************************************************/
921static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch,
922 const enum tile_special_type *idx,
923 bool rivers_overlay)
924{
925 int i, bin;
926 const char *pch = strchr(hex_chars, ch);
927
928 if (!pch || ch == '\0') {
929 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
930 bin = 0;
931 } else {
932 bin = pch - hex_chars;
933 }
934
935 for (i = 0; i < 4; i++) {
936 enum tile_special_type sp = idx[i];
937
938 if (sp == S_LAST) {
939 continue;
940 }
941 if (rivers_overlay && sp != S_OLD_RIVER) {
942 continue;
943 }
944
945 if (sp == S_HUT && !wld.map.server.have_huts) {
946 /* It would be logical to have this in the saving side -
947 * really not saving the huts in the first place, BUT
948 * 1) They have been saved by older versions, so we
949 * have to deal with such savegames.
950 * 2) This makes scenario author less likely to lose
951 * one's work completely after carefully placing huts
952 * and then saving with 'have_huts' disabled. */
953 continue;
954 }
955
956 if (bin & (1 << i)) {
957 if (sp == S_OLD_ROAD) {
958 struct road_type *proad;
959
961 if (proad) {
963 }
964 } else if (sp == S_OLD_RAILROAD) {
965 struct road_type *proad;
966
968 if (proad) {
970 }
971 } else if (sp == S_OLD_RIVER) {
972 struct road_type *proad;
973
975 if (proad) {
977 }
978 } else {
979 struct extra_type *pextra = NULL;
980 enum extra_cause cause = EC_COUNT;
981
982 /* Converting from old hardcoded specials to as sensible extra as we can */
983 switch (sp) {
984 case S_IRRIGATION:
985 case S_FARMLAND:
986 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
987 * gets applied twice, which hopefully has the correct result. */
988 cause = EC_IRRIGATION;
989 break;
990 case S_MINE:
991 cause = EC_MINE;
992 break;
993 case S_POLLUTION:
994 cause = EC_POLLUTION;
995 break;
996 case S_HUT:
997 cause = EC_HUT;
998 break;
999 case S_FALLOUT:
1000 cause = EC_FALLOUT;
1001 break;
1002 default:
1004 break;
1005 }
1006
1007 if (cause != EC_COUNT) {
1008 struct tile *vtile = tile_virtual_new(ptile);
1009 struct terrain *pterr = tile_terrain(vtile);
1010 const struct req_context tile_ctxt = { .tile = vtile };
1011
1012 /* Do not let the extras already set to the real tile mess with setup
1013 * of the player tiles if that's what we're doing. */
1014 dbv_to_bv(vtile->extras.vec, extras);
1015
1016 /* It's ok not to know which player or which unit originally built the extra -
1017 * in the rules used when specials were saved these could not have made any
1018 * difference. */
1019 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
1020
1021 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
1022 && (cause != EC_MINE || pterr->mining_time != 0)
1023 && (cause != EC_BASE || pterr->base_time != 0)
1024 && (cause != EC_ROAD || pterr->road_time != 0)) {
1028 || tile_city(vtile) != NULL
1029 || extra_base_get(candidate)->border_sq <= 0)
1031 &candidate->reqs,
1032 RPT_POSSIBLE)) {
1033 pextra = candidate;
1034 break;
1035 }
1036 }
1038 }
1039
1041 }
1042
1043 if (pextra) {
1044 dbv_set(extras, extra_index(pextra));
1045 }
1046 }
1047 }
1048 }
1049}
1050
1051/************************************************************************/
1058static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch,
1059 const enum tile_special_type *idx,
1060 bool rivers_overlay)
1061{
1062 int i, bin;
1063 const char *pch = strchr(hex_chars, ch);
1064
1065 if (!pch || ch == '\0') {
1066 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1067 bin = 0;
1068 } else {
1069 bin = pch - hex_chars;
1070 }
1071
1072 for (i = 0; i < 4; i++) {
1073 enum tile_special_type sp = idx[i];
1074
1075 if (sp == S_LAST) {
1076 continue;
1077 }
1078 if (rivers_overlay && sp != S_OLD_RIVER) {
1079 continue;
1080 }
1081
1082 if (sp == S_HUT && !wld.map.server.have_huts) {
1083 /* It would be logical to have this in the saving side -
1084 * really not saving the huts in the first place, BUT
1085 * 1) They have been saved by older versions, so we
1086 * have to deal with such savegames.
1087 * 2) This makes scenario author less likely to lose
1088 * one's work completely after carefully placing huts
1089 * and then saving with 'have_huts' disabled. */
1090 continue;
1091 }
1092
1093 if (bin & (1 << i)) {
1094 if (sp == S_OLD_ROAD) {
1095 struct road_type *proad;
1096
1098 if (proad) {
1100 }
1101 } else if (sp == S_OLD_RAILROAD) {
1102 struct road_type *proad;
1103
1105 if (proad) {
1107 }
1108 } else if (sp == S_OLD_RIVER) {
1109 struct road_type *proad;
1110
1112 if (proad) {
1114 }
1115 } else {
1116 struct extra_type *pextra = NULL;
1117 enum extra_cause cause = EC_COUNT;
1118
1119 /* Converting from old hardcoded specials to as sensible extra as we can */
1120 switch (sp) {
1121 case S_IRRIGATION:
1122 case S_FARMLAND:
1123 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
1124 * gets applied twice, which hopefully has the correct result. */
1125 cause = EC_IRRIGATION;
1126 break;
1127 case S_MINE:
1128 cause = EC_MINE;
1129 break;
1130 case S_POLLUTION:
1131 cause = EC_POLLUTION;
1132 break;
1133 case S_HUT:
1134 cause = EC_HUT;
1135 break;
1136 case S_FALLOUT:
1137 cause = EC_FALLOUT;
1138 break;
1139 default:
1141 break;
1142 }
1143
1144 if (cause != EC_COUNT) {
1145 struct tile *vtile = tile_virtual_new(ptile);
1146 struct terrain *pterr = tile_terrain(vtile);
1147 const struct req_context tile_ctxt = { .tile = vtile };
1148
1149 /* Do not let the extras already set to the real tile mess with setup
1150 * of the player tiles if that's what we're doing. */
1151 vtile->extras = *extras;
1152
1153 /* It's ok not to know which player or which unit originally built the extra -
1154 * in the rules used when specials were saved these could not have made any
1155 * difference. */
1156 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
1157
1158 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
1159 && (cause != EC_MINE || pterr->mining_time != 0)
1160 && (cause != EC_BASE || pterr->base_time != 0)
1161 && (cause != EC_ROAD || pterr->road_time != 0)) {
1165 || tile_city(vtile) != NULL
1166 || extra_base_get(candidate)->border_sq <= 0)
1168 &candidate->reqs,
1169 RPT_POSSIBLE)) {
1170 pextra = candidate;
1171 break;
1172 }
1173 }
1175 }
1176
1178 }
1179
1180 if (pextra) {
1181 BV_SET(*extras, extra_index(pextra));
1182 }
1183 }
1184 }
1185 }
1186}
1187
1188/************************************************************************/
1195static void sg_bases_set_dbv(struct dbv *extras, char ch,
1196 struct base_type **idx)
1197{
1198 int i, bin;
1199 const char *pch = strchr(hex_chars, ch);
1200
1201 if (!pch || ch == '\0') {
1202 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1203 bin = 0;
1204 } else {
1205 bin = pch - hex_chars;
1206 }
1207
1208 for (i = 0; i < 4; i++) {
1209 struct base_type *pbase = idx[i];
1210
1211 if (pbase == NULL) {
1212 continue;
1213 }
1214 if (bin & (1 << i)) {
1216 }
1217 }
1218}
1219
1220/************************************************************************/
1227static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx)
1228{
1229 int i, bin;
1230 const char *pch = strchr(hex_chars, ch);
1231
1232 if (!pch || ch == '\0') {
1233 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1234 bin = 0;
1235 } else {
1236 bin = pch - hex_chars;
1237 }
1238
1239 for (i = 0; i < 4; i++) {
1240 struct base_type *pbase = idx[i];
1241
1242 if (pbase == NULL) {
1243 continue;
1244 }
1245 if (bin & (1 << i)) {
1247 }
1248 }
1249}
1250
1251/************************************************************************/
1258static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx)
1259{
1260 int i, bin;
1261 const char *pch = strchr(hex_chars, ch);
1262
1263 if (!pch || ch == '\0') {
1264 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1265 bin = 0;
1266 } else {
1267 bin = pch - hex_chars;
1268 }
1269
1270 for (i = 0; i < 4; i++) {
1271 struct road_type *proad = idx[i];
1272
1273 if (proad == NULL) {
1274 continue;
1275 }
1276 if (bin & (1 << i)) {
1278 }
1279 }
1280}
1281
1282/************************************************************************/
1289static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx)
1290{
1291 int i, bin;
1292 const char *pch = strchr(hex_chars, ch);
1293
1294 if (!pch || ch == '\0') {
1295 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1296 bin = 0;
1297 } else {
1298 bin = pch - hex_chars;
1299 }
1300
1301 for (i = 0; i < 4; i++) {
1302 struct road_type *proad = idx[i];
1303
1304 if (proad == NULL) {
1305 continue;
1306 }
1307 if (bin & (1 << i)) {
1309 }
1310 }
1311}
1312
1313/************************************************************************/
1316static struct extra_type *char2resource(char c)
1317{
1318 /* speed common values */
1320 || c == RESOURCE_NONE_IDENTIFIER) {
1321 return NULL;
1322 }
1323
1324 return resource_by_identifier(c);
1325}
1326
1327/************************************************************************/
1331static struct terrain *char2terrain(char ch)
1332{
1333 /* terrain_by_identifier plus fatal error */
1335 return T_UNKNOWN;
1336 }
1337 terrain_type_iterate(pterrain) {
1338 if (pterrain->identifier == ch) {
1339 return pterrain;
1340 }
1342
1343 log_fatal("Unknown terrain identifier '%c' in savegame.", ch);
1344
1346
1348}
1349
1350/************************************************************************/
1355 const char *path, int plrno)
1356{
1357 char path_with_name[128];
1358 const char *name;
1359 struct advance *padvance;
1360
1362 "%s_name", path);
1363
1365
1366 if (!name || name[0] == '\0') {
1367 /* used by researching_saved */
1368 return A_UNKNOWN;
1369 }
1370 if (fc_strcasecmp(name, "A_FUTURE") == 0) {
1371 return A_FUTURE;
1372 }
1373 if (fc_strcasecmp(name, "A_NONE") == 0) {
1374 return A_NONE;
1375 }
1376 if (fc_strcasecmp(name, "A_UNSET") == 0) {
1377 return A_UNSET;
1378 }
1379
1382 "%s: unknown technology \"%s\".", path_with_name, name);
1383
1384 return advance_number(padvance);
1385}
1386
1387/* =======================================================================
1388 * Load savefile data.
1389 * ======================================================================= */
1390
1391/************************************************************************/
1395{
1396 const char *ruleset = secfile_lookup_str_default(loading->file,
1398 "savefile.rulesetdir");
1399
1400 /* Load ruleset. */
1402 if (!strcmp("default", game.server.rulesetdir)) {
1403 int version;
1404
1405 version = secfile_lookup_int_default(loading->file, -1, "savefile.version");
1406 if (version >= 30) {
1407 /* Here 'default' really means current default.
1408 * Saving happens with real ruleset name, so savegames containing this
1409 * are special scenarios. */
1411 } else {
1412 /* 'default' is the old name of the classic ruleset */
1413 sz_strlcpy(game.server.rulesetdir, "classic");
1414 }
1415 log_verbose("Savegame specified ruleset '%s'. Really loading '%s'.",
1417 }
1419 /* Failed to load correct ruleset */
1420 sg_failure_ret(FALSE, _("Failed to load ruleset '%s' needed for savegame."),
1421 ruleset);
1422 }
1423}
1424
1425/************************************************************************/
1429{
1430 int i;
1431 const char *terr_name;
1432 const char *str;
1433
1434 /* Check status and return if not OK (sg_success FALSE). */
1435 sg_check_ret();
1436
1437 /* Load savefile options. */
1438 loading->secfile_options
1439 = secfile_lookup_str(loading->file, "savefile.options");
1440
1441 /* We don't need these entries, but read them anyway to avoid
1442 * warnings about unread secfile entries. */
1443 (void) secfile_entry_by_path(loading->file, "savefile.reason");
1444 (void) secfile_entry_by_path(loading->file, "savefile.revision");
1445
1446 str = secfile_lookup_str(loading->file, "savefile.orig_version");
1448
1449 /* In case of savegame2.c saves, missing entry means savegame older than support
1450 * for saving last_updated by turn. So this must default to TRUE. */
1452 "savefile.last_updated_as_year");
1453
1454 /* Load improvements. */
1455 loading->improvement.size
1457 "savefile.improvement_size");
1458 if (loading->improvement.size) {
1459 loading->improvement.order
1460 = secfile_lookup_str_vec(loading->file, &loading->improvement.size,
1461 "savefile.improvement_vector");
1462 sg_failure_ret(loading->improvement.size != 0,
1463 "Failed to load improvement order: %s",
1464 secfile_error());
1465 }
1466
1467 /* Load technologies. */
1468 loading->technology.size
1470 "savefile.technology_size");
1471 if (loading->technology.size) {
1472 loading->technology.order
1473 = secfile_lookup_str_vec(loading->file, &loading->technology.size,
1474 "savefile.technology_vector");
1475 sg_failure_ret(loading->technology.size != 0,
1476 "Failed to load technology order: %s",
1477 secfile_error());
1478 }
1479
1480 /* Load Activities. */
1481 loading->activities.size
1483 "savefile.activities_size");
1484 if (loading->activities.size) {
1485 loading->activities.order
1486 = secfile_lookup_str_vec(loading->file, &loading->activities.size,
1487 "savefile.activities_vector");
1488 sg_failure_ret(loading->activities.size != 0,
1489 "Failed to load activity order: %s",
1490 secfile_error());
1491 }
1492
1493 /* Load traits. */
1494 loading->trait.size
1496 "savefile.trait_size");
1497 if (loading->trait.size) {
1498 loading->trait.order
1499 = secfile_lookup_str_vec(loading->file, &loading->trait.size,
1500 "savefile.trait_vector");
1501 sg_failure_ret(loading->trait.size != 0,
1502 "Failed to load trait order: %s",
1503 secfile_error());
1504 }
1505
1506 /* Load extras. */
1507 loading->extra.size
1509 "savefile.extras_size");
1510 if (loading->extra.size) {
1511 const char **modname;
1512 size_t nmod;
1513 int j;
1514
1515 modname = secfile_lookup_str_vec(loading->file, &loading->extra.size,
1516 "savefile.extras_vector");
1517 sg_failure_ret(loading->extra.size != 0,
1518 "Failed to load extras order: %s",
1519 secfile_error());
1521 "Number of extras defined by the ruleset (= %d) are "
1522 "lower than the number in the savefile (= %d).",
1523 game.control.num_extra_types, (int)loading->extra.size);
1524 /* make sure that the size of the array is divisible by 4 */
1525 nmod = 4 * ((loading->extra.size + 3) / 4);
1526 loading->extra.order = fc_calloc(nmod, sizeof(*loading->extra.order));
1527 for (j = 0; j < loading->extra.size; j++) {
1528 loading->extra.order[j] = extra_type_by_rule_name(modname[j]);
1529 }
1530 free(modname);
1531 for (; j < nmod; j++) {
1532 loading->extra.order[j] = NULL;
1533 }
1534 }
1535
1536 /* Load multipliers. */
1537 loading->multiplier.size
1539 "savefile.multipliers_size");
1540 if (loading->multiplier.size) {
1541 const char **modname;
1542 int j;
1543
1544 modname = secfile_lookup_str_vec(loading->file, &loading->multiplier.size,
1545 "savefile.multipliers_vector");
1546 sg_failure_ret(loading->multiplier.size != 0,
1547 "Failed to load multipliers order: %s",
1548 secfile_error());
1549 /* It's OK for the set of multipliers in the savefile to differ
1550 * from those in the ruleset. */
1551 loading->multiplier.order = fc_calloc(loading->multiplier.size,
1552 sizeof(*loading->multiplier.order));
1553 for (j = 0; j < loading->multiplier.size; j++) {
1554 loading->multiplier.order[j] = multiplier_by_rule_name(modname[j]);
1555 if (!loading->multiplier.order[j]) {
1556 log_verbose("Multiplier \"%s\" in savegame but not in ruleset, "
1557 "discarding", modname[j]);
1558 }
1559 }
1560 free(modname);
1561 }
1562
1563 /* Load specials. */
1564 loading->special.size
1566 "savefile.specials_size");
1567 if (loading->special.size) {
1568 const char **modname;
1569 size_t nmod;
1570 enum tile_special_type j;
1571
1572 modname = secfile_lookup_str_vec(loading->file, &loading->special.size,
1573 "savefile.specials_vector");
1574 sg_failure_ret(loading->special.size != 0,
1575 "Failed to load specials order: %s",
1576 secfile_error());
1577 /* make sure that the size of the array is divisible by 4 */
1578 /* Allocating extra 4 slots, just a couple of bytes,
1579 * in case of special.size being divisible by 4 already is intentional.
1580 * Added complexity would cost those couple of bytes in code size alone,
1581 * and we actually need at least one slot immediately after last valid
1582 * one. That's where S_LAST is (or was in version that saved the game)
1583 * and in some cases S_LAST gets written to savegame, at least as
1584 * activity target special when activity targets some base or road
1585 * instead. By having current S_LAST in that index allows us to map
1586 * that old S_LAST to current S_LAST, just like any real special within
1587 * special.size gets mapped. */
1588 nmod = loading->special.size + (4 - (loading->special.size % 4));
1589 loading->special.order = fc_calloc(nmod,
1590 sizeof(*loading->special.order));
1591 for (j = 0; j < loading->special.size; j++) {
1592 if (!fc_strcasecmp("Road", modname[j])) {
1593 loading->special.order[j] = S_OLD_ROAD;
1594 } else if (!fc_strcasecmp("Railroad", modname[j])) {
1595 loading->special.order[j] = S_OLD_RAILROAD;
1596 } else if (!fc_strcasecmp("River", modname[j])) {
1597 loading->special.order[j] = S_OLD_RIVER;
1598 } else {
1599 loading->special.order[j] = special_by_rule_name(modname[j]);
1600 }
1601 }
1602 free(modname);
1603 for (; j < nmod; j++) {
1604 loading->special.order[j] = S_LAST;
1605 }
1606 }
1607
1608 /* Load bases. */
1609 loading->base.size
1611 "savefile.bases_size");
1612 if (loading->base.size) {
1613 const char **modname;
1614 size_t nmod;
1615 int j;
1616
1617 modname = secfile_lookup_str_vec(loading->file, &loading->base.size,
1618 "savefile.bases_vector");
1619 sg_failure_ret(loading->base.size != 0,
1620 "Failed to load bases order: %s",
1621 secfile_error());
1622 /* make sure that the size of the array is divisible by 4 */
1623 nmod = 4 * ((loading->base.size + 3) / 4);
1624 loading->base.order = fc_calloc(nmod, sizeof(*loading->base.order));
1625 for (j = 0; j < loading->base.size; j++) {
1626 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1627
1628 sg_failure_ret(pextra != NULL
1629 || game.control.num_base_types >= loading->base.size,
1630 "Unknown base type %s in savefile.",
1631 modname[j]);
1632
1633 if (pextra != NULL) {
1634 loading->base.order[j] = extra_base_get(pextra);
1635 } else {
1636 loading->base.order[j] = NULL;
1637 }
1638 }
1639 free(modname);
1640 for (; j < nmod; j++) {
1641 loading->base.order[j] = NULL;
1642 }
1643 }
1644
1645 /* Load roads. */
1646 loading->road.size
1648 "savefile.roads_size");
1649 if (loading->road.size) {
1650 const char **modname;
1651 size_t nmod;
1652 int j;
1653
1654 modname = secfile_lookup_str_vec(loading->file, &loading->road.size,
1655 "savefile.roads_vector");
1656 sg_failure_ret(loading->road.size != 0,
1657 "Failed to load roads order: %s",
1658 secfile_error());
1660 "Number of roads defined by the ruleset (= %d) are "
1661 "lower than the number in the savefile (= %d).",
1662 game.control.num_road_types, (int)loading->road.size);
1663 /* make sure that the size of the array is divisible by 4 */
1664 nmod = 4 * ((loading->road.size + 3) / 4);
1665 loading->road.order = fc_calloc(nmod, sizeof(*loading->road.order));
1666 for (j = 0; j < loading->road.size; j++) {
1667 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1668
1669 if (pextra != NULL) {
1670 loading->road.order[j] = extra_road_get(pextra);
1671 } else {
1672 loading->road.order[j] = NULL;
1673 }
1674 }
1675 free(modname);
1676 for (; j < nmod; j++) {
1677 loading->road.order[j] = NULL;
1678 }
1679 }
1680
1681 /* Load specialists. */
1682 loading->specialist.size
1684 "savefile.specialists_size");
1685 if (loading->specialist.size) {
1686 const char **modname;
1687 size_t nmod;
1688 int j;
1689
1690 modname = secfile_lookup_str_vec(loading->file, &loading->specialist.size,
1691 "savefile.specialists_vector");
1692 sg_failure_ret(loading->specialist.size != 0,
1693 "Failed to load specialists order: %s",
1694 secfile_error());
1696 "Number of specialists defined by the ruleset (= %d) are "
1697 "lower than the number in the savefile (= %d).",
1698 game.control.num_specialist_types, (int)loading->specialist.size);
1699 /* make sure that the size of the array is divisible by 4 */
1700 /* That's not really needed with specialists at the moment, but done this way
1701 * for consistency with other types, and to be prepared for the time it needs
1702 * to be this way. */
1703 nmod = 4 * ((loading->specialist.size + 3) / 4);
1704 loading->specialist.order = fc_calloc(nmod, sizeof(*loading->specialist.order));
1705 for (j = 0; j < loading->specialist.size; j++) {
1706 loading->specialist.order[j] = specialist_by_rule_name(modname[j]);
1707 }
1708 free(modname);
1709 for (; j < nmod; j++) {
1710 loading->specialist.order[j] = NULL;
1711 }
1712 }
1713
1714 /* Load diplomatic state type order. */
1715 loading->ds_t.size
1717 "savefile.diplstate_type_size");
1718
1719 sg_failure_ret(loading->ds_t.size > 0,
1720 "Failed to load diplomatic state type order: %s",
1721 secfile_error());
1722
1723 if (loading->ds_t.size) {
1724 const char **modname;
1725 int j;
1726
1727 modname = secfile_lookup_str_vec(loading->file, &loading->ds_t.size,
1728 "savefile.diplstate_type_vector");
1729
1730 loading->ds_t.order = fc_calloc(loading->ds_t.size,
1731 sizeof(*loading->ds_t.order));
1732
1733 for (j = 0; j < loading->ds_t.size; j++) {
1734 loading->ds_t.order[j] = diplstate_type_by_name(modname[j],
1736 }
1737
1738 free(modname);
1739 }
1740
1741 /* Load city options order. */
1742 loading->coptions.size
1744 "savefile.city_options_size");
1745
1746 {
1747 const char *modname_old[] = { "Disband", "Sci_Specialists", "Tax_Specialists" };
1748 const char **modname;
1749 int j;
1750 bool compat;
1751
1752 if (loading->coptions.size > 0) {
1753 modname = secfile_lookup_str_vec(loading->file, &loading->coptions.size,
1754 "savefile.city_options_vector");
1755 compat = FALSE;
1756 } else {
1758 loading->coptions.size = 3;
1759 compat = TRUE;
1760 }
1761
1762 loading->coptions.order = fc_calloc(loading->coptions.size,
1763 sizeof(*loading->coptions.order));
1764
1765 for (j = 0; j < loading->coptions.size; j++) {
1766 loading->coptions.order[j] = city_options_by_name(modname[j],
1768 }
1769
1770 if (!compat) {
1771 free(modname);
1772 }
1773 }
1774
1775 /* Terrain identifiers */
1777 pterr->identifier_load = '\0';
1779
1780 i = 0;
1782 "savefile.terrident%d.name", i)) != NULL) {
1784
1785 if (pterr != NULL) {
1786 const char *iptr = secfile_lookup_str_default(loading->file, NULL,
1787 "savefile.terrident%d.identifier", i);
1788
1789 pterr->identifier_load = *iptr;
1790 } else {
1791 log_error("Identifier for unknown terrain type %s.", terr_name);
1792 }
1793 i++;
1794 }
1795
1798 if (pterr != pterr2 && pterr->identifier_load != '\0') {
1799 sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1800 "%s and %s share a saved identifier",
1802 }
1805}
1806
1807/* =======================================================================
1808 * Load game status.
1809 * ======================================================================= */
1810
1811/************************************************************************/
1815{
1816 int i;
1817 const char *name;
1818
1819 /* Check status and return if not OK (sg_success FALSE). */
1820 sg_check_ret();
1821
1822 for (i = 0;
1824 "ruledata.government%d.name", i));
1825 i++) {
1827
1828 if (gov != NULL) {
1830 "ruledata.government%d.changes", i);
1831 }
1832 }
1833}
1834
1835/************************************************************************/
1838static void sg_load_game(struct loaddata *loading)
1839{
1840 int game_version;
1841 const char *str;
1842 int i;
1843
1844 /* Check status and return if not OK (sg_success FALSE). */
1845 sg_check_ret();
1846
1847 /* Load version. */
1849 = secfile_lookup_int_default(loading->file, 0, "game.version");
1850 /* We require at least version 2.2.99 */
1851 sg_failure_ret(20299 <= game_version, "Saved game is too old, at least "
1852 "version 2.2.99 required.");
1853
1854 loading->full_version = game_version;
1855
1856 secfile_entry_ignore(loading->file, "scenario.game_version");
1857
1858 /* Load server state. */
1859 str = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
1860 "game.server_state");
1861 loading->server_state = server_states_by_name(str, strcmp);
1862 if (!server_states_is_valid(loading->server_state)) {
1863 /* Don't take any risk! */
1864 loading->server_state = S_S_INITIAL;
1865 }
1866
1869 "game.meta_patches");
1871
1873 /* Do not overwrite this if the user requested a specific metaserver
1874 * from the command line (option --Metaserver). */
1878 "game.meta_server"));
1879 }
1880
1881 if ('\0' == srvarg.serverid[0]) {
1882 /* Do not overwrite this if the user requested a specific metaserver
1883 * from the command line (option --serverid). */
1886 "game.serverid"));
1887 }
1888 sz_strlcpy(server.game_identifier,
1889 secfile_lookup_str_default(loading->file, "", "game.id"));
1890 /* We are not checking game_identifier legality just yet.
1891 * That's done when we are sure that rand seed has been initialized,
1892 * so that we can generate new game_identifier, if needed.
1893 * See sq_load_sanitycheck(). */
1894
1897 "game.phase_mode");
1900 "game.phase_mode_stored");
1903 "game.phase");
1907 "game.scoreturn");
1908
1911 "game.timeoutint");
1914 "game.timeoutintinc");
1917 "game.timeoutinc");
1920 "game.timeoutincmult");
1923 "game.timeoutcounter");
1924
1925 game.info.turn
1926 = secfile_lookup_int_default(loading->file, 0, "game.turn");
1928 "game.year"), "%s", secfile_error());
1930 = secfile_lookup_bool_default(loading->file, FALSE, "game.year_0_hack");
1931
1933 = secfile_lookup_int_default(loading->file, 0, "game.globalwarming");
1935 = secfile_lookup_int_default(loading->file, 0, "game.heating");
1937 = secfile_lookup_int_default(loading->file, 0, "game.warminglevel");
1938
1940 = secfile_lookup_int_default(loading->file, 0, "game.nuclearwinter");
1942 = secfile_lookup_int_default(loading->file, 0, "game.cooling");
1944 = secfile_lookup_int_default(loading->file, 0, "game.coolinglevel");
1945
1946 /* Savegame may have stored random_seed for documentation purposes only,
1947 * but we want to keep it for resaving. */
1948 game.server.seed = secfile_lookup_int_default(loading->file, 0, "game.random_seed");
1949
1950 /* Global advances. */
1952 "game.global_advances");
1953 if (str != NULL) {
1954 sg_failure_ret(strlen(str) == loading->technology.size,
1955 "Invalid length of 'game.global_advances' ("
1956 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
1957 strlen(str), loading->technology.size);
1958 for (i = 0; i < loading->technology.size; i++) {
1959 sg_failure_ret(str[i] == '1' || str[i] == '0',
1960 "Undefined value '%c' within 'game.global_advances'.",
1961 str[i]);
1962 if (str[i] == '1') {
1963 struct advance *padvance =
1964 advance_by_rule_name(loading->technology.order[i]);
1965
1966 if (padvance != NULL) {
1968 }
1969 }
1970 }
1971 }
1972
1974 = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
1975
1977 = secfile_lookup_int_default(loading->file, 0, "game.last_turn_change_time") / 100.0;
1978}
1979
1980/* =======================================================================
1981 * Load random status.
1982 * ======================================================================= */
1983
1984/************************************************************************/
1987static void sg_load_random(struct loaddata *loading)
1988{
1989 /* Check status and return if not OK (sg_success FALSE). */
1990 sg_check_ret();
1991
1992 if (secfile_lookup_bool_default(loading->file, FALSE, "random.saved")) {
1993 const char *str;
1994 int i;
1995
1996 /* Since random state was previously saved, save it also when resaving.
1997 * This affects only pre-2.6 scenarios where scenario.save_random
1998 * is not defined.
1999 * - If this is 2.6 or later scenario -> it would have saved random.saved = TRUE
2000 * only if scenario.save_random is already TRUE
2001 *
2002 * Do NOT touch this in case of regular savegame. They always have random.saved
2003 * set, but if one starts to make scenario based on a savegame, we want
2004 * default scenario settings in the beginning (default save_random = FALSE).
2005 */
2008 }
2009
2011 "random.index_J"), "%s", secfile_error());
2013 "random.index_K"), "%s", secfile_error());
2015 "random.index_X"), "%s", secfile_error());
2016
2017 for (i = 0; i < 8; i++) {
2018 str = secfile_lookup_str(loading->file, "random.table%d",i);
2019 sg_failure_ret(NULL != str, "%s", secfile_error());
2020 sscanf(str, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
2021 &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
2022 &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
2023 &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
2024 }
2025 loading->rstate.is_init = TRUE;
2026 fc_rand_set_state(loading->rstate);
2027 } else {
2028 /* No random values - mark the setting. */
2029 (void) secfile_entry_by_path(loading->file, "random.saved");
2030
2031 /* We're loading a game without a seed (which is okay, if it's a scenario).
2032 * We need to generate the game seed now because it will be needed later
2033 * during the load. */
2035 loading->rstate = fc_rand_state();
2036 }
2037}
2038
2039/* =======================================================================
2040 * Load lua script data.
2041 * ======================================================================= */
2042
2043/************************************************************************/
2046static void sg_load_script(struct loaddata *loading)
2047{
2048 /* Check status and return if not OK (sg_success FALSE). */
2049 sg_check_ret();
2050
2052}
2053
2054/* =======================================================================
2055 * Load scenario data.
2056 * ======================================================================= */
2057
2058/************************************************************************/
2062{
2063 const char *buf;
2064 bool lake_flood_default;
2065
2066 /* Check status and return if not OK (sg_success FALSE). */
2067 sg_check_ret();
2068
2069 if (NULL == secfile_section_lookup(loading->file, "scenario")) {
2071
2072 return;
2073 }
2074
2075 /* Default is that when there's scenario section (which we already checked)
2076 * this is a scenario. Only if it explicitly says that it's not, we consider
2077 * this regular savegame */
2078 game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
2079
2080 if (!game.scenario.is_scenario) {
2081 return;
2082 }
2083
2084 buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
2085 if (buf[0] != '\0') {
2087 }
2088
2090 "scenario.authors");
2091 if (buf[0] != '\0') {
2093 } else {
2094 game.scenario.authors[0] = '\0';
2095 }
2096
2098 "scenario.description");
2099 if (buf[0] != '\0') {
2101 } else {
2102 game.scenario_desc.description[0] = '\0';
2103 }
2104
2106 = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
2108 = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
2111 "scenario.startpos_nations");
2112
2115 "scenario.prevent_new_cities");
2116 if (loading->version < 20599) {
2117 /* Lake flooding may break some old scenarios where rivers made out of
2118 * lake terrains, so play safe there */
2120 } else {
2121 /* If lake flooding is a problem for a newer scenario, it could explicitly
2122 * disable it. */
2124 }
2127 "scenario.lake_flooding");
2130 "scenario.handmade");
2133 "scenario.allow_ai_type_fallback");
2135
2136 sg_failure_ret(loading->server_state == S_S_INITIAL
2137 || (loading->server_state == S_S_RUNNING
2138 && game.scenario.players),
2139 "Invalid scenario definition (server state '%s' and "
2140 "players are %s).",
2141 server_states_name(loading->server_state),
2142 game.scenario.players ? "saved" : "not saved");
2143
2144 /* Remove all defined players. They are recreated with the skill level
2145 * defined by the scenario. */
2146 (void) aifill(0);
2147}
2148
2149/* =======================================================================
2150 * Load game settings.
2151 * ======================================================================= */
2152
2153/************************************************************************/
2157{
2158 /* Check status and return if not OK (sg_success FALSE). */
2159 sg_check_ret();
2160
2161 settings_game_load(loading->file, "settings");
2162
2163 /* Save current status of fogofwar. */
2165
2166 /* Add all compatibility settings here. */
2167}
2168
2169/* =======================================================================
2170 * Load the main map.
2171 * ======================================================================= */
2172
2173/************************************************************************/
2176static void sg_load_map(struct loaddata *loading)
2177{
2178 /* Check status and return if not OK (sg_success FALSE). */
2179 sg_check_ret();
2180
2181 /* This defaults to TRUE even if map has not been generated. Also,
2182 * old versions have also explicitly saved TRUE even in pre-game.
2183 * We rely on that
2184 * 1) scenario maps have it explicitly right.
2185 * 2) when map is actually generated, it re-initialize this to FALSE. */
2187 = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
2188
2189 /* Savegame may have stored random_seed for documentation purposes only,
2190 * but we want to keep it for resaving. */
2192 = secfile_lookup_int_default(loading->file, 0, "map.random_seed");
2193
2194 if (S_S_INITIAL == loading->server_state
2196 /* Generator MAPGEN_SCENARIO is used;
2197 * this map was done with the map editor. */
2198
2199 /* Load tiles. */
2202
2203 if (loading->version >= 30) {
2204 /* 2.6.0 or newer */
2206 } else {
2208 if (loading->version >= 20) {
2209 /* 2.5.0 or newer */
2211 }
2212 if (has_capability("specials", loading->secfile_options)) {
2213 /* Load specials. */
2215 }
2216 }
2217
2218 /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
2220 if (has_capability("specials", loading->secfile_options)) {
2221 /* Load resources. */
2223 } else if (has_capability("riversoverlay", loading->secfile_options)) {
2224 /* Load only rivers overlay. */
2226 }
2227
2228 /* Nothing more needed for a scenario. */
2229 return;
2230 }
2231
2232 if (S_S_INITIAL == loading->server_state) {
2233 /* Nothing more to do if it is not a scenario but in initial state. */
2234 return;
2235 }
2236
2239 if (loading->version >= 30) {
2240 /* 2.6.0 or newer */
2242 } else {
2244 if (loading->version >= 20) {
2245 /* 2.5.0 or newer */
2247 }
2249 }
2254}
2255
2256/************************************************************************/
2260{
2261 /* Check status and return if not OK (sg_success FALSE). */
2262 sg_check_ret();
2263
2264 /* Initialize the map for the current topology. 'map.xsize' and
2265 * 'map.ysize' must be set. */
2267
2268 /* Allocate map. */
2270
2271 /* get the terrain type */
2272 LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
2273 "map.t%04d");
2275
2276 /* Check for special tile sprites. */
2277 whole_map_iterate(&(wld.map), ptile) {
2278 const char *spec_sprite;
2279 const char *label;
2280 int nat_x, nat_y;
2281
2283 spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
2284 nat_x, nat_y);
2285 label = secfile_lookup_str_default(loading->file, NULL, "map.label_%d_%d",
2286 nat_x, nat_y);
2287 if (NULL != ptile->spec_sprite) {
2288 ptile->spec_sprite = fc_strdup(spec_sprite);
2289 }
2290 if (label != NULL) {
2291 tile_set_label(ptile, label);
2292 }
2294}
2295
2296/************************************************************************/
2300{
2301 /* Check status and return if not OK (sg_success FALSE). */
2302 sg_check_ret();
2303
2304 /* Load extras. */
2305 halfbyte_iterate_extras(j, loading->extra.size) {
2306 LOAD_MAP_CHAR(ch, ptile, sg_extras_set_bv(&ptile->extras,
2307 ch, loading->extra.order + 4 * j),
2308 loading->file, "map.e%02d_%04d", j);
2310}
2311
2312/************************************************************************/
2316{
2317 /* Check status and return if not OK (sg_success FALSE). */
2318 sg_check_ret();
2319
2320 /* Load bases. */
2321 halfbyte_iterate_bases(j, loading->base.size) {
2322 LOAD_MAP_CHAR(ch, ptile, sg_bases_set_bv(&ptile->extras, ch,
2323 loading->base.order + 4 * j),
2324 loading->file, "map.b%02d_%04d", j);
2326}
2327
2328/************************************************************************/
2332{
2333 /* Check status and return if not OK (sg_success FALSE). */
2334 sg_check_ret();
2335
2336 /* Load roads. */
2337 halfbyte_iterate_roads(j, loading->road.size) {
2338 LOAD_MAP_CHAR(ch, ptile, sg_roads_set_bv(&ptile->extras, ch,
2339 loading->road.order + 4 * j),
2340 loading->file, "map.r%02d_%04d", j);
2342}
2343
2344/************************************************************************/
2348 bool rivers_overlay)
2349{
2350 /* Check status and return if not OK (sg_success FALSE). */
2351 sg_check_ret();
2352
2353 /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
2354 * from the savegame file.
2355 *
2356 * A scenario may define the terrain of the map but not list the specials
2357 * on it (thus allowing users to control the placement of specials).
2358 * However rivers are a special case and must be included in the map along
2359 * with the scenario. Thus in those cases this function should be called
2360 * to load the river information separate from any other special data.
2361 *
2362 * This does not need to be called from map_load(), because map_load()
2363 * loads the rivers overlay along with the rest of the specials. Call this
2364 * only if you've already called map_load_tiles(), and want to load only
2365 * the rivers overlay but no other specials. Scenarios that encode things
2366 * this way should have the "riversoverlay" capability. */
2367 halfbyte_iterate_special(j, loading->special.size) {
2368 LOAD_MAP_CHAR(ch, ptile, sg_special_set_bv(ptile, &ptile->extras, ch,
2369 loading->special.order + 4 * j,
2371 loading->file, "map.spe%02d_%04d", j);
2373}
2374
2375/************************************************************************/
2379{
2380 /* Check status and return if not OK (sg_success FALSE). */
2381 sg_check_ret();
2382
2384 loading->file, "map.res%04d");
2385
2386 /* After the resources are loaded, indicate those currently valid. */
2387 whole_map_iterate(&(wld.map), ptile) {
2388 if (NULL == ptile->resource) {
2389 continue;
2390 }
2391
2392 if (ptile->terrain == NULL || !terrain_has_resource(ptile->terrain, ptile->resource)) {
2393 BV_CLR(ptile->extras, extra_index(ptile->resource));
2394 }
2396
2399}
2400
2401/************************************************************************/
2406{
2407 struct nation_type *pnation;
2408 struct startpos *psp;
2409 struct tile *ptile;
2410 const char SEPARATOR = '#';
2411 const char *nation_names;
2412 int nat_x, nat_y;
2413 bool exclude;
2414 int i, startpos_count;
2415
2416 /* Check status and return if not OK (sg_success FALSE). */
2417 sg_check_ret();
2418
2420 = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
2421
2422 if (0 == startpos_count) {
2423 /* Nothing to do. */
2424 return;
2425 }
2426
2427 for (i = 0; i < startpos_count; i++) {
2428 if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
2429 || !secfile_lookup_int(loading->file, &nat_y,
2430 "map.startpos%d.y", i)) {
2431 log_sg("Warning: Undefined coordinates for startpos %d", i);
2432 continue;
2433 }
2434
2435 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
2436 if (NULL == ptile) {
2437 log_error("Start position native coordinates (%d, %d) do not exist "
2438 "in this map. Skipping...", nat_x, nat_y);
2439 continue;
2440 }
2441
2442 exclude = secfile_lookup_bool_default(loading->file, FALSE,
2443 "map.startpos%d.exclude", i);
2444
2445 psp = map_startpos_new(ptile);
2446
2448 "map.startpos%d.nations", i);
2449 if (NULL != nation_names && '\0' != nation_names[0]) {
2450 const size_t size = strlen(nation_names) + 1;
2451 char buf[size], *start, *end;
2452
2454 for (start = buf - 1; NULL != start; start = end) {
2455 start++;
2456 if ((end = strchr(start, SEPARATOR))) {
2457 *end = '\0';
2458 }
2459
2460 pnation = nation_by_rule_name(start);
2461 if (NO_NATION_SELECTED != pnation) {
2462 if (exclude) {
2463 startpos_disallow(psp, pnation);
2464 } else {
2465 startpos_allow(psp, pnation);
2466 }
2467 } else {
2468 log_verbose("Missing nation \"%s\".", start);
2469 }
2470 }
2471 }
2472 }
2473
2474 if (0 < map_startpos_count()
2475 && loading->server_state == S_S_INITIAL
2477 log_verbose("Number of starts (%d) are lower than rules.max_players "
2478 "(%d), lowering rules.max_players.",
2481 }
2482
2483 /* Re-initialize nation availability in light of start positions.
2484 * This has to be after loading [scenario] and [map].startpos and
2485 * before we seek nations for players. */
2487}
2488
2489/************************************************************************/
2493{
2494 int x, y;
2495 struct player *owner = NULL;
2496 struct tile *claimer = NULL;
2497 struct player *eowner = NULL;
2498
2499 /* Check status and return if not OK (sg_success FALSE). */
2500 sg_check_ret();
2501
2502 if (game.info.is_new_game) {
2503 /* No owner/source information for a new game / scenario. */
2504 return;
2505 }
2506
2507 /* Owner and ownership source are stored as plain numbers */
2508 for (y = 0; y < wld.map.ysize; y++) {
2509 const char *buffer1 = secfile_lookup_str(loading->file,
2510 "map.owner%04d", y);
2511 const char *buffer2 = secfile_lookup_str(loading->file,
2512 "map.source%04d", y);
2513 const char *buffer3 = secfile_lookup_str(loading->file,
2514 "map.eowner%04d", y);
2515 const char *ptr1 = buffer1;
2516 const char *ptr2 = buffer2;
2517 const char *ptr3 = buffer3;
2518
2521 if (loading->version >= 30) {
2523 }
2524
2525 for (x = 0; x < wld.map.xsize; x++) {
2526 char token1[TOKEN_SIZE];
2527 char token2[TOKEN_SIZE];
2528 char token3[TOKEN_SIZE];
2529 int number;
2530 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2531
2532 scanin(&ptr1, ",", token1, sizeof(token1));
2533 sg_failure_ret(token1[0] != '\0',
2534 "Map size not correct (map.owner%d).", y);
2535 if (strcmp(token1, "-") == 0) {
2536 owner = NULL;
2537 } else {
2539 "Got map owner %s in (%d, %d).", token1, x, y);
2540 owner = player_by_number(number);
2541 }
2542
2543 scanin(&ptr2, ",", token2, sizeof(token2));
2544 sg_failure_ret(token2[0] != '\0',
2545 "Map size not correct (map.source%d).", y);
2546 if (strcmp(token2, "-") == 0) {
2547 claimer = NULL;
2548 } else {
2550 "Got map source %s in (%d, %d).", token2, x, y);
2551 claimer = index_to_tile(&(wld.map), number);
2552 }
2553
2554 if (loading->version >= 30) {
2555 scanin(&ptr3, ",", token3, sizeof(token3));
2556 sg_failure_ret(token3[0] != '\0',
2557 "Map size not correct (map.eowner%d).", y);
2558 if (strcmp(token3, "-") == 0) {
2559 eowner = NULL;
2560 } else {
2562 "Got base owner %s in (%d, %d).", token3, x, y);
2563 eowner = player_by_number(number);
2564 }
2565 } else {
2566 eowner = owner;
2567 }
2568
2570 tile_claim_bases(ptile, eowner);
2571 log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
2572 }
2573 }
2574}
2575
2576/************************************************************************/
2580{
2581 int x, y;
2582
2583 /* Check status and return if not OK (sg_success FALSE). */
2584 sg_check_ret();
2585
2586 sg_failure_ret(loading->worked_tiles == NULL,
2587 "City worked map not loaded!");
2588
2589 loading->worked_tiles = fc_malloc(MAP_INDEX_SIZE *
2590 sizeof(*loading->worked_tiles));
2591
2592 for (y = 0; y < wld.map.ysize; y++) {
2593 const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
2594 y);
2595 const char *ptr = buffer;
2596
2597 sg_failure_ret(NULL != buffer,
2598 "Savegame corrupt - map line %d not found.", y);
2599 for (x = 0; x < wld.map.xsize; x++) {
2600 char token[TOKEN_SIZE];
2601 int number;
2602 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2603
2604 scanin(&ptr, ",", token, sizeof(token));
2605 sg_failure_ret('\0' != token[0],
2606 "Savegame corrupt - map size not correct.");
2607 if (strcmp(token, "-") == 0) {
2608 number = -1;
2609 } else {
2610 sg_failure_ret(str_to_int(token, &number) && 0 < number,
2611 "Savegame corrupt - got tile worked by city "
2612 "id=%s in (%d, %d).", token, x, y);
2613 }
2614
2615 loading->worked_tiles[ptile->index] = number;
2616 }
2617 }
2618}
2619
2620/************************************************************************/
2624{
2625 /* Check status and return if not OK (sg_success FALSE). */
2626 sg_check_ret();
2627
2628 players_iterate(pplayer) {
2629 /* Allocate player private map here; it is needed in different modules
2630 * besides this one ((i.e. sg_load_player_*()). */
2631 player_map_init(pplayer);
2633
2635 "game.save_known")) {
2636 int lines = player_slot_max_used_number()/32 + 1, j, p, l, i;
2637 unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
2638
2639 for (l = 0; l < lines; l++) {
2640 for (j = 0; j < 8; j++) {
2641 for (i = 0; i < 4; i++) {
2642 /* Only bother trying to load the map for this halfbyte if at least
2643 * one of the corresponding player slots is in use. */
2644 if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
2645 LOAD_MAP_CHAR(ch, ptile,
2646 known[l * MAP_INDEX_SIZE + tile_index(ptile)]
2647 |= ascii_hex2bin(ch, j),
2648 loading->file, "map.k%02d_%04d", l * 8 + j);
2649 break;
2650 }
2651 }
2652 }
2653 }
2654
2655 players_iterate(pplayer) {
2656 dbv_clr_all(&pplayer->tile_known);
2658
2659 /* HACK: we read the known data from hex into 32-bit integers, and
2660 * now we convert it to the known tile data of each player. */
2661 whole_map_iterate(&(wld.map), ptile) {
2662 players_iterate(pplayer) {
2663 p = player_index(pplayer);
2664 l = player_index(pplayer) / 32;
2665
2666 if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
2667 map_set_known(ptile, pplayer);
2668 }
2671
2672 FC_FREE(known);
2673 }
2674}
2675
2676/* =======================================================================
2677 * Load player data.
2678 *
2679 * This is split into two parts as some data can only be loaded if the
2680 * number of players is known and the corresponding player slots are
2681 * defined.
2682 * ======================================================================= */
2683
2684/************************************************************************/
2688{
2689 int i, k, nplayers;
2690 const char *str;
2691 bool shuffle_loaded = TRUE;
2692
2693 /* Check status and return if not OK (sg_success FALSE). */
2694 sg_check_ret();
2695
2696 if (S_S_INITIAL == loading->server_state
2697 || game.info.is_new_game) {
2698 /* Nothing more to do. */
2699 return;
2700 }
2701
2702 /* Load destroyed wonders: */
2704 "players.destroyed_wonders");
2705 sg_failure_ret(str != NULL, "%s", secfile_error());
2706 sg_failure_ret(strlen(str) == loading->improvement.size,
2707 "Invalid length for 'players.destroyed_wonders' ("
2708 SIZE_T_PRINTF" ~= " SIZE_T_PRINTF ")",
2709 strlen(str), loading->improvement.size);
2710 for (k = 0; k < loading->improvement.size; k++) {
2711 sg_failure_ret(str[k] == '1' || str[k] == '0',
2712 "Undefined value '%c' within "
2713 "'players.destroyed_wonders'.", str[k]);
2714
2715 if (str[k] == '1') {
2716 struct impr_type *pimprove =
2717 improvement_by_rule_name(loading->improvement.order[k]);
2718
2719 if (pimprove) {
2722 }
2723 }
2724 }
2725
2726 server.identity_number
2727 = secfile_lookup_int_default(loading->file, server.identity_number,
2728 "players.identity_number_used");
2729
2730 /* First remove all defined players. */
2731 players_iterate(pplayer) {
2732 server_remove_player(pplayer);
2734
2735 /* Now, load the players from the savefile. */
2736 player_slots_iterate(pslot) {
2737 struct player *pplayer;
2738 struct rgbcolor *prgbcolor = NULL;
2739 int pslot_id = player_slot_index(pslot);
2740
2741 if (NULL == secfile_section_lookup(loading->file, "player%d",
2742 pslot_id)) {
2743 continue;
2744 }
2745
2746 /* Get player AI type. */
2747 str = secfile_lookup_str(loading->file, "player%d.ai_type",
2748 player_slot_index(pslot));
2749 sg_failure_ret(str != NULL, "%s", secfile_error());
2750
2751 /* Get player color */
2752 if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
2753 pslot_id)) {
2754 if (loading->version >= 10 && game_was_started()) {
2755 /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
2756 * as they predate the introduction of configurable player colors. */
2757 log_sg("Game has started, yet player %d has no color defined.",
2758 pslot_id);
2759 /* This will be fixed up later */
2760 } else {
2761 log_verbose("No color defined for player %d.", pslot_id);
2762 /* Colors will be assigned on game start, or at end of savefile
2763 * loading if game has already started */
2764 }
2765 }
2766
2767 /* Create player. */
2768 pplayer = server_create_player(player_slot_index(pslot), str,
2769 prgbcolor,
2772 sg_failure_ret(pplayer != NULL, "Invalid AI type: '%s'!", str);
2773
2774 server_player_init(pplayer, FALSE, FALSE);
2775
2776 /* Free the color definition. */
2778
2779 /* Multipliers (policies) */
2780
2781 /* First initialise player values with ruleset defaults; this will
2782 * cover any in the ruleset not known when the savefile was created. */
2783 multipliers_iterate(pmul) {
2784 pplayer->multipliers[multiplier_index(pmul)].value
2785 = pplayer->multipliers[multiplier_index(pmul)].target = pmul->def;
2787
2788 /* Now override with any values from the savefile. */
2789 for (k = 0; k < loading->multiplier.size; k++) {
2790 const struct multiplier *pmul = loading->multiplier.order[k];
2791
2792 if (pmul) {
2794 int val =
2796 "player%d.multiplier%d.val",
2797 player_slot_index(pslot), k);
2798 int rval = (((CLIP(pmul->start, val, pmul->stop)
2799 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2800
2801 if (rval != val) {
2802 log_verbose("Player %d had illegal value for multiplier \"%s\": "
2803 "was %d, clamped to %d", pslot_id,
2804 multiplier_rule_name(pmul), val, rval);
2805 }
2806 pplayer->multipliers[idx].value = rval;
2807
2808 val =
2810 pplayer->multipliers[idx].value,
2811 "player%d.multiplier%d.target",
2812 player_slot_index(pslot), k);
2813 rval = (((CLIP(pmul->start, val, pmul->stop)
2814 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2815
2816 if (rval != val) {
2817 log_verbose("Player %d had illegal value for multiplier_target "
2818 "\"%s\": was %d, clamped to %d", pslot_id,
2819 multiplier_rule_name(pmul), val, rval);
2820 }
2821 pplayer->multipliers[idx].target = rval;
2822
2823 /* Never present in savegame2 format */
2824 pplayer->multipliers[idx].changed = 0;
2825 } /* else silently discard multiplier not in current ruleset */
2826 }
2827
2828 /* Just in case savecompat starts adding it in the future. */
2829 pplayer->server.border_vision =
2831 "player%d.border_vision",
2832 player_slot_index(pslot));
2834
2835 /* check number of players */
2836 nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
2837 sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
2838 "(%d) from the loaded game does not match the number of "
2839 "players present (%d).", nplayers, player_count());
2840
2841 /* Load team information. */
2842 players_iterate(pplayer) {
2843 int team;
2844 struct team_slot *tslot = NULL;
2845
2847 "player%d.team_no",
2848 player_number(pplayer))
2850 "Invalid team definition for player %s (nb %d).",
2851 player_name(pplayer), player_number(pplayer));
2852 /* Should never fail when slot given is not NULL */
2853 team_add_player(pplayer, team_new(tslot));
2855
2856 /* Loading the shuffle list is quite complex. At the time of saving the
2857 * shuffle data is saved as
2858 * shuffled_player_<number> = player_slot_id
2859 * where number is an increasing number and player_slot_id is a number
2860 * between 0 and the maximum number of player slots. Now we have to create
2861 * a list
2862 * shuffler_players[number] = player_slot_id
2863 * where all player slot IDs are used exactly one time. The code below
2864 * handles this ... */
2865 if (secfile_lookup_int_default(loading->file, -1,
2866 "players.shuffled_player_%d", 0) >= 0) {
2867 int slots = player_slot_count();
2868 int plrcount = player_count();
2871
2872 for (i = 0; i < slots; i++) {
2873 /* Array to save used numbers. */
2875 /* List of all player IDs (needed for set_shuffled_players()). It is
2876 * initialised with the value -1 to indicate that no value is set. */
2877 shuffled_players[i] = -1;
2878 }
2879
2880 /* Load shuffled player list. */
2881 for (i = 0; i < plrcount; i++) {
2882 int shuffle
2884 "players.shuffled_player_%d", i);
2885
2886 if (shuffle == -1) {
2887 log_sg("Missing player shuffle information (index %d) "
2888 "- reshuffle player list!", i);
2890 break;
2891 } else if (shuffled_player_set[shuffle]) {
2892 log_sg("Player shuffle %d used two times "
2893 "- reshuffle player list!", shuffle);
2895 break;
2896 }
2897 /* Set this ID as used. */
2899
2900 /* Save the player ID in the shuffle list. */
2902 }
2903
2904 if (shuffle_loaded) {
2905 /* Insert missing numbers. */
2906 int shuffle_index = plrcount;
2907
2908 for (i = 0; i < slots; i++) {
2909 if (!shuffled_player_set[i]) {
2911 }
2912
2913 /* shuffle_index must not grow higher than size of shuffled_players. */
2915 "Invalid player shuffle data!");
2916 }
2917
2918#ifdef FREECIV_DEBUG
2919 log_debug("[load shuffle] player_count() = %d", player_count());
2920 player_slots_iterate(pslot) {
2921 int plrid = player_slot_index(pslot);
2922
2923 log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
2925 shuffled_player_set[plrid] ? "is used" : "-");
2927#endif /* FREECIV_DEBUG */
2928
2929 /* Set shuffle list from savegame. */
2931 }
2932 }
2933
2934 if (!shuffle_loaded) {
2935 /* No shuffled players included or error loading them, so shuffle them
2936 * (this may include scenarios). */
2938 }
2939}
2940
2941/************************************************************************/
2945{
2946 /* Check status and return if not OK (sg_success FALSE). */
2947 sg_check_ret();
2948
2949 if (game.info.is_new_game) {
2950 /* Nothing to do. */
2951 return;
2952 }
2953
2954 players_iterate(pplayer) {
2955 sg_load_player_main(loading, pplayer);
2957 sg_load_player_units(loading, pplayer);
2959
2960 /* Check the success of the functions above. */
2961 sg_check_ret();
2962
2963 /* Print out some information */
2964 if (is_ai(pplayer)) {
2965 log_normal(_("%s has been added as %s level AI-controlled player "
2966 "(%s)."), player_name(pplayer),
2967 ai_level_translated_name(pplayer->ai_common.skill_level),
2968 ai_name(pplayer->ai));
2969 } else {
2970 log_normal(_("%s has been added as human player."),
2971 player_name(pplayer));
2972 }
2974
2975 /* Also load the transport status of the units here. It must be a special
2976 * case as all units must be known (unit on an allied transporter). */
2977 players_iterate(pplayer) {
2978 /* Load unit transport status. */
2981
2982 /* Savegame may contain nation assignments that are incompatible with the
2983 * current nationset -- for instance, if it predates the introduction of
2984 * nationsets. Ensure they are compatible, one way or another. */
2986
2987 /* Some players may have invalid nations in the ruleset. Once all players
2988 * are loaded, pick one of the remaining nations for them. */
2989 players_iterate(pplayer) {
2990 if (pplayer->nation == NO_NATION_SELECTED) {
2993 /* TRANS: Minor error message: <Leader> ... <Poles>. */
2994 log_sg(_("%s had invalid nation; changing to %s."),
2995 player_name(pplayer), nation_plural_for_player(pplayer));
2996
2997 ai_traits_init(pplayer);
2998 }
3000
3001 /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
3004 if (pplayers_allied(plr, aplayer)) {
3006 DS_ALLIANCE);
3007
3010 log_sg("Illegal alliance structure detected: "
3011 "%s alliance to %s reduced to peace treaty.",
3016 }
3017 }
3020
3021 /* Update cached city illness. This can depend on trade routes,
3022 * so can't be calculated until all players have been loaded. */
3023 if (game.info.illness_on) {
3024 cities_iterate(pcity) {
3025 pcity->server.illness
3026 = city_illness_calc(pcity, NULL, NULL,
3027 &(pcity->illness_trade), NULL);
3029 }
3030
3031 /* Update all city information. This must come after all cities are
3032 * loaded (in player_load) but before player (dumb) cities are loaded
3033 * in player_load_vision(). */
3034 players_iterate(plr) {
3035 city_list_iterate(plr->cities, pcity) {
3036 city_refresh(pcity);
3037 sanity_check_city(pcity);
3038 CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
3041
3042 /* Since the cities must be placed on the map to put them on the
3043 player map we do this afterwards */
3044 players_iterate(pplayer) {
3046 /* Check the success of the function above. */
3047 sg_check_ret();
3049
3050 /* Check shared vision. Shared tiles are never given in savegame2 save */
3051 players_iterate(pplayer) {
3052 BV_CLR_ALL(pplayer->gives_shared_vision);
3053 BV_CLR_ALL(pplayer->gives_shared_tiles);
3054 BV_CLR_ALL(pplayer->server.really_gives_vision);
3056
3057 /* Set up shared vision... */
3058 players_iterate(pplayer) {
3059 int plr1 = player_index(pplayer);
3060
3062 int plr2 = player_index(pplayer2);
3063
3065 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
3066 give_shared_vision(pplayer, pplayer2);
3067 }
3070
3071 /* ...and check it */
3074 /* TODO: Is there a good reason player is not marked as
3075 * giving shared vision to themselves -> really_gives_vision()
3076 * returning FALSE when pplayer1 == pplayer2 */
3077 if (pplayer1 != pplayer2
3080 sg_regr(3000900,
3081 _("%s did not give shared vision to team member %s."),
3084 }
3086 sg_regr(3000900,
3087 _("%s did not give shared vision to team member %s."),
3090 }
3091 }
3094
3097
3098 /* All vision is ready; this calls city_thaw_workers_queue(). */
3100
3101 /* Make sure everything is consistent. */
3102 players_iterate(pplayer) {
3103 unit_list_iterate(pplayer->units, punit) {
3105 struct tile *ptile = unit_tile(punit);
3106
3107 log_sg("%s doing illegal activity in savegame!",
3109 log_sg("Activity: %s, Target: %s, Tile: (%d, %d), Terrain: %s",
3113 : "missing",
3114 TILE_XY(ptile), terrain_rule_name(tile_terrain(ptile)));
3116 }
3119
3120 cities_iterate(pcity) {
3121 city_refresh(pcity);
3122 city_thaw_workers(pcity); /* may auto_arrange_workers() */
3124
3125 /* Player colors are always needed once game has started. Pre-2.4 savegames
3126 * lack them. This cannot be in compatibility conversion layer as we need
3127 * all the player data available to be able to assign best colors. */
3128 if (game_was_started()) {
3130 }
3131}
3132
3133/************************************************************************/
3137 struct player *plr)
3138{
3139 const char **slist;
3140 int i, plrno = player_number(plr);
3141 const char *str;
3142 struct government *gov;
3143 const char *level;
3144 const char *barb_str;
3145 size_t nval;
3146
3147 /* Check status and return if not OK (sg_success FALSE). */
3148 sg_check_ret();
3149
3150 /* Basic player data. */
3151 str = secfile_lookup_str(loading->file, "player%d.name", plrno);
3152 sg_failure_ret(str != NULL, "%s", secfile_error());
3154 sz_strlcpy(plr->username,
3156 "player%d.username", plrno));
3158 "player%d.unassigned_user", plrno),
3159 "%s", secfile_error());
3162 "player%d.orig_username",
3163 plrno));
3166 "player%d.ranked_username",
3167 plrno));
3169 "player%d.unassigned_ranked", plrno),
3170 "%s", secfile_error());
3172 "player%d.delegation_username",
3173 plrno);
3174 /* Defaults to no delegation. */
3175 if (strlen(str)) {
3177 }
3178
3179 /* Player flags */
3180 BV_CLR_ALL(plr->flags);
3181 slist = secfile_lookup_str_vec(loading->file, &nval, "player%d.flags", plrno);
3182 for (i = 0; i < nval; i++) {
3183 const char *sval = slist[i];
3185
3186 sg_failure_ret(plr_flag_id_is_valid(fid), "Invalid player flag \"%s\".", sval);
3187
3188 BV_SET(plr->flags, fid);
3189 }
3190 free(slist);
3191
3192 /* Nation */
3193 str = secfile_lookup_str(loading->file, "player%d.nation", plrno);
3195 if (plr->nation != NULL) {
3196 ai_traits_init(plr);
3197 }
3198
3199 /* Government */
3200 str = secfile_lookup_str(loading->file, "player%d.government_name",
3201 plrno);
3203 sg_failure_ret(gov != NULL, "Player%d: unsupported government \"%s\".",
3204 plrno, str);
3205 plr->government = gov;
3206
3207 /* Target government */
3209 "player%d.target_government_name", plrno);
3210 if (str != NULL) {
3212 } else {
3213 plr->target_government = NULL;
3214 }
3217 "player%d.revolution_finishes", plrno);
3218
3219 /* Load diplomatic data (diplstate + embassy + vision).
3220 * Shared vision is loaded in sg_load_players(). */
3222 players_iterate(pplayer) {
3223 char buf[32];
3224 int unconverted;
3225 struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
3226 i = player_index(pplayer);
3227
3228 /* load diplomatic status */
3229 fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
3230
3231 unconverted =
3232 secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
3233 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
3234 /* Look up what state the unconverted number represents. */
3235 ds->type = loading->ds_t.order[unconverted];
3236 } else {
3237 log_sg("No valid diplomatic state type between players %d and %d",
3238 plrno, i);
3239
3240 ds->type = DS_WAR;
3241 }
3242
3243 unconverted =
3244 secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
3245 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
3246 /* Look up what state the unconverted number represents. */
3247 ds->max_state = loading->ds_t.order[unconverted];
3248 } else {
3249 log_sg("No valid diplomatic max_state between players %d and %d",
3250 plrno, i);
3251
3252 ds->max_state = DS_WAR;
3253 }
3254
3255 /* FIXME: If either party is barbarian, we cannot enforce below check */
3256#if 0
3257 if (ds->type == DS_WAR && ds->first_contact_turn <= 0) {
3258 sg_regr(3020000,
3259 "Player%d: War with player %d who has never been met. "
3260 "Reverted to No Contact state.", plrno, i);
3261 ds->type = DS_NO_CONTACT;
3262 }
3263#endif
3264
3265 if (valid_dst_closest(ds) != ds->max_state) {
3266 sg_regr(3020000,
3267 "Player%d: closest diplstate to player %d less than current. "
3268 "Updated.", plrno, i);
3269 ds->max_state = ds->type;
3270 }
3271
3272 ds->first_contact_turn =
3274 "%s.first_contact_turn", buf);
3275 ds->turns_left =
3276 secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
3277 ds->has_reason_to_cancel =
3279 "%s.has_reason_to_cancel", buf);
3280 ds->contact_turns_left =
3282 "%s.contact_turns_left", buf);
3283
3284 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
3285 buf)) {
3286 BV_SET(plr->real_embassy, i);
3287 }
3288 /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
3289 * must be known. */
3291
3292 /* load ai data */
3294 char buf[32];
3295
3296 fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
3298
3300 secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
3301 CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
3303
3304 CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
3305
3306 /* Some sane defaults */
3307 plr->ai_common.fuzzy = 0;
3308 plr->ai_common.expand = 100;
3309 plr->ai_common.science_cost = 100;
3310
3311
3313 "player%d.ai.level", plrno);
3314 if (level != NULL) {
3315 if (!fc_strcasecmp("Handicapped", level)) {
3316 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
3318 } else {
3320 }
3321 } else {
3323 }
3324
3329 "player%d.ai.skill_level",
3330 plrno));
3331 }
3332
3334 "player%d.ai.barb_type", plrno);
3336
3338 log_sg("Player%d: Invalid barbarian type \"%s\". "
3339 "Changed to \"None\".", plrno, barb_str);
3341 }
3342
3343 if (is_barbarian(plr)) {
3344 server.nbarbarians++;
3345 }
3346
3347 if (is_ai(plr)) {
3349 CALL_PLR_AI_FUNC(gained_control, plr, plr);
3350 }
3351
3352 /* Load nation style. */
3353 {
3354 struct nation_style *style;
3355
3356 str = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
3357
3358 /* Handle pre-2.6 savegames */
3359 if (str == NULL) {
3360 str = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
3361 plrno);
3362 }
3363
3364 sg_failure_ret(str != NULL, "%s", secfile_error());
3365 style = style_by_rule_name(str);
3366 if (style == NULL) {
3367 style = style_by_number(0);
3368 log_sg("Player%d: unsupported city_style_name \"%s\". "
3369 "Changed to \"%s\".", plrno, str, style_rule_name(style));
3370 }
3371 plr->style = style;
3372 }
3373
3375 "player%d.idle_turns", plrno),
3376 "%s", secfile_error());
3378 "player%d.is_male", plrno);
3380 "player%d.is_alive", plrno),
3381 "%s", secfile_error());
3383 "player%d.turns_alive", plrno),
3384 "%s", secfile_error());
3386 "player%d.last_war", plrno),
3387 "%s", secfile_error());
3389 "player%d.phase_done", plrno);
3391 "player%d.gold", plrno),
3392 "%s", secfile_error());
3394 "player%d.rates.tax", plrno),
3395 "%s", secfile_error());
3397 "player%d.rates.science", plrno),
3398 "%s", secfile_error());
3400 "player%d.rates.luxury", plrno),
3401 "%s", secfile_error());
3402 plr->server.bulbs_last_turn =
3404 "player%d.research.bulbs_last_turn", plrno);
3405
3406 /* Traits */
3407 if (plr->nation) {
3408 for (i = 0; i < loading->trait.size; i++) {
3409 enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
3410
3411 if (trait_is_valid(tr)) {
3412 int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
3413 plrno, i);
3414
3415 if (val != -1) {
3416 plr->ai_common.traits[tr].val = val;
3417 }
3418
3420 "player%d.trait%d.mod", plrno, i),
3421 "%s", secfile_error());
3422 plr->ai_common.traits[tr].mod = val;
3423 }
3424 }
3425 }
3426
3427 /* Achievements */
3428 {
3429 int count;
3430
3431 count = secfile_lookup_int_default(loading->file, -1,
3432 "player%d.achievement_count", plrno);
3433
3434 if (count > 0) {
3435 for (i = 0; i < count; i++) {
3436 const char *name;
3437 struct achievement *pach;
3438 bool first;
3439
3441 "player%d.achievement%d.name", plrno, i);
3443
3445 "Unknown achievement \"%s\".", name);
3446
3448 "player%d.achievement%d.first",
3449 plrno, i),
3450 "achievement error: %s", secfile_error());
3451
3452 sg_failure_ret(pach->first == NULL || !first,
3453 "Multiple players listed as first to get achievement \"%s\".",
3454 name);
3455
3456 BV_SET(pach->achievers, player_index(plr));
3457
3458 if (first) {
3459 pach->first = plr;
3460 }
3461 }
3462 }
3463 }
3464
3465 /* Player score. */
3466 plr->score.happy =
3468 "score%d.happy", plrno);
3469 plr->score.content =
3471 "score%d.content", plrno);
3472 plr->score.unhappy =
3474 "score%d.unhappy", plrno);
3475 plr->score.angry =
3477 "score%d.angry", plrno);
3478
3479 /* Make sure that the score about specialists in current ruleset that
3480 * were not present at saving time are set to zero. */
3482 plr->score.specialists[sp] = 0;
3484
3485 for (i = 0; i < loading->specialist.size; i++) {
3486 plr->score.specialists[specialist_index(loading->specialist.order[i])]
3488 "score%d.specialists%d", plrno, i);
3489 }
3490
3491 plr->score.wonders =
3493 "score%d.wonders", plrno);
3494 plr->score.techs =
3496 "score%d.techs", plrno);
3497 plr->score.techout =
3499 "score%d.techout", plrno);
3500 plr->score.landarea =
3502 "score%d.landarea", plrno);
3503 plr->score.settledarea =
3505 "score%d.settledarea", plrno);
3506 plr->score.population =
3508 "score%d.population", plrno);
3509 plr->score.cities =
3511 "score%d.cities", plrno);
3512 plr->score.units =
3514 "score%d.units", plrno);
3515 plr->score.pollution =
3517 "score%d.pollution", plrno);
3518 plr->score.literacy =
3520 "score%d.literacy", plrno);
3521 plr->score.bnp =
3523 "score%d.bnp", plrno);
3524 plr->score.mfg =
3526 "score%d.mfg", plrno);
3527 plr->score.spaceship =
3529 "score%d.spaceship", plrno);
3530 plr->score.units_built =
3532 "score%d.units_built", plrno);
3533 plr->score.units_killed =
3535 "score%d.units_killed", plrno);
3536 plr->score.units_lost =
3538 "score%d.units_lost", plrno);
3539 plr->score.units_used = 0; /* Was never saved to savegame2.c saves */
3540 plr->score.culture =
3542 "score%d.culture", plrno);
3543 plr->score.game =
3545 "score%d.total", plrno);
3546
3547 /* Load space ship data. */
3548 {
3549 struct player_spaceship *ship = &plr->spaceship;
3550 char prefix[32];
3551 const char *st;
3552 int ei;
3553
3554 fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
3557 &ei,
3558 "%s.state", prefix),
3559 "%s", secfile_error());
3560 ship->state = ei;
3561
3562 if (ship->state != SSHIP_NONE) {
3563 sg_failure_ret(secfile_lookup_int(loading->file, &ship->structurals,
3564 "%s.structurals", prefix),
3565 "%s", secfile_error());
3566 sg_failure_ret(secfile_lookup_int(loading->file, &ship->components,
3567 "%s.components", prefix),
3568 "%s", secfile_error());
3570 "%s.modules", prefix),
3571 "%s", secfile_error());
3573 "%s.fuel", prefix),
3574 "%s", secfile_error());
3575 sg_failure_ret(secfile_lookup_int(loading->file, &ship->propulsion,
3576 "%s.propulsion", prefix),
3577 "%s", secfile_error());
3578 sg_failure_ret(secfile_lookup_int(loading->file, &ship->habitation,
3579 "%s.habitation", prefix),
3580 "%s", secfile_error());
3581 sg_failure_ret(secfile_lookup_int(loading->file, &ship->life_support,
3582 "%s.life_support", prefix),
3583 "%s", secfile_error());
3584 sg_failure_ret(secfile_lookup_int(loading->file, &ship->solar_panels,
3585 "%s.solar_panels", prefix),
3586 "%s", secfile_error());
3587
3588 st = secfile_lookup_str(loading->file, "%s.structure", prefix);
3589 sg_failure_ret(st != NULL, "%s", secfile_error())
3590 for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
3591 sg_failure_ret(st[i] == '1' || st[i] == '0',
3592 "Undefined value '%c' within '%s.structure'.", st[i],
3593 prefix)
3594
3595 if (!(st[i] == '0')) {
3596 BV_SET(ship->structure, i);
3597 }
3598 }
3599 if (ship->state >= SSHIP_LAUNCHED) {
3600 sg_failure_ret(secfile_lookup_int(loading->file, &ship->launch_year,
3601 "%s.launch_year", prefix),
3602 "%s", secfile_error());
3603 }
3605 }
3606 }
3607
3608 /* Load lost wonder data. */
3609 str = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
3610 /* If not present, probably an old savegame; nothing to be done */
3611 if (str != NULL) {
3612 int k;
3613
3614 sg_failure_ret(strlen(str) == loading->improvement.size,
3615 "Invalid length for 'player%d.lost_wonders' ("
3616 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ")",
3617 plrno, strlen(str), loading->improvement.size);
3618 for (k = 0; k < loading->improvement.size; k++) {
3619 sg_failure_ret(str[k] == '1' || str[k] == '0',
3620 "Undefined value '%c' within "
3621 "'player%d.lost_wonders'.", plrno, str[k]);
3622
3623 if (str[k] == '1') {
3624 struct impr_type *pimprove =
3625 improvement_by_rule_name(loading->improvement.order[k]);
3626
3627 if (pimprove) {
3628 plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
3629 }
3630 }
3631 }
3632 }
3633
3634 plr->history =
3635 secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
3636 plr->server.huts =
3637 secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
3638}
3639
3640/************************************************************************/
3644 struct player *plr)
3645{
3646 int ncities, i, plrno = player_number(plr);
3647 bool tasks_handled;
3648 int wlist_max_length;
3649
3650 /* Check status and return if not OK (sg_success FALSE). */
3651 sg_check_ret();
3652
3654 "player%d.ncities", plrno),
3655 "%s", secfile_error());
3656
3657 if (!plr->is_alive && ncities > 0) {
3658 log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
3659 ncities = 0;
3660 }
3661
3662 if (!player_has_flag(plr, PLRF_FIRST_CITY) && ncities > 0) {
3663 /* Probably barbarians in an old savegame; fix up */
3665 }
3666
3668 "player%d.wl_max_length",
3669 plrno);
3670
3671 /* Load all cities of the player. */
3672 for (i = 0; i < ncities; i++) {
3673 char buf[32];
3674 struct city *pcity;
3675
3676 fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
3677
3678 /* Create a dummy city. */
3679 pcity = create_city_virtual(plr, NULL, buf);
3680 adv_city_alloc(pcity);
3681 if (!sg_load_player_city(loading, plr, pcity, buf, wlist_max_length)) {
3682 adv_city_free(pcity);
3683 destroy_city_virtual(pcity);
3684 sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
3685 }
3686
3688 idex_register_city(&wld, pcity);
3689
3690 /* Load the information about the nationality of citizens. This is done
3691 * here because the city sanity check called by citizens_update() requires
3692 * that the city is registered. */
3694
3695 /* After everything is loaded, but before vision. */
3696 map_claim_ownership(city_tile(pcity), plr, city_tile(pcity), TRUE);
3697
3698 /* adding the city contribution to fog-of-war */
3699 pcity->server.vision = vision_new(plr, city_tile(pcity));
3701 city_refresh_vision(pcity);
3702
3703 city_list_append(plr->cities, pcity);
3704 }
3705
3707 for (i = 0; !tasks_handled; i++) {
3708 int city_id;
3709 struct city *pcity = NULL;
3710
3711 city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
3712 plrno, i);
3713
3714 if (city_id != -1) {
3715 pcity = player_city_by_number(plr, city_id);
3716 }
3717
3718 if (pcity != NULL) {
3719 const char *str;
3720 int nat_x, nat_y;
3721 struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
3722
3723 nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
3724 nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
3725
3726 ptask->ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3727
3728 str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
3730
3732 "Unknown workertask activity %s", str);
3733
3734 str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
3735
3736 if (strcmp("-", str)) {
3738
3739 sg_failure_ret(ptask->tgt != NULL,
3740 "Unknown workertask target %s", str);
3741 } else {
3742 ptask->tgt = NULL;
3743 }
3744
3745 ptask->want = secfile_lookup_int_default(loading->file, 1,
3746 "player%d.task%d.want", plrno, i);
3747
3749 } else {
3751 }
3752 }
3753}
3754
3755/************************************************************************/
3758static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
3759 struct city *pcity, const char *citystr,
3760 int wlist_max_length)
3761{
3762 struct player *past;
3763 const char *kind, *name, *str;
3764 int id, i, repair, sp_count = 0, workers = 0, value;
3765 int nat_x, nat_y;
3766 citizens size;
3767 const char *stylename;
3768 const struct civ_map *nmap = &(wld.map);
3769
3771 FALSE, "%s", secfile_error());
3773 FALSE, "%s", secfile_error());
3774 pcity->tile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3775 sg_warn_ret_val(NULL != pcity->tile, FALSE,
3776 "%s has invalid center tile (%d, %d)",
3777 citystr, nat_x, nat_y);
3779 "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
3780
3781 /* Instead of dying, use 'citystr' string for damaged name. */
3783 "%s.name", citystr));
3784
3785 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->id, "%s.id",
3786 citystr), FALSE, "%s", secfile_error());
3787
3789 "%s.original", citystr);
3790 past = player_by_number(id);
3791 if (NULL != past) {
3792 pcity->original = past;
3793 }
3794
3795 /* savegame2 saves never had this information. Guess. */
3796 if (pcity->original != plr) {
3797 pcity->acquire_t = CACQ_CONQUEST;
3798 } else {
3799 pcity->acquire_t = CACQ_FOUNDED;
3800 }
3801
3802 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
3803 citystr), FALSE, "%s", secfile_error());
3804 size = (citizens)value; /* Set the correct type */
3805 sg_warn_ret_val(value == (int)size, FALSE,
3806 "Invalid city size: %d, set to %d", value, size);
3807 city_size_set(pcity, size);
3808
3809 for (i = 0; i < loading->specialist.size; i++) {
3810 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
3811 citystr, i),
3812 FALSE, "%s", secfile_error());
3813 pcity->specialists[specialist_index(loading->specialist.order[i])]
3814 = (citizens)value;
3815 sp_count += value;
3816 }
3817
3818 /* savegame2.c saves were ever saved with MAX_TRADE_ROUTES_OLD routes max */
3819 for (i = 0; i < MAX_TRADE_ROUTES_OLD; i++) {
3820 int partner = secfile_lookup_int_default(loading->file, 0,
3821 "%s.traderoute%d", citystr, i);
3822
3823 if (partner != 0) {
3824 struct trade_route *proute = fc_malloc(sizeof(struct trade_route));
3825
3826 proute->partner = partner;
3828 proute->goods = goods_by_number(0); /* First good */
3829
3831 }
3832 }
3833
3835 "%s.food_stock", citystr),
3836 FALSE, "%s", secfile_error());
3838 "%s.shield_stock", citystr),
3839 FALSE, "%s", secfile_error());
3840 pcity->history =
3841 secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
3842
3843 pcity->airlift =
3844 secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
3845 pcity->was_happy =
3846 secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
3847 citystr);
3848 pcity->had_famine = FALSE;
3849
3850 pcity->turn_plague =
3851 secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
3852
3854 "%s.anarchy", citystr),
3855 FALSE, "%s", secfile_error());
3856 pcity->rapture =
3857 secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
3858 pcity->steal =
3859 secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
3860
3861 /* Before did_buy for undocumented hack */
3862 pcity->turn_founded =
3863 secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
3864 citystr);
3865 sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
3866 citystr), FALSE, "%s", secfile_error());
3867 pcity->did_buy = (i != 0);
3868 if (i == -1 && pcity->turn_founded == -2) {
3869 /* Undocumented hack */
3870 pcity->turn_founded = game.info.turn;
3871 }
3872
3873 pcity->did_sell
3874 = secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
3875
3877 "%s.turn_last_built", citystr),
3878 FALSE, "%s", secfile_error());
3879
3880 kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
3881 citystr);
3882 name = secfile_lookup_str(loading->file, "%s.currently_building_name",
3883 citystr);
3884 pcity->production = universal_by_rule_name(kind, name);
3886 "%s.currently_building: unknown \"%s\" \"%s\".",
3887 citystr, kind, name);
3888
3889 kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
3890 citystr);
3891 name = secfile_lookup_str(loading->file, "%s.changed_from_name",
3892 citystr);
3895 "%s.changed_from: unknown \"%s\" \"%s\".",
3896 citystr, kind, name);
3897
3898 pcity->before_change_shields =
3900 "%s.before_change_shields", citystr);
3901 pcity->caravan_shields =
3903 "%s.caravan_shields", citystr);
3904 pcity->disbanded_shields =
3906 "%s.disbanded_shields", citystr);
3909 "%s.last_turns_shield_surplus",
3910 citystr);
3911
3913 "%s.style", citystr);
3914 if (stylename != NULL) {
3916 } else {
3917 pcity->style = 0;
3918 }
3919 if (pcity->style < 0) {
3920 pcity->style = city_style(pcity);
3921 }
3922
3923 pcity->server.synced = FALSE; /* Must re-sync with clients */
3924
3925 /* Initialise list of city improvements. */
3926 for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
3927 pcity->built[i].turn = I_NEVER;
3928 }
3929
3930 /* Load city improvements. */
3931 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
3933 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
3934 "Invalid length of '%s.improvements' ("
3935 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
3936 citystr, strlen(str), loading->improvement.size);
3937 for (i = 0; i < loading->improvement.size; i++) {
3938 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
3939 "Undefined value '%c' within '%s.improvements'.",
3940 str[i], citystr)
3941
3942 if (str[i] == '1') {
3943 struct impr_type *pimprove =
3944 improvement_by_rule_name(loading->improvement.order[i]);
3945
3946 if (pimprove) {
3947 city_add_improvement(pcity, pimprove);
3948 }
3949 }
3950 }
3951
3952 sg_failure_ret_val(loading->worked_tiles != NULL, FALSE,
3953 "No worked tiles map defined.");
3954
3955 city_freeze_workers(pcity);
3956
3957 /* Load new savegame with variable (squared) city radius and worked
3958 * tiles map */
3959
3960 int radius_sq
3961 = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
3962 citystr);
3963 city_map_radius_sq_set(pcity, radius_sq);
3964
3966 if (loading->worked_tiles[ptile->index] == pcity->id) {
3967 if (sq_map_distance(ptile, pcity->tile) > radius_sq) {
3968 log_sg("[%s] '%s' (%d, %d) has worker outside current radius "
3969 "at (%d, %d); repairing", citystr, city_name_get(pcity),
3970 TILE_XY(pcity->tile), TILE_XY(ptile));
3972 sp_count++;
3973 } else {
3974 tile_set_worked(ptile, pcity);
3975 workers++;
3976 }
3977
3978#ifdef FREECIV_DEBUG
3979 /* Set this tile to unused; a check for not reset tiles is
3980 * included in game_load_internal() */
3981 loading->worked_tiles[ptile->index] = -1;
3982#endif /* FREECIV_DEBUG */
3983 }
3985
3986 if (tile_worked(city_tile(pcity)) != pcity) {
3987 struct city *pwork = tile_worked(city_tile(pcity));
3988
3989 if (NULL != pwork) {
3990 log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
3991 "(%d,%d) [%d]; repairing", citystr, city_name_get(pcity),
3994
3995 tile_set_worked(city_tile(pcity), NULL); /* remove tile from pwork */
3996 pwork->specialists[DEFAULT_SPECIALIST]++;
3998 } else {
3999 log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing",
4000 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)),
4001 city_size_get(pcity));
4002 }
4003
4004 /* repair pcity */
4005 tile_set_worked(city_tile(pcity), pcity);
4006 city_repair_size(pcity, -1);
4007 }
4008
4009 repair = city_size_get(pcity) - sp_count - (workers - FREE_WORKED_TILES);
4010 if (0 != repair) {
4011 log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
4012 "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
4013 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)), city_size_get(pcity),
4014 workers, FREE_WORKED_TILES, sp_count);
4015
4016 /* repair pcity */
4017 city_repair_size(pcity, repair);
4018 }
4019
4020 /* worklist_init() done in create_city_virtual() */
4021 worklist_load(loading->file, wlist_max_length, &pcity->worklist, "%s", citystr);
4022
4023 /* Load city options. */
4024 BV_CLR_ALL(pcity->city_options);
4025 for (i = 0; i < loading->coptions.size; i++) {
4026 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
4027 citystr, i)) {
4028 BV_SET(pcity->city_options, loading->coptions.order[i]);
4029 }
4030 }
4031 /* Was never stored to savegame2 saves */
4032 pcity->wlcb = WLCB_SMART;
4033
4034 CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
4035
4036 return TRUE;
4037}
4038
4039/************************************************************************/
4043 struct player *plr,
4044 struct city *pcity,
4045 const char *citystr)
4046{
4048 citizens size;
4049
4050 citizens_init(pcity);
4051 player_slots_iterate(pslot) {
4052 int nationality;
4053
4055 "%s.citizen%d", citystr,
4056 player_slot_index(pslot));
4057 if (nationality > 0 && !player_slot_is_used(pslot)) {
4058 log_sg("Citizens of an invalid nation for %s (player slot %d)!",
4059 city_name_get(pcity), player_slot_index(pslot));
4060 continue;
4061 }
4062
4063 if (nationality != -1 && player_slot_is_used(pslot)) {
4065 "Invalid value for citizens of player %d in %s: %d.",
4067 citizens_nation_set(pcity, pslot, nationality);
4068 }
4070 /* Sanity check. */
4071 size = citizens_count(pcity);
4072 if (size != city_size_get(pcity)) {
4073 if (size != 0) {
4074 /* size == 0 can be result from the fact that ruleset had no
4075 * nationality enabled at saving time, so no citizens at all
4076 * were saved. But something more serious must be going on if
4077 * citizens have been saved partially - if some of them are there. */
4078 log_sg("City size and number of citizens does not match in %s "
4079 "(%d != %d)! Repairing ...", city_name_get(pcity),
4080 city_size_get(pcity), size);
4081 }
4082 citizens_update(pcity, NULL);
4083 }
4084 }
4085}
4086
4087/************************************************************************/
4091 struct player *plr)
4092{
4093 int nunits, i, plrno = player_number(plr);
4094
4095 /* Check status and return if not OK (sg_success FALSE). */
4096 sg_check_ret();
4097
4099 "player%d.nunits", plrno),
4100 "%s", secfile_error());
4101 if (!plr->is_alive && nunits > 0) {
4102 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4103 nunits = 0; /* Some old savegames may be buggy. */
4104 }
4105
4106 for (i = 0; i < nunits; i++) {
4107 struct unit *punit;
4108 struct city *pcity;
4109 const char *name;
4110 char buf[32];
4111 struct unit_type *type;
4112 struct tile *ptile;
4113
4114 fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
4115
4116 name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
4118 sg_failure_ret(type != NULL, "%s: unknown unit type \"%s\".", buf, name);
4119
4120 /* Create a dummy unit. */
4121 punit = unit_virtual_create(plr, NULL, type, 0);
4122 if (!sg_load_player_unit(loading, plr, punit, buf)) {
4124 sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
4125 }
4126
4129
4130 if ((pcity = game_city_by_number(punit->homecity))) {
4132 } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
4133 log_sg("%s: bad home city %d.", buf, punit->homecity);
4135 }
4136
4137 ptile = unit_tile(punit);
4138
4139 /* allocate the unit's contribution to fog of war */
4142 /* NOTE: There used to be some map_set_known calls here. These were
4143 * unneeded since unfogging the tile when the unit sees it will
4144 * automatically reveal that tile. */
4145
4148
4149 /* Claim ownership of fortress? */
4150 if ((extra_owner(ptile) == NULL
4151 || pplayers_at_war(extra_owner(ptile), plr))
4153 tile_claim_bases(ptile, plr);
4154 }
4155 }
4156}
4157
4158/************************************************************************/
4168static int sg_order_to_action(int order, struct unit *act_unit,
4169 struct tile *tgt_tile)
4170{
4171 switch (order) {
4173 if (tile_city(tgt_tile)
4175 /* The player's cities are loaded right before their units. It wasn't
4176 * possible for rulesets to allow joining foreign cities before 3.0.
4177 * This means that a converted build city order only can be a Join
4178 * City order if it targets a domestic city. */
4179 return ACTION_JOIN_CITY;
4180 } else {
4181 /* Assume that the intention was to found a new city. */
4182 return ACTION_FOUND_CITY;
4183 }
4185 /* Maps one to one with each other. */
4186 return ACTION_HELP_WONDER;
4188 /* Maps one to one with each other. */
4189 return ACTION_TRADE_ROUTE;
4190 case ORDER_OLD_DISBAND:
4191 /* Added to the order system in the same commit as Help Wonder. Assume
4192 * that anyone that intended to order Help Wonder used Help Wonder. */
4193 /* Could in theory be intended as an order to disband in the field. Why
4194 * would the player give a unit an order to go to a non city location
4195 * and disband there? Assume the intention was to recover production
4196 * until a non recovering disband order is found. */
4198 case ORDER_OLD_HOMECITY:
4199 return ACTION_HOME_CITY;
4200 }
4201
4202 /* The order hasn't been replaced by an action. */
4203 return ACTION_NONE;
4204}
4205
4206/************************************************************************/
4210 struct player *plr, struct unit *punit,
4211 const char *unitstr)
4212{
4213 int activity;
4214 int nat_x, nat_y;
4215 enum tile_special_type target;
4216 struct extra_type *pextra = NULL;
4217 struct base_type *pbase = NULL;
4218 struct road_type *proad = NULL;
4219 struct tile *ptile;
4220 int extra_id;
4221 int base_id;
4222 int road_id;
4223 int ei;
4224 const char *facing_str;
4226 int natnbr;
4227 bool ai_controlled;
4228
4230 unitstr), FALSE, "%s", secfile_error());
4232 FALSE, "%s", secfile_error());
4234 FALSE, "%s", secfile_error());
4235
4236 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
4237 sg_warn_ret_val(NULL != ptile, FALSE, "%s invalid tile (%d, %d)",
4238 unitstr, nat_x, nat_y);
4239 unit_tile_set(punit, ptile);
4240
4243 "%s.facing", unitstr);
4244 if (facing_str[0] != 'x') {
4245 /* We don't touch punit->facing if savegame does not contain that
4246 * information. Initial orientation set by unit_virtual_create()
4247 * is as good as any. */
4248 enum direction8 facing = char2dir(facing_str[0]);
4249
4250 if (direction8_is_valid(facing)) {
4251 punit->facing = facing;
4252 } else {
4253 log_error("Illegal unit orientation '%s'", facing_str);
4254 }
4255 }
4256
4257 /* If savegame has unit nationality, it doesn't hurt to
4258 * internally set it even if nationality rules are disabled. */
4260 player_number(plr),
4261 "%s.nationality", unitstr);
4262
4264 if (punit->nationality == NULL) {
4265 punit->nationality = plr;
4266 }
4267
4269 "%s.homecity", unitstr), FALSE,
4270 "%s", secfile_error());
4272 "%s.moves", unitstr), FALSE,
4273 "%s", secfile_error());
4275 "%s.fuel", unitstr), FALSE,
4276 "%s", secfile_error());
4278 "%s.activity", unitstr), FALSE,
4279 "%s", secfile_error());
4280 activity = unit_activity_by_name(loading->activities.order[ei],
4282
4285 "%s.born", unitstr);
4287
4289 "%s.activity_tgt", unitstr);
4290
4291 if (extra_id != -2) {
4292 if (extra_id >= 0 && extra_id < loading->extra.size) {
4293 pextra = loading->extra.order[extra_id];
4294 set_unit_activity_targeted(punit, activity, pextra);
4295 } else if (activity == ACTIVITY_IRRIGATE) {
4299 punit);
4300 if (tgt != NULL) {
4302 } else {
4304 }
4305 } else if (activity == ACTIVITY_MINE) {
4307 EC_MINE,
4309 punit);
4310 if (tgt != NULL) {
4312 } else {
4314 }
4315 } else {
4316 set_unit_activity(punit, activity);
4317 }
4318 } else {
4319 /* extra_id == -2 -> activity_tgt not set */
4321 "%s.activity_base", unitstr);
4322 if (base_id >= 0 && base_id < loading->base.size) {
4323 pbase = loading->base.order[base_id];
4324 }
4326 "%s.activity_road", unitstr);
4327 if (road_id >= 0 && road_id < loading->road.size) {
4328 proad = loading->road.order[road_id];
4329 }
4330
4331 {
4333 loading->special.size /* S_LAST */,
4334 "%s.activity_target", unitstr);
4335 if (tgt_no >= 0 && tgt_no < loading->special.size) {
4336 target = loading->special.order[tgt_no];
4337 } else {
4338 target = S_LAST;
4339 }
4340 }
4341
4342 if (target == S_OLD_ROAD) {
4343 target = S_LAST;
4345 } else if (target == S_OLD_RAILROAD) {
4346 target = S_LAST;
4348 }
4349
4350 if (activity == ACTIVITY_OLD_ROAD) {
4351 activity = ACTIVITY_GEN_ROAD;
4353 } else if (activity == ACTIVITY_OLD_RAILROAD) {
4354 activity = ACTIVITY_GEN_ROAD;
4356 }
4357
4358 /* We need changed_from == ACTIVITY_IDLE by now so that
4359 * set_unit_activity() and friends don't spuriously restore activity
4360 * points -- unit should have been created this way */
4362
4363 if (activity == ACTIVITY_BASE) {
4364 if (pbase) {
4366 } else {
4367 log_sg("Cannot find base %d for %s to build",
4370 }
4371 } else if (activity == ACTIVITY_GEN_ROAD) {
4372 if (proad) {
4374 } else {
4375 log_sg("Cannot find road %d for %s to build",
4378 }
4379 } else if (activity == ACTIVITY_PILLAGE) {
4380 struct extra_type *a_target;
4381
4382 if (target != S_LAST) {
4383 a_target = special_extra_get(target);
4384 } else if (pbase != NULL) {
4386 } else if (proad != NULL) {
4388 } else {
4389 a_target = NULL;
4390 }
4391 /* An out-of-range base number is seen with old savegames. We take
4392 * it as indicating undirected pillaging. We will assign pillage
4393 * targets before play starts. */
4395 } else if (activity == ACTIVITY_IRRIGATE) {
4399 punit);
4400 if (tgt != NULL) {
4402 } else {
4404 }
4405 } else if (activity == ACTIVITY_MINE) {
4407 EC_MINE,
4409 punit);
4410 if (tgt != NULL) {
4412 } else {
4414 }
4415 } else if (activity == ACTIVITY_OLD_POLLUTION_SG2
4416 || activity == ACTIVITY_OLD_FALLOUT_SG2) {
4418 ERM_CLEAN,
4420 punit);
4421 if (tgt != NULL) {
4423 } else {
4425 }
4426 } else {
4428 }
4429 } /* activity_tgt == NULL */
4430
4432 "%s.activity_count", unitstr), FALSE,
4433 "%s", secfile_error());
4434
4437 "%s.changed_from", unitstr);
4438
4440 "%s.changed_from_tgt", unitstr);
4441
4442 if (extra_id != -2) {
4443 if (extra_id >= 0 && extra_id < loading->extra.size) {
4444 punit->changed_from_target = loading->extra.order[extra_id];
4445 } else {
4447 }
4448 } else {
4449 /* extra_id == -2 -> changed_from_tgt not set */
4450
4451 cfspe =
4453 "%s.changed_from_target", unitstr);
4454 base_id =
4456 "%s.changed_from_base", unitstr);
4457 road_id =
4459 "%s.changed_from_road", unitstr);
4460
4461 if (road_id == -1) {
4462 if (cfspe == S_OLD_ROAD) {
4464 if (proad) {
4466 }
4467 } else if (cfspe == S_OLD_RAILROAD) {
4469 if (proad) {
4471 }
4472 }
4473 }
4474
4475 if (base_id >= 0 && base_id < loading->base.size) {
4477 } else if (road_id >= 0 && road_id < loading->road.size) {
4479 } else if (cfspe != S_LAST) {
4481 } else {
4483 }
4484
4489 punit);
4490 if (tgt != NULL) {
4492 } else {
4494 }
4495 } else if (punit->changed_from == ACTIVITY_MINE) {
4497 EC_MINE,
4499 punit);
4500 if (tgt != NULL) {
4502 } else {
4504 }
4508 ERM_CLEAN,
4510 punit);
4511 if (tgt != NULL) {
4513 } else {
4515 }
4516 }
4517 }
4518
4521 "%s.changed_from_count", unitstr);
4522
4523 /* Special case: for a long time, we accidentally incremented
4524 * activity_count while a unit was sentried, so it could increase
4525 * without bound (bug #20641) and be saved in old savefiles.
4526 * We zero it to prevent potential trouble overflowing the range
4527 * in network packets, etc. */
4528 if (activity == ACTIVITY_SENTRY) {
4529 punit->activity_count = 0;
4530 }
4533 }
4534
4535 punit->veteran
4536 = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
4537 {
4538 /* Protect against change in veteran system in ruleset */
4539 const int levels = utype_veteran_levels(unit_type_get(punit));
4540 if (punit->veteran >= levels) {
4541 fc_assert(levels >= 1);
4542 punit->veteran = levels - 1;
4543 }
4544 }
4547 "%s.done_moving", unitstr);
4550 "%s.battlegroup", unitstr);
4551
4553 "%s.go", unitstr)) {
4554 int gnat_x, gnat_y;
4555
4557 "%s.goto_x", unitstr), FALSE,
4558 "%s", secfile_error());
4560 "%s.goto_y", unitstr), FALSE,
4561 "%s", secfile_error());
4562
4564 } else {
4565 punit->goto_tile = NULL;
4566
4567 /* These variables are not used but needed for saving the unit table.
4568 * Load them to prevent unused variables errors. */
4569 (void) secfile_entry_lookup(loading->file, "%s.goto_x", unitstr);
4570 (void) secfile_entry_lookup(loading->file, "%s.goto_y", unitstr);
4571 }
4572
4573 /* Load AI data of the unit. */
4574 CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
4575
4578 "%s.ai", unitstr), FALSE,
4579 "%s", secfile_error());
4580 if (ai_controlled) {
4581 /* Autosettler and Autoexplore are separated by
4582 * compat_post_load_030100() when set to SSA_AUTOSETTLER */
4584 } else {
4586 }
4588 "%s.hp", unitstr), FALSE,
4589 "%s", secfile_error());
4590
4592 = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
4594 = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
4595 punit->moved
4596 = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
4599 "%s.paradropped", unitstr);
4600
4601 /* The transport status (punit->transported_by) is loaded in
4602 * sg_player_units_transport(). */
4603
4604 /* Initialize upkeep values: these are hopefully initialized
4605 * elsewhere before use (specifically, in city_support(); but
4606 * fixme: check whether always correctly initialized?).
4607 * Below is mainly for units which don't have homecity --
4608 * otherwise these don't get initialized (and AI calculations
4609 * etc may use junk values). */
4613
4617 "%s.action_decision_want", unitstr);
4618
4620 /* Load the tile to act against. */
4621 int adwt_x, adwt_y;
4622
4623 if (secfile_lookup_int(loading->file, &adwt_x,
4624 "%s.action_decision_tile_x", unitstr)
4626 "%s.action_decision_tile_y", unitstr)) {
4628 adwt_x, adwt_y);
4629 } else {
4632 log_sg("Bad action_decision_tile for unit %d", punit->id);
4633 }
4634 } else {
4635 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_x", unitstr);
4636 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_y", unitstr);
4638 }
4639
4640 /* Load the unit orders */
4641 {
4642 int len = secfile_lookup_int_default(loading->file, 0,
4643 "%s.orders_length", unitstr);
4644
4645 if (len > 0) {
4646 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
4647 const char *tgt_unitstr;
4648 const char *base_unitstr = NULL;
4649 const char *road_unitstr = NULL;
4652 int j;
4653
4654 punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
4658 "%s.orders_index", unitstr);
4661 "%s.orders_repeat", unitstr);
4664 "%s.orders_vigilant", unitstr);
4665
4668 "%s.orders_list", unitstr);
4671 "%s.dir_list", unitstr);
4674 "%s.activity_list", unitstr);
4676 = secfile_lookup_str_default(loading->file, NULL, "%s.tgt_list", unitstr);
4677
4678 if (tgt_unitstr == NULL) {
4680 = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
4682 = secfile_lookup_str_default(loading->file, NULL, "%s.road_list", unitstr);
4683 }
4684
4686
4687 for (j = 0; j < len; j++) {
4688 struct unit_order *order = &punit->orders.list[j];
4689
4690 if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
4691 || act_unitstr[j] == '\0') {
4692 log_sg("Invalid unit orders.");
4694 break;
4695 }
4696 order->order = char2order(orders_unitstr[j]);
4697 order->dir = char2dir(dir_unitstr[j]);
4698 order->activity = char2activity(act_unitstr[j]);
4699 /* Target, if needed, is set in compat_post_load_030100() */
4700 order->target = NO_TARGET;
4701 order->sub_target = NO_TARGET;
4702
4703 if (order->order == ORDER_LAST
4704 || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
4705 || (order->order == ORDER_ACTION_MOVE
4706 && !direction8_is_valid(order->dir))
4707 || (order->order == ORDER_ACTIVITY
4708 && order->activity == ACTIVITY_LAST)) {
4709 /* An invalid order. Just drop the orders for this unit. */
4711 punit->orders.list = NULL;
4713 break;
4714 }
4715
4716 /* The order may have been replaced by the perform action order */
4717 order->action = sg_order_to_action(order->order, punit,
4718 punit->goto_tile);
4719 if (order->action != ACTION_NONE) {
4720 /* The order was converted by order_to_action */
4721 order->order = ORDER_PERFORM_ACTION;
4722 }
4723
4724 if (tgt_unitstr) {
4725 if (tgt_unitstr[j] != '?') {
4727
4728 if (extra_id < 0 || extra_id >= loading->extra.size) {
4729 log_sg("Cannot find extra %d for %s to build",
4731 order->sub_target = EXTRA_NONE;
4732 } else {
4733 order->sub_target = extra_id;
4734 }
4735 } else {
4736 order->sub_target = EXTRA_NONE;
4737 }
4738 } else {
4739 /* In pre-2.6 savegames, base_list and road_list were only saved
4740 * for those activities (and not e.g. pillaging) */
4741 if (base_unitstr && base_unitstr[j] != '?'
4742 && order->activity == ACTIVITY_BASE) {
4744
4745 if (base_id < 0 || base_id >= loading->base.size) {
4746 log_sg("Cannot find base %d for %s to build",
4749 NULL, NULL));
4750 }
4751
4752 order->sub_target
4754 } else if (road_unitstr && road_unitstr[j] != '?'
4755 && order->activity == ACTIVITY_GEN_ROAD) {
4757
4758 if (road_id < 0 || road_id >= loading->road.size) {
4759 log_sg("Cannot find road %d for %s to build",
4761 road_id = 0;
4762 }
4763
4764 order->sub_target
4766 } else {
4767 order->sub_target = EXTRA_NONE;
4768 }
4769
4770 if (order->activity == ACTIVITY_OLD_ROAD) {
4771 order->activity = ACTIVITY_GEN_ROAD;
4772 order->sub_target
4774 } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
4775 order->activity = ACTIVITY_GEN_ROAD;
4776 order->sub_target
4778 }
4779 }
4780 }
4781 } else {
4783 punit->orders.list = NULL;
4784
4785 (void) secfile_entry_lookup(loading->file, "%s.orders_index", unitstr);
4786 (void) secfile_entry_lookup(loading->file, "%s.orders_repeat", unitstr);
4787 (void) secfile_entry_lookup(loading->file, "%s.orders_vigilant", unitstr);
4788 (void) secfile_entry_lookup(loading->file, "%s.orders_list", unitstr);
4789 (void) secfile_entry_lookup(loading->file, "%s.dir_list", unitstr);
4790 (void) secfile_entry_lookup(loading->file, "%s.activity_list", unitstr);
4791 (void) secfile_entry_lookup(loading->file, "%s.tgt_list", unitstr);
4792 }
4793 }
4794
4795 return TRUE;
4796}
4797
4798/************************************************************************/
4803 struct player *plr)
4804{
4805 int nunits, i, plrno = player_number(plr);
4806
4807 /* Check status and return if not OK (sg_success FALSE). */
4808 sg_check_ret();
4809
4810 /* Recheck the number of units for the player. This is a copied from
4811 * sg_load_player_units(). */
4813 "player%d.nunits", plrno),
4814 "%s", secfile_error());
4815 if (!plr->is_alive && nunits > 0) {
4816 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4817 nunits = 0; /* Some old savegames may be buggy. */
4818 }
4819
4820 for (i = 0; i < nunits; i++) {
4821 int id_unit, id_trans;
4822 struct unit *punit, *ptrans;
4823
4825 "player%d.u%d.id",
4826 plrno, i);
4828 fc_assert_action(punit != NULL, continue);
4829
4831 "player%d.u%d.transported_by",
4832 plrno, i);
4833 if (id_trans == -1) {
4834 /* Not transported. */
4835 continue;
4836 }
4837
4839 fc_assert_action(id_trans == -1 || ptrans != NULL, continue);
4840
4841 if (ptrans) {
4842#ifndef FREECIV_NDEBUG
4843 bool load_success =
4844#endif
4846
4847 fc_assert_action(load_success, continue);
4848 }
4849 }
4850}
4851
4852/************************************************************************/
4856 struct player *plr)
4857{
4858 int plrno = player_number(plr);
4859
4860 /* Check status and return if not OK (sg_success FALSE). */
4861 sg_check_ret();
4862
4863 /* Toss any existing attribute_block (should not exist) */
4864 if (plr->attribute_block.data) {
4866 plr->attribute_block.data = NULL;
4867 }
4868
4869 /* This is a big heap of opaque data for the client, check everything! */
4871 loading->file, 0, "player%d.attribute_v2_block_length", plrno);
4872
4873 if (0 > plr->attribute_block.length) {
4874 log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
4875 plr->attribute_block.length);
4876 plr->attribute_block.length = 0;
4877 } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
4878 log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
4880 plr->attribute_block.length = 0;
4881 } else if (0 < plr->attribute_block.length) {
4882 int part_nr, parts;
4883 int quoted_length;
4884 char *quoted;
4885#ifndef FREECIV_NDEBUG
4886 size_t actual_length;
4887#endif
4888
4891 "player%d.attribute_v2_block_length_quoted",
4892 plrno), "%s", secfile_error());
4895 "player%d.attribute_v2_block_parts", plrno),
4896 "%s", secfile_error());
4897
4899 quoted[0] = '\0';
4901 for (part_nr = 0; part_nr < parts; part_nr++) {
4902 const char *current =
4904 "player%d.attribute_v2_block_data.part%d",
4905 plrno, part_nr);
4906 if (!current) {
4907 log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
4908 break;
4909 }
4910 log_debug("attribute_v2_block_length_quoted=%d"
4911 " have=" SIZE_T_PRINTF " part=" SIZE_T_PRINTF,
4912 quoted_length, strlen(quoted), strlen(current));
4913 fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
4914 strcat(quoted, current);
4915 }
4917 "attribute_v2_block_length_quoted=%d"
4918 " actual=" SIZE_T_PRINTF,
4920
4921#ifndef FREECIV_NDEBUG
4923#endif
4925 plr->attribute_block.data,
4926 plr->attribute_block.length);
4928 free(quoted);
4929 }
4930}
4931
4932/************************************************************************/
4936 struct player *plr)
4937{
4938 int plrno = player_number(plr);
4939 int total_ncities =
4941 "player%d.dc_total", plrno);
4942 int i;
4943 bool someone_alive = FALSE;
4944
4945 /* Check status and return if not OK (sg_success FALSE). */
4946 sg_check_ret();
4947
4950 if (pteam_member->is_alive) {
4952 break;
4953 }
4955
4956 if (!someone_alive) {
4957 /* Reveal all for completely dead teams. */
4959 }
4960 }
4961
4962 if (!plr->is_alive
4963 || -1 == total_ncities
4964 || !game.info.fogofwar
4966 "game.save_private_map")) {
4967 /* We have:
4968 * - a dead player;
4969 * - fogged cities are not saved for any reason;
4970 * - a savegame with fog of war turned off;
4971 * - or game.save_private_map is not set to FALSE in the scenario /
4972 * savegame. The players private knowledge is set to be what they could
4973 * see without fog of war. */
4974 whole_map_iterate(&(wld.map), ptile) {
4975 if (map_is_known(ptile, plr)) {
4976 struct city *pcity = tile_city(ptile);
4977
4978 update_player_tile_last_seen(plr, ptile);
4979 update_player_tile_knowledge(plr, ptile);
4980
4981 if (NULL != pcity) {
4982 update_dumb_city(plr, pcity);
4983 }
4984 }
4986
4987 /* Nothing more to do; */
4988 return;
4989 }
4990
4991 /* Load player map (terrain). */
4992 LOAD_MAP_CHAR(ch, ptile,
4993 map_get_player_tile(ptile, plr)->terrain
4994 = char2terrain(ch), loading->file,
4995 "player%d.map_t%04d", plrno);
4996
4997 /* Load player map (resources). */
4998 LOAD_MAP_CHAR(ch, ptile,
4999 map_get_player_tile(ptile, plr)->resource
5000 = char2resource(ch), loading->file,
5001 "player%d.map_res%04d", plrno);
5002
5003 if (loading->version >= 30) {
5004 /* 2.6.0 or newer */
5005
5006 /* Load player map (extras). */
5007 halfbyte_iterate_extras(j, loading->extra.size) {
5008 LOAD_MAP_CHAR(ch, ptile,
5010 ch, loading->extra.order + 4 * j),
5011 loading->file, "player%d.map_e%02d_%04d", plrno, j);
5013 } else {
5014 /* Load player map (specials). */
5015 halfbyte_iterate_special(j, loading->special.size) {
5016 LOAD_MAP_CHAR(ch, ptile,
5017 sg_special_set_dbv(ptile,
5018 &(map_get_player_tile(ptile, plr)->extras),
5019 ch, loading->special.order + 4 * j, FALSE),
5020 loading->file, "player%d.map_spe%02d_%04d", plrno, j);
5022
5023 /* Load player map (bases). */
5024 halfbyte_iterate_bases(j, loading->base.size) {
5025 LOAD_MAP_CHAR(ch, ptile,
5027 ch, loading->base.order + 4 * j),
5028 loading->file, "player%d.map_b%02d_%04d", plrno, j);
5030
5031 /* Load player map (roads). */
5032 if (loading->version >= 20) {
5033 /* 2.5.0 or newer */
5034 halfbyte_iterate_roads(j, loading->road.size) {
5035 LOAD_MAP_CHAR(ch, ptile,
5037 ch, loading->road.order + 4 * j),
5038 loading->file, "player%d.map_r%02d_%04d", plrno, j);
5040 }
5041 }
5042
5044 /* Load player map (border). */
5045 int x, y;
5046
5047 for (y = 0; y < wld.map.ysize; y++) {
5048 const char *buffer
5049 = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
5050 plrno, y);
5051 const char *buffer2
5052 = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
5053 plrno, y);
5054 const char *ptr = buffer;
5055 const char *ptr2 = buffer2;
5056
5057 sg_failure_ret(NULL != buffer,
5058 "Savegame corrupt - map line %d not found.", y);
5059 for (x = 0; x < wld.map.xsize; x++) {
5060 char token[TOKEN_SIZE];
5061 char token2[TOKEN_SIZE];
5062 int number;
5063 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
5064
5065 scanin(&ptr, ",", token, sizeof(token));
5066 sg_failure_ret('\0' != token[0],
5067 "Savegame corrupt - map size not correct.");
5068 if (strcmp(token, "-") == 0) {
5069 map_get_player_tile(ptile, plr)->owner = NULL;
5070 } else {
5071 sg_failure_ret(str_to_int(token, &number),
5072 "Savegame corrupt - got tile owner=%s in (%d, %d).",
5073 token, x, y);
5074 map_get_player_tile(ptile, plr)->owner = player_by_number(number);
5075 }
5076
5077 if (loading->version >= 30) {
5078 scanin(&ptr2, ",", token2, sizeof(token2));
5079 sg_failure_ret('\0' != token2[0],
5080 "Savegame corrupt - map size not correct.");
5081 if (strcmp(token2, "-") == 0) {
5082 map_get_player_tile(ptile, plr)->extras_owner = NULL;
5083 } else {
5085 "Savegame corrupt - got extras owner=%s in (%d, %d).",
5086 token, x, y);
5087 map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
5088 }
5089 } else {
5091 = map_get_player_tile(ptile, plr)->owner;
5092 }
5093 }
5094 }
5095 }
5096
5097 /* Load player map (update time). */
5098 for (i = 0; i < 4; i++) {
5099 /* put 4-bit segments of 16-bit "updated" field */
5100 if (i == 0) {
5101 LOAD_MAP_CHAR(ch, ptile,
5102 map_get_player_tile(ptile, plr)->last_updated
5103 = ascii_hex2bin(ch, i),
5104 loading->file, "player%d.map_u%02d_%04d", plrno, i);
5105 } else {
5106 LOAD_MAP_CHAR(ch, ptile,
5107 map_get_player_tile(ptile, plr)->last_updated
5108 |= ascii_hex2bin(ch, i),
5109 loading->file, "player%d.map_u%02d_%04d", plrno, i);
5110 }
5111 }
5112
5113 /* Load player map known cities. */
5114 for (i = 0; i < total_ncities; i++) {
5115 struct vision_site *pdcity;
5116 char buf[32];
5117 fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
5118
5122 pdcity);
5124 } else {
5125 /* Error loading the data. */
5126 log_sg("Skipping seen city %d for player %d.", i, plrno);
5127 if (pdcity != NULL) {
5129 }
5130 }
5131 }
5132
5133 /* Repair inconsistent player maps. */
5134 whole_map_iterate(&(wld.map), ptile) {
5135 if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
5136 struct city *pcity = tile_city(ptile);
5137
5138 update_player_tile_knowledge(plr, ptile);
5139 reality_check_city(plr, ptile);
5140
5141 if (NULL != pcity) {
5142 update_dumb_city(plr, pcity);
5143 }
5144 } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
5145 /* Non fogged borders aren't loaded. See hrm Bug #879084 */
5146 struct player_tile *plrtile = map_get_player_tile(ptile, plr);
5147
5148 plrtile->owner = tile_owner(ptile);
5149 }
5151}
5152
5153/************************************************************************/
5157 struct player *plr,
5158 struct vision_site *pdcity,
5159 const char *citystr)
5160{
5161 const char *str;
5162 int i, id, size;
5163 citizens city_size;
5164 int nat_x, nat_y;
5165 const char *stylename;
5166 const char *vname;
5167
5169 citystr),
5170 FALSE, "%s", secfile_error());
5172 citystr),
5173 FALSE, "%s", secfile_error());
5174 pdcity->location = native_pos_to_tile(&(wld.map), nat_x, nat_y);
5175 sg_warn_ret_val(NULL != pdcity->location, FALSE,
5176 "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
5177
5178 sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
5179 citystr),
5180 FALSE, "%s", secfile_error());
5181 pdcity->owner = player_by_number(id);
5182 sg_warn_ret_val(NULL != pdcity->owner, FALSE,
5183 "%s has invalid owner (%d); skipping.", citystr, id);
5184
5186 "%s.id", citystr),
5187 FALSE, "%s", secfile_error());
5189 "%s has invalid id (%d); skipping.", citystr, id);
5190
5192 "%s.size", citystr),
5193 FALSE, "%s", secfile_error());
5194 city_size = (citizens)size; /* set the correct type */
5195 sg_warn_ret_val(size == (int)city_size, FALSE,
5196 "Invalid city size: %d; set to %d.", size, city_size);
5197 vision_site_size_set(pdcity, city_size);
5198
5199 /* Initialise list of improvements */
5200 BV_CLR_ALL(pdcity->improvements);
5201 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
5203 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
5204 "Invalid length of '%s.improvements' ("
5205 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5206 citystr, strlen(str), loading->improvement.size);
5207 for (i = 0; i < loading->improvement.size; i++) {
5208 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
5209 "Undefined value '%c' within '%s.improvements'.",
5210 str[i], citystr)
5211
5212 if (str[i] == '1') {
5213 struct impr_type *pimprove =
5214 improvement_by_rule_name(loading->improvement.order[i]);
5215
5216 if (pimprove) {
5217 BV_SET(pdcity->improvements, improvement_index(pimprove));
5218 }
5219 }
5220 }
5221
5223 "%s.name", citystr);
5224
5225 if (vname != NULL) {
5226 pdcity->name = fc_strdup(vname);
5227 }
5228
5230 "%s.occupied", citystr);
5232 "%s.walls", citystr);
5234 "%s.happy", citystr);
5236 "%s.unhappy", citystr);
5238 "%s.style", citystr);
5239 if (stylename != NULL) {
5241 } else {
5242 pdcity->style = 0;
5243 }
5244 if (pdcity->style < 0) {
5245 pdcity->style = 0;
5246 }
5247
5248 pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
5249 "%s.city_image", citystr);
5250
5251 pdcity->capital = CAPITAL_NOT;
5252
5253 return TRUE;
5254}
5255
5256/* =======================================================================
5257 * Load the researches.
5258 * ======================================================================= */
5259
5260/************************************************************************/
5264{
5265 struct research *presearch;
5266 int count;
5267 int number;
5268 const char *str;
5269 int i, j;
5270 bool got_tech;
5271
5272 /* Check status and return if not OK (sg_success FALSE). */
5273 sg_check_ret();
5274
5275 /* Initialize all researches. */
5279
5280 /* May be unsaved (e.g. scenario case). */
5281 count = secfile_lookup_int_default(loading->file, 0, "research.count");
5282 for (i = 0; i < count; i++) {
5284 "research.r%d.number", i),
5285 "%s", secfile_error());
5286 presearch = research_by_number(number);
5288 "Invalid research number %d in 'research.r%d.number'",
5289 number, i);
5290
5291 presearch->tech_goal = technology_load(loading->file,
5292 "research.r%d.goal", i);
5294 &presearch->techs_researched,
5295 "research.r%d.techs", i),
5296 "%s", secfile_error());
5298 &presearch->future_tech,
5299 "research.r%d.futuretech", i),
5300 "%s", secfile_error());
5302 &presearch->bulbs_researched,
5303 "research.r%d.bulbs", i),
5304 "%s", secfile_error());
5306 &presearch->bulbs_researching_saved,
5307 "research.r%d.bulbs_before", i),
5308 "%s", secfile_error());
5309 presearch->researching_saved = technology_load(loading->file,
5310 "research.r%d.saved", i);
5311 presearch->researching = technology_load(loading->file,
5312 "research.r%d.now", i);
5314 &got_tech,
5315 "research.r%d.got_tech", i),
5316 "%s", secfile_error());
5317 if (got_tech) {
5318 presearch->free_bulbs = presearch->bulbs_researched;
5319 }
5320
5321 str = secfile_lookup_str(loading->file, "research.r%d.done", i);
5322 sg_failure_ret(str != NULL, "%s", secfile_error());
5323 sg_failure_ret(strlen(str) == loading->technology.size,
5324 "Invalid length of 'research.r%d.done' ("
5325 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5326 i, strlen(str), loading->technology.size);
5327 for (j = 0; j < loading->technology.size; j++) {
5328 sg_failure_ret(str[j] == '1' || str[j] == '0',
5329 "Undefined value '%c' within 'research.r%d.done'.",
5330 str[j], i);
5331
5332 if (str[j] == '1') {
5333 struct advance *padvance =
5334 advance_by_rule_name(loading->technology.order[j]);
5335
5336 if (padvance) {
5338 TECH_KNOWN);
5339 }
5340 }
5341 }
5342 }
5343
5344 /* In case of tech_leakage, we can update research only after all the
5345 * researches have been loaded */
5349}
5350
5351/* =======================================================================
5352 * Load the event cache. Should be the last thing to do.
5353 * ======================================================================= */
5354
5355/************************************************************************/
5359{
5360 /* Check status and return if not OK (sg_success FALSE). */
5361 sg_check_ret();
5362
5363 event_cache_load(loading->file, "event_cache");
5364}
5365
5366/* =======================================================================
5367 * Load the open treaties
5368 * ======================================================================= */
5369
5370/************************************************************************/
5374{
5375 int tidx;
5376 const char *plr0;
5377
5378 /* Check status and return if not OK (sg_success FALSE). */
5379 sg_check_ret();
5380
5381 for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, NULL,
5382 "treaty%d.plr0", tidx)) != NULL ;
5383 tidx++) {
5384 const char *plr1;
5385 const char *ct;
5386 int cidx;
5387 struct player *p0, *p1;
5388
5389 plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
5390
5391 p0 = player_by_name(plr0);
5392 p1 = player_by_name(plr1);
5393
5394 if (p0 == NULL || p1 == NULL) {
5395 log_error("Treaty between unknown players %s and %s", plr0, plr1);
5396 } else {
5397 struct Treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
5398
5401
5402 for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, NULL,
5403 "treaty%d.clause%d.type",
5404 tidx, cidx)) != NULL ;
5405 cidx++ ) {
5407 const char *plrx;
5408
5409 if (!clause_type_is_valid(type)) {
5410 log_error("Invalid clause type \"%s\"", ct);
5411 } else {
5412 struct player *pgiver = NULL;
5413
5414 plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
5415 tidx, cidx);
5416
5417 if (!fc_strcasecmp(plrx, plr0)) {
5418 pgiver = p0;
5419 } else if (!fc_strcasecmp(plrx, plr1)) {
5420 pgiver = p1;
5421 } else {
5422 log_error("Clause giver %s is not participant of the treaty"
5423 "between %s and %s", plrx, plr0, plr1);
5424 }
5425
5426 if (pgiver != NULL) {
5427 int value;
5428
5429 value = secfile_lookup_int_default(loading->file, 0,
5430 "treaty%d.clause%d.value",
5431 tidx, cidx);
5432
5433 add_clause(ptreaty, pgiver, type, value, NULL);
5434 }
5435 }
5436 }
5437
5438 /* These must be after clauses have been added so that acceptance
5439 * does not get cleared by what seems like changes to the treaty. */
5441 "treaty%d.accept0", tidx);
5443 "treaty%d.accept1", tidx);
5444 }
5445 }
5446}
5447
5448/* =======================================================================
5449 * Load the history report
5450 * ======================================================================= */
5451
5452/************************************************************************/
5456{
5458 int turn;
5459
5460 /* Check status and return if not OK (sg_success FALSE). */
5461 sg_check_ret();
5462
5463 turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
5464
5465 if (turn != -2) {
5466 hist->turn = turn;
5467 }
5468
5469 if (turn + 1 >= game.info.turn) {
5470 const char *str;
5471
5472 str = secfile_lookup_str(loading->file, "history.title");
5473 sg_failure_ret(str != NULL, "%s", secfile_error());
5474 sz_strlcpy(hist->title, str);
5475 str = secfile_lookup_str(loading->file, "history.body");
5476 sg_failure_ret(str != NULL, "%s", secfile_error());
5477 sz_strlcpy(hist->body, str);
5478 }
5479}
5480
5481/* =======================================================================
5482 * Load the mapimg definitions.
5483 * ======================================================================= */
5484
5485/************************************************************************/
5488static void sg_load_mapimg(struct loaddata *loading)
5489{
5490 int mapdef_count, i;
5491
5492 /* Check status and return if not OK (sg_success FALSE). */
5493 sg_check_ret();
5494
5495 /* Clear all defined map images. */
5496 while (mapimg_count() > 0) {
5497 mapimg_delete(0);
5498 }
5499
5501 "mapimg.count");
5502 log_verbose("Saved map image definitions: %d.", mapdef_count);
5503
5504 if (0 >= mapdef_count) {
5505 return;
5506 }
5507
5508 for (i = 0; i < mapdef_count; i++) {
5509 const char *p;
5510
5511 p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
5512 if (NULL == p) {
5513 log_verbose("[Mapimg %4d] Missing definition.", i);
5514 continue;
5515 }
5516
5517 if (!mapimg_define(p, FALSE)) {
5518 log_error("Invalid map image definition %4d: %s.", i, p);
5519 }
5520
5521 log_verbose("Mapimg %4d loaded.", i);
5522 }
5523}
5524
5525/* =======================================================================
5526 * Sanity checks for loading a game.
5527 * ======================================================================= */
5528
5529/************************************************************************/
5533{
5534 int players;
5535
5536 /* Check status and return if not OK (sg_success FALSE). */
5537 sg_check_ret();
5538
5539 if (game.info.is_new_game) {
5540 /* Nothing to do for new games (or not started scenarios). */
5541 return;
5542 }
5543
5544 /* Old savegames may have maxplayers lower than current player count,
5545 * fix. */
5546 players = normal_player_count();
5547 if (game.server.max_players < players) {
5548 log_verbose("Max players lower than current players, fixing");
5549 game.server.max_players = players;
5550 }
5551
5552 /* Fix ferrying sanity */
5553 players_iterate(pplayer) {
5554 unit_list_iterate_safe(pplayer->units, punit) {
5557 log_sg("Removing %s unferried %s in %s at (%d, %d)",
5563 }
5566
5567 /* Fix stacking issues. We don't rely on the savegame preserving
5568 * alliance invariants (old savegames often did not) so if there are any
5569 * unallied units on the same tile we just bounce them. */
5570 players_iterate(pplayer) {
5572 resolve_unit_stacks(pplayer, aplayer, TRUE);
5575
5576 /* Recalculate the potential buildings for each city. Has caused some
5577 * problems with game random state.
5578 * This also changes the game state if you save the game directly after
5579 * loading it and compare the results. */
5580 players_iterate(pplayer) {
5581 /* Building advisor needs data phase open in order to work */
5582 adv_data_phase_init(pplayer, FALSE);
5583 building_advisor(pplayer);
5584 /* Close data phase again so it can be opened again when game starts. */
5585 adv_data_phase_done(pplayer);
5587
5588 /* Prevent a buggy or intentionally crafted save game from crashing
5589 * Freeciv. See hrm Bug #887748 */
5590 players_iterate(pplayer) {
5591 city_list_iterate(pplayer->cities, pcity) {
5592 worker_task_list_iterate(pcity->task_reqs, ptask) {
5593 if (!worker_task_is_sane(ptask)) {
5594 log_error("[city id: %d] Bad worker task %d.",
5595 pcity->id, ptask->act);
5596 worker_task_list_remove(pcity->task_reqs, ptask);
5597 free(ptask);
5598 ptask = NULL;
5599 }
5603
5604 /* Check worked tiles map */
5605#ifdef FREECIV_DEBUG
5606 if (loading->worked_tiles != NULL) {
5607 /* check the entire map for unused worked tiles */
5608 whole_map_iterate(&(wld.map), ptile) {
5609 if (loading->worked_tiles[ptile->index] != -1) {
5610 log_error("[city id: %d] Unused worked tile at (%d, %d).",
5611 loading->worked_tiles[ptile->index], TILE_XY(ptile));
5612 }
5614 }
5615#endif /* FREECIV_DEBUG */
5616
5617 /* Check researching technologies and goals. */
5619 int techs;
5620
5621 if (presearch->researching != A_UNSET
5622 && !is_future_tech(presearch->researching)
5623 && (valid_advance_by_number(presearch->researching) == NULL
5625 != TECH_PREREQS_KNOWN))) {
5626 log_sg(_("%s had invalid researching technology."),
5628 presearch->researching = A_UNSET;
5629 }
5630 if (presearch->tech_goal != A_UNSET
5631 && !is_future_tech(presearch->tech_goal)
5632 && (valid_advance_by_number(presearch->tech_goal) == NULL
5635 == TECH_KNOWN))) {
5636 log_sg(_("%s had invalid technology goal."),
5638 presearch->tech_goal = A_UNSET;
5639 }
5640
5642
5643 if (presearch->techs_researched != techs) {
5644 sg_regr(3000300,
5645 _("%s had finished researches count wrong."),
5647 presearch->techs_researched = techs;
5648 }
5650
5651 players_iterate(pplayer) {
5652 unit_list_iterate_safe(pplayer->units, punit) {
5654 punit->orders.list)) {
5655 log_sg("Invalid unit orders for unit %d.", punit->id);
5657 }
5660
5661 /* Check max rates (rules may have changed since saving) */
5662 players_iterate(pplayer) {
5665
5666 if (0 == strlen(server.game_identifier)
5667 || !is_base64url(server.game_identifier)) {
5668 /* This uses fc_rand(), so random state has to be initialized before. */
5669 randomize_base64url_string(server.game_identifier,
5670 sizeof(server.game_identifier));
5671 }
5672
5673 /* Check if some player has more than one of some UTYF_UNIQUE unit type */
5674 players_iterate(pplayer) {
5675 int unique_count[U_LAST];
5676
5677 memset(unique_count, 0, sizeof(unique_count));
5678
5679 unit_list_iterate(pplayer->units, punit) {
5682
5685 log_sg(_("%s has multiple units of type %s though it should be possible "
5686 "to have only one."),
5688 }
5691
5692 /* Restore game random state, just in case various initialization code
5693 * inexplicably altered the previously existing state. */
5694 if (!game.info.is_new_game) {
5695 fc_rand_set_state(loading->rstate);
5696
5697 if (loading->version < 30) {
5698 /* For older savegames we have to recalculate the score with current data,
5699 * instead of using beginning-of-turn saved scores. */
5700 players_iterate(pplayer) {
5701 calc_civ_score(pplayer);
5703 }
5704 }
5705
5706 /* At the end do the default sanity checks. */
5707 sanity_check();
5708}
struct achievement * achievement_by_rule_name(const char *name)
#define ACTION_NONE
Definition actions.h:311
void building_advisor(struct player *pplayer)
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Definition advdata.c:263
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:565
const char * ai_name(const struct ai_type *ai)
Definition ai.c:335
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:387
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:377
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:92
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:101
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:139
struct base_type * base_by_number(const Base_type_id id)
Definition base.c:76
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c:144
void dbv_clr_all(struct dbv *pdbv)
Definition bitvector.c:179
void dbv_to_bv(unsigned char *dest, const struct dbv *src)
Definition bitvector.c:235
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_CLR(bv, bit)
Definition bitvector.h:86
bool has_capability(const char *cap, const char *capstr)
Definition capability.c:77
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:1145
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3430
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2870
void city_size_set(struct city *pcity, citizens size)
Definition city.c:1180
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3357
void destroy_city_virtual(struct city *pcity)
Definition city.c:3516
int city_style_by_rule_name(const char *s)
Definition city.c:1738
#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:564
#define cities_iterate(pcity)
Definition city.h:512
#define CITY_MAP_MAX_RADIUS_SQ
Definition city.h:86
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define output_type_iterate(output)
Definition city.h:845
#define city_owner(_pcity_)
Definition city.h:563
#define FREE_WORKED_TILES
Definition city.h:882
#define MAX_CITY_SIZE
Definition city.h:106
#define city_list_iterate_end
Definition city.h:510
#define I_NEVER
Definition city.h:247
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:230
#define city_tile_iterate_end
Definition city.h:238
#define output_type_iterate_end
Definition city.h:851
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2769
bool send_city_suppression(bool now)
Definition citytools.c:2166
static void void city_freeze_workers(struct city *pcity)
Definition citytools.c:137
void city_thaw_workers(struct city *pcity)
Definition citytools.c:147
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2840
void city_refresh_vision(struct city *pcity)
Definition citytools.c:3442
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:852
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
char * techs
Definition comments.c:31
char * incite_cost
Definition comments.c:75
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:2910
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2931
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:74
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:111
struct Treaty * ptreaty
Definition diplodlg_g.h:28
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
void treaty_add(struct Treaty *ptreaty)
Definition diptreaty.c:361
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:765
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:1114
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:790
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:163
#define NO_TARGET
Definition fc_types.h:354
int Road_type_id
Definition fc_types.h:384
@ ROCO_RAILROAD
Definition fc_types.h:1253
@ ROCO_RIVER
Definition fc_types.h:1253
@ ROCO_ROAD
Definition fc_types.h:1253
int Tech_type_id
Definition fc_types.h:377
unsigned char citizens
Definition fc_types.h:388
@ RPT_POSSIBLE
Definition fc_types.h:700
int Base_type_id
Definition fc_types.h:383
int Multiplier_type_id
Definition fc_types.h:386
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:92
#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:116
void initialize_globals(void)
Definition game.c:683
struct city * game_city_by_number(int id)
Definition game.c:107
#define GAME_DEFAULT_TIMEOUTINTINC
Definition game.h:598
#define GAME_DEFAULT_SCORETURN
Definition game.h:582
#define GAME_DEFAULT_TIMEOUTINT
Definition game.h:597
#define GAME_DEFAULT_TIMEOUTINCMULT
Definition game.h:600
#define GAME_DEFAULT_TIMEOUTINC
Definition game.h:599
#define GAME_DEFAULT_RULESETDIR
Definition game.h:676
#define GAME_DEFAULT_TIMEOUTCOUNTER
Definition game.h:602
#define GAME_DEFAULT_PHASE_MODE
Definition game.h:617
struct government * government_by_rule_name(const char *name)
Definition government.c:55
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:501
void adv_city_alloc(struct city *pcity)
Definition infracache.c:488
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define log_fatal(message,...)
Definition log.h:100
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1660
#define nat_x
#define nat_y
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:641
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1866
void map_init_topology(struct civ_map *nmap)
Definition map.c:303
void main_map_allocate(void)
Definition map.c:519
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:456
int map_startpos_count(void)
Definition map.c:1853
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:443
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1643
#define MAP_INDEX_SIZE
Definition map.h:137
#define whole_map_iterate(_map, _tile)
Definition map.h:545
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:157
#define whole_map_iterate_end
Definition map.h:554
@ MAPGEN_SCENARIO
Definition map_types.h:47
void assign_continent_numbers(void)
void player_map_init(struct player *pplayer)
Definition maphand.c:1221
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1467
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2207
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:894
bool send_tile_suppression(bool now)
Definition maphand.c:475
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:345
void map_know_and_see_all(struct player *pplayer)
Definition maphand.c:1196
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1398
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2220
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1178
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:920
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1159
void map_calculate_borders(void)
Definition maphand.c:2373
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1632
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1382
bool mapimg_define(const char *maparg, bool check)
Definition mapimg.c:769
bool mapimg_delete(int id)
Definition mapimg.c:1204
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:319
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:444
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:132
char * lines
Definition packhand.c:131
int len
Definition packhand.c:127
bool player_slot_is_used(const struct player_slot *pslot)
Definition player.c:448
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
struct player * player_by_number(const int player_id)
Definition player.c:849
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1476
int player_count(void)
Definition player.c:817
int player_slot_count(void)
Definition player.c:418
struct player_slot * player_slot_by_number(int player_id)
Definition player.c:463
int player_number(const struct player *pplayer)
Definition player.c:837
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Definition player.c:159
const char * player_name(const struct player *pplayer)
Definition player.c:895
int player_slot_max_used_number(void)
Definition player.c:476
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
int player_slot_index(const struct player_slot *pslot)
Definition player.c:426
struct player * player_by_name(const char *name)
Definition player.c:881
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1990
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
int player_index(const struct player *pplayer)
Definition player.c:829
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Definition player.c:861
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
struct player_slot * slots
Definition player.c:51
#define players_iterate_end
Definition player.h:537
dipl_reason
Definition player.h:190
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition player.h:192
@ DIPL_ALLIANCE_PROBLEM_US
Definition player.h:192
#define players_iterate(_pplayer)
Definition player.h:532
#define MAX_ATTRIBUTE_BLOCK
Definition player.h:221
#define player_list_iterate(playerlist, pplayer)
Definition player.h:555
static bool is_barbarian(const struct player *pplayer)
Definition player.h:489
#define player_slots_iterate(_pslot)
Definition player.h:523
#define is_ai(plr)
Definition player.h:230
#define player_list_iterate_end
Definition player.h:557
#define players_iterate_alive_end
Definition player.h:547
#define player_slots_iterate_end
Definition player.h:527
#define players_iterate_alive(_pplayer)
Definition player.h:542
void server_player_set_name(struct player *pplayer, const char *name)
Definition plrhand.c:2267
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Definition plrhand.c:1893
int normal_player_count(void)
Definition plrhand.c:3204
void player_limit_to_max_rates(struct player *pplayer)
Definition plrhand.c:2056
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:2452
void set_shuffled_players(int *shuffled_players)
Definition plrhand.c:2402
void player_delegation_set(struct player *pplayer, const char *username)
Definition plrhand.c:3250
void shuffle_players(void)
Definition plrhand.c:2377
void server_remove_player(struct player *pplayer)
Definition plrhand.c:1942
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Definition plrhand.c:1618
void assign_player_colors(void)
Definition plrhand.c:1733
void fit_nationset_to_players(void)
Definition plrhand.c:2658
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,...)
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str(const struct section_file *secfile, 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 entry * secfile_entry_by_path(const struct section_file *secfile, 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_,...)
struct history_report * history_report_get(void)
Definition report.c:1824
bool are_reqs_active(const struct req_context *context, const struct player *other_player, 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:668
const char * research_name_translation(const struct research *presearch)
Definition research.c:156
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:637
struct research * research_by_number(int number)
Definition research.c:118
int recalculate_techs_researched(const struct research *presearch)
Definition research.c:1345
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
void research_update(struct research *presearch)
Definition research.c:501
#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:74
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, char *path,...)
Definition rgbcolor.c:90
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 ruleset.c:9358
#define sanity_check()
Definition sanitycheck.h:43
#define sanity_check_city(x)
Definition sanitycheck.h:41
struct extra_type * resource_by_identifier(const char identifier)
Definition savecompat.c:306
static struct compatibility compat[]
Definition savecompat.c:105
int char2num(char ch)
Definition savecompat.c:251
void sg_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:138
enum ai_level ai_level_convert(int old_level)
int ascii_hex2bin(char ch, int halfbyte)
Definition savecompat.c:227
struct extra_type * special_extra_get(int spe)
Definition savecompat.c:292
enum tile_special_type special_by_rule_name(const char *name)
Definition savecompat.c:266
void sg_load_post_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:183
const char * special_rule_name(enum tile_special_type type)
Definition savecompat.c:282
#define sg_check_ret(...)
Definition savecompat.h:150
#define sg_warn(condition, message,...)
Definition savecompat.h:160
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:44
@ S_FARMLAND
Definition savecompat.h:34
@ S_OLD_ROAD
Definition savecompat.h:42
@ S_LAST
Definition savecompat.h:38
@ S_IRRIGATION
Definition savecompat.h:30
@ S_OLD_RAILROAD
Definition savecompat.h:43
#define hex_chars
Definition savecompat.h:205
#define sg_failure_ret_val(condition, _val, message,...)
Definition savecompat.h:184
#define sg_failure_ret(condition, message,...)
Definition savecompat.h:177
#define MAX_TRADE_ROUTES_OLD
Definition savecompat.h:222
#define sg_regr(fixversion, message,...)
Definition savecompat.h:193
@ SAVEGAME_2
Definition savecompat.h:27
#define log_sg
Definition savecompat.h:146
#define sg_warn_ret_val(condition, _val, message,...)
Definition savecompat.h:171
static void unit_ordering_apply(void)
Definition savegame2.c:834
static void sg_load_players_basic(struct loaddata *loading)
Definition savegame2.c:2687
static struct loaddata * loaddata_new(struct section_file *file)
Definition savegame2.c:471
#define ACTIVITY_OLD_POLLUTION_SG2
Definition savegame2.c:145
static void sg_load_map_known(struct loaddata *loading)
Definition savegame2.c:2623
#define halfbyte_iterate_roads_end
Definition savegame2.c:280
static struct extra_type * char2resource(char c)
Definition savegame2.c:1316
static void sg_load_map_owner(struct loaddata *loading)
Definition savegame2.c:2492
bool sg_success
Definition savecompat.c:34
#define halfbyte_iterate_extras_end
Definition savegame2.c:250
static void sg_load_map_tiles_roads(struct loaddata *loading)
Definition savegame2.c:2331
#define halfbyte_iterate_extras(e, num_extras_types)
Definition savegame2.c:245
static void sg_load_map(struct loaddata *loading)
Definition savegame2.c:2176
static enum unit_orders char2order(char order)
Definition savegame2.c:597
static int unquote_block(const char *const quoted_, void *dest, int dest_length)
Definition savegame2.c:740
static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx)
Definition savegame2.c:1227
#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath,...)
Definition savegame2.c:209
#define ACTIVITY_OLD_RAILROAD
Definition savegame2.c:144
static void sg_load_player_city_citizens(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr)
Definition savegame2.c:4042
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3643
static void sg_load_map_tiles(struct loaddata *loading)
Definition savegame2.c:2259
static char activity2char(int activity)
Definition savegame2.c:665
static void sg_load_savefile(struct loaddata *loading)
Definition savegame2.c:1428
#define ACTIVITY_OLD_FALLOUT_SG2
Definition savegame2.c:146
static bool sg_load_player_unit(struct loaddata *loading, struct player *plr, struct unit *punit, const char *unitstr)
Definition savegame2.c:4209
static void set_unit_activity_base(struct unit *punit, Base_type_id base)
Definition savegame2.c:573
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:3758
static void sg_load_settings(struct loaddata *loading)
Definition savegame2.c:2156
static void sg_bases_set_dbv(struct dbv *extras, char ch, struct base_type **idx)
Definition savegame2.c:1195
static void sg_load_player_units(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4090
#define halfbyte_iterate_special(s, num_specials_types)
Definition savegame2.c:255
void savegame2_load(struct section_file *file)
Definition savegame2.c:402
static void sg_load_researches(struct loaddata *loading)
Definition savegame2.c:5263
#define halfbyte_iterate_bases_end
Definition savegame2.c:270
static void sg_load_map_worked(struct loaddata *loading)
Definition savegame2.c:2579
static void sg_load_random(struct loaddata *loading)
Definition savegame2.c:1987
#define halfbyte_iterate_special_end
Definition savegame2.c:260
#define halfbyte_iterate_bases(b, num_bases_types)
Definition savegame2.c:265
static void sg_load_player_units_transport(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4802
static void sg_load_history(struct loaddata *loading)
Definition savegame2.c:5455
static int char2activity(char activity)
Definition savegame2.c:719
#define ORDER_OLD_BUILD_WONDER
Definition savegame2.c:288
static void sg_load_map_tiles_specials(struct loaddata *loading, bool rivers_overlay)
Definition savegame2.c:2347
#define TOKEN_SIZE
Definition savegame2.c:284
static void sg_load_script(struct loaddata *loading)
Definition savegame2.c:2046
static void sg_load_scenario(struct loaddata *loading)
Definition savegame2.c:2061
static void sg_load_ruleset(struct loaddata *loading)
Definition savegame2.c:1394
static void sg_load_game(struct loaddata *loading)
Definition savegame2.c:1838
static void sg_load_player_main(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3136
#define ACTIVITY_OLD_ROAD
Definition savegame2.c:143
static void sg_load_treaties(struct loaddata *loading)
Definition savegame2.c:5373
static void sg_extras_set_bv(bv_extras *extras, char ch, struct extra_type **idx)
Definition savegame2.c:888
static void set_unit_activity_road(struct unit *punit, Road_type_id road)
Definition savegame2.c:583
static Tech_type_id technology_load(struct section_file *file, const char *path, int plrno)
Definition savegame2.c:1354
static enum direction8 char2dir(char dir)
Definition savegame2.c:636
static void sg_load_map_tiles_resources(struct loaddata *loading)
Definition savegame2.c:2378
#define ORDER_OLD_BUILD_CITY
Definition savegame2.c:286
static struct terrain * char2terrain(char ch)
Definition savegame2.c:1331
#define ORDER_OLD_DISBAND
Definition savegame2.c:287
static void sg_load_mapimg(struct loaddata *loading)
Definition savegame2.c:5488
#define ORDER_OLD_HOMECITY
Definition savegame2.c:290
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:1058
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4855
static void sg_load_ruledata(struct loaddata *loading)
Definition savegame2.c:1814
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:921
static void sg_load_player_vision(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4935
static void worklist_load(struct section_file *file, int wlist_max_length, struct worklist *pwl, const char *path,...)
Definition savegame2.c:788
static bool sg_load_player_vision_city(struct loaddata *loading, struct player *plr, struct vision_site *pdcity, const char *citystr)
Definition savegame2.c:5156
static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx)
Definition savegame2.c:1289
static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx)
Definition savegame2.c:1258
static void sg_load_map_startpos(struct loaddata *loading)
Definition savegame2.c:2405
static void loaddata_destroy(struct loaddata *loading)
Definition savegame2.c:512
static void sg_load_players(struct loaddata *loading)
Definition savegame2.c:2944
#define ORDER_OLD_TRADE_ROUTE
Definition savegame2.c:289
static void sg_load_map_tiles_extras(struct loaddata *loading)
Definition savegame2.c:2299
static void sg_load_sanitycheck(struct loaddata *loading)
Definition savegame2.c:5532
static void sg_load_event_cache(struct loaddata *loading)
Definition savegame2.c:5358
static void sg_load_map_tiles_bases(struct loaddata *loading)
Definition savegame2.c:2315
static void sg_extras_set_dbv(struct dbv *extras, char ch, struct extra_type **idx)
Definition savegame2.c:855
#define ACTIVITY_LAST_SAVEGAME2
Definition savegame2.c:147
static int sg_order_to_action(int order, struct unit *act_unit, struct tile *tgt_tile)
Definition savegame2.c:4168
#define halfbyte_iterate_roads(r, num_roads_types)
Definition savegame2.c:275
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:4946
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
bool str_to_int(const char *str, int *pint)
Definition shared.c:517
bool is_base64url(const char *s)
Definition shared.c:318
char scanin(const char **buf, char *delimiters, char *dest, int size)
Definition shared.c:1922
void randomize_base64url_string(char *s, size_t n)
Definition shared.c:339
#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:112
Specialist_type_id specialist_index(const struct specialist *sp)
Definition specialist.c:82
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#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
void server_game_init(bool keep_ruleset_value)
Definition srv_main.c:3463
const char * aifill(int amount)
Definition srv_main.c:2465
bool game_was_started(void)
Definition srv_main.c:349
void identity_number_reserve(int id)
Definition srv_main.c:1994
struct server_arguments srvarg
Definition srv_main.c:176
void init_game_seed(void)
Definition srv_main.c:203
void update_nations_with_startpos(void)
Definition srv_main.c:2270
void server_game_free(void)
Definition srv_main.c:3487
bool accept0
Definition diptreaty.h:80
bool accept1
Definition diptreaty.h:80
struct player * first
int val
Definition traits.h:38
int mod
Definition traits.h:39
int turn
Definition city.h:246
Definition city.h:320
struct worker_task_list * task_reqs
Definition city.h:412
int turn_last_built
Definition city.h:387
enum city_wl_cancel_behavior wlcb
Definition city.h:404
int food_stock
Definition city.h:367
struct built_status built[B_LAST]
Definition city.h:394
struct player * original
Definition city.h:324
int history
Definition city.h:410
bool did_sell
Definition city.h:380
int id
Definition city.h:326
int last_turns_shield_surplus
Definition city.h:392
int disbanded_shields
Definition city.h:391
int turn_plague
Definition city.h:374
bv_city_options city_options
Definition city.h:403
bool was_happy
Definition city.h:381
enum city_acquire_type acquire_t
Definition city.h:329
int turn_founded
Definition city.h:386
int airlift
Definition city.h:378
int caravan_shields
Definition city.h:390
bool did_buy
Definition city.h:379
struct trade_route_list * routes
Definition city.h:344
int anarchy
Definition city.h:384
struct worklist worklist
Definition city.h:401
struct universal production
Definition city.h:396
citizens * nationality
Definition city.h:341
int steal
Definition city.h:414
int before_change_shields
Definition city.h:389
int style
Definition city.h:327
bool had_famine
Definition city.h:382
bool synced
Definition city.h:448
citizens specialists[SP_MAX]
Definition city.h:336
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
struct vision * vision
Definition city.h:455
struct city::@17::@19 server
struct universal changed_from
Definition city.h:399
struct unit_list * units_supported
Definition city.h:406
int rapture
Definition city.h:385
bool last_updated_year
Definition game.h:240
float turn_change_time
Definition game.h:222
bool vision_reveal_tiles
Definition game.h:204
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:238
struct packet_game_info info
Definition game.h:89
int timeoutcounter
Definition game.h:211
char rulesetdir[MAX_LEN_NAME]
Definition game.h:242
int scoreturn
Definition game.h:229
randseed seed
Definition game.h:231
struct packet_scenario_info scenario
Definition game.h:87
int timeoutint
Definition game.h:207
unsigned revealmap
Definition game.h:181
char orig_game_version[MAX_LEN_NAME]
Definition game.h:225
bool foggedborders
Definition game.h:151
struct civ_game::@31::@35 server
int timeoutincmult
Definition game.h:209
int timeoutinc
Definition game.h:208
int phase_mode_stored
Definition game.h:220
int max_players
Definition game.h:160
int timeoutintinc
Definition game.h:210
int xsize
Definition map_types.h:78
randseed seed
Definition map_types.h:92
int ysize
Definition map_types.h:78
bool have_resources
Definition map_types.h:108
struct civ_map::@42::@44 server
bool have_huts
Definition map_types.h:107
enum map_generator generator
Definition map_types.h:98
int changed_to_times
Definition government.h:64
const char ** order
Definition savecompat.h:54
struct section_file * file
Definition savecompat.h:48
int great_wonder_owners[B_LAST]
bool global_advances[A_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:114
struct ai_trait * traits
Definition player.h:124
enum barbarian_type barbarian_type
Definition player.h:120
int science_cost
Definition player.h:117
int love[MAX_NUM_PLAYER_SLOTS]
Definition player.h:122
int expand
Definition player.h:116
int fuzzy
Definition player.h:115
enum diplstate_type type
Definition player.h:197
int units_killed
Definition player.h:103
int landarea
Definition player.h:92
int population
Definition player.h:94
int pollution
Definition player.h:97
int wonders
Definition player.h:89
int settledarea
Definition player.h:93
int units_used
Definition player.h:106
int specialists[SP_MAX]
Definition player.h:88
int units_lost
Definition player.h:104
int angry
Definition player.h:87
int techout
Definition player.h:91
int units
Definition player.h:96
int units_built
Definition player.h:102
int content
Definition player.h:85
int happy
Definition player.h:84
int spaceship
Definition player.h:101
int culture
Definition player.h:107
int unhappy
Definition player.h:86
int cities
Definition player.h:95
int literacy
Definition player.h:98
int techs
Definition player.h:90
struct player * extras_owner
Definition maphand.h:35
struct player * owner
Definition maphand.h:34
struct city_list * cities
Definition player.h:279
int bulbs_last_turn
Definition player.h:349
struct player_ai ai_common
Definition player.h:286
bv_plr_flags flags
Definition player.h:290
bool is_male
Definition player.h:255
int wonders[B_LAST]
Definition player.h:303
bool unassigned_ranked
Definition player.h:253
struct government * target_government
Definition player.h:257
char username[MAX_LEN_NAME]
Definition player.h:250
int revolution_finishes
Definition player.h:271
int nturns_idle
Definition player.h:263
struct government * government
Definition player.h:256
struct team * team
Definition player.h:259
int turns_alive
Definition player.h:264
struct unit_list * units
Definition player.h:280
char ranked_username[MAX_LEN_NAME]
Definition player.h:252
int huts
Definition player.h:347
bool is_alive
Definition player.h:266
bv_player real_embassy
Definition player.h:275
struct player_economic economic
Definition player.h:282
struct player_spaceship spaceship
Definition player.h:284
struct attribute_block_s attribute_block
Definition player.h:305
struct player_score score
Definition player.h:281
struct multiplier_value multipliers[MAX_NUM_MULTIPLIERS]
Definition player.h:312
struct nation_type * nation
Definition player.h:258
struct nation_style * style
Definition player.h:277
bool border_vision
Definition player.h:325
bool phase_done
Definition player.h:261
struct player::@70::@72 server
int history
Definition player.h:314
char orig_username[MAX_LEN_NAME]
Definition player.h:345
int last_war_action
Definition player.h:268
bool unassigned_user
Definition player.h:251
const struct tile * tile
char metaserver_addr[256]
Definition srv_main.h:29
char serverid[256]
Definition srv_main.h:49
Definition map.c:41
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
enum unit_orders order
Definition unit.h:93
Definition unit.h:138
int length
Definition unit.h:195
int upkeep[O_LAST]
Definition unit.h:148
bool has_orders
Definition unit.h:193
struct unit::@80 orders
enum action_decision action_decision_want
Definition unit.h:202
int battlegroup
Definition unit.h:191
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
int ord_city
Definition unit.h:242
bool moved
Definition unit.h:173
int ord_map
Definition unit.h:241
int index
Definition unit.h:195
struct vision * vision
Definition unit.h:244
bool vigilant
Definition unit.h:197
int hp
Definition unit.h:151
int fuel
Definition unit.h:153
struct extra_type * changed_from_target
Definition unit.h:170
int current_form_turn
Definition unit.h:208
enum direction8 facing
Definition unit.h:142
struct unit::@81::@84 server
struct extra_type * activity_target
Definition unit.h:164
int activity_count
Definition unit.h:162
struct unit_order * list
Definition unit.h:198
enum unit_activity changed_from
Definition unit.h:168
struct player * nationality
Definition unit.h:144
bool repeat
Definition unit.h:196
int homecity
Definition unit.h:146
bool paradropped
Definition unit.h:174
bool done_moving
Definition unit.h:181
int birth_turn
Definition unit.h:207
struct tile * goto_tile
Definition unit.h:155
struct tile * action_decision_tile
Definition unit.h:203
int veteran
Definition unit.h:152
int changed_from_count
Definition unit.h:169
enum server_side_agent ssa_controller
Definition unit.h:172
enum universals_n kind
Definition fc_types.h:902
struct civ_map map
int city_style(struct city *pcity)
Definition style.c:241
struct nation_style * style_by_rule_name(const char *name)
Definition style.c:117
struct nation_style * style_by_number(int id)
Definition style.c:88
const char * style_rule_name(const struct nation_style *pstyle)
Definition style.c:108
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:900
#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:175
bool team_add_player(struct player *pplayer, struct team *pteam)
Definition team.c:467
struct team * team_new(struct team_slot *tslot)
Definition team.c:317
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
struct advance * advance_by_rule_name(const char *name)
Definition tech.c:200
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#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:1094
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:186
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Definition terrain.c:255
#define terrain_type_iterate(_p)
Definition terrain.h:373
#define T_UNKNOWN
Definition terrain.h:57
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:195
#define terrain_type_iterate_end
Definition terrain.h:379
#define RESOURCE_NONE_IDENTIFIER
Definition terrain.h:47
#define RESOURCE_NULL_IDENTIFIER
Definition terrain.h:46
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:215
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1033
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
bool tile_set_label(struct tile *ptile, const char *label)
Definition tile.c:1095
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Definition tile.c:349
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:106
#define tile_index(_pt_)
Definition tile.h:88
#define tile_worked(_tile)
Definition tile.h:114
#define tile_terrain(_tile)
Definition tile.h:110
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
#define tile_owner(_tile)
Definition tile.h:96
struct goods_type * goods_by_number(Goods_type_id id)
void free_unit_orders(struct unit *punit)
Definition unit.c:1769
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2370
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1088
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2441
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:841
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1105
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1624
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2649
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1729
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1255
#define unit_tile(_pu)
Definition unit.h:397
#define BATTLEGROUP_NONE
Definition unit.h:190
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:396
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:1394
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:4840
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1221
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1767
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2625
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_type_iterate(_p)
Definition unittype.h:855
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:862
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