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