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