Freeciv-3.3
Loading...
Searching...
No Matches
savegame2.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/*
15 This file includes the definition of a new savegame format introduced with
16 2.3.0. It is defined by the mandatory option '+version2'. The main load
17 function checks if this option is present. If not, the old (pre-2.3.0)
18 loading routines are used.
19 The format version is also saved in the settings section of the savefile, as an
20 integer (savefile.version). The integer is used to determine the version
21 of the savefile.
22
23 Structure of this file:
24
25 - The real work is done by savegame2_load().
26 This function call all submodules (settings, players, etc.)
27
28 - The remaining part of this file is split into several sections:
29 * helper functions
30 * load functions for all submodules (and their subsubmodules)
31
32 - If possible, all functions for load submodules should exit in
33 pairs named sg_load_<submodule>. If one is not
34 needed please add a comment why.
35
36 - The submodules can be further divided as:
37 sg_load_<submodule>_<subsubmodule>
38
39 - If needed (due to static variables in the *.c files) these functions
40 can be located in the corresponding source files (as done for the settings
41 and the event_cache).
42
43 Loading a savegame:
44
45 - The status of the process is saved within the static variable
46 'sg_success'. This variable is set to TRUE within savegame2_load().
47 If you encounter an error use sg_failure_*() to set it to FALSE and
48 return an error message. Furthermore, sg_check_* should be used at the
49 start of each (submodule) function to return if previous functions failed.
50
51 - While the loading process dependencies between different modules exits.
52 They can be handled within the struct loaddata *loading which is used as
53 first argument for all sg_load_*() function. Please indicate the
54 dependencies within the definition of this struct.
55
56*/
57
58#ifdef HAVE_CONFIG_H
59#include <fc_config.h>
60#endif
61
62#include <ctype.h>
63#include <stdarg.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67
68/* utility */
69#include "bitvector.h"
70#include "fcintl.h"
71#include "idex.h"
72#include "log.h"
73#include "mem.h"
74#include "rand.h"
75#include "registry.h"
76#include "shared.h"
77#include "support.h" /* bool type */
78#include "timing.h"
79
80/* common */
81#include "achievements.h"
82#include "ai.h"
83#include "bitvector.h"
84#include "capability.h"
85#include "citizens.h"
86#include "city.h"
87#include "game.h"
88#include "government.h"
89#include "map.h"
90#include "mapimg.h"
91#include "movement.h"
92#include "multipliers.h"
93#include "packets.h"
94#include "research.h"
95#include "rgbcolor.h"
96#include "specialist.h"
97#include "unit.h"
98#include "unitlist.h"
99#include "version.h"
100
101/* server */
102#include "barbarian.h"
103#include "citizenshand.h"
104#include "citytools.h"
105#include "cityturn.h"
106#include "diplhand.h"
107#include "maphand.h"
108#include "meta.h"
109#include "notify.h"
110#include "plrhand.h"
111#include "report.h"
112#include "ruleload.h"
113#include "sanitycheck.h"
114#include "savecompat.h"
115#include "score.h"
116#include "settings.h"
117#include "spacerace.h"
118#include "srv_main.h"
119#include "stdinhand.h"
120#include "techtools.h"
121#include "unittools.h"
122
123/* server/advisors */
124#include "advdata.h"
125#include "advbuilding.h"
126#include "infracache.h"
127
128/* server/generator */
129#include "mapgen.h"
130#include "mapgen_utils.h"
131
132/* server/scripting */
133#include "script_server.h"
134
135/* ai */
136#include "aitraits.h"
137#include "difficulty.h"
138
139#include "savegame2.h"
140
141extern bool sg_success;
142
143#define ACTIVITY_OLD_ROAD (ACTIVITY_LAST + 1)
144#define ACTIVITY_OLD_RAILROAD (ACTIVITY_LAST + 2)
145#define ACTIVITY_OLD_POLLUTION_SG2 (ACTIVITY_OLD_RAILROAD + 1)
146#define ACTIVITY_OLD_FALLOUT_SG2 (ACTIVITY_OLD_POLLUTION_SG2 + 1)
147#define ACTIVITY_LAST_SAVEGAME2 (ACTIVITY_OLD_FALLOUT_SG2 + 1)
148
149/*
150 * This loops over the entire map to save data. It collects all the data of
151 * a line using GET_XY_CHAR and then executes the macro SECFILE_INSERT_LINE.
152 *
153 * Parameters:
154 * ptile: current tile within the line (used by GET_XY_CHAR)
155 * GET_XY_CHAR: macro returning the map character for each position
156 * secfile: a secfile struct
157 * secpath, ...: path as used for sprintf() with arguments; the last item
158 * will be the y coordinate
159 * Example:
160 * SAVE_MAP_CHAR(ptile, terrain2char(ptile->terrain), file, "map.t%04d");
161 */
162#define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath, ...) \
163{ \
164 char _line[MAP_NATIVE_WIDTH + 1]; \
165 int _nat_x, _nat_y; \
166 \
167 for (_nat_y = 0; _nat_y < MAP_NATIVE_HEIGHT; _nat_y++) { \
168 for (_nat_x = 0; _nat_x < MAP_NATIVE_WIDTH; _nat_x++) { \
169 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
170 fc_assert_action(ptile != NULL, continue); \
171 _line[_nat_x] = (GET_XY_CHAR); \
172 sg_failure_ret(fc_isprint(_line[_nat_x] & 0x7f), \
173 "Trying to write invalid map data at position " \
174 "(%d, %d) for path %s: '%c' (%d)", _nat_x, _nat_y, \
175 secpath, _line[_nat_x], _line[_nat_x]); \
176 } \
177 _line[MAP_NATIVE_WIDTH] = '\0'; \
178 secfile_insert_str(secfile, _line, secpath, ## __VA_ARGS__, _nat_y); \
179 } \
180}
181
182/*
183 * This loops over the entire map to load data. It inputs a line of data
184 * using the macro SECFILE_LOOKUP_LINE and then loops using the macro
185 * SET_XY_CHAR to load each char into the map at (map_x, map_y). Internal
186 * variables ch, map_x, map_y, nat_x, and nat_y are allocated within the
187 * macro but definable by the caller.
188 *
189 * Parameters:
190 * ch: a variable to hold a char (data for a single position,
191 * used by SET_XY_CHAR)
192 * ptile: current tile within the line (used by SET_XY_CHAR)
193 * SET_XY_CHAR: macro to load the map character at each (map_x, map_y)
194 * secfile: a secfile struct
195 * secpath, ...: path as used for sprintf() with arguments; the last item
196 * will be the y coordinate
197 * Example:
198 * LOAD_MAP_CHAR(ch, ptile,
199 * map_get_player_tile(ptile, plr)->terrain
200 * = char2terrain(ch), file, "player%d.map_t%04d", plrno);
201 *
202 * Note: some (but not all) of the code this is replacing used to skip over
203 * lines that did not exist. This allowed for backward-compatibility.
204 * We could add another parameter that specified whether it was OK to
205 * skip the data, but there's not really much advantage to exiting
206 * early in this case. Instead, we let any map data type to be empty,
207 * and just print an informative warning message about it.
208 */
209#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath, ...) \
210{ \
211 int _nat_x, _nat_y; \
212 bool _printed_warning = FALSE; \
213 for (_nat_y = 0; _nat_y < MAP_NATIVE_HEIGHT; _nat_y++) { \
214 const char *_line = secfile_lookup_str(secfile, secpath, \
215 ## __VA_ARGS__, _nat_y); \
216 if (NULL == _line) { \
217 char buf[64]; \
218 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
219 log_verbose("Line not found='%s'", buf); \
220 _printed_warning = TRUE; \
221 continue; \
222 } else if (strlen(_line) != MAP_NATIVE_WIDTH) { \
223 char buf[64]; \
224 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
225 log_verbose("Line too short (expected %d got " SIZE_T_PRINTF \
226 ")='%s'", MAP_NATIVE_WIDTH, strlen(_line), buf); \
227 _printed_warning = TRUE; \
228 continue; \
229 } \
230 for (_nat_x = 0; _nat_x < MAP_NATIVE_WIDTH; _nat_x++) { \
231 const char ch = _line[_nat_x]; \
232 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
233 (SET_XY_CHAR); \
234 } \
235 } \
236 if (_printed_warning) { \
237 /* TRANS: Minor error message. */ \
238 log_sg(_("Saved game contains incomplete map data. This can" \
239 " happen with old saved games, or it may indicate an" \
240 " invalid saved game file. Proceed at your own risk.")); \
241 } \
242}
243
244/* Iterate on the extras half-bytes */
245#define halfbyte_iterate_extras(e, num_extras_types) \
246{ \
247 int e; \
248 for (e = 0; 4 * e < (num_extras_types); e++) {
249
250#define halfbyte_iterate_extras_end \
251 } \
252}
253
254/* Iterate on the specials half-bytes */
255#define halfbyte_iterate_special(s, num_specials_types) \
256{ \
257 enum tile_special_type s; \
258 for (s = 0; 4 * s < (num_specials_types); s++) {
259
260#define halfbyte_iterate_special_end \
261 } \
262}
263
264/* Iterate on the bases half-bytes */
265#define halfbyte_iterate_bases(b, num_bases_types) \
266{ \
267 int b; \
268 for (b = 0; 4 * b < (num_bases_types); b++) {
269
270#define halfbyte_iterate_bases_end \
271 } \
272}
273
274/* Iterate on the roads half-bytes */
275#define halfbyte_iterate_roads(r, num_roads_types) \
276{ \
277 int r; \
278 for (r = 0; 4 * r < (num_roads_types); r++) {
279
280#define halfbyte_iterate_roads_end \
281 } \
282}
283
284#define TOKEN_SIZE 10
285
286#define ORDER_OLD_BUILD_CITY (-1)
287#define ORDER_OLD_DISBAND (-2)
288#define ORDER_OLD_BUILD_WONDER (-3)
289#define ORDER_OLD_TRADE_ROUTE (-4)
290#define ORDER_OLD_HOMECITY (-5)
291
292static struct loaddata *loaddata_new(struct section_file *file);
293static void loaddata_destroy(struct loaddata *loading);
294
295static enum unit_orders char2order(char order);
296static enum direction8 char2dir(char dir);
297static char activity2char(int activity);
298static int char2activity(char activity);
299static int unquote_block(const char *const quoted_, void *dest,
300 int dest_length);
301static void worklist_load(struct section_file *file, int wlist_max_length,
302 struct worklist *pwl,
303 const char *path, ...);
304static void unit_ordering_apply(void);
305static void sg_extras_set_dbv(struct dbv *extras, char ch,
306 struct extra_type **idx);
307static void sg_extras_set_bv(bv_extras *extras, char ch,
308 struct extra_type **idx);
309static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch,
310 const enum tile_special_type *idx,
311 bool rivers_overlay);
312static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch,
313 const enum tile_special_type *idx,
314 bool rivers_overlay);
315static void sg_bases_set_dbv(struct dbv *extras, char ch, struct base_type **idx);
316static void sg_bases_set_bv(bv_extras *extras, char ch, struct base_type **idx);
317static void sg_roads_set_dbv(struct dbv *extras, char ch, struct road_type **idx);
318static void sg_roads_set_bv(bv_extras *extras, char ch, struct road_type **idx);
319static struct extra_type *char2resource(char c);
320static struct terrain *char2terrain(char ch);
321static Tech_type_id technology_load(struct section_file *file,
322 const char *path, int plrno);
323
324static void sg_load_ruleset(struct loaddata *loading);
325static void sg_load_savefile(struct loaddata *loading);
326
327static void sg_load_game(struct loaddata *loading);
328
329static void sg_load_ruledata(struct loaddata *loading);
330
331static void sg_load_random(struct loaddata *loading);
332
333static void sg_load_script(struct loaddata *loading);
334
335static void sg_load_scenario(struct loaddata *loading);
336
337static void sg_load_settings(struct loaddata *loading);
338
339static void sg_load_map(struct loaddata *loading);
340static void sg_load_map_tiles(struct loaddata *loading);
341static void sg_load_map_tiles_extras(struct loaddata *loading);
342static void sg_load_map_tiles_bases(struct loaddata *loading);
343static void sg_load_map_tiles_roads(struct loaddata *loading);
345 bool rivers_overlay);
346static void sg_load_map_tiles_resources(struct loaddata *loading);
347
348static void sg_load_map_startpos(struct loaddata *loading);
349static void sg_load_map_owner(struct loaddata *loading);
350static void sg_load_map_worked(struct loaddata *loading);
351static void sg_load_map_known(struct loaddata *loading);
352
353static void sg_load_players_basic(struct loaddata *loading);
354static void sg_load_players(struct loaddata *loading);
355static void sg_load_player_main(struct loaddata *loading,
356 struct player *plr);
357static void sg_load_player_cities(struct loaddata *loading,
358 struct player *plr);
359static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
360 struct city *pcity, const char *citystr,
361 int wlist_max_length);
363 struct player *plr,
364 struct city *pcity,
365 const char *citystr);
366static void sg_load_player_units(struct loaddata *loading,
367 struct player *plr);
368static bool sg_load_player_unit(struct loaddata *loading,
369 struct player *plr, struct unit *punit,
370 const char *unitstr);
372 struct player *plr);
373static void sg_load_player_attributes(struct loaddata *loading,
374 struct player *plr);
375static void sg_load_player_vision(struct loaddata *loading,
376 struct player *plr);
378 struct player *plr,
379 struct vision_site *pdcity,
380 const char *citystr);
381
382static void sg_load_researches(struct loaddata *loading);
383
384static void sg_load_event_cache(struct loaddata *loading);
385
386static void sg_load_treaties(struct loaddata *loading);
387
388static void sg_load_history(struct loaddata *loading);
389
390static void sg_load_mapimg(struct loaddata *loading);
391
392static void sg_load_sanitycheck(struct loaddata *loading);
393
394
395/* =======================================================================
396 * Basic load / save functions.
397 * ======================================================================= */
398
399/************************************************************************/
402void savegame2_load(struct section_file *file)
403{
404 struct loaddata *loading;
406
407 /* initialise loading */
412
413 /* Load the savegame data. */
414 /* Set up correct ruleset */
416 /* [compat] */
418 /* [savefile] */
420 /* [game] */
422 /* [scenario] */
424 /* [random] */
426 /* [settings] */
428 /* [ruledata] */
430 /* [players] (basic data) */
432 /* [map]; needs width and height loaded by [settings] */
434 /* [research] */
436 /* [player<i>] */
438 /* [event_cache] */
440 /* [treaties] */
442 /* [history] */
444 /* [mapimg] */
446 /* [script] -- must come last as may reference game objects */
448 /* [post_load_compat]; needs the game loaded by [savefile] */
450
451 /* Sanity checks for the loaded game. */
453
454 /* deinitialise loading */
458
459 if (!sg_success) {
460 log_error("Failure loading savegame!");
461 /* Try to get the server back to a vaguely sane state */
465 }
466}
467
468/************************************************************************/
471static struct loaddata *loaddata_new(struct section_file *file)
472{
473 struct loaddata *loading = calloc(1, sizeof(*loading));
474 loading->file = file;
475 loading->secfile_options = NULL;
476
477 loading->improvement.order = NULL;
478 loading->improvement.size = -1;
479 loading->technology.order = NULL;
480 loading->technology.size = -1;
481 loading->activities.order = NULL;
482 loading->activities.size = -1;
483 loading->trait.order = NULL;
484 loading->trait.size = -1;
485 loading->extra.order = NULL;
486 loading->extra.size = -1;
487 loading->multiplier.order = NULL;
488 loading->multiplier.size = -1;
489 loading->special.order = NULL;
490 loading->special.size = -1;
491 loading->base.order = NULL;
492 loading->base.size = -1;
493 loading->road.order = NULL;
494 loading->road.size = -1;
495 loading->specialist.order = NULL;
496 loading->specialist.size = -1;
497 loading->ds_t.order = NULL;
498 loading->ds_t.size = -1;
499 loading->coptions.order = NULL;
500 loading->coptions.size = -1;
501
502 loading->server_state = S_S_INITIAL;
503 loading->rstate = fc_rand_state();
504 loading->worked_tiles = NULL;
505
506 return loading;
507}
508
509/************************************************************************/
513{
514 if (loading->improvement.order != NULL) {
515 free(loading->improvement.order);
516 }
517
518 if (loading->technology.order != NULL) {
519 free(loading->technology.order);
520 }
521
522 if (loading->activities.order != NULL) {
523 free(loading->activities.order);
524 }
525
526 if (loading->trait.order != NULL) {
527 free(loading->trait.order);
528 }
529
530 if (loading->extra.order != NULL) {
531 free(loading->extra.order);
532 }
533
534 if (loading->multiplier.order != NULL) {
535 free(loading->multiplier.order);
536 }
537
538 if (loading->special.order != NULL) {
539 free(loading->special.order);
540 }
541
542 if (loading->base.order != NULL) {
543 free(loading->base.order);
544 }
545
546 if (loading->road.order != NULL) {
547 free(loading->road.order);
548 }
549
550 if (loading->specialist.order != NULL) {
551 free(loading->specialist.order);
552 }
553
554 if (loading->ds_t.order != NULL) {
555 free(loading->ds_t.order);
556 }
557
558 if (loading->coptions.order != NULL) {
559 free(loading->coptions.order);
560 }
561
562 if (loading->worked_tiles != NULL) {
563 free(loading->worked_tiles);
564 }
565
566 free(loading);
567}
568
569
570/************************************************************************/
580
581/************************************************************************/
591
592/* =======================================================================
593 * Helper functions.
594 * ======================================================================= */
595
596/************************************************************************/
599static enum unit_orders char2order(char order)
600{
601 switch (order) {
602 case 'm':
603 case 'M':
604 return ORDER_MOVE;
605 case 'w':
606 case 'W':
607 return ORDER_FULL_MP;
608 case 'b':
609 case 'B':
611 case 'a':
612 case 'A':
613 return ORDER_ACTIVITY;
614 case 'd':
615 case 'D':
616 return ORDER_OLD_DISBAND;
617 case 'u':
618 case 'U':
620 case 't':
621 case 'T':
623 case 'h':
624 case 'H':
625 return ORDER_OLD_HOMECITY;
626 case 'x':
627 case 'X':
628 return ORDER_ACTION_MOVE;
629 }
630
631 /* This can happen if the savegame is invalid. */
632 return ORDER_LAST;
633}
634
635/************************************************************************/
638static enum direction8 char2dir(char dir)
639{
640 /* Numberpad values for the directions. */
641 switch (dir) {
642 case '1':
643 return DIR8_SOUTHWEST;
644 case '2':
645 return DIR8_SOUTH;
646 case '3':
647 return DIR8_SOUTHEAST;
648 case '4':
649 return DIR8_WEST;
650 case '6':
651 return DIR8_EAST;
652 case '7':
653 return DIR8_NORTHWEST;
654 case '8':
655 return DIR8_NORTH;
656 case '9':
657 return DIR8_NORTHEAST;
658 }
659
660 /* This can happen if the savegame is invalid. */
661 return direction8_invalid();
662}
663
664/************************************************************************/
667static char activity2char(int activity)
668{
669 switch (activity) {
670 case ACTIVITY_IDLE:
671 return 'w';
672 case ACTIVITY_CLEAN:
673 return 'C';
675 return 'p';
677 return 'r';
678 case ACTIVITY_MINE:
679 return 'm';
681 return 'i';
683 return 'f';
684 case ACTIVITY_SENTRY:
685 return 's';
687 return 'l';
688 case ACTIVITY_PILLAGE:
689 return 'e';
690 case ACTIVITY_GOTO:
691 return 'g';
692 case ACTIVITY_EXPLORE:
693 return 'x';
695 return 'o';
697 return 'y';
699 return 'u';
700 case ACTIVITY_BASE:
701 return 'b';
703 return 'R';
704 case ACTIVITY_CONVERT:
705 return 'c';
707 case ACTIVITY_PLANT:
708 return '?';
709 case ACTIVITY_LAST:
710 break;
711 }
712
714
715 return '?';
716}
717
718/************************************************************************/
721static int char2activity(char activity)
722{
723 int a;
724
725 for (a = 0; a < ACTIVITY_LAST_SAVEGAME2; a++) {
726 char achar = activity2char(a);
727
728 if (activity == achar) {
729 return a;
730 }
731 }
732
733 /* This can happen if the savegame is invalid. */
734 return ACTIVITY_LAST;
735}
736
737/************************************************************************/
742static int unquote_block(const char *const quoted_, void *dest,
743 int dest_length)
744{
745 int i, length, parsed, tmp;
746 char *endptr;
747 const char *quoted = quoted_;
748
749 parsed = sscanf(quoted, "%d", &length);
750
751 if (parsed != 1) {
752 log_error(_("Syntax error in attribute block."));
753 return 0;
754 }
755
756 if (length > dest_length) {
757 return 0;
758 }
759
760 quoted = strchr(quoted, ':');
761
762 if (quoted == NULL) {
763 log_error(_("Syntax error in attribute block."));
764 return 0;
765 }
766
767 quoted++;
768
769 for (i = 0; i < length; i++) {
770 tmp = strtol(quoted, &endptr, 16);
771
772 if ((endptr - quoted) != 2
773 || *endptr != ' '
774 || (tmp & 0xff) != tmp) {
775 log_error(_("Syntax error in attribute block."));
776 return 0;
777 }
778
779 ((unsigned char *) dest)[i] = tmp;
780 quoted += 3;
781 }
782
783 return length;
784}
785
786/************************************************************************/
791 struct worklist *pwl, const char *path, ...)
792{
793 int i;
794 const char *kind;
795 const char *name;
796 char path_str[1024];
797 va_list ap;
798
799 /* The first part of the registry path is taken from the varargs to the
800 * function. */
801 va_start(ap, path);
802 fc_vsnprintf(path_str, sizeof(path_str), path, ap);
803 va_end(ap);
804
807 "%s.wl_length", path_str);
808
809 for (i = 0; i < pwl->length; i++) {
810 kind = secfile_lookup_str(file, "%s.wl_kind%d", path_str, i);
811
812 /* We lookup the production value by name. An invalid entry isn't a
813 * fatal error; we just truncate the worklist. */
814 name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
815 path_str, i);
816 pwl->entries[i] = universal_by_rule_name(kind, name);
817 if (pwl->entries[i].kind == universals_n_invalid()) {
818 log_sg("%s.wl_value%d: unknown \"%s\" \"%s\".", path_str, i, kind,
819 name);
820 pwl->length = i;
821 break;
822 }
823 }
824
825 /* Padding entries */
826 for (; i < wlist_max_length; i++) {
827 (void) secfile_entry_lookup(file, "%s.wl_kind%d", path_str, i);
828 (void) secfile_entry_lookup(file, "%s.wl_value%d", path_str, i);
829 }
830}
831
832/************************************************************************/
836static void unit_ordering_apply(void)
837{
838 players_iterate(pplayer) {
839 city_list_iterate(pplayer->cities, pcity) {
840 unit_list_sort_ord_city(pcity->units_supported);
841 }
844
845 whole_map_iterate(&(wld.map), ptile) {
846 unit_list_sort_ord_map(ptile->units);
848}
849
850/************************************************************************/
857static void sg_extras_set_dbv(struct dbv *extras, char ch,
858 struct extra_type **idx)
859{
860 int i, bin;
861 const char *pch = strchr(hex_chars, ch);
862
863 if (!pch || ch == '\0') {
864 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
865 bin = 0;
866 } else {
867 bin = pch - hex_chars;
868 }
869
870 for (i = 0; i < 4; i++) {
871 struct extra_type *pextra = idx[i];
872
873 if (pextra == NULL) {
874 continue;
875 }
876 if ((bin & (1 << i))
877 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
878 dbv_set(extras, extra_index(pextra));
879 }
880 }
881}
882
883/************************************************************************/
891 struct extra_type **idx)
892{
893 int i, bin;
894 const char *pch = strchr(hex_chars, ch);
895
896 if (!pch || ch == '\0') {
897 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
898 bin = 0;
899 } else {
900 bin = pch - hex_chars;
901 }
902
903 for (i = 0; i < 4; i++) {
904 struct extra_type *pextra = idx[i];
905
906 if (pextra == NULL) {
907 continue;
908 }
909 if ((bin & (1 << i))
910 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
911 BV_SET(*extras, extra_index(pextra));
912 }
913 }
914}
915
916/************************************************************************/
923static void sg_special_set_dbv(struct tile *ptile, struct dbv *extras, char ch,
924 const enum tile_special_type *idx,
925 bool rivers_overlay)
926{
927 int i, bin;
928 const char *pch = strchr(hex_chars, ch);
929
930 if (!pch || ch == '\0') {
931 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
932 bin = 0;
933 } else {
934 bin = pch - hex_chars;
935 }
936
937 for (i = 0; i < 4; i++) {
938 enum tile_special_type sp = idx[i];
939
940 if (sp == S_LAST) {
941 continue;
942 }
943 if (rivers_overlay && sp != S_OLD_RIVER) {
944 continue;
945 }
946
947 if (sp == S_HUT && !wld.map.server.have_huts) {
948 /* It would be logical to have this in the saving side -
949 * really not saving the huts in the first place, BUT
950 * 1) They have been saved by older versions, so we
951 * have to deal with such savegames.
952 * 2) This makes scenario author less likely to lose
953 * one's work completely after carefully placing huts
954 * and then saving with 'have_huts' disabled. */
955 continue;
956 }
957
958 if (bin & (1 << i)) {
959 if (sp == S_OLD_ROAD) {
960 struct road_type *proad;
961
963 if (proad) {
965 }
966 } else if (sp == S_OLD_RAILROAD) {
967 struct road_type *proad;
968
970 if (proad) {
972 }
973 } else if (sp == S_OLD_RIVER) {
974 struct road_type *proad;
975
977 if (proad) {
979 }
980 } else {
981 struct extra_type *pextra = NULL;
982 enum extra_cause cause = EC_COUNT;
983
984 /* Converting from old hardcoded specials to as sensible extra as we can */
985 switch (sp) {
986 case S_IRRIGATION:
987 case S_FARMLAND:
988 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
989 * gets applied twice, which hopefully has the correct result. */
990 cause = EC_IRRIGATION;
991 break;
992 case S_MINE:
993 cause = EC_MINE;
994 break;
995 case S_POLLUTION:
996 cause = EC_POLLUTION;
997 break;
998 case S_HUT:
999 cause = EC_HUT;
1000 break;
1001 case S_FALLOUT:
1002 cause = EC_FALLOUT;
1003 break;
1004 default:
1006 break;
1007 }
1008
1009 if (cause != EC_COUNT) {
1010 struct tile *vtile = tile_virtual_new(ptile);
1011 struct terrain *pterr = tile_terrain(vtile);
1012 const struct req_context tile_ctxt = { .tile = vtile };
1013
1014 /* Do not let the extras already set to the real tile mess with setup
1015 * of the player tiles if that's what we're doing. */
1016 dbv_to_bv(vtile->extras.vec, extras);
1017
1018 /* It's ok not to know which player or which unit originally built the extra -
1019 * in the rules used when specials were saved these could not have made any
1020 * difference. */
1021 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
1022
1023 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
1024 && (cause != EC_MINE || pterr->mining_time != 0)
1025 && (cause != EC_BASE || pterr->base_time != 0)
1026 && (cause != EC_ROAD || pterr->road_time != 0)) {
1030 || tile_city(vtile) != NULL
1031 || extra_base_get(candidate)->border_sq <= 0)
1033 &(const struct req_context) {
1034 .player = tile_owner(vtile),
1035 },
1036 &candidate->reqs,
1037 RPT_POSSIBLE)) {
1038 pextra = candidate;
1039 break;
1040 }
1041 }
1043 }
1044
1046 }
1047
1048 if (pextra) {
1049 dbv_set(extras, extra_index(pextra));
1050 }
1051 }
1052 }
1053 }
1054}
1055
1056/************************************************************************/
1063static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch,
1064 const enum tile_special_type *idx,
1065 bool rivers_overlay)
1066{
1067 int i, bin;
1068 const char *pch = strchr(hex_chars, ch);
1069
1070 if (!pch || ch == '\0') {
1071 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1072 bin = 0;
1073 } else {
1074 bin = pch - hex_chars;
1075 }
1076
1077 for (i = 0; i < 4; i++) {
1078 enum tile_special_type sp = idx[i];
1079
1080 if (sp == S_LAST) {
1081 continue;
1082 }
1083 if (rivers_overlay && sp != S_OLD_RIVER) {
1084 continue;
1085 }
1086
1087 if (sp == S_HUT && !wld.map.server.have_huts) {
1088 /* It would be logical to have this in the saving side -
1089 * really not saving the huts in the first place, BUT
1090 * 1) They have been saved by older versions, so we
1091 * have to deal with such savegames.
1092 * 2) This makes scenario author less likely to lose
1093 * one's work completely after carefully placing huts
1094 * and then saving with 'have_huts' disabled. */
1095 continue;
1096 }
1097
1098 if (bin & (1 << i)) {
1099 if (sp == S_OLD_ROAD) {
1100 struct road_type *proad;
1101
1103 if (proad) {
1105 }
1106 } else if (sp == S_OLD_RAILROAD) {
1107 struct road_type *proad;
1108
1110 if (proad) {
1112 }
1113 } else if (sp == S_OLD_RIVER) {
1114 struct road_type *proad;
1115
1117 if (proad) {
1119 }
1120 } else {
1121 struct extra_type *pextra = NULL;
1122 enum extra_cause cause = EC_COUNT;
1123
1124 /* Converting from old hardcoded specials to as sensible extra as we can */
1125 switch (sp) {
1126 case S_IRRIGATION:
1127 case S_FARMLAND:
1128 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
1129 * gets applied twice, which hopefully has the correct result. */
1130 cause = EC_IRRIGATION;
1131 break;
1132 case S_MINE:
1133 cause = EC_MINE;
1134 break;
1135 case S_POLLUTION:
1136 cause = EC_POLLUTION;
1137 break;
1138 case S_HUT:
1139 cause = EC_HUT;
1140 break;
1141 case S_FALLOUT:
1142 cause = EC_FALLOUT;
1143 break;
1144 default:
1146 break;
1147 }
1148
1149 if (cause != EC_COUNT) {
1150 struct tile *vtile = tile_virtual_new(ptile);
1151 struct terrain *pterr = tile_terrain(vtile);
1152 const struct req_context tile_ctxt = { .tile = vtile };
1153
1154 /* Do not let the extras already set to the real tile mess with setup
1155 * of the player tiles if that's what we're doing. */
1156 vtile->extras = *extras;
1157
1158 /* It's ok not to know which player or which unit originally built the extra -
1159 * in the rules used when specials were saved these could not have made any
1160 * difference. */
1161 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
1162
1163 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
1164 && (cause != EC_MINE || pterr->mining_time != 0)
1165 && (cause != EC_BASE || pterr->base_time != 0)
1166 && (cause != EC_ROAD || pterr->road_time != 0)) {
1170 || tile_city(vtile) != NULL
1171 || extra_base_get(candidate)->border_sq <= 0)
1173 &(const struct req_context) {
1174 .player = tile_owner(vtile),
1175 },
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/************************************************************************/
1363 const char *path, int plrno)
1364{
1365 char path_with_name[128];
1366 const char *name;
1367 struct advance *padvance;
1368
1370 "%s_name", path);
1371
1373
1374 if (!name || name[0] == '\0') {
1375 /* used by researching_saved */
1376 return A_UNKNOWN;
1377 }
1378 if (fc_strcasecmp(name, "A_FUTURE") == 0) {
1379 return A_FUTURE;
1380 }
1381 if (fc_strcasecmp(name, "A_NONE") == 0) {
1382 return A_NONE;
1383 }
1384 if (fc_strcasecmp(name, "A_UNSET") == 0) {
1385 return A_UNSET;
1386 }
1387
1390 "%s: unknown technology \"%s\".", path_with_name, name);
1391
1392 return advance_number(padvance);
1393}
1394
1395/* =======================================================================
1396 * Load savefile data.
1397 * ======================================================================= */
1398
1399/************************************************************************/
1403{
1404 const char *ruleset = secfile_lookup_str_default(loading->file,
1406 "savefile.rulesetdir");
1407
1408 /* Load ruleset. */
1410 if (!strcmp("default", game.server.rulesetdir)) {
1411 int version;
1412
1413 version = secfile_lookup_int_default(loading->file, -1, "savefile.version");
1414 if (version >= 30) {
1415 /* Here 'default' really means current default.
1416 * Saving happens with real ruleset name, so savegames containing this
1417 * are special scenarios. */
1419 } else {
1420 /* 'default' is the old name of the classic ruleset */
1421 sz_strlcpy(game.server.rulesetdir, "classic");
1422 }
1423 log_verbose("Savegame specified ruleset '%s'. Really loading '%s'.",
1425 }
1427 /* Failed to load correct ruleset */
1428 sg_failure_ret(FALSE, _("Failed to load ruleset '%s' needed for savegame."),
1429 ruleset);
1430 }
1431}
1432
1433/************************************************************************/
1437{
1438 int i;
1439 const char *terr_name;
1440 const char *str;
1441
1442 /* Check status and return if not OK (sg_success FALSE). */
1443 sg_check_ret();
1444
1445 /* Load savefile options. */
1446 loading->secfile_options
1447 = secfile_lookup_str(loading->file, "savefile.options");
1448
1449 /* We don't need these entries, but read them anyway to avoid
1450 * warnings about unread secfile entries. */
1451 (void) secfile_entry_by_path(loading->file, "savefile.reason");
1452 (void) secfile_entry_by_path(loading->file, "savefile.revision");
1453
1454 str = secfile_lookup_str(loading->file, "savefile.orig_version");
1456
1457 /* In case of savegame2.c saves, missing entry means savegame older than support
1458 * for saving last_updated by turn. So this must default to TRUE. */
1460 "savefile.last_updated_as_year");
1461
1462 /* Load improvements. */
1463 loading->improvement.size
1465 "savefile.improvement_size");
1466 if (loading->improvement.size) {
1467 loading->improvement.order
1468 = secfile_lookup_str_vec(loading->file, &loading->improvement.size,
1469 "savefile.improvement_vector");
1470 sg_failure_ret(loading->improvement.size != 0,
1471 "Failed to load improvement order: %s",
1472 secfile_error());
1473 }
1474
1475 /* Load technologies. */
1476 loading->technology.size
1478 "savefile.technology_size");
1479 if (loading->technology.size) {
1480 loading->technology.order
1481 = secfile_lookup_str_vec(loading->file, &loading->technology.size,
1482 "savefile.technology_vector");
1483 sg_failure_ret(loading->technology.size != 0,
1484 "Failed to load technology order: %s",
1485 secfile_error());
1486 }
1487
1488 /* Load Activities. */
1489 loading->activities.size
1491 "savefile.activities_size");
1492 if (loading->activities.size) {
1493 loading->activities.order
1494 = secfile_lookup_str_vec(loading->file, &loading->activities.size,
1495 "savefile.activities_vector");
1496 sg_failure_ret(loading->activities.size != 0,
1497 "Failed to load activity order: %s",
1498 secfile_error());
1499 }
1500
1501 /* Load traits. */
1502 loading->trait.size
1504 "savefile.trait_size");
1505 if (loading->trait.size) {
1506 loading->trait.order
1507 = secfile_lookup_str_vec(loading->file, &loading->trait.size,
1508 "savefile.trait_vector");
1509 sg_failure_ret(loading->trait.size != 0,
1510 "Failed to load trait order: %s",
1511 secfile_error());
1512 }
1513
1514 /* Load extras. */
1515 loading->extra.size
1517 "savefile.extras_size");
1518 if (loading->extra.size) {
1519 const char **modname;
1520 size_t nmod;
1521 int j;
1522
1523 modname = secfile_lookup_str_vec(loading->file, &loading->extra.size,
1524 "savefile.extras_vector");
1525 sg_failure_ret(loading->extra.size != 0,
1526 "Failed to load extras order: %s",
1527 secfile_error());
1529 "Number of extras defined by the ruleset (= %d) are "
1530 "lower than the number in the savefile (= %d).",
1531 game.control.num_extra_types, (int)loading->extra.size);
1532 /* make sure that the size of the array is divisible by 4 */
1533 nmod = 4 * ((loading->extra.size + 3) / 4);
1534 loading->extra.order = fc_calloc(nmod, sizeof(*loading->extra.order));
1535 for (j = 0; j < loading->extra.size; j++) {
1536 loading->extra.order[j] = extra_type_by_rule_name(modname[j]);
1537 }
1538 free(modname);
1539 for (; j < nmod; j++) {
1540 loading->extra.order[j] = NULL;
1541 }
1542 }
1543
1544 /* Load multipliers. */
1545 loading->multiplier.size
1547 "savefile.multipliers_size");
1548 if (loading->multiplier.size) {
1549 const char **modname;
1550 int j;
1551
1552 modname = secfile_lookup_str_vec(loading->file, &loading->multiplier.size,
1553 "savefile.multipliers_vector");
1554 sg_failure_ret(loading->multiplier.size != 0,
1555 "Failed to load multipliers order: %s",
1556 secfile_error());
1557 /* It's OK for the set of multipliers in the savefile to differ
1558 * from those in the ruleset. */
1559 loading->multiplier.order = fc_calloc(loading->multiplier.size,
1560 sizeof(*loading->multiplier.order));
1561 for (j = 0; j < loading->multiplier.size; j++) {
1562 loading->multiplier.order[j] = multiplier_by_rule_name(modname[j]);
1563 if (!loading->multiplier.order[j]) {
1564 log_verbose("Multiplier \"%s\" in savegame but not in ruleset, "
1565 "discarding", modname[j]);
1566 }
1567 }
1568 free(modname);
1569 }
1570
1571 /* Load specials. */
1572 loading->special.size
1574 "savefile.specials_size");
1575 if (loading->special.size) {
1576 const char **modname;
1577 size_t nmod;
1578 enum tile_special_type j;
1579
1580 modname = secfile_lookup_str_vec(loading->file, &loading->special.size,
1581 "savefile.specials_vector");
1582 sg_failure_ret(loading->special.size != 0,
1583 "Failed to load specials order: %s",
1584 secfile_error());
1585 /* make sure that the size of the array is divisible by 4 */
1586 /* Allocating extra 4 slots, just a couple of bytes,
1587 * in case of special.size being divisible by 4 already is intentional.
1588 * Added complexity would cost those couple of bytes in code size alone,
1589 * and we actually need at least one slot immediately after last valid
1590 * one. That's where S_LAST is (or was in version that saved the game)
1591 * and in some cases S_LAST gets written to savegame, at least as
1592 * activity target special when activity targets some base or road
1593 * instead. By having current S_LAST in that index allows us to map
1594 * that old S_LAST to current S_LAST, just like any real special within
1595 * special.size gets mapped. */
1596 nmod = loading->special.size + (4 - (loading->special.size % 4));
1597 loading->special.order = fc_calloc(nmod,
1598 sizeof(*loading->special.order));
1599 for (j = 0; j < loading->special.size; j++) {
1600 if (!fc_strcasecmp("Road", modname[j])) {
1601 loading->special.order[j] = S_OLD_ROAD;
1602 } else if (!fc_strcasecmp("Railroad", modname[j])) {
1603 loading->special.order[j] = S_OLD_RAILROAD;
1604 } else if (!fc_strcasecmp("River", modname[j])) {
1605 loading->special.order[j] = S_OLD_RIVER;
1606 } else {
1607 loading->special.order[j] = special_by_rule_name(modname[j]);
1608 }
1609 }
1610 free(modname);
1611 for (; j < nmod; j++) {
1612 loading->special.order[j] = S_LAST;
1613 }
1614 }
1615
1616 /* Load bases. */
1617 loading->base.size
1619 "savefile.bases_size");
1620 if (loading->base.size) {
1621 const char **modname;
1622 size_t nmod;
1623 int j;
1624
1625 modname = secfile_lookup_str_vec(loading->file, &loading->base.size,
1626 "savefile.bases_vector");
1627 sg_failure_ret(loading->base.size != 0,
1628 "Failed to load bases order: %s",
1629 secfile_error());
1630 /* make sure that the size of the array is divisible by 4 */
1631 nmod = 4 * ((loading->base.size + 3) / 4);
1632 loading->base.order = fc_calloc(nmod, sizeof(*loading->base.order));
1633 for (j = 0; j < loading->base.size; j++) {
1634 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1635
1636 sg_failure_ret(pextra != NULL
1637 || game.control.num_base_types >= loading->base.size,
1638 "Unknown base type %s in savefile.",
1639 modname[j]);
1640
1641 if (pextra != NULL) {
1642 loading->base.order[j] = extra_base_get(pextra);
1643 } else {
1644 loading->base.order[j] = NULL;
1645 }
1646 }
1647 free(modname);
1648 for (; j < nmod; j++) {
1649 loading->base.order[j] = NULL;
1650 }
1651 }
1652
1653 /* Load roads. */
1654 loading->road.size
1656 "savefile.roads_size");
1657 if (loading->road.size) {
1658 const char **modname;
1659 size_t nmod;
1660 int j;
1661
1662 modname = secfile_lookup_str_vec(loading->file, &loading->road.size,
1663 "savefile.roads_vector");
1664 sg_failure_ret(loading->road.size != 0,
1665 "Failed to load roads order: %s",
1666 secfile_error());
1668 "Number of roads defined by the ruleset (= %d) are "
1669 "lower than the number in the savefile (= %d).",
1670 game.control.num_road_types, (int)loading->road.size);
1671 /* make sure that the size of the array is divisible by 4 */
1672 nmod = 4 * ((loading->road.size + 3) / 4);
1673 loading->road.order = fc_calloc(nmod, sizeof(*loading->road.order));
1674 for (j = 0; j < loading->road.size; j++) {
1675 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1676
1677 if (pextra != NULL) {
1678 loading->road.order[j] = extra_road_get(pextra);
1679 } else {
1680 loading->road.order[j] = NULL;
1681 }
1682 }
1683 free(modname);
1684 for (; j < nmod; j++) {
1685 loading->road.order[j] = NULL;
1686 }
1687 }
1688
1689 /* Load specialists. */
1690 loading->specialist.size
1692 "savefile.specialists_size");
1693 if (loading->specialist.size) {
1694 const char **modname;
1695 size_t nmod;
1696 int j;
1697
1698 modname = secfile_lookup_str_vec(loading->file, &loading->specialist.size,
1699 "savefile.specialists_vector");
1700 sg_failure_ret(loading->specialist.size != 0,
1701 "Failed to load specialists order: %s",
1702 secfile_error());
1704 "Number of specialists defined by the ruleset (= %d) are "
1705 "lower than the number in the savefile (= %d).",
1706 game.control.num_specialist_types, (int)loading->specialist.size);
1707 /* make sure that the size of the array is divisible by 4 */
1708 /* That's not really needed with specialists at the moment, but done this way
1709 * for consistency with other types, and to be prepared for the time it needs
1710 * to be this way. */
1711 nmod = 4 * ((loading->specialist.size + 3) / 4);
1712 loading->specialist.order = fc_calloc(nmod, sizeof(*loading->specialist.order));
1713 for (j = 0; j < loading->specialist.size; j++) {
1714 loading->specialist.order[j] = specialist_by_rule_name(modname[j]);
1715 }
1716 free(modname);
1717 for (; j < nmod; j++) {
1718 loading->specialist.order[j] = NULL;
1719 }
1720 }
1721
1722 /* Load diplomatic state type order. */
1723 loading->ds_t.size
1725 "savefile.diplstate_type_size");
1726
1727 sg_failure_ret(loading->ds_t.size > 0,
1728 "Failed to load diplomatic state type order: %s",
1729 secfile_error());
1730
1731 if (loading->ds_t.size) {
1732 const char **modname;
1733 int j;
1734
1735 modname = secfile_lookup_str_vec(loading->file, &loading->ds_t.size,
1736 "savefile.diplstate_type_vector");
1737
1738 loading->ds_t.order = fc_calloc(loading->ds_t.size,
1739 sizeof(*loading->ds_t.order));
1740
1741 for (j = 0; j < loading->ds_t.size; j++) {
1742 loading->ds_t.order[j] = diplstate_type_by_name(modname[j],
1744 }
1745
1746 free(modname);
1747 }
1748
1749 /* Load city options order. */
1750 loading->coptions.size
1752 "savefile.city_options_size");
1753
1754 {
1755 const char *modname_old[] = { "Disband", "Sci_Specialists", "Tax_Specialists" };
1756 const char **modname;
1757 int j;
1758 bool compat;
1759
1760 if (loading->coptions.size > 0) {
1761 modname = secfile_lookup_str_vec(loading->file, &loading->coptions.size,
1762 "savefile.city_options_vector");
1763 compat = FALSE;
1764 } else {
1766 loading->coptions.size = 3;
1767 compat = TRUE;
1768 }
1769
1770 loading->coptions.order = fc_calloc(loading->coptions.size,
1771 sizeof(*loading->coptions.order));
1772
1773 for (j = 0; j < loading->coptions.size; j++) {
1774 loading->coptions.order[j] = city_options_by_name(modname[j],
1776 }
1777
1778 if (!compat) {
1779 free(modname);
1780 }
1781 }
1782
1783 /* Terrain identifiers */
1785 pterr->identifier_load = '\0';
1787
1788 i = 0;
1790 "savefile.terrident%d.name", i)) != NULL) {
1792
1793 if (pterr != NULL) {
1794 const char *iptr = secfile_lookup_str_default(loading->file, NULL,
1795 "savefile.terrident%d.identifier", i);
1796
1797 pterr->identifier_load = *iptr;
1798 } else {
1799 log_error("Identifier for unknown terrain type %s.", terr_name);
1800 }
1801 i++;
1802 }
1803
1806 if (pterr != pterr2 && pterr->identifier_load != '\0') {
1807 sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1808 "%s and %s share a saved identifier",
1810 }
1813}
1814
1815/* =======================================================================
1816 * Load game status.
1817 * ======================================================================= */
1818
1819/************************************************************************/
1823{
1824 int i;
1825 const char *name;
1826
1827 /* Check status and return if not OK (sg_success FALSE). */
1828 sg_check_ret();
1829
1830 for (i = 0;
1832 "ruledata.government%d.name", i));
1833 i++) {
1835
1836 if (gov != NULL) {
1838 "ruledata.government%d.changes", i);
1839 }
1840 }
1841}
1842
1843/************************************************************************/
1846static void sg_load_game(struct loaddata *loading)
1847{
1848 int game_version;
1849 const char *str;
1850 int i;
1851
1852 /* Check status and return if not OK (sg_success FALSE). */
1853 sg_check_ret();
1854
1855 /* Load version. */
1857 = secfile_lookup_int_default(loading->file, 0, "game.version");
1858 /* We require at least version 2.2.99 */
1859 sg_failure_ret(20299 <= game_version, "Saved game is too old, at least "
1860 "version 2.2.99 required.");
1861
1862 loading->full_version = game_version;
1863
1864 /* Load server state. */
1865 str = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
1866 "game.server_state");
1867 loading->server_state = server_states_by_name(str, strcmp);
1868 if (!server_states_is_valid(loading->server_state)) {
1869 /* Don't take any risk! */
1870 loading->server_state = S_S_INITIAL;
1871 }
1872
1875 "game.meta_patches");
1877
1879 /* Do not overwrite this if the user requested a specific metaserver
1880 * from the command line (option --Metaserver). */
1884 "game.meta_server"));
1885 }
1886
1887 if ('\0' == srvarg.serverid[0]) {
1888 /* Do not overwrite this if the user requested a specific metaserver
1889 * from the command line (option --serverid). */
1892 "game.serverid"));
1893 }
1894 sz_strlcpy(server.game_identifier,
1895 secfile_lookup_str_default(loading->file, "", "game.id"));
1896 /* We are not checking game_identifier legality just yet.
1897 * That's done when we are sure that rand seed has been initialized,
1898 * so that we can generate new game_identifier, if needed.
1899 * See sq_load_sanitycheck(). */
1900
1903 "game.phase_mode");
1906 "game.phase_mode_stored");
1909 "game.phase");
1913 "game.scoreturn");
1914
1917 "game.timeoutint");
1920 "game.timeoutintinc");
1923 "game.timeoutinc");
1926 "game.timeoutincmult");
1929 "game.timeoutcounter");
1930
1931 game.info.turn
1932 = secfile_lookup_int_default(loading->file, 0, "game.turn");
1934 "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 /* Global advances. */
1955 "game.global_advances");
1956 if (str != NULL) {
1957 sg_failure_ret(strlen(str) == loading->technology.size,
1958 "Invalid length of 'game.global_advances' ("
1959 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
1960 strlen(str), loading->technology.size);
1961 for (i = 0; i < loading->technology.size; i++) {
1962 sg_failure_ret(str[i] == '1' || str[i] == '0',
1963 "Undefined value '%c' within 'game.global_advances'.",
1964 str[i]);
1965 if (str[i] == '1') {
1966 struct advance *padvance =
1967 advance_by_rule_name(loading->technology.order[i]);
1968
1969 if (padvance != NULL) {
1971 }
1972 }
1973 }
1974 }
1975
1977 = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
1978
1980 = secfile_lookup_int_default(loading->file, 0, "game.last_turn_change_time") / 100.0;
1981}
1982
1983/* =======================================================================
1984 * Load random status.
1985 * ======================================================================= */
1986
1987/************************************************************************/
1990static void sg_load_random(struct loaddata *loading)
1991{
1992 /* Check status and return if not OK (sg_success FALSE). */
1993 sg_check_ret();
1994
1995 if (secfile_lookup_bool_default(loading->file, FALSE, "random.saved")) {
1996 const char *str;
1997 int i;
1998
1999 /* Since random state was previously saved, save it also when resaving.
2000 * This affects only pre-2.6 scenarios where scenario.save_random
2001 * is not defined.
2002 * - If this is 2.6 or later scenario -> it would have saved random.saved = TRUE
2003 * only if scenario.save_random is already TRUE
2004 *
2005 * Do NOT touch this in case of regular savegame. They always have random.saved
2006 * set, but if one starts to make scenario based on a savegame, we want
2007 * default scenario settings in the beginning (default save_random = FALSE).
2008 */
2011 }
2012
2014 "random.index_J"), "%s", secfile_error());
2016 "random.index_K"), "%s", secfile_error());
2018 "random.index_X"), "%s", secfile_error());
2019
2020 for (i = 0; i < 8; i++) {
2021 str = secfile_lookup_str(loading->file, "random.table%d",i);
2022 sg_failure_ret(NULL != str, "%s", secfile_error());
2023 sscanf(str, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
2024 &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
2025 &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
2026 &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
2027 }
2028 loading->rstate.is_init = TRUE;
2029 fc_rand_set_state(loading->rstate);
2030 } else {
2031 /* No random values - mark the setting. */
2032 (void) secfile_entry_by_path(loading->file, "random.saved");
2033
2034 /* We're loading a game without a seed (which is okay, if it's a scenario).
2035 * We need to generate the game seed now because it will be needed later
2036 * during the load. */
2038 loading->rstate = fc_rand_state();
2039 }
2040}
2041
2042/* =======================================================================
2043 * Load lua script data.
2044 * ======================================================================= */
2045
2046/************************************************************************/
2049static void sg_load_script(struct loaddata *loading)
2050{
2051 /* Check status and return if not OK (sg_success FALSE). */
2052 sg_check_ret();
2053
2055}
2056
2057/* =======================================================================
2058 * Load scenario data.
2059 * ======================================================================= */
2060
2061/************************************************************************/
2065{
2066 const char *buf;
2067 bool lake_flood_default;
2068
2069 /* Check status and return if not OK (sg_success FALSE). */
2070 sg_check_ret();
2071
2072 if (NULL == secfile_section_lookup(loading->file, "scenario")) {
2074
2075 return;
2076 }
2077
2078 /* Default is that when there's scenario section (which we already checked)
2079 * this is a scenario. Only if it explicitly says that it's not, we consider
2080 * this regular savegame */
2081 game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
2082
2083 if (!game.scenario.is_scenario) {
2084 return;
2085 }
2086
2087 buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
2088 if (buf[0] != '\0') {
2090 }
2091
2093 "scenario.authors");
2094 if (buf[0] != '\0') {
2096 } else {
2097 game.scenario.authors[0] = '\0';
2098 }
2099
2101 "scenario.description");
2102 if (buf[0] != '\0') {
2104 } else {
2105 game.scenario_desc.description[0] = '\0';
2106 }
2107
2109 = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
2111 = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
2114 "scenario.startpos_nations");
2115
2118 "scenario.prevent_new_cities");
2119 if (loading->version < 20599) {
2120 /* Lake flooding may break some old scenarios where rivers made out of
2121 * lake terrains, so play safe there */
2123 } else {
2124 /* If lake flooding is a problem for a newer scenario, it could explicitly
2125 * disable it. */
2127 }
2130 "scenario.lake_flooding");
2133 "scenario.handmade");
2136 "scenario.allow_ai_type_fallback");
2138
2139 sg_failure_ret(loading->server_state == S_S_INITIAL
2140 || (loading->server_state == S_S_RUNNING
2141 && game.scenario.players),
2142 "Invalid scenario definition (server state '%s' and "
2143 "players are %s).",
2144 server_states_name(loading->server_state),
2145 game.scenario.players ? "saved" : "not saved");
2146
2147 /* Remove all defined players. They are recreated with the skill level
2148 * defined by the scenario. */
2149 (void) aifill(0);
2150}
2151
2152/* =======================================================================
2153 * Load game settings.
2154 * ======================================================================= */
2155
2156/************************************************************************/
2160{
2161 /* Check status and return if not OK (sg_success FALSE). */
2162 sg_check_ret();
2163
2164 settings_game_load(loading->file, "settings");
2165
2166 /* Save current status of fogofwar. */
2168
2169 /* Add all compatibility settings here. */
2170}
2171
2172/* =======================================================================
2173 * Load the main map.
2174 * ======================================================================= */
2175
2176/************************************************************************/
2179static void sg_load_map(struct loaddata *loading)
2180{
2181 /* Check status and return if not OK (sg_success FALSE). */
2182 sg_check_ret();
2183
2184 /* This defaults to TRUE even if map has not been generated. Also,
2185 * old versions have also explicitly saved TRUE even in pre-game.
2186 * We rely on that
2187 * 1) scenario maps have it explicitly right.
2188 * 2) when map is actually generated, it re-initialize this to FALSE. */
2190 = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
2191
2192 if (S_S_INITIAL == loading->server_state
2194 /* Generator MAPGEN_SCENARIO is used;
2195 * this map was done with the map editor. */
2196
2197 /* Load tiles. */
2200
2201 if (loading->version >= 30) {
2202 /* 2.6.0 or newer */
2204 } else {
2206 if (loading->version >= 20) {
2207 /* 2.5.0 or newer */
2209 }
2210 if (has_capability("specials", loading->secfile_options)) {
2211 /* Load specials. */
2213 }
2214 }
2215
2216 /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
2218 if (has_capability("specials", loading->secfile_options)) {
2219 /* Load resources. */
2221 } else if (has_capability("riversoverlay", loading->secfile_options)) {
2222 /* Load only rivers overlay. */
2224 }
2225
2226 /* Nothing more needed for a scenario. */
2227 return;
2228 }
2229
2230 if (S_S_INITIAL == loading->server_state) {
2231 /* Nothing more to do if it is not a scenario but in initial state. */
2232 return;
2233 }
2234
2237 if (loading->version >= 30) {
2238 /* 2.6.0 or newer */
2240 } else {
2242 if (loading->version >= 20) {
2243 /* 2.5.0 or newer */
2245 }
2247 }
2252}
2253
2254/************************************************************************/
2258{
2259 /* Check status and return if not OK (sg_success FALSE). */
2260 sg_check_ret();
2261
2262 /* Initialize the map for the current topology. 'map.xsize' and
2263 * 'map.ysize' must be set. */
2265
2266 /* Allocate map. */
2268
2269 /* get the terrain type */
2270 LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
2271 "map.t%04d");
2273
2274 /* Check for special tile sprites. */
2275 whole_map_iterate(&(wld.map), ptile) {
2276 const char *spec_sprite;
2277 const char *label;
2278 int nat_x, nat_y;
2279
2281 spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
2282 nat_x, nat_y);
2283 label = secfile_lookup_str_default(loading->file, NULL, "map.label_%d_%d",
2284 nat_x, nat_y);
2285 if (NULL != ptile->spec_sprite) {
2286 ptile->spec_sprite = fc_strdup(spec_sprite);
2287 }
2288 if (label != NULL) {
2289 tile_set_label(ptile, label);
2290 }
2292}
2293
2294/************************************************************************/
2298{
2299 /* Check status and return if not OK (sg_success FALSE). */
2300 sg_check_ret();
2301
2302 /* Load extras. */
2303 halfbyte_iterate_extras(j, loading->extra.size) {
2304 LOAD_MAP_CHAR(ch, ptile, sg_extras_set_bv(&ptile->extras,
2305 ch, loading->extra.order + 4 * j),
2306 loading->file, "map.e%02d_%04d", j);
2308}
2309
2310/************************************************************************/
2314{
2315 /* Check status and return if not OK (sg_success FALSE). */
2316 sg_check_ret();
2317
2318 /* Load bases. */
2319 halfbyte_iterate_bases(j, loading->base.size) {
2320 LOAD_MAP_CHAR(ch, ptile, sg_bases_set_bv(&ptile->extras, ch,
2321 loading->base.order + 4 * j),
2322 loading->file, "map.b%02d_%04d", j);
2324}
2325
2326/************************************************************************/
2330{
2331 /* Check status and return if not OK (sg_success FALSE). */
2332 sg_check_ret();
2333
2334 /* Load roads. */
2335 halfbyte_iterate_roads(j, loading->road.size) {
2336 LOAD_MAP_CHAR(ch, ptile, sg_roads_set_bv(&ptile->extras, ch,
2337 loading->road.order + 4 * j),
2338 loading->file, "map.r%02d_%04d", j);
2340}
2341
2342/************************************************************************/
2346 bool rivers_overlay)
2347{
2348 /* Check status and return if not OK (sg_success FALSE). */
2349 sg_check_ret();
2350
2351 /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
2352 * from the savegame file.
2353 *
2354 * A scenario may define the terrain of the map but not list the specials
2355 * on it (thus allowing users to control the placement of specials).
2356 * However rivers are a special case and must be included in the map along
2357 * with the scenario. Thus in those cases this function should be called
2358 * to load the river information separate from any other special data.
2359 *
2360 * This does not need to be called from map_load(), because map_load()
2361 * loads the rivers overlay along with the rest of the specials. Call this
2362 * only if you've already called map_load_tiles(), and want to load only
2363 * the rivers overlay but no other specials. Scenarios that encode things
2364 * this way should have the "riversoverlay" capability. */
2365 halfbyte_iterate_special(j, loading->special.size) {
2366 LOAD_MAP_CHAR(ch, ptile, sg_special_set_bv(ptile, &ptile->extras, ch,
2367 loading->special.order + 4 * j,
2369 loading->file, "map.spe%02d_%04d", j);
2371}
2372
2373/************************************************************************/
2377{
2378 /* Check status and return if not OK (sg_success FALSE). */
2379 sg_check_ret();
2380
2382 loading->file, "map.res%04d");
2383
2384 /* After the resources are loaded, indicate those currently valid. */
2385 whole_map_iterate(&(wld.map), ptile) {
2386 if (NULL == ptile->resource) {
2387 continue;
2388 }
2389
2390 if (ptile->terrain == NULL || !terrain_has_resource(ptile->terrain, ptile->resource)) {
2391 BV_CLR(ptile->extras, extra_index(ptile->resource));
2392 }
2394
2397}
2398
2399/************************************************************************/
2404{
2405 struct nation_type *pnation;
2406 struct startpos *psp;
2407 struct tile *ptile;
2408 const char SEPARATOR = '#';
2409 const char *nation_names;
2410 int nat_x, nat_y;
2411 bool exclude;
2412 int i, startpos_count;
2413
2414 /* Check status and return if not OK (sg_success FALSE). */
2415 sg_check_ret();
2416
2418 = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
2419
2420 if (0 == startpos_count) {
2421 /* Nothing to do. */
2422 return;
2423 }
2424
2425 for (i = 0; i < startpos_count; i++) {
2426 if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
2427 || !secfile_lookup_int(loading->file, &nat_y,
2428 "map.startpos%d.y", i)) {
2429 log_sg("Warning: Undefined coordinates for startpos %d", i);
2430 continue;
2431 }
2432
2433 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
2434 if (NULL == ptile) {
2435 log_error("Start position native coordinates (%d, %d) do not exist "
2436 "in this map. Skipping...", nat_x, nat_y);
2437 continue;
2438 }
2439
2440 exclude = secfile_lookup_bool_default(loading->file, FALSE,
2441 "map.startpos%d.exclude", i);
2442
2443 psp = map_startpos_new(ptile);
2444
2446 "map.startpos%d.nations", i);
2447 if (NULL != nation_names && '\0' != nation_names[0]) {
2448 const size_t size = strlen(nation_names) + 1;
2449 char buf[size], *start, *end;
2450
2452 for (start = buf - 1; NULL != start; start = end) {
2453 start++;
2454 if ((end = strchr(start, SEPARATOR))) {
2455 *end = '\0';
2456 }
2457
2458 pnation = nation_by_rule_name(start);
2459 if (NO_NATION_SELECTED != pnation) {
2460 if (exclude) {
2461 startpos_disallow(psp, pnation);
2462 } else {
2463 startpos_allow(psp, pnation);
2464 }
2465 } else {
2466 log_verbose("Missing nation \"%s\".", start);
2467 }
2468 }
2469 }
2470 }
2471
2472 if (0 < map_startpos_count()
2473 && loading->server_state == S_S_INITIAL
2475 log_verbose("Number of starts (%d) are lower than rules.max_players "
2476 "(%d), lowering rules.max_players.",
2479 }
2480
2481 /* Re-initialize nation availability in light of start positions.
2482 * This has to be after loading [scenario] and [map].startpos and
2483 * before we seek nations for players. */
2485}
2486
2487/************************************************************************/
2491{
2492 int x, y;
2493 struct player *owner = NULL;
2494 struct tile *claimer = NULL;
2495 struct player *eowner = NULL;
2496
2497 /* Check status and return if not OK (sg_success FALSE). */
2498 sg_check_ret();
2499
2500 if (game.info.is_new_game) {
2501 /* No owner/source information for a new game / scenario. */
2502 return;
2503 }
2504
2505 /* Owner and ownership source are stored as plain numbers */
2506 for (y = 0; y < MAP_NATIVE_HEIGHT; y++) {
2507 const char *buffer1 = secfile_lookup_str(loading->file,
2508 "map.owner%04d", y);
2509 const char *buffer2 = secfile_lookup_str(loading->file,
2510 "map.source%04d", y);
2511 const char *buffer3 = secfile_lookup_str(loading->file,
2512 "map.eowner%04d", y);
2513 const char *ptr1 = buffer1;
2514 const char *ptr2 = buffer2;
2515 const char *ptr3 = buffer3;
2516
2519 if (loading->version >= 30) {
2521 }
2522
2523 for (x = 0; x < MAP_NATIVE_WIDTH; x++) {
2524 char token1[TOKEN_SIZE];
2525 char token2[TOKEN_SIZE];
2526 char token3[TOKEN_SIZE];
2527 int number;
2528 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2529
2530 scanin(&ptr1, ",", token1, sizeof(token1));
2531 sg_failure_ret(token1[0] != '\0',
2532 "Map size not correct (map.owner%d).", y);
2533 if (strcmp(token1, "-") == 0) {
2534 owner = NULL;
2535 } else {
2537 "Got map owner %s in (%d, %d).", token1, x, y);
2538 owner = player_by_number(number);
2539 }
2540
2541 scanin(&ptr2, ",", token2, sizeof(token2));
2542 sg_failure_ret(token2[0] != '\0',
2543 "Map size not correct (map.source%d).", y);
2544 if (strcmp(token2, "-") == 0) {
2545 claimer = NULL;
2546 } else {
2548 "Got map source %s in (%d, %d).", token2, x, y);
2549 claimer = index_to_tile(&(wld.map), number);
2550 }
2551
2552 if (loading->version >= 30) {
2553 scanin(&ptr3, ",", token3, sizeof(token3));
2554 sg_failure_ret(token3[0] != '\0',
2555 "Map size not correct (map.eowner%d).", y);
2556 if (strcmp(token3, "-") == 0) {
2557 eowner = NULL;
2558 } else {
2560 "Got base owner %s in (%d, %d).", token3, x, y);
2561 eowner = player_by_number(number);
2562 }
2563 } else {
2564 eowner = owner;
2565 }
2566
2568 tile_claim_bases(ptile, eowner);
2569 log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
2570 }
2571 }
2572}
2573
2574/************************************************************************/
2578{
2579 int x, y;
2580
2581 /* Check status and return if not OK (sg_success FALSE). */
2582 sg_check_ret();
2583
2584 sg_failure_ret(loading->worked_tiles == NULL,
2585 "City worked map not loaded!");
2586
2587 loading->worked_tiles = fc_malloc(MAP_INDEX_SIZE *
2588 sizeof(*loading->worked_tiles));
2589
2590 for (y = 0; y < MAP_NATIVE_HEIGHT; y++) {
2591 const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
2592 y);
2593 const char *ptr = buffer;
2594
2595 sg_failure_ret(NULL != buffer,
2596 "Savegame corrupt - map line %d not found.", y);
2597 for (x = 0; x < MAP_NATIVE_WIDTH; x++) {
2598 char token[TOKEN_SIZE];
2599 int number;
2600 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2601
2602 scanin(&ptr, ",", token, sizeof(token));
2603 sg_failure_ret('\0' != token[0],
2604 "Savegame corrupt - map size not correct.");
2605 if (strcmp(token, "-") == 0) {
2606 number = -1;
2607 } else {
2608 sg_failure_ret(str_to_int(token, &number) && 0 < number,
2609 "Savegame corrupt - got tile worked by city "
2610 "id=%s in (%d, %d).", token, x, y);
2611 }
2612
2613 loading->worked_tiles[ptile->index] = number;
2614 }
2615 }
2616}
2617
2618/************************************************************************/
2622{
2623 /* Check status and return if not OK (sg_success FALSE). */
2624 sg_check_ret();
2625
2626 players_iterate(pplayer) {
2627 /* Allocate player private map here; it is needed in different modules
2628 * besides this one ((i.e. sg_load_player_*()). */
2629 player_map_init(pplayer);
2631
2633 "game.save_known")) {
2634 int lines = player_slot_max_used_number()/32 + 1, j, p, l, i;
2635 unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
2636
2637 for (l = 0; l < lines; l++) {
2638 for (j = 0; j < 8; j++) {
2639 for (i = 0; i < 4; i++) {
2640 /* Only bother trying to load the map for this halfbyte if at least
2641 * one of the corresponding player slots is in use. */
2642 if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
2643 LOAD_MAP_CHAR(ch, ptile,
2644 known[l * MAP_INDEX_SIZE + tile_index(ptile)]
2645 |= ascii_hex2bin(ch, j),
2646 loading->file, "map.k%02d_%04d", l * 8 + j);
2647 break;
2648 }
2649 }
2650 }
2651 }
2652
2653 players_iterate(pplayer) {
2654 dbv_clr_all(&pplayer->tile_known);
2656
2657 /* HACK: we read the known data from hex into 32-bit integers, and
2658 * now we convert it to the known tile data of each player. */
2659 whole_map_iterate(&(wld.map), ptile) {
2660 players_iterate(pplayer) {
2661 p = player_index(pplayer);
2662 l = player_index(pplayer) / 32;
2663
2664 if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
2665 map_set_known(ptile, pplayer);
2666 }
2669
2670 FC_FREE(known);
2671 }
2672}
2673
2674/* =======================================================================
2675 * Load player data.
2676 *
2677 * This is splitted into two parts as some data can only be loaded if the
2678 * number of players is known and the corresponding player slots are
2679 * defined.
2680 * ======================================================================= */
2681
2682/************************************************************************/
2686{
2687 int i, k, nplayers;
2688 const char *str;
2689 bool shuffle_loaded = TRUE;
2690
2691 /* Check status and return if not OK (sg_success FALSE). */
2692 sg_check_ret();
2693
2694 if (S_S_INITIAL == loading->server_state
2695 || game.info.is_new_game) {
2696 /* Nothing more to do. */
2697 return;
2698 }
2699
2700 /* Load destroyed wonders: */
2702 "players.destroyed_wonders");
2703 sg_failure_ret(str != NULL, "%s", secfile_error());
2704 sg_failure_ret(strlen(str) == loading->improvement.size,
2705 "Invalid length for 'players.destroyed_wonders' ("
2706 SIZE_T_PRINTF" ~= " SIZE_T_PRINTF ")",
2707 strlen(str), loading->improvement.size);
2708 for (k = 0; k < loading->improvement.size; k++) {
2709 sg_failure_ret(str[k] == '1' || str[k] == '0',
2710 "Undefined value '%c' within "
2711 "'players.destroyed_wonders'.", str[k]);
2712
2713 if (str[k] == '1') {
2714 struct impr_type *pimprove =
2715 improvement_by_rule_name(loading->improvement.order[k]);
2716
2717 if (pimprove) {
2720 }
2721 }
2722 }
2723
2724 server.identity_number
2725 = secfile_lookup_int_default(loading->file, server.identity_number,
2726 "players.identity_number_used");
2727
2728 /* First remove all defined players. */
2729 players_iterate(pplayer) {
2730 server_remove_player(pplayer);
2732
2733 /* Now, load the players from the savefile. */
2734 player_slots_iterate(pslot) {
2735 struct player *pplayer;
2736 struct rgbcolor *prgbcolor = NULL;
2737 int pslot_id = player_slot_index(pslot);
2738
2739 if (NULL == secfile_section_lookup(loading->file, "player%d",
2740 pslot_id)) {
2741 continue;
2742 }
2743
2744 /* Get player AI type. */
2745 str = secfile_lookup_str(loading->file, "player%d.ai_type",
2746 player_slot_index(pslot));
2747 sg_failure_ret(str != NULL, "%s", secfile_error());
2748
2749 /* Get player color */
2750 if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
2751 pslot_id)) {
2752 if (loading->version >= 10 && game_was_started()) {
2753 /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
2754 * as they predate the introduction of configurable player colors. */
2755 log_sg("Game has started, yet player %d has no color defined.",
2756 pslot_id);
2757 /* This will be fixed up later */
2758 } else {
2759 log_verbose("No color defined for player %d.", pslot_id);
2760 /* Colors will be assigned on game start, or at end of savefile
2761 * loading if game has already started */
2762 }
2763 }
2764
2765 /* Create player. */
2766 pplayer = server_create_player(player_slot_index(pslot), str,
2767 prgbcolor,
2770 sg_failure_ret(pplayer != NULL, "Invalid AI type: '%s'!", str);
2771
2772 server_player_init(pplayer, FALSE, FALSE);
2773
2774 /* Free the color definition. */
2776
2777 /* Multipliers (policies) */
2778
2779 /* First initialise player values with ruleset defaults; this will
2780 * cover any in the ruleset not known when the savefile was created. */
2781 multipliers_iterate(pmul) {
2782 pplayer->multipliers[multiplier_index(pmul)].value
2783 = pplayer->multipliers[multiplier_index(pmul)].target = pmul->def;
2785
2786 /* Now override with any values from the savefile. */
2787 for (k = 0; k < loading->multiplier.size; k++) {
2788 const struct multiplier *pmul = loading->multiplier.order[k];
2789
2790 if (pmul) {
2792 int val =
2794 "player%d.multiplier%d.val",
2795 player_slot_index(pslot), k);
2796 int rval = (((CLIP(pmul->start, val, pmul->stop)
2797 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2798
2799 if (rval != val) {
2800 log_verbose("Player %d had illegal value for multiplier \"%s\": "
2801 "was %d, clamped to %d", pslot_id,
2802 multiplier_rule_name(pmul), val, rval);
2803 }
2804 pplayer->multipliers[idx].value = rval;
2805
2806 val =
2808 pplayer->multipliers[idx].value,
2809 "player%d.multiplier%d.target",
2810 player_slot_index(pslot), k);
2811 rval = (((CLIP(pmul->start, val, pmul->stop)
2812 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2813
2814 if (rval != val) {
2815 log_verbose("Player %d had illegal value for multiplier_target "
2816 "\"%s\": was %d, clamped to %d", pslot_id,
2817 multiplier_rule_name(pmul), val, rval);
2818 }
2819 pplayer->multipliers[idx].target = rval;
2820
2821 /* Never present in savegame2 format */
2822 pplayer->multipliers[idx].changed = 0;
2823 } /* else silently discard multiplier not in current ruleset */
2824 }
2825
2826 /* Just in case savecompat starts adding it in the future. */
2827 pplayer->server.border_vision =
2829 "player%d.border_vision",
2830 player_slot_index(pslot));
2832
2833 /* check number of players */
2834 nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
2835 sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
2836 "(%d) from the loaded game does not match the number of "
2837 "players present (%d).", nplayers, player_count());
2838
2839 /* Load team informations. */
2840 players_iterate(pplayer) {
2841 int team;
2842 struct team_slot *tslot = NULL;
2843
2845 "player%d.team_no",
2846 player_number(pplayer))
2848 "Invalid team definition for player %s (nb %d).",
2849 player_name(pplayer), player_number(pplayer));
2850 /* Should never fail when slot given is not nullptr */
2851 team_add_player(pplayer, team_new(tslot));
2853
2854 /* Loading the shuffle list is quite complex. At the time of saving the
2855 * shuffle data is saved as
2856 * shuffled_player_<number> = player_slot_id
2857 * where number is an increasing number and player_slot_id is a number
2858 * between 0 and the maximum number of player slots. Now we have to create
2859 * a list
2860 * shuffler_players[number] = player_slot_id
2861 * where all player slot IDs are used exactly one time. The code below
2862 * handles this ... */
2863 if (secfile_lookup_int_default(loading->file, -1,
2864 "players.shuffled_player_%d", 0) >= 0) {
2865 int slots = player_slot_count();
2866 int plrcount = player_count();
2869
2870 for (i = 0; i < slots; i++) {
2871 /* Array to save used numbers. */
2873 /* List of all player IDs (needed for set_shuffled_players()). It is
2874 * initialised with the value -1 to indicate that no value is set. */
2875 shuffled_players[i] = -1;
2876 }
2877
2878 /* Load shuffled player list. */
2879 for (i = 0; i < plrcount; i++) {
2880 int shuffle
2882 "players.shuffled_player_%d", i);
2883
2884 if (shuffle == -1) {
2885 log_sg("Missing player shuffle information (index %d) "
2886 "- reshuffle player list!", i);
2888 break;
2889 } else if (shuffled_player_set[shuffle]) {
2890 log_sg("Player shuffle %d used two times "
2891 "- reshuffle player list!", shuffle);
2893 break;
2894 }
2895 /* Set this ID as used. */
2897
2898 /* Save the player ID in the shuffle list. */
2900 }
2901
2902 if (shuffle_loaded) {
2903 /* Insert missing numbers. */
2904 int shuffle_index = plrcount;
2905
2906 for (i = 0; i < slots; i++) {
2907 if (!shuffled_player_set[i]) {
2909 }
2910
2911 /* shuffle_index must not grow higher than size of shuffled_players. */
2913 "Invalid player shuffle data!");
2914 }
2915
2916#ifdef FREECIV_DEBUG
2917 log_debug("[load shuffle] player_count() = %d", player_count());
2918 player_slots_iterate(pslot) {
2919 int plrid = player_slot_index(pslot);
2920
2921 log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
2923 shuffled_player_set[plrid] ? "is used" : "-");
2925#endif /* FREECIV_DEBUG */
2926
2927 /* Set shuffle list from savegame. */
2929 }
2930 }
2931
2932 if (!shuffle_loaded) {
2933 /* No shuffled players included or error loading them, so shuffle them
2934 * (this may include scenarios). */
2936 }
2937}
2938
2939/************************************************************************/
2943{
2944 /* Check status and return if not OK (sg_success FALSE). */
2945 sg_check_ret();
2946
2947 if (game.info.is_new_game) {
2948 /* Nothing to do. */
2949 return;
2950 }
2951
2952 players_iterate(pplayer) {
2953 sg_load_player_main(loading, pplayer);
2955 sg_load_player_units(loading, pplayer);
2957
2958 /* Check the success of the functions above. */
2959 sg_check_ret();
2960
2961 /* print out some informations */
2962 if (is_ai(pplayer)) {
2963 log_normal(_("%s has been added as %s level AI-controlled player "
2964 "(%s)."), player_name(pplayer),
2965 ai_level_translated_name(pplayer->ai_common.skill_level),
2966 ai_name(pplayer->ai));
2967 } else {
2968 log_normal(_("%s has been added as human player."),
2969 player_name(pplayer));
2970 }
2972
2973 /* Also load the transport status of the units here. It must be a special
2974 * case as all units must be known (unit on an allied transporter). */
2975 players_iterate(pplayer) {
2976 /* Load unit transport status. */
2979
2980 /* Savegame may contain nation assignments that are incompatible with the
2981 * current nationset -- for instance, if it predates the introduction of
2982 * nationsets. Ensure they are compatible, one way or another. */
2984
2985 /* Some players may have invalid nations in the ruleset. Once all players
2986 * are loaded, pick one of the remaining nations for them. */
2987 players_iterate(pplayer) {
2988 if (pplayer->nation == NO_NATION_SELECTED) {
2991 /* TRANS: Minor error message: <Leader> ... <Poles>. */
2992 log_sg(_("%s had invalid nation; changing to %s."),
2993 player_name(pplayer), nation_plural_for_player(pplayer));
2994
2995 ai_traits_init(pplayer);
2996 }
2998
2999 /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
3002 if (pplayers_allied(plr, aplayer)) {
3004 DS_ALLIANCE);
3005
3008 log_sg("Illegal alliance structure detected: "
3009 "%s alliance to %s reduced to peace treaty.",
3014 }
3015 }
3018
3019 /* Update cached city illness. This can depend on trade routes,
3020 * so can't be calculated until all players have been loaded. */
3021 if (game.info.illness_on) {
3022 cities_iterate(pcity) {
3023 pcity->server.illness
3024 = city_illness_calc(pcity, NULL, NULL,
3025 &(pcity->illness_trade), NULL);
3027 }
3028
3029 /* Update all city information. This must come after all cities are
3030 * loaded (in player_load) but before player (dumb) cities are loaded
3031 * in player_load_vision(). */
3032 players_iterate(plr) {
3033 city_list_iterate(plr->cities, pcity) {
3034 city_refresh(pcity);
3035 sanity_check_city(pcity);
3036 CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
3039
3040 /* Since the cities must be placed on the map to put them on the
3041 player map we do this afterwards */
3042 players_iterate(pplayer) {
3044 /* Check the success of the function above. */
3045 sg_check_ret();
3047
3048 /* Check shared vision. Shared tiles are never given in savegame2 save */
3049 players_iterate(pplayer) {
3050 BV_CLR_ALL(pplayer->gives_shared_vision);
3051 BV_CLR_ALL(pplayer->gives_shared_tiles);
3052 BV_CLR_ALL(pplayer->server.really_gives_vision);
3054
3055 /* Set up shared vision... */
3056 players_iterate(pplayer) {
3057 int plr1 = player_index(pplayer);
3058
3060 int plr2 = player_index(pplayer2);
3061
3063 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
3064 give_shared_vision(pplayer, pplayer2);
3065 }
3068
3069 /* ...and check it */
3072 /* TODO: Is there a good reason player is not marked as
3073 * giving shared vision to themselves -> really_gives_vision()
3074 * returning FALSE when pplayer1 == pplayer2 */
3075 if (pplayer1 != pplayer2
3078 sg_regr(3000900,
3079 _("%s did not give shared vision to team member %s."),
3082 }
3084 sg_regr(3000900,
3085 _("%s did not give shared vision to team member %s."),
3088 }
3089 }
3092
3095
3096 /* All vision is ready; this calls city_thaw_workers_queue(). */
3098
3099 /* Make sure everything is consistent. */
3100 players_iterate(pplayer) {
3101 unit_list_iterate(pplayer->units, punit) {
3103 struct tile *ptile = unit_tile(punit);
3104
3105 log_sg("%s doing illegal activity in savegame!",
3107 log_sg("Activity: %s, Target: %s, Tile: (%d, %d), Terrain: %s",
3111 : "missing",
3112 TILE_XY(ptile), terrain_rule_name(tile_terrain(ptile)));
3114 }
3117
3118 cities_iterate(pcity) {
3119 city_refresh(pcity);
3120 city_thaw_workers(pcity); /* may auto_arrange_workers() */
3122
3123 /* Player colors are always needed once game has started. Pre-2.4 savegames
3124 * lack them. This cannot be in compatibility conversion layer as we need
3125 * all the player data available to be able to assign best colors. */
3126 if (game_was_started()) {
3128 }
3129}
3130
3131/************************************************************************/
3135 struct player *plr)
3136{
3137 const char **slist;
3138 int i, plrno = player_number(plr);
3139 const char *str;
3140 struct government *gov;
3141 const char *level;
3142 const char *barb_str;
3143 size_t nval;
3144
3145 /* Check status and return if not OK (sg_success FALSE). */
3146 sg_check_ret();
3147
3148 /* Basic player data. */
3149 str = secfile_lookup_str(loading->file, "player%d.name", plrno);
3150 sg_failure_ret(str != NULL, "%s", secfile_error());
3152 sz_strlcpy(plr->username,
3154 "player%d.username", plrno));
3156 "player%d.unassigned_user", plrno),
3157 "%s", secfile_error());
3160 "player%d.orig_username",
3161 plrno));
3164 "player%d.ranked_username",
3165 plrno));
3167 "player%d.unassigned_ranked", plrno),
3168 "%s", secfile_error());
3170 "player%d.delegation_username",
3171 plrno);
3172 /* Defaults to no delegation. */
3173 if (strlen(str)) {
3175 }
3176
3177 /* Player flags */
3178 BV_CLR_ALL(plr->flags);
3179 slist = secfile_lookup_str_vec(loading->file, &nval, "player%d.flags", plrno);
3180 for (i = 0; i < nval; i++) {
3181 const char *sval = slist[i];
3183
3184 sg_failure_ret(plr_flag_id_is_valid(fid), "Invalid player flag \"%s\".", sval);
3185
3186 BV_SET(plr->flags, fid);
3187 }
3188 free(slist);
3189
3190 /* Nation */
3191 str = secfile_lookup_str(loading->file, "player%d.nation", plrno);
3193 if (plr->nation != NULL) {
3194 ai_traits_init(plr);
3195 }
3196
3197 /* Government */
3198 str = secfile_lookup_str(loading->file, "player%d.government_name",
3199 plrno);
3201 sg_failure_ret(gov != NULL, "Player%d: unsupported government \"%s\".",
3202 plrno, str);
3203 plr->government = gov;
3204
3205 /* Target government */
3207 "player%d.target_government_name", plrno);
3208 if (str != NULL) {
3210 } else {
3211 plr->target_government = NULL;
3212 }
3215 "player%d.revolution_finishes", plrno);
3216
3217 /* Load diplomatic data (diplstate + embassy + vision).
3218 * Shared vision is loaded in sg_load_players(). */
3220 players_iterate(pplayer) {
3221 char buf[32];
3222 int unconverted;
3223 struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
3224 i = player_index(pplayer);
3225
3226 /* load diplomatic status */
3227 fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
3228
3229 unconverted =
3230 secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
3231 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
3232 /* Look up what state the unconverted number represents. */
3233 ds->type = loading->ds_t.order[unconverted];
3234 } else {
3235 log_sg("No valid diplomatic state type between players %d and %d",
3236 plrno, i);
3237
3238 ds->type = DS_WAR;
3239 }
3240
3241 unconverted =
3242 secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
3243 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
3244 /* Look up what state the unconverted number represents. */
3245 ds->max_state = loading->ds_t.order[unconverted];
3246 } else {
3247 log_sg("No valid diplomatic max_state between players %d and %d",
3248 plrno, i);
3249
3250 ds->max_state = DS_WAR;
3251 }
3252
3253 /* FIXME: If either party is barbarian, we cannot enforce below check */
3254#if 0
3255 if (ds->type == DS_WAR && ds->first_contact_turn <= 0) {
3256 sg_regr(3020000,
3257 "Player%d: War with player %d who has never been met. "
3258 "Reverted to No Contact state.", plrno, i);
3259 ds->type = DS_NO_CONTACT;
3260 }
3261#endif
3262
3263 if (valid_dst_closest(ds) != ds->max_state) {
3264 sg_regr(3020000,
3265 "Player%d: closest diplstate to player %d less than current. "
3266 "Updated.", plrno, i);
3267 ds->max_state = ds->type;
3268 }
3269
3270 ds->first_contact_turn =
3272 "%s.first_contact_turn", buf);
3273 ds->turns_left =
3274 secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
3275 ds->has_reason_to_cancel =
3277 "%s.has_reason_to_cancel", buf);
3278 ds->contact_turns_left =
3280 "%s.contact_turns_left", buf);
3281
3282 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
3283 buf)) {
3284 BV_SET(plr->real_embassy, i);
3285 }
3286 /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
3287 * must be known. */
3289
3290 /* load ai data */
3292 char buf[32];
3293
3294 fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
3296
3298 secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
3299 CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
3301
3302 CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
3303
3304 /* Some sane defaults */
3305 plr->ai_common.fuzzy = 0;
3306 plr->ai_common.expand = 100;
3307 plr->ai_common.science_cost = 100;
3308
3309
3311 "player%d.ai.level", plrno);
3312 if (level != NULL) {
3313 if (!fc_strcasecmp("Handicapped", level)) {
3314 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
3316 } else {
3318 }
3319 } else {
3321 }
3322
3327 "player%d.ai.skill_level",
3328 plrno));
3329 }
3330
3332 "player%d.ai.barb_type", plrno);
3334
3336 log_sg("Player%d: Invalid barbarian type \"%s\". "
3337 "Changed to \"None\".", plrno, barb_str);
3339 }
3340
3341 if (is_barbarian(plr)) {
3342 server.nbarbarians++;
3343 }
3344
3345 if (is_ai(plr)) {
3347 CALL_PLR_AI_FUNC(gained_control, plr, plr);
3348 }
3349
3350 /* Load nation style. */
3351 {
3352 struct nation_style *style;
3353
3354 str = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
3355
3356 /* Handle pre-2.6 savegames */
3357 if (str == NULL) {
3358 str = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
3359 plrno);
3360 }
3361
3362 sg_failure_ret(str != NULL, "%s", secfile_error());
3363 style = style_by_rule_name(str);
3364 if (style == NULL) {
3365 style = style_by_number(0);
3366 log_sg("Player%d: unsupported city_style_name \"%s\". "
3367 "Changed to \"%s\".", plrno, str, style_rule_name(style));
3368 }
3369 plr->style = style;
3370 }
3371
3373 "player%d.idle_turns", plrno),
3374 "%s", secfile_error());
3376 "player%d.is_male", plrno);
3378 "player%d.is_alive", plrno),
3379 "%s", secfile_error());
3381 "player%d.turns_alive", plrno),
3382 "%s", secfile_error());
3384 "player%d.last_war", plrno),
3385 "%s", secfile_error());
3387 "player%d.phase_done", plrno);
3389 "player%d.gold", plrno),
3390 "%s", secfile_error());
3392 "player%d.rates.tax", plrno),
3393 "%s", secfile_error());
3395 "player%d.rates.science", plrno),
3396 "%s", secfile_error());
3398 "player%d.rates.luxury", plrno),
3399 "%s", secfile_error());
3400 plr->server.bulbs_last_turn =
3402 "player%d.research.bulbs_last_turn", plrno);
3403
3404 /* Traits */
3405 if (plr->nation) {
3406 for (i = 0; i < loading->trait.size; i++) {
3407 enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
3408
3409 if (trait_is_valid(tr)) {
3410 int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
3411 plrno, i);
3412
3413 if (val != -1) {
3414 plr->ai_common.traits[tr].val = val;
3415 }
3416
3418 "player%d.trait%d.mod", plrno, i),
3419 "%s", secfile_error());
3420 plr->ai_common.traits[tr].mod = val;
3421 }
3422 }
3423 }
3424
3425 /* Achievements */
3426 {
3427 int count;
3428
3429 count = secfile_lookup_int_default(loading->file, -1,
3430 "player%d.achievement_count", plrno);
3431
3432 if (count > 0) {
3433 for (i = 0; i < count; i++) {
3434 const char *name;
3435 struct achievement *pach;
3436 bool first;
3437
3439 "player%d.achievement%d.name", plrno, i);
3441
3443 "Unknown achievement \"%s\".", name);
3444
3446 "player%d.achievement%d.first",
3447 plrno, i),
3448 "achievement error: %s", secfile_error());
3449
3450 sg_failure_ret(pach->first == NULL || !first,
3451 "Multiple players listed as first to get achievement \"%s\".",
3452 name);
3453
3454 BV_SET(pach->achievers, player_index(plr));
3455
3456 if (first) {
3457 pach->first = plr;
3458 }
3459 }
3460 }
3461 }
3462
3463 /* Player score. */
3464 plr->score.happy =
3466 "score%d.happy", plrno);
3467 plr->score.content =
3469 "score%d.content", plrno);
3470 plr->score.unhappy =
3472 "score%d.unhappy", plrno);
3473 plr->score.angry =
3475 "score%d.angry", plrno);
3476
3477 /* Make sure that the score about specialists in current ruleset that
3478 * were not present at saving time are set to zero. */
3480 plr->score.specialists[sp] = 0;
3482
3483 for (i = 0; i < loading->specialist.size; i++) {
3484 plr->score.specialists[specialist_index(loading->specialist.order[i])]
3486 "score%d.specialists%d", plrno, i);
3487 }
3488
3489 plr->score.wonders =
3491 "score%d.wonders", plrno);
3492 plr->score.techs =
3494 "score%d.techs", plrno);
3495 plr->score.techout =
3497 "score%d.techout", plrno);
3498 plr->score.landarea =
3500 "score%d.landarea", plrno);
3501 plr->score.settledarea =
3503 "score%d.settledarea", plrno);
3504 plr->score.population =
3506 "score%d.population", plrno);
3507 plr->score.cities =
3509 "score%d.cities", plrno);
3510 plr->score.units =
3512 "score%d.units", plrno);
3513 plr->score.pollution =
3515 "score%d.pollution", plrno);
3516 plr->score.literacy =
3518 "score%d.literacy", plrno);
3519 plr->score.bnp =
3521 "score%d.bnp", plrno);
3522 plr->score.mfg =
3524 "score%d.mfg", plrno);
3525 plr->score.spaceship =
3527 "score%d.spaceship", plrno);
3528 plr->score.units_built =
3530 "score%d.units_built", plrno);
3531 plr->score.units_killed =
3533 "score%d.units_killed", plrno);
3534 plr->score.units_lost =
3536 "score%d.units_lost", plrno);
3537 plr->score.units_used = 0; /* Was never saved to savegame2.c saves */
3538 plr->score.culture =
3540 "score%d.culture", plrno);
3541 plr->score.game =
3543 "score%d.total", plrno);
3544
3545 /* Load space ship data. */
3546 {
3547 struct player_spaceship *ship = &plr->spaceship;
3548 char prefix[32];
3549 const char *st;
3550 int ei;
3551
3552 fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
3555 &ei,
3556 "%s.state", prefix),
3557 "%s", secfile_error());
3558 ship->state = ei;
3559
3560 if (ship->state != SSHIP_NONE) {
3561 sg_failure_ret(secfile_lookup_int(loading->file, &ship->structurals,
3562 "%s.structurals", prefix),
3563 "%s", secfile_error());
3564 sg_failure_ret(secfile_lookup_int(loading->file, &ship->components,
3565 "%s.components", prefix),
3566 "%s", secfile_error());
3568 "%s.modules", prefix),
3569 "%s", secfile_error());
3571 "%s.fuel", prefix),
3572 "%s", secfile_error());
3573 sg_failure_ret(secfile_lookup_int(loading->file, &ship->propulsion,
3574 "%s.propulsion", prefix),
3575 "%s", secfile_error());
3576 sg_failure_ret(secfile_lookup_int(loading->file, &ship->habitation,
3577 "%s.habitation", prefix),
3578 "%s", secfile_error());
3579 sg_failure_ret(secfile_lookup_int(loading->file, &ship->life_support,
3580 "%s.life_support", prefix),
3581 "%s", secfile_error());
3582 sg_failure_ret(secfile_lookup_int(loading->file, &ship->solar_panels,
3583 "%s.solar_panels", prefix),
3584 "%s", secfile_error());
3585
3586 st = secfile_lookup_str(loading->file, "%s.structure", prefix);
3587 sg_failure_ret(st != NULL, "%s", secfile_error())
3588 for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
3589 sg_failure_ret(st[i] == '1' || st[i] == '0',
3590 "Undefined value '%c' within '%s.structure'.", st[i],
3591 prefix)
3592
3593 if (!(st[i] == '0')) {
3594 BV_SET(ship->structure, i);
3595 }
3596 }
3597 if (ship->state >= SSHIP_LAUNCHED) {
3598 sg_failure_ret(secfile_lookup_int(loading->file, &ship->launch_year,
3599 "%s.launch_year", prefix),
3600 "%s", secfile_error());
3601 }
3603 }
3604 }
3605
3606 /* Load lost wonder data. */
3607 str = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
3608 /* If not present, probably an old savegame; nothing to be done */
3609 if (str != NULL) {
3610 int k;
3611
3612 sg_failure_ret(strlen(str) == loading->improvement.size,
3613 "Invalid length for 'player%d.lost_wonders' ("
3614 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ")",
3615 plrno, strlen(str), loading->improvement.size);
3616 for (k = 0; k < loading->improvement.size; k++) {
3617 sg_failure_ret(str[k] == '1' || str[k] == '0',
3618 "Undefined value '%c' within "
3619 "'player%d.lost_wonders'.", plrno, str[k]);
3620
3621 if (str[k] == '1') {
3622 struct impr_type *pimprove =
3623 improvement_by_rule_name(loading->improvement.order[k]);
3624
3625 if (pimprove) {
3626 plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
3627 }
3628 }
3629 }
3630 }
3631
3632 plr->history =
3633 secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
3634 plr->server.huts =
3635 secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
3636}
3637
3638/************************************************************************/
3642 struct player *plr)
3643{
3644 int ncities, i, plrno = player_number(plr);
3645 bool tasks_handled;
3646 int wlist_max_length;
3647
3648 /* Check status and return if not OK (sg_success FALSE). */
3649 sg_check_ret();
3650
3652 "player%d.ncities", plrno),
3653 "%s", secfile_error());
3654
3655 if (!plr->is_alive && ncities > 0) {
3656 log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
3657 ncities = 0;
3658 }
3659
3660 if (!player_has_flag(plr, PLRF_FIRST_CITY) && ncities > 0) {
3661 /* Probably barbarians in an old savegame; fix up */
3663 }
3664
3666 "player%d.wl_max_length",
3667 plrno);
3668
3669 /* Load all cities of the player. */
3670 for (i = 0; i < ncities; i++) {
3671 char buf[32];
3672 struct city *pcity;
3673
3674 fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
3675
3676 /* Create a dummy city. */
3677 pcity = create_city_virtual(plr, NULL, buf);
3678 adv_city_alloc(pcity);
3679 if (!sg_load_player_city(loading, plr, pcity, buf, wlist_max_length)) {
3680 adv_city_free(pcity);
3681 destroy_city_virtual(pcity);
3682 sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
3683 }
3684
3686 idex_register_city(&wld, pcity);
3687
3688 /* Load the information about the nationality of citizens. This is done
3689 * here because the city sanity check called by citizens_update() requires
3690 * that the city is registered. */
3692
3693 /* After everything is loaded, but before vision. */
3694 map_claim_ownership(city_tile(pcity), plr, city_tile(pcity), TRUE);
3695
3696 /* adding the city contribution to fog-of-war */
3697 pcity->server.vision = vision_new(plr, city_tile(pcity));
3699 city_refresh_vision(pcity);
3700
3701 city_list_append(plr->cities, pcity);
3702 }
3703
3705 for (i = 0; !tasks_handled; i++) {
3706 int city_id;
3707 struct city *pcity = NULL;
3708
3709 city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
3710 plrno, i);
3711
3712 if (city_id != -1) {
3713 pcity = player_city_by_number(plr, city_id);
3714 }
3715
3716 if (pcity != NULL) {
3717 const char *str;
3718 int nat_x, nat_y;
3719 struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
3720
3721 nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
3722 nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
3723
3724 ptask->ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3725
3726 str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
3728
3730 "Unknown workertask activity %s", str);
3731
3732 str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
3733
3734 if (strcmp("-", str)) {
3736
3737 sg_failure_ret(ptask->tgt != NULL,
3738 "Unknown workertask target %s", str);
3739 } else {
3740 ptask->tgt = NULL;
3741 }
3742
3743 ptask->want = secfile_lookup_int_default(loading->file, 1,
3744 "player%d.task%d.want", plrno, i);
3745
3747 } else {
3749 }
3750 }
3751}
3752
3753/************************************************************************/
3756static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
3757 struct city *pcity, const char *citystr,
3758 int wlist_max_length)
3759{
3760 struct player *past;
3761 const char *kind, *name, *str;
3762 int id, i, repair, sp_count = 0, workers = 0, value;
3763 int nat_x, nat_y;
3764 citizens size;
3765 const char *stylename;
3766 const struct civ_map *nmap = &(wld.map);
3767
3769 FALSE, "%s", secfile_error());
3771 FALSE, "%s", secfile_error());
3772 pcity->tile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3773 sg_warn_ret_val(NULL != pcity->tile, FALSE,
3774 "%s has invalid center tile (%d, %d)",
3775 citystr, nat_x, nat_y);
3777 "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
3778
3779 /* Instead of dying, use 'citystr' string for damaged name. */
3781 "%s.name", citystr));
3782
3783 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->id, "%s.id",
3784 citystr), FALSE, "%s", secfile_error());
3785
3787 "%s.original", citystr);
3788 past = player_by_number(id);
3789 if (NULL != past) {
3790 pcity->original = past;
3791 }
3792
3793 /* savegame2 saves never had this information. Guess. */
3794 if (pcity->original != plr) {
3795 pcity->acquire_t = CACQ_CONQUEST;
3796 } else {
3797 pcity->acquire_t = CACQ_FOUNDED;
3798 }
3799
3800 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
3801 citystr), FALSE, "%s", secfile_error());
3802 size = (citizens)value; /* Set the correct type */
3803 sg_warn_ret_val(value == (int)size, FALSE,
3804 "Invalid city size: %d, set to %d", value, size);
3805 city_size_set(pcity, size);
3806
3807 for (i = 0; i < loading->specialist.size; i++) {
3808 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
3809 citystr, i),
3810 FALSE, "%s", secfile_error());
3811 pcity->specialists[specialist_index(loading->specialist.order[i])]
3812 = (citizens)value;
3813 sp_count += value;
3814 }
3815
3816 /* savegame2.c saves were ever saved with MAX_TRADE_ROUTES_OLD routes max */
3817 for (i = 0; i < MAX_TRADE_ROUTES_OLD; i++) {
3818 int partner = secfile_lookup_int_default(loading->file, 0,
3819 "%s.traderoute%d", citystr, i);
3820
3821 if (partner != 0) {
3822 struct trade_route *proute = fc_malloc(sizeof(struct trade_route));
3823
3824 proute->partner = partner;
3826 proute->goods = goods_by_number(0); /* First good */
3827
3829 }
3830 }
3831
3833 "%s.food_stock", citystr),
3834 FALSE, "%s", secfile_error());
3836 "%s.shield_stock", citystr),
3837 FALSE, "%s", secfile_error());
3838 pcity->history =
3839 secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
3840
3841 pcity->airlift =
3842 secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
3843 pcity->was_happy =
3844 secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
3845 citystr);
3846 pcity->had_famine = FALSE;
3847
3848 pcity->turn_plague =
3849 secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
3850
3852 "%s.anarchy", citystr),
3853 FALSE, "%s", secfile_error());
3854 pcity->rapture =
3855 secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
3856 pcity->steal =
3857 secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
3858
3859 /* Before did_buy for undocumented hack */
3860 pcity->turn_founded =
3861 secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
3862 citystr);
3863 sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
3864 citystr), FALSE, "%s", secfile_error());
3865 pcity->did_buy = (i != 0);
3866 if (i == -1 && pcity->turn_founded == -2) {
3867 /* Undocumented hack */
3868 pcity->turn_founded = game.info.turn;
3869 }
3870
3871 pcity->did_sell
3872 = secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
3873
3875 "%s.turn_last_built", citystr),
3876 FALSE, "%s", secfile_error());
3877
3878 kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
3879 citystr);
3880 name = secfile_lookup_str(loading->file, "%s.currently_building_name",
3881 citystr);
3882 pcity->production = universal_by_rule_name(kind, name);
3884 "%s.currently_building: unknown \"%s\" \"%s\".",
3885 citystr, kind, name);
3886
3887 kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
3888 citystr);
3889 name = secfile_lookup_str(loading->file, "%s.changed_from_name",
3890 citystr);
3893 "%s.changed_from: unknown \"%s\" \"%s\".",
3894 citystr, kind, name);
3895
3896 pcity->before_change_shields =
3898 "%s.before_change_shields", citystr);
3899 pcity->caravan_shields =
3901 "%s.caravan_shields", citystr);
3902 pcity->disbanded_shields =
3904 "%s.disbanded_shields", citystr);
3907 "%s.last_turns_shield_surplus",
3908 citystr);
3909
3911 "%s.style", citystr);
3912 if (stylename != NULL) {
3914 } else {
3915 pcity->style = 0;
3916 }
3917 if (pcity->style < 0) {
3918 pcity->style = city_style(pcity);
3919 }
3920
3921 pcity->server.synced = FALSE; /* Must re-sync with clients */
3922
3923 /* Initialise list of city improvements. */
3924 for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
3925 pcity->built[i].turn = I_NEVER;
3926 }
3927
3928 /* Load city improvements. */
3929 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
3931 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
3932 "Invalid length of '%s.improvements' ("
3933 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
3934 citystr, strlen(str), loading->improvement.size);
3935 for (i = 0; i < loading->improvement.size; i++) {
3936 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
3937 "Undefined value '%c' within '%s.improvements'.",
3938 str[i], citystr)
3939
3940 if (str[i] == '1') {
3941 struct impr_type *pimprove =
3942 improvement_by_rule_name(loading->improvement.order[i]);
3943
3944 if (pimprove) {
3945 city_add_improvement(pcity, pimprove);
3946 }
3947 }
3948 }
3949
3950 sg_failure_ret_val(loading->worked_tiles != NULL, FALSE,
3951 "No worked tiles map defined.");
3952
3953 city_freeze_workers(pcity);
3954
3955 /* Load new savegame with variable (squared) city radius and worked
3956 * tiles map */
3957
3958 int radius_sq
3959 = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
3960 citystr);
3961 city_map_radius_sq_set(pcity, radius_sq);
3962
3964 if (loading->worked_tiles[ptile->index] == pcity->id) {
3965 if (sq_map_distance(ptile, pcity->tile) > radius_sq) {
3966 log_sg("[%s] '%s' (%d, %d) has worker outside current radius "
3967 "at (%d, %d); repairing", citystr, city_name_get(pcity),
3968 TILE_XY(pcity->tile), TILE_XY(ptile));
3970 sp_count++;
3971 } else {
3972 tile_set_worked(ptile, pcity);
3973 workers++;
3974 }
3975
3976#ifdef FREECIV_DEBUG
3977 /* Set this tile to unused; a check for not resetted tiles is
3978 * included in game_load_internal() */
3979 loading->worked_tiles[ptile->index] = -1;
3980#endif /* FREECIV_DEBUG */
3981 }
3983
3984 if (tile_worked(city_tile(pcity)) != pcity) {
3985 struct city *pwork = tile_worked(city_tile(pcity));
3986
3987 if (NULL != pwork) {
3988 log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
3989 "(%d,%d) [%d]; repairing", citystr, city_name_get(pcity),
3992
3993 tile_set_worked(city_tile(pcity), NULL); /* remove tile from pwork */
3994 pwork->specialists[DEFAULT_SPECIALIST]++;
3996 } else {
3997 log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing",
3998 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)),
3999 city_size_get(pcity));
4000 }
4001
4002 /* repair pcity */
4003 tile_set_worked(city_tile(pcity), pcity);
4004 city_repair_size(pcity, -1);
4005 }
4006
4007 repair = city_size_get(pcity) - sp_count - (workers - FREE_WORKED_TILES);
4008 if (0 != repair) {
4009 log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
4010 "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
4011 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)), city_size_get(pcity),
4012 workers, FREE_WORKED_TILES, sp_count);
4013
4014 /* repair pcity */
4015 city_repair_size(pcity, repair);
4016 }
4017
4018 /* worklist_init() done in create_city_virtual() */
4019 worklist_load(loading->file, wlist_max_length, &pcity->worklist, "%s", citystr);
4020
4021 /* Load city options. */
4022 BV_CLR_ALL(pcity->city_options);
4023 for (i = 0; i < loading->coptions.size; i++) {
4024 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
4025 citystr, i)) {
4026 BV_SET(pcity->city_options, loading->coptions.order[i]);
4027 }
4028 }
4029 /* Was never stored to savegame2 saves */
4030 pcity->wlcb = WLCB_SMART;
4031
4032 CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
4033
4034 return TRUE;
4035}
4036
4037/************************************************************************/
4041 struct player *plr,
4042 struct city *pcity,
4043 const char *citystr)
4044{
4046 citizens size;
4047
4048 citizens_init(pcity);
4049 player_slots_iterate(pslot) {
4050 int nationality;
4051
4053 "%s.citizen%d", citystr,
4054 player_slot_index(pslot));
4055 if (nationality > 0 && !player_slot_is_used(pslot)) {
4056 log_sg("Citizens of an invalid nation for %s (player slot %d)!",
4057 city_name_get(pcity), player_slot_index(pslot));
4058 continue;
4059 }
4060
4061 if (nationality != -1 && player_slot_is_used(pslot)) {
4063 "Invalid value for citizens of player %d in %s: %d.",
4065 citizens_nation_set(pcity, pslot, nationality);
4066 }
4068 /* Sanity check. */
4069 size = citizens_count(pcity);
4070 if (size != city_size_get(pcity)) {
4071 if (size != 0) {
4072 /* size == 0 can be result from the fact that ruleset had no
4073 * nationality enabled at saving time, so no citizens at all
4074 * were saved. But something more serious must be going on if
4075 * citizens have been saved partially - if some of them are there. */
4076 log_sg("City size and number of citizens does not match in %s "
4077 "(%d != %d)! Repairing ...", city_name_get(pcity),
4078 city_size_get(pcity), size);
4079 }
4080 citizens_update(pcity, NULL);
4081 }
4082 }
4083}
4084
4085/************************************************************************/
4089 struct player *plr)
4090{
4091 int nunits, i, plrno = player_number(plr);
4092
4093 /* Check status and return if not OK (sg_success FALSE). */
4094 sg_check_ret();
4095
4097 "player%d.nunits", plrno),
4098 "%s", secfile_error());
4099 if (!plr->is_alive && nunits > 0) {
4100 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4101 nunits = 0; /* Some old savegames may be buggy. */
4102 }
4103
4104 for (i = 0; i < nunits; i++) {
4105 struct unit *punit;
4106 struct city *pcity;
4107 const char *name;
4108 char buf[32];
4109 struct unit_type *type;
4110 struct tile *ptile;
4111
4112 fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
4113
4114 name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
4116 sg_failure_ret(type != NULL, "%s: unknown unit type \"%s\".", buf, name);
4117
4118 /* Create a dummy unit. */
4119 punit = unit_virtual_create(plr, NULL, type, 0);
4120 if (!sg_load_player_unit(loading, plr, punit, buf)) {
4122 sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
4123 }
4124
4127
4128 if ((pcity = game_city_by_number(punit->homecity))) {
4130 } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
4131 log_sg("%s: bad home city %d.", buf, punit->homecity);
4133 }
4134
4135 ptile = unit_tile(punit);
4136
4137 /* allocate the unit's contribution to fog of war */
4140 /* NOTE: There used to be some map_set_known calls here. These were
4141 * unneeded since unfogging the tile when the unit sees it will
4142 * automatically reveal that tile. */
4143
4146
4147 /* Claim ownership of fortress? */
4148 if ((extra_owner(ptile) == NULL
4149 || pplayers_at_war(extra_owner(ptile), plr))
4151 tile_claim_bases(ptile, plr);
4152 }
4153 }
4154}
4155
4156/************************************************************************/
4166static int sg_order_to_action(int order, struct unit *act_unit,
4167 struct tile *tgt_tile)
4168{
4169 switch (order) {
4171 if (tile_city(tgt_tile)
4173 /* The player's cities are loaded right before their units. It wasn't
4174 * possible for rulesets to allow joining foreign cities before 3.0.
4175 * This means that a converted build city order only can be a Join
4176 * City order if it targets a domestic city. */
4177 return ACTION_JOIN_CITY;
4178 } else {
4179 /* Assume that the intention was to found a new city. */
4180 return ACTION_FOUND_CITY;
4181 }
4183 /* Maps one to one with each other. */
4184 return ACTION_HELP_WONDER;
4186 /* Maps one to one with each other. */
4187 return ACTION_TRADE_ROUTE;
4188 case ORDER_OLD_DISBAND:
4189 /* Added to the order system in the same commit as Help Wonder. Assume
4190 * that anyone that intended to order Help Wonder used Help Wonder. */
4191 /* Could in theory be intended as an order to disband in the field. Why
4192 * would the player give a unit an order to go to a non city location
4193 * and disband there? Assume the intention was to recover production
4194 * until a non recovering disband order is found. */
4196 case ORDER_OLD_HOMECITY:
4197 return ACTION_HOME_CITY;
4198 }
4199
4200 /* The order hasn't been replaced by an action. */
4201 return ACTION_NONE;
4202}
4203
4204/************************************************************************/
4208 struct player *plr, struct unit *punit,
4209 const char *unitstr)
4210{
4211 int activity;
4212 int nat_x, nat_y;
4213 enum tile_special_type target;
4214 struct extra_type *pextra = NULL;
4215 struct base_type *pbase = NULL;
4216 struct road_type *proad = NULL;
4217 struct tile *ptile;
4218 int extra_id;
4219 int base_id;
4220 int road_id;
4221 int ei;
4222 const char *facing_str;
4224 int natnbr;
4225 bool ai_controlled;
4226
4228 unitstr), FALSE, "%s", secfile_error());
4230 FALSE, "%s", secfile_error());
4232 FALSE, "%s", secfile_error());
4233
4234 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
4235 sg_warn_ret_val(NULL != ptile, FALSE, "%s invalid tile (%d, %d)",
4236 unitstr, nat_x, nat_y);
4237 unit_tile_set(punit, ptile);
4238
4241 "%s.facing", unitstr);
4242 if (facing_str[0] != 'x') {
4243 /* We don't touch punit->facing if savegame does not contain that
4244 * information. Initial orientation set by unit_virtual_create()
4245 * is as good as any. */
4246 enum direction8 facing = char2dir(facing_str[0]);
4247
4248 if (direction8_is_valid(facing)) {
4249 punit->facing = facing;
4250 } else {
4251 log_error("Illegal unit orientation '%s'", facing_str);
4252 }
4253 }
4254
4255 /* If savegame has unit nationality, it doesn't hurt to
4256 * internally set it even if nationality rules are disabled. */
4258 player_number(plr),
4259 "%s.nationality", unitstr);
4260
4262 if (punit->nationality == NULL) {
4263 punit->nationality = plr;
4264 }
4265
4267 "%s.homecity", unitstr), FALSE,
4268 "%s", secfile_error());
4270 "%s.moves", unitstr), FALSE,
4271 "%s", secfile_error());
4273 "%s.fuel", unitstr), FALSE,
4274 "%s", secfile_error());
4276 "%s.activity", unitstr), FALSE,
4277 "%s", secfile_error());
4278 activity = unit_activity_by_name(loading->activities.order[ei],
4280
4283 "%s.born", unitstr);
4285
4287 "%s.activity_tgt", unitstr);
4288
4289 if (extra_id != -2) {
4290 if (extra_id >= 0 && extra_id < loading->extra.size) {
4291 pextra = loading->extra.order[extra_id];
4292 set_unit_activity_targeted(punit, activity, pextra,
4293 activity_default_action(activity));
4294 } else if (activity == ACTIVITY_IRRIGATE) {
4298 punit);
4299 if (tgt != NULL) {
4302 } else {
4305 }
4306 } else if (activity == ACTIVITY_MINE) {
4308 EC_MINE,
4310 punit);
4311 if (tgt != NULL) {
4314 } else {
4317 }
4318 } else {
4319 set_unit_activity(punit, activity,
4320 activity_default_action(activity));
4321 }
4322 } else {
4323 /* extra_id == -2 -> activity_tgt not set */
4325 "%s.activity_base", unitstr);
4326 if (base_id >= 0 && base_id < loading->base.size) {
4327 pbase = loading->base.order[base_id];
4328 }
4330 "%s.activity_road", unitstr);
4331 if (road_id >= 0 && road_id < loading->road.size) {
4332 proad = loading->road.order[road_id];
4333 }
4334
4335 {
4337 loading->special.size /* S_LAST */,
4338 "%s.activity_target", unitstr);
4339 if (tgt_no >= 0 && tgt_no < loading->special.size) {
4340 target = loading->special.order[tgt_no];
4341 } else {
4342 target = S_LAST;
4343 }
4344 }
4345
4346 if (target == S_OLD_ROAD) {
4347 target = S_LAST;
4349 } else if (target == S_OLD_RAILROAD) {
4350 target = S_LAST;
4352 }
4353
4354 if (activity == ACTIVITY_OLD_ROAD) {
4355 activity = ACTIVITY_GEN_ROAD;
4357 } else if (activity == ACTIVITY_OLD_RAILROAD) {
4358 activity = ACTIVITY_GEN_ROAD;
4360 }
4361
4362 /* We need changed_from == ACTIVITY_IDLE by now so that
4363 * set_unit_activity() and friends don't spuriously restore activity
4364 * points -- unit should have been created this way */
4366
4367 if (activity == ACTIVITY_BASE) {
4368 if (pbase) {
4370 } else {
4371 log_sg("Cannot find base %d for %s to build",
4375 }
4376 } else if (activity == ACTIVITY_GEN_ROAD) {
4377 if (proad) {
4379 } else {
4380 log_sg("Cannot find road %d for %s to build",
4384 }
4385 } else if (activity == ACTIVITY_PILLAGE) {
4386 struct extra_type *a_target;
4387
4388 if (target != S_LAST) {
4389 a_target = special_extra_get(target);
4390 } else if (pbase != NULL) {
4392 } else if (proad != NULL) {
4394 } else {
4395 a_target = NULL;
4396 }
4397 /* An out-of-range base number is seen with old savegames. We take
4398 * it as indicating undirected pillaging. We will assign pillage
4399 * targets before play starts. */
4401 activity_default_action(activity));
4402 } else if (activity == ACTIVITY_IRRIGATE) {
4406 punit);
4407 if (tgt != NULL) {
4410 } else {
4413 }
4414 } else if (activity == ACTIVITY_MINE) {
4416 EC_MINE,
4418 punit);
4419 if (tgt != NULL) {
4422 } else {
4425 }
4426 } else if (activity == ACTIVITY_OLD_POLLUTION_SG2
4427 || activity == ACTIVITY_OLD_FALLOUT_SG2) {
4429 ERM_CLEAN,
4431 punit);
4432 if (tgt != NULL) {
4435 } else {
4438 }
4439 } else {
4441 activity_default_action(activity));
4442 }
4443 } /* activity_tgt == NULL */
4444
4446 "%s.activity_count", unitstr), FALSE,
4447 "%s", secfile_error());
4448
4451 "%s.changed_from", unitstr);
4452
4454 "%s.changed_from_tgt", unitstr);
4455
4456 if (extra_id != -2) {
4457 if (extra_id >= 0 && extra_id < loading->extra.size) {
4458 punit->changed_from_target = loading->extra.order[extra_id];
4459 } else {
4461 }
4462 } else {
4463 /* extra_id == -2 -> changed_from_tgt not set */
4464
4465 cfspe =
4467 "%s.changed_from_target", unitstr);
4468 base_id =
4470 "%s.changed_from_base", unitstr);
4471 road_id =
4473 "%s.changed_from_road", unitstr);
4474
4475 if (road_id == -1) {
4476 if (cfspe == S_OLD_ROAD) {
4478 if (proad) {
4480 }
4481 } else if (cfspe == S_OLD_RAILROAD) {
4483 if (proad) {
4485 }
4486 }
4487 }
4488
4489 if (base_id >= 0 && base_id < loading->base.size) {
4491 } else if (road_id >= 0 && road_id < loading->road.size) {
4493 } else if (cfspe != S_LAST) {
4495 } else {
4497 }
4498
4503 punit);
4504 if (tgt != NULL) {
4506 } else {
4508 }
4509 } else if (punit->changed_from == ACTIVITY_MINE) {
4511 EC_MINE,
4513 punit);
4514 if (tgt != NULL) {
4516 } else {
4518 }
4522 ERM_CLEAN,
4524 punit);
4525 if (tgt != NULL) {
4527 } else {
4529 }
4530 }
4531 }
4532
4535 "%s.changed_from_count", unitstr);
4536
4537 /* Special case: for a long time, we accidentally incremented
4538 * activity_count while a unit was sentried, so it could increase
4539 * without bound (bug #20641) and be saved in old savefiles.
4540 * We zero it to prevent potential trouble overflowing the range
4541 * in network packets, etc. */
4542 if (activity == ACTIVITY_SENTRY) {
4543 punit->activity_count = 0;
4544 }
4547 }
4548
4549 punit->veteran
4550 = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
4551 {
4552 /* Protect against change in veteran system in ruleset */
4553 const int levels = utype_veteran_levels(unit_type_get(punit));
4554 if (punit->veteran >= levels) {
4555 fc_assert(levels >= 1);
4556 punit->veteran = levels - 1;
4557 }
4558 }
4561 "%s.done_moving", unitstr);
4564 "%s.battlegroup", unitstr);
4565
4567 "%s.go", unitstr)) {
4568 int gnat_x, gnat_y;
4569
4571 "%s.goto_x", unitstr), FALSE,
4572 "%s", secfile_error());
4574 "%s.goto_y", unitstr), FALSE,
4575 "%s", secfile_error());
4576
4578 } else {
4579 punit->goto_tile = NULL;
4580
4581 /* These variables are not used but needed for saving the unit table.
4582 * Load them to prevent unused variables errors. */
4583 (void) secfile_entry_lookup(loading->file, "%s.goto_x", unitstr);
4584 (void) secfile_entry_lookup(loading->file, "%s.goto_y", unitstr);
4585 }
4586
4587 /* Load AI data of the unit. */
4588 CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
4589
4592 "%s.ai", unitstr), FALSE,
4593 "%s", secfile_error());
4594 if (ai_controlled) {
4595 /* Autoworker and Autoexplore are separated by
4596 * compat_post_load_030100() when set to SSA_AUTOWORKER */
4598 } else {
4600 }
4602 "%s.hp", unitstr), FALSE,
4603 "%s", secfile_error());
4604
4606 = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
4608 = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
4609 punit->moved
4610 = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
4613 "%s.paradropped", unitstr);
4614
4615 /* The transport status (punit->transported_by) is loaded in
4616 * sg_player_units_transport(). */
4617
4618 /* Initialize upkeep values: these are hopefully initialized
4619 * elsewhere before use (specifically, in city_support(); but
4620 * fixme: check whether always correctly initialized?).
4621 * Below is mainly for units which don't have homecity --
4622 * otherwise these don't get initialized (and AI calculations
4623 * etc may use junk values). */
4627
4631 "%s.action_decision_want", unitstr);
4632
4634 /* Load the tile to act against. */
4635 int adwt_x, adwt_y;
4636
4637 if (secfile_lookup_int(loading->file, &adwt_x,
4638 "%s.action_decision_tile_x", unitstr)
4640 "%s.action_decision_tile_y", unitstr)) {
4642 adwt_x, adwt_y);
4643 } else {
4646 log_sg("Bad action_decision_tile for unit %d", punit->id);
4647 }
4648 } else {
4649 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_x", unitstr);
4650 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_y", unitstr);
4652 }
4653
4654 /* Load the unit orders */
4655 {
4656 int len = secfile_lookup_int_default(loading->file, 0,
4657 "%s.orders_length", unitstr);
4658
4659 if (len > 0) {
4660 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
4661 const char *tgt_unitstr;
4662 const char *base_unitstr = NULL;
4663 const char *road_unitstr = NULL;
4666 int j;
4667
4668 punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
4672 "%s.orders_index", unitstr);
4675 "%s.orders_repeat", unitstr);
4678 "%s.orders_vigilant", unitstr);
4679
4682 "%s.orders_list", unitstr);
4685 "%s.dir_list", unitstr);
4688 "%s.activity_list", unitstr);
4690 = secfile_lookup_str_default(loading->file, NULL, "%s.tgt_list", unitstr);
4691
4692 if (tgt_unitstr == NULL) {
4694 = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
4696 = secfile_lookup_str_default(loading->file, NULL, "%s.road_list", unitstr);
4697 }
4698
4700
4701 for (j = 0; j < len; j++) {
4702 struct unit_order *order = &punit->orders.list[j];
4703
4704 if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
4705 || act_unitstr[j] == '\0') {
4706 log_sg("Invalid unit orders.");
4708 break;
4709 }
4710 order->order = char2order(orders_unitstr[j]);
4711 order->dir = char2dir(dir_unitstr[j]);
4712 order->activity = char2activity(act_unitstr[j]);
4713 /* Target, if needed, is set in compat_post_load_030100() */
4714 order->target = NO_TARGET;
4715 order->sub_target = NO_TARGET;
4716
4717 if (order->order == ORDER_LAST
4718 || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
4719 || (order->order == ORDER_ACTION_MOVE
4720 && !direction8_is_valid(order->dir))
4721 || (order->order == ORDER_ACTIVITY
4722 && order->activity == ACTIVITY_LAST)) {
4723 /* An invalid order. Just drop the orders for this unit. */
4725 punit->orders.list = NULL;
4727 break;
4728 }
4729
4730 /* The order may have been replaced by the perform action order */
4731 order->action = sg_order_to_action(order->order, punit,
4732 punit->goto_tile);
4733 if (order->action != ACTION_NONE) {
4734 /* The order was converted by sg_order_to_action() */
4735 order->order = ORDER_PERFORM_ACTION;
4736 }
4737
4738 if (tgt_unitstr) {
4739 if (tgt_unitstr[j] != '?') {
4741
4742 if (extra_id < 0 || extra_id >= loading->extra.size) {
4743 log_sg("Cannot find extra %d for %s to build",
4745 order->sub_target = EXTRA_NONE;
4746 } else {
4747 order->sub_target = extra_id;
4748 }
4749 } else {
4750 order->sub_target = EXTRA_NONE;
4751 }
4752 } else {
4753 /* In pre-2.6 savegames, base_list and road_list were only saved
4754 * for those activities (and not e.g. pillaging) */
4755 if (base_unitstr && base_unitstr[j] != '?'
4756 && order->activity == ACTIVITY_BASE) {
4758
4759 if (base_id < 0 || base_id >= loading->base.size) {
4760 log_sg("Cannot find base %d for %s to build",
4763 NULL, NULL));
4764 }
4765
4766 order->sub_target
4768 } else if (road_unitstr && road_unitstr[j] != '?'
4769 && order->activity == ACTIVITY_GEN_ROAD) {
4771
4772 if (road_id < 0 || road_id >= loading->road.size) {
4773 log_sg("Cannot find road %d for %s to build",
4775 road_id = 0;
4776 }
4777
4778 order->sub_target
4780 } else {
4781 order->sub_target = EXTRA_NONE;
4782 }
4783
4784 if (order->activity == ACTIVITY_OLD_ROAD) {
4785 order->activity = ACTIVITY_GEN_ROAD;
4786 order->sub_target
4788 } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
4789 order->activity = ACTIVITY_GEN_ROAD;
4790 order->sub_target
4792 }
4793 }
4794 }
4795 } else {
4797 punit->orders.list = NULL;
4798
4799 (void) secfile_entry_lookup(loading->file, "%s.orders_index", unitstr);
4800 (void) secfile_entry_lookup(loading->file, "%s.orders_repeat", unitstr);
4801 (void) secfile_entry_lookup(loading->file, "%s.orders_vigilant", unitstr);
4802 (void) secfile_entry_lookup(loading->file, "%s.orders_list", unitstr);
4803 (void) secfile_entry_lookup(loading->file, "%s.dir_list", unitstr);
4804 (void) secfile_entry_lookup(loading->file, "%s.activity_list", unitstr);
4805 (void) secfile_entry_lookup(loading->file, "%s.tgt_list", unitstr);
4806 }
4807 }
4808
4809 return TRUE;
4810}
4811
4812/************************************************************************/
4817 struct player *plr)
4818{
4819 int nunits, i, plrno = player_number(plr);
4820
4821 /* Check status and return if not OK (sg_success FALSE). */
4822 sg_check_ret();
4823
4824 /* Recheck the number of units for the player. This is a copied from
4825 * sg_load_player_units(). */
4827 "player%d.nunits", plrno),
4828 "%s", secfile_error());
4829 if (!plr->is_alive && nunits > 0) {
4830 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4831 nunits = 0; /* Some old savegames may be buggy. */
4832 }
4833
4834 for (i = 0; i < nunits; i++) {
4835 int id_unit, id_trans;
4836 struct unit *punit, *ptrans;
4837
4839 "player%d.u%d.id",
4840 plrno, i);
4842 fc_assert_action(punit != NULL, continue);
4843
4845 "player%d.u%d.transported_by",
4846 plrno, i);
4847 if (id_trans == -1) {
4848 /* Not transported. */
4849 continue;
4850 }
4851
4853 fc_assert_action(id_trans == -1 || ptrans != NULL, continue);
4854
4855 if (ptrans) {
4856#ifndef FREECIV_NDEBUG
4857 bool load_success =
4858#endif
4860
4861 fc_assert_action(load_success, continue);
4862 }
4863 }
4864}
4865
4866/************************************************************************/
4870 struct player *plr)
4871{
4872 int plrno = player_number(plr);
4873
4874 /* Check status and return if not OK (sg_success FALSE). */
4875 sg_check_ret();
4876
4877 /* Toss any existing attribute_block (should not exist) */
4878 if (plr->attribute_block.data) {
4880 plr->attribute_block.data = NULL;
4881 }
4882
4883 /* This is a big heap of opaque data for the client, check everything! */
4885 loading->file, 0, "player%d.attribute_v2_block_length", plrno);
4886
4887 if (0 > plr->attribute_block.length) {
4888 log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
4889 plr->attribute_block.length);
4890 plr->attribute_block.length = 0;
4891 } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
4892 log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
4894 plr->attribute_block.length = 0;
4895 } else if (0 < plr->attribute_block.length) {
4896 int part_nr, parts;
4897 int quoted_length;
4898 char *quoted;
4899#ifndef FREECIV_NDEBUG
4900 size_t actual_length;
4901#endif
4902
4905 "player%d.attribute_v2_block_length_quoted",
4906 plrno), "%s", secfile_error());
4909 "player%d.attribute_v2_block_parts", plrno),
4910 "%s", secfile_error());
4911
4913 quoted[0] = '\0';
4915 for (part_nr = 0; part_nr < parts; part_nr++) {
4916 const char *current =
4918 "player%d.attribute_v2_block_data.part%d",
4919 plrno, part_nr);
4920 if (!current) {
4921 log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
4922 break;
4923 }
4924 log_debug("attribute_v2_block_length_quoted=%d"
4925 " have=" SIZE_T_PRINTF " part=" SIZE_T_PRINTF,
4926 quoted_length, strlen(quoted), strlen(current));
4927 fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
4928 strcat(quoted, current);
4929 }
4931 "attribute_v2_block_length_quoted=%d"
4932 " actual=" SIZE_T_PRINTF,
4934
4935#ifndef FREECIV_NDEBUG
4937#endif
4939 plr->attribute_block.data,
4940 plr->attribute_block.length);
4942 free(quoted);
4943 }
4944}
4945
4946/************************************************************************/
4950 struct player *plr)
4951{
4952 int plrno = player_number(plr);
4953 int total_ncities =
4955 "player%d.dc_total", plrno);
4956 int i;
4957 bool someone_alive = FALSE;
4958
4959 /* Check status and return if not OK (sg_success FALSE). */
4960 sg_check_ret();
4961
4964 if (pteam_member->is_alive) {
4966 break;
4967 }
4969
4970 if (!someone_alive) {
4971 /* Reveal all for completely dead teams. */
4973 }
4974 }
4975
4976 if (!plr->is_alive
4977 || -1 == total_ncities
4978 || !game.info.fogofwar
4980 "game.save_private_map")) {
4981 /* We have:
4982 * - a dead player;
4983 * - fogged cities are not saved for any reason;
4984 * - a savegame with fog of war turned off;
4985 * - or game.save_private_map is not set to FALSE in the scenario /
4986 * savegame. The players private knowledge is set to be what they could
4987 * see without fog of war. */
4988 whole_map_iterate(&(wld.map), ptile) {
4989 if (map_is_known(ptile, plr)) {
4990 struct city *pcity = tile_city(ptile);
4991
4992 update_player_tile_last_seen(plr, ptile);
4993 update_player_tile_knowledge(plr, ptile);
4994
4995 if (NULL != pcity) {
4996 update_dumb_city(plr, pcity);
4997 }
4998 }
5000
5001 /* Nothing more to do; */
5002 return;
5003 }
5004
5005 /* Load player map (terrain). */
5006 LOAD_MAP_CHAR(ch, ptile,
5007 map_get_player_tile(ptile, plr)->terrain
5008 = char2terrain(ch), loading->file,
5009 "player%d.map_t%04d", plrno);
5010
5011 /* Load player map (resources). */
5012 LOAD_MAP_CHAR(ch, ptile,
5013 map_get_player_tile(ptile, plr)->resource
5014 = char2resource(ch), loading->file,
5015 "player%d.map_res%04d", plrno);
5016
5017 if (loading->version >= 30) {
5018 /* 2.6.0 or newer */
5019
5020 /* Load player map (extras). */
5021 halfbyte_iterate_extras(j, loading->extra.size) {
5022 LOAD_MAP_CHAR(ch, ptile,
5024 ch, loading->extra.order + 4 * j),
5025 loading->file, "player%d.map_e%02d_%04d", plrno, j);
5027 } else {
5028 /* Load player map (specials). */
5029 halfbyte_iterate_special(j, loading->special.size) {
5030 LOAD_MAP_CHAR(ch, ptile,
5031 sg_special_set_dbv(ptile,
5032 &(map_get_player_tile(ptile, plr)->extras),
5033 ch, loading->special.order + 4 * j, FALSE),
5034 loading->file, "player%d.map_spe%02d_%04d", plrno, j);
5036
5037 /* Load player map (bases). */
5038 halfbyte_iterate_bases(j, loading->base.size) {
5039 LOAD_MAP_CHAR(ch, ptile,
5041 ch, loading->base.order + 4 * j),
5042 loading->file, "player%d.map_b%02d_%04d", plrno, j);
5044
5045 /* Load player map (roads). */
5046 if (loading->version >= 20) {
5047 /* 2.5.0 or newer */
5048 halfbyte_iterate_roads(j, loading->road.size) {
5049 LOAD_MAP_CHAR(ch, ptile,
5051 ch, loading->road.order + 4 * j),
5052 loading->file, "player%d.map_r%02d_%04d", plrno, j);
5054 }
5055 }
5056
5058 /* Load player map (border). */
5059 int x, y;
5060
5061 for (y = 0; y < MAP_NATIVE_HEIGHT; y++) {
5062 const char *buffer
5063 = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
5064 plrno, y);
5065 const char *buffer2
5066 = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
5067 plrno, y);
5068 const char *ptr = buffer;
5069 const char *ptr2 = buffer2;
5070
5071 sg_failure_ret(NULL != buffer,
5072 "Savegame corrupt - map line %d not found.", y);
5073 for (x = 0; x < MAP_NATIVE_WIDTH; x++) {
5074 char token[TOKEN_SIZE];
5075 char token2[TOKEN_SIZE];
5076 int number;
5077 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
5078
5079 scanin(&ptr, ",", token, sizeof(token));
5080 sg_failure_ret('\0' != token[0],
5081 "Savegame corrupt - map size not correct.");
5082 if (strcmp(token, "-") == 0) {
5083 map_get_player_tile(ptile, plr)->owner = NULL;
5084 } else {
5085 sg_failure_ret(str_to_int(token, &number),
5086 "Savegame corrupt - got tile owner=%s in (%d, %d).",
5087 token, x, y);
5088 map_get_player_tile(ptile, plr)->owner = player_by_number(number);
5089 }
5090
5091 if (loading->version >= 30) {
5092 scanin(&ptr2, ",", token2, sizeof(token2));
5093 sg_failure_ret('\0' != token2[0],
5094 "Savegame corrupt - map size not correct.");
5095 if (strcmp(token2, "-") == 0) {
5096 map_get_player_tile(ptile, plr)->extras_owner = NULL;
5097 } else {
5099 "Savegame corrupt - got extras owner=%s in (%d, %d).",
5100 token, x, y);
5101 map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
5102 }
5103 } else {
5105 = map_get_player_tile(ptile, plr)->owner;
5106 }
5107 }
5108 }
5109 }
5110
5111 /* Load player map (update time). */
5112 for (i = 0; i < 4; i++) {
5113 /* put 4-bit segments of 16-bit "updated" field */
5114 if (i == 0) {
5115 LOAD_MAP_CHAR(ch, ptile,
5116 map_get_player_tile(ptile, plr)->last_updated
5117 = ascii_hex2bin(ch, i),
5118 loading->file, "player%d.map_u%02d_%04d", plrno, i);
5119 } else {
5120 LOAD_MAP_CHAR(ch, ptile,
5121 map_get_player_tile(ptile, plr)->last_updated
5122 |= ascii_hex2bin(ch, i),
5123 loading->file, "player%d.map_u%02d_%04d", plrno, i);
5124 }
5125 }
5126
5127 /* Load player map known cities. */
5128 for (i = 0; i < total_ncities; i++) {
5129 struct vision_site *pdcity;
5130 char buf[32];
5131 fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
5132
5136 pdcity);
5138 } else {
5139 /* Error loading the data. */
5140 log_sg("Skipping seen city %d for player %d.", i, plrno);
5141 if (pdcity != NULL) {
5143 }
5144 }
5145 }
5146
5147 /* Repair inconsistent player maps. */
5148 whole_map_iterate(&(wld.map), ptile) {
5149 if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
5150 struct city *pcity = tile_city(ptile);
5151
5152 update_player_tile_knowledge(plr, ptile);
5153 reality_check_city(plr, ptile);
5154
5155 if (NULL != pcity) {
5156 update_dumb_city(plr, pcity);
5157 }
5158 } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
5159 /* Non fogged borders aren't loaded. See hrm Bug #879084 */
5160 struct player_tile *plrtile = map_get_player_tile(ptile, plr);
5161
5162 plrtile->owner = tile_owner(ptile);
5163 }
5165}
5166
5167/************************************************************************/
5171 struct player *plr,
5172 struct vision_site *pdcity,
5173 const char *citystr)
5174{
5175 const char *str;
5176 int i, id, size;
5177 citizens city_size;
5178 int nat_x, nat_y;
5179 const char *stylename;
5180 const char *vname;
5181
5183 citystr),
5184 FALSE, "%s", secfile_error());
5186 citystr),
5187 FALSE, "%s", secfile_error());
5188 pdcity->location = native_pos_to_tile(&(wld.map), nat_x, nat_y);
5189 sg_warn_ret_val(NULL != pdcity->location, FALSE,
5190 "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
5191
5192 sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
5193 citystr),
5194 FALSE, "%s", secfile_error());
5195 pdcity->owner = player_by_number(id);
5196 sg_warn_ret_val(NULL != pdcity->owner, FALSE,
5197 "%s has invalid owner (%d); skipping.", citystr, id);
5198
5200 "%s.id", citystr),
5201 FALSE, "%s", secfile_error());
5203 "%s has invalid id (%d); skipping.", citystr, id);
5204
5206 "%s.size", citystr),
5207 FALSE, "%s", secfile_error());
5208 city_size = (citizens)size; /* set the correct type */
5209 sg_warn_ret_val(size == (int)city_size, FALSE,
5210 "Invalid city size: %d; set to %d.", size, city_size);
5211 vision_site_size_set(pdcity, city_size);
5212
5213 /* Initialise list of improvements */
5214 BV_CLR_ALL(pdcity->improvements);
5215 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
5217 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
5218 "Invalid length of '%s.improvements' ("
5219 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5220 citystr, strlen(str), loading->improvement.size);
5221 for (i = 0; i < loading->improvement.size; i++) {
5222 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
5223 "Undefined value '%c' within '%s.improvements'.",
5224 str[i], citystr)
5225
5226 if (str[i] == '1') {
5227 struct impr_type *pimprove =
5228 improvement_by_rule_name(loading->improvement.order[i]);
5229
5230 if (pimprove) {
5231 BV_SET(pdcity->improvements, improvement_index(pimprove));
5232 }
5233 }
5234 }
5235
5237 "%s.name", citystr);
5238
5239 if (vname != NULL) {
5240 pdcity->name = fc_strdup(vname);
5241 }
5242
5244 "%s.occupied", citystr);
5246 "%s.walls", citystr);
5248 "%s.happy", citystr);
5250 "%s.unhappy", citystr);
5252 "%s.style", citystr);
5253 if (stylename != NULL) {
5255 } else {
5256 pdcity->style = 0;
5257 }
5258 if (pdcity->style < 0) {
5259 pdcity->style = 0;
5260 }
5261
5262 pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
5263 "%s.city_image", citystr);
5264
5265 pdcity->capital = CAPITAL_NOT;
5266
5267 return TRUE;
5268}
5269
5270/* =======================================================================
5271 * Load the researches.
5272 * ======================================================================= */
5273
5274/************************************************************************/
5278{
5279 struct research *presearch;
5280 int count;
5281 int number;
5282 const char *str;
5283 int i, j;
5284 bool got_tech;
5285
5286 /* Check status and return if not OK (sg_success FALSE). */
5287 sg_check_ret();
5288
5289 /* Initialize all researches. */
5293
5294 /* May be unsaved (e.g. scenario case). */
5295 count = secfile_lookup_int_default(loading->file, 0, "research.count");
5296 for (i = 0; i < count; i++) {
5298 "research.r%d.number", i),
5299 "%s", secfile_error());
5300 presearch = research_by_number(number);
5302 "Invalid research number %d in 'research.r%d.number'",
5303 number, i);
5304
5305 presearch->tech_goal = technology_load(loading->file,
5306 "research.r%d.goal", i);
5308 &presearch->techs_researched,
5309 "research.r%d.techs", i),
5310 "%s", secfile_error());
5312 &presearch->future_tech,
5313 "research.r%d.futuretech", i),
5314 "%s", secfile_error());
5316 &presearch->bulbs_researched,
5317 "research.r%d.bulbs", i),
5318 "%s", secfile_error());
5320 &presearch->bulbs_researching_saved,
5321 "research.r%d.bulbs_before", i),
5322 "%s", secfile_error());
5323 presearch->researching_saved = technology_load(loading->file,
5324 "research.r%d.saved", i);
5325 presearch->researching = technology_load(loading->file,
5326 "research.r%d.now", i);
5328 &got_tech,
5329 "research.r%d.got_tech", i),
5330 "%s", secfile_error());
5331 if (got_tech) {
5332 presearch->free_bulbs = presearch->bulbs_researched;
5333 }
5334
5335 str = secfile_lookup_str(loading->file, "research.r%d.done", i);
5336 sg_failure_ret(str != NULL, "%s", secfile_error());
5337 sg_failure_ret(strlen(str) == loading->technology.size,
5338 "Invalid length of 'research.r%d.done' ("
5339 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5340 i, strlen(str), loading->technology.size);
5341 for (j = 0; j < loading->technology.size; j++) {
5342 sg_failure_ret(str[j] == '1' || str[j] == '0',
5343 "Undefined value '%c' within 'research.r%d.done'.",
5344 str[j], i);
5345
5346 if (str[j] == '1') {
5347 struct advance *padvance =
5348 advance_by_rule_name(loading->technology.order[j]);
5349
5350 if (padvance) {
5352 TECH_KNOWN);
5353 }
5354 }
5355 }
5356 }
5357
5358 /* In case of tech_leakage, we can update research only after all the
5359 * researches have been loaded */
5363}
5364
5365/* =======================================================================
5366 * Load the event cache. Should be the last thing to do.
5367 * ======================================================================= */
5368
5369/************************************************************************/
5373{
5374 /* Check status and return if not OK (sg_success FALSE). */
5375 sg_check_ret();
5376
5377 event_cache_load(loading->file, "event_cache");
5378}
5379
5380/* =======================================================================
5381 * Load the open treaties
5382 * ======================================================================= */
5383
5384/************************************************************************/
5388{
5389 int tidx;
5390 const char *plr0;
5391
5392 /* Check status and return if not OK (sg_success FALSE). */
5393 sg_check_ret();
5394
5395 for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, NULL,
5396 "treaty%d.plr0", tidx)) != NULL ;
5397 tidx++) {
5398 const char *plr1;
5399 const char *ct;
5400 int cidx;
5401 struct player *p0, *p1;
5402
5403 plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
5404
5405 p0 = player_by_name(plr0);
5406 p1 = player_by_name(plr1);
5407
5408 if (p0 == NULL || p1 == NULL) {
5409 log_error("Treaty between unknown players %s and %s", plr0, plr1);
5410 } else {
5411 struct Treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
5412
5415
5416 for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, NULL,
5417 "treaty%d.clause%d.type",
5418 tidx, cidx)) != NULL ;
5419 cidx++ ) {
5421 const char *plrx;
5422
5423 if (!clause_type_is_valid(type)) {
5424 log_error("Invalid clause type \"%s\"", ct);
5425 } else {
5426 struct player *pgiver = NULL;
5427
5428 plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
5429 tidx, cidx);
5430
5431 if (!fc_strcasecmp(plrx, plr0)) {
5432 pgiver = p0;
5433 } else if (!fc_strcasecmp(plrx, plr1)) {
5434 pgiver = p1;
5435 } else {
5436 log_error("Clause giver %s is not participant of the treaty"
5437 "between %s and %s", plrx, plr0, plr1);
5438 }
5439
5440 if (pgiver != NULL) {
5441 int value;
5442
5443 value = secfile_lookup_int_default(loading->file, 0,
5444 "treaty%d.clause%d.value",
5445 tidx, cidx);
5446
5447 add_clause(ptreaty, pgiver, type, value, NULL);
5448 }
5449 }
5450 }
5451
5452 /* These must be after clauses have been added so that acceptance
5453 * does not get cleared by what seems like changes to the treaty. */
5455 "treaty%d.accept0", tidx);
5457 "treaty%d.accept1", tidx);
5458 }
5459 }
5460}
5461
5462/* =======================================================================
5463 * Load the history report
5464 * ======================================================================= */
5465
5466/************************************************************************/
5470{
5472 int turn;
5473
5474 /* Check status and return if not OK (sg_success FALSE). */
5475 sg_check_ret();
5476
5477 turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
5478
5479 if (turn != -2) {
5480 hist->turn = turn;
5481 }
5482
5483 if (turn + 1 >= game.info.turn) {
5484 const char *str;
5485
5486 str = secfile_lookup_str(loading->file, "history.title");
5487 sg_failure_ret(str != NULL, "%s", secfile_error());
5488 sz_strlcpy(hist->title, str);
5489 str = secfile_lookup_str(loading->file, "history.body");
5490 sg_failure_ret(str != NULL, "%s", secfile_error());
5491 sz_strlcpy(hist->body, str);
5492 }
5493}
5494
5495/* =======================================================================
5496 * Load the mapimg definitions.
5497 * ======================================================================= */
5498
5499/************************************************************************/
5502static void sg_load_mapimg(struct loaddata *loading)
5503{
5504 int mapdef_count, i;
5505
5506 /* Check status and return if not OK (sg_success FALSE). */
5507 sg_check_ret();
5508
5509 /* Clear all defined map images. */
5510 while (mapimg_count() > 0) {
5511 mapimg_delete(0);
5512 }
5513
5515 "mapimg.count");
5516 log_verbose("Saved map image definitions: %d.", mapdef_count);
5517
5518 if (0 >= mapdef_count) {
5519 return;
5520 }
5521
5522 for (i = 0; i < mapdef_count; i++) {
5523 const char *p;
5524
5525 p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
5526 if (NULL == p) {
5527 log_verbose("[Mapimg %4d] Missing definition.", i);
5528 continue;
5529 }
5530
5531 if (!mapimg_define(p, FALSE)) {
5532 log_error("Invalid map image definition %4d: %s.", i, p);
5533 }
5534
5535 log_verbose("Mapimg %4d loaded.", i);
5536 }
5537}
5538
5539/* =======================================================================
5540 * Sanity checks for loading a game.
5541 * ======================================================================= */
5542
5543/************************************************************************/
5547{
5548 int players;
5549
5550 /* Check status and return if not OK (sg_success FALSE). */
5551 sg_check_ret();
5552
5553 if (game.info.is_new_game) {
5554 /* Nothing to do for new games (or not started scenarios). */
5555 return;
5556 }
5557
5558 /* Old savegames may have maxplayers lower than current player count,
5559 * fix. */
5560 players = normal_player_count();
5561 if (game.server.max_players < players) {
5562 log_verbose("Max players lower than current players, fixing");
5563 game.server.max_players = players;
5564 }
5565
5566 /* Fix ferrying sanity */
5567 players_iterate(pplayer) {
5568 unit_list_iterate_safe(pplayer->units, punit) {
5571 log_sg("Removing %s unferried %s in %s at (%d, %d)",
5577 }
5580
5581 /* Fix stacking issues. We don't rely on the savegame preserving
5582 * alliance invariants (old savegames often did not) so if there are any
5583 * unallied units on the same tile we just bounce them. */
5584 players_iterate(pplayer) {
5586 resolve_unit_stacks(pplayer, aplayer, TRUE);
5589
5590 /* Recalculate the potential buildings for each city. Has caused some
5591 * problems with game random state.
5592 * This also changes the game state if you save the game directly after
5593 * loading it and compare the results. */
5594 players_iterate(pplayer) {
5595 /* Building advisor needs data phase open in order to work */
5596 adv_data_phase_init(pplayer, FALSE);
5597 building_advisor(pplayer);
5598 /* Close data phase again so it can be opened again when game starts. */
5599 adv_data_phase_done(pplayer);
5601
5602 /* Prevent a buggy or intentionally crafted save game from crashing
5603 * Freeciv. See hrm Bug #887748 */
5604 players_iterate(pplayer) {
5605 city_list_iterate(pplayer->cities, pcity) {
5606 worker_task_list_iterate(pcity->task_reqs, ptask) {
5607 if (!worker_task_is_sane(ptask)) {
5608 log_error("[city id: %d] Bad worker task %d.",
5609 pcity->id, ptask->act);
5610 worker_task_list_remove(pcity->task_reqs, ptask);
5611 free(ptask);
5612 ptask = NULL;
5613 }
5617
5618 /* Check worked tiles map */
5619#ifdef FREECIV_DEBUG
5620 if (loading->worked_tiles != NULL) {
5621 /* check the entire map for unused worked tiles */
5622 whole_map_iterate(&(wld.map), ptile) {
5623 if (loading->worked_tiles[ptile->index] != -1) {
5624 log_error("[city id: %d] Unused worked tile at (%d, %d).",
5625 loading->worked_tiles[ptile->index], TILE_XY(ptile));
5626 }
5628 }
5629#endif /* FREECIV_DEBUG */
5630
5631 /* Check researching technologies and goals. */
5633 int techs;
5634
5635 if (presearch->researching != A_UNSET
5636 && !is_future_tech(presearch->researching)
5637 && (valid_advance_by_number(presearch->researching) == NULL
5639 != TECH_PREREQS_KNOWN))) {
5640 log_sg(_("%s had invalid researching technology."),
5642 presearch->researching = A_UNSET;
5643 }
5644 if (presearch->tech_goal != A_UNSET
5645 && !is_future_tech(presearch->tech_goal)
5646 && (valid_advance_by_number(presearch->tech_goal) == NULL
5649 == TECH_KNOWN))) {
5650 log_sg(_("%s had invalid technology goal."),
5652 presearch->tech_goal = A_UNSET;
5653 }
5654
5656
5657 if (presearch->techs_researched != techs) {
5658 sg_regr(3000300,
5659 _("%s had finished researches count wrong."),
5661 presearch->techs_researched = techs;
5662 }
5664
5665 players_iterate(pplayer) {
5666 unit_list_iterate_safe(pplayer->units, punit) {
5668 punit->orders.list)) {
5669 log_sg("Invalid unit orders for unit %d.", punit->id);
5671 }
5674
5675 /* Check max rates (rules may have changed since saving) */
5676 players_iterate(pplayer) {
5679
5680 if (0 == strlen(server.game_identifier)
5681 || !is_base64url(server.game_identifier)) {
5682 /* This uses fc_rand(), so random state has to be initialized before. */
5683 randomize_base64url_string(server.game_identifier,
5684 sizeof(server.game_identifier));
5685 }
5686
5687 /* Check if some player has more than one of some UTYF_UNIQUE unit type */
5688 players_iterate(pplayer) {
5689 int unique_count[U_LAST];
5690
5691 memset(unique_count, 0, sizeof(unique_count));
5692
5693 unit_list_iterate(pplayer->units, punit) {
5696
5699 log_sg(_("%s has multiple units of type %s though it should be possible "
5700 "to have only one."),
5702 }
5705
5706 /* Restore game random state, just in case various initialization code
5707 * inexplicably altered the previously existing state. */
5708 if (!game.info.is_new_game) {
5709 fc_rand_set_state(loading->rstate);
5710
5711 if (loading->version < 30) {
5712 /* For older savegames we have to recalculate the score with current data,
5713 * instead of using beginning-of-turn saved scores. */
5714 players_iterate(pplayer) {
5715 calc_civ_score(pplayer);
5717 }
5718 }
5719
5720 /* At the end do the default sanity checks. */
5721 sanity_check();
5722}
struct achievement * achievement_by_rule_name(const char *name)
#define ACTION_NONE
Definition actions.h:55
void building_advisor(struct player *pplayer)
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Definition advdata.c:262
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:564
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:96
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:105
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:143
struct base_type * base_by_number(const Base_type_id id)
Definition base.c:80
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c: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:79
void citizens_nation_set(struct city *pcity, const struct player_slot *pslot, citizens count)
Definition citizens.c:145
citizens citizens_count(const struct city *pcity)
Definition citizens.c:162
void citizens_init(struct city *pcity)
Definition citizens.c:32
void citizens_update(struct city *pcity, struct player *plr)
void city_map_radius_sq_set(struct city *pcity, int radius_sq)
Definition city.c:148
void city_name_set(struct city *pcity, const char *new_name)
Definition city.c:1141
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3426
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2867
void city_size_set(struct city *pcity, citizens size)
Definition city.c:1176
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3353
void destroy_city_virtual(struct city *pcity)
Definition city.c:3512
int city_style_by_rule_name(const char *s)
Definition city.c:1734
#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:836
#define city_owner(_pcity_)
Definition city.h:563
#define FREE_WORKED_TILES
Definition city.h:873
#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:842
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2751
bool send_city_suppression(bool now)
Definition citytools.c:2159
static void void city_freeze_workers(struct city *pcity)
Definition citytools.c:136
void city_thaw_workers(struct city *pcity)
Definition citytools.c:146
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2822
void city_refresh_vision(struct city *pcity)
Definition citytools.c:3426
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:365
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:850
bool city_refresh(struct city *pcity)
Definition cityturn.c:158
char * techs
Definition comments.c:30
char * incite_cost
Definition comments.c:74
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:2917
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2938
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Definition difficulty.c:39
enum diplstate_type valid_dst_closest(struct player_diplstate *dst)
Definition diplhand.c:108
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:377
int int id
Definition editgui_g.h:28
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:779
struct extra_type * extra_type_by_rule_name(const char *name)
Definition extras.c:212
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
int extra_number(const struct extra_type *pextra)
Definition extras.c:161
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:804
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define EXTRA_NONE
Definition extras.h:85
#define extra_base_get(_e_)
Definition extras.h:190
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
static char * ruleset
Definition fc_manual.c:159
#define NO_TARGET
Definition fc_types.h:358
int Road_type_id
Definition fc_types.h:388
@ ROCO_RAILROAD
Definition fc_types.h:1233
@ ROCO_RIVER
Definition fc_types.h:1233
@ ROCO_ROAD
Definition fc_types.h:1233
int Tech_type_id
Definition fc_types.h:381
unsigned char citizens
Definition fc_types.h:392
@ RPT_POSSIBLE
Definition fc_types.h:677
int Base_type_id
Definition fc_types.h:387
int Multiplier_type_id
Definition fc_types.h:390
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:92
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
struct unit * game_unit_by_number(int id)
Definition game.c:115
void initialize_globals(void)
Definition game.c:686
struct city * game_city_by_number(int id)
Definition game.c:106
#define GAME_DEFAULT_TIMEOUTINTINC
Definition game.h:595
#define GAME_DEFAULT_SCORETURN
Definition game.h:579
#define GAME_DEFAULT_TIMEOUTINT
Definition game.h:594
#define GAME_DEFAULT_TIMEOUTINCMULT
Definition game.h:597
#define GAME_DEFAULT_TIMEOUTINC
Definition game.h:596
#define GAME_DEFAULT_RULESETDIR
Definition game.h:673
#define GAME_DEFAULT_TIMEOUTCOUNTER
Definition game.h:599
#define GAME_DEFAULT_PHASE_MODE
Definition game.h:614
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:502
void adv_city_alloc(struct city *pcity)
Definition infracache.c:489
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h: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:1678
#define nat_x
#define nat_y
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:647
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1895
void main_map_allocate(void)
Definition map.c:525
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:462
int map_startpos_count(void)
Definition map.c:1882
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:449
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1661
void map_init_topology(void)
Definition map.c:306
#define whole_map_iterate(_map, _tile)
Definition map.h:531
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:150
#define whole_map_iterate_end
Definition map.h:540
@ MAPGEN_SCENARIO
Definition map_types.h:47
void assign_continent_numbers(void)
void player_map_init(struct player *pplayer)
Definition maphand.c:1228
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1474
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2212
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:901
bool send_tile_suppression(bool now)
Definition maphand.c: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:1203
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1405
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2225
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1185
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:927
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1166
void map_calculate_borders(void)
Definition maphand.c:2378
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1639
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1389
bool mapimg_define(const char *maparg, bool check)
Definition mapimg.c:769
bool mapimg_delete(int id)
Definition mapimg.c:1207
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:318
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:784
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:1480
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:1996
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:1409
struct player_slot * slots
Definition player.c:51
#define players_iterate_end
Definition player.h:539
dipl_reason
Definition player.h:192
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition player.h:194
@ DIPL_ALLIANCE_PROBLEM_US
Definition player.h:194
#define players_iterate(_pplayer)
Definition player.h:534
#define MAX_ATTRIBUTE_BLOCK
Definition player.h:223
#define player_list_iterate(playerlist, pplayer)
Definition player.h:557
static bool is_barbarian(const struct player *pplayer)
Definition player.h:491
#define player_slots_iterate(_pslot)
Definition player.h:525
#define is_ai(plr)
Definition player.h:232
#define player_list_iterate_end
Definition player.h:559
#define players_iterate_alive_end
Definition player.h:549
#define player_slots_iterate_end
Definition player.h:529
#define players_iterate_alive(_pplayer)
Definition player.h:544
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:3211
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:3257
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:1618
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,...)
struct history_report * history_report_get(void)
Definition report.c:1825
bool are_reqs_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
struct universal universal_by_rule_name(const char *kind, const char *value)
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c: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:1353
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 ruleload.c:9115
#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:327
static struct compatibility compat[]
Definition savecompat.c:112
int char2num(char ch)
Definition savecompat.c:272
void sg_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:147
enum ai_level ai_level_convert(int old_level)
int ascii_hex2bin(char ch, int halfbyte)
Definition savecompat.c:248
struct extra_type * special_extra_get(int spe)
Definition savecompat.c:313
enum tile_special_type special_by_rule_name(const char *name)
Definition savecompat.c:287
void sg_load_post_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:198
const char * special_rule_name(enum tile_special_type type)
Definition savecompat.c:303
#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:836
static void sg_load_players_basic(struct loaddata *loading)
Definition savegame2.c:2685
static struct loaddata * loaddata_new(struct section_file *file)
Definition savegame2.c:471
#define ACTIVITY_OLD_POLLUTION_SG2
Definition savegame2.c:145
static void sg_load_map_known(struct loaddata *loading)
Definition savegame2.c:2621
#define halfbyte_iterate_roads_end
Definition savegame2.c:280
static struct extra_type * char2resource(char c)
Definition savegame2.c:1324
static void sg_load_map_owner(struct loaddata *loading)
Definition savegame2.c:2490
bool sg_success
Definition savecompat.c:34
#define halfbyte_iterate_extras_end
Definition savegame2.c:250
static void sg_load_map_tiles_roads(struct loaddata *loading)
Definition savegame2.c:2329
#define halfbyte_iterate_extras(e, num_extras_types)
Definition savegame2.c:245
static void sg_load_map(struct loaddata *loading)
Definition savegame2.c:2179
static enum unit_orders char2order(char order)
Definition savegame2.c:599
static int unquote_block(const char *const quoted_, void *dest, int dest_length)
Definition savegame2.c:742
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:209
#define ACTIVITY_OLD_RAILROAD
Definition savegame2.c:144
static void sg_load_player_city_citizens(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr)
Definition savegame2.c:4040
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3641
static void sg_load_map_tiles(struct loaddata *loading)
Definition savegame2.c:2257
static char activity2char(int activity)
Definition savegame2.c:667
static void sg_load_savefile(struct loaddata *loading)
Definition savegame2.c:1436
#define ACTIVITY_OLD_FALLOUT_SG2
Definition savegame2.c:146
static bool sg_load_player_unit(struct loaddata *loading, struct player *plr, struct unit *punit, const char *unitstr)
Definition savegame2.c:4207
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:3756
static void sg_load_settings(struct loaddata *loading)
Definition savegame2.c:2159
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:4088
#define halfbyte_iterate_special(s, num_specials_types)
Definition savegame2.c:255
void savegame2_load(struct section_file *file)
Definition savegame2.c:402
static void sg_load_researches(struct loaddata *loading)
Definition savegame2.c:5277
#define halfbyte_iterate_bases_end
Definition savegame2.c:270
static void sg_load_map_worked(struct loaddata *loading)
Definition savegame2.c:2577
static void sg_load_random(struct loaddata *loading)
Definition savegame2.c:1990
#define halfbyte_iterate_special_end
Definition savegame2.c:260
#define halfbyte_iterate_bases(b, num_bases_types)
Definition savegame2.c:265
static void sg_load_player_units_transport(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4816
static void sg_load_history(struct loaddata *loading)
Definition savegame2.c:5469
static int char2activity(char activity)
Definition savegame2.c:721
#define ORDER_OLD_BUILD_WONDER
Definition savegame2.c:288
static void sg_load_map_tiles_specials(struct loaddata *loading, bool rivers_overlay)
Definition savegame2.c:2345
#define TOKEN_SIZE
Definition savegame2.c:284
static void sg_load_script(struct loaddata *loading)
Definition savegame2.c:2049
static void sg_load_scenario(struct loaddata *loading)
Definition savegame2.c:2064
static void sg_load_ruleset(struct loaddata *loading)
Definition savegame2.c:1402
static void sg_load_game(struct loaddata *loading)
Definition savegame2.c:1846
static void sg_load_player_main(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3134
#define ACTIVITY_OLD_ROAD
Definition savegame2.c:143
static void sg_load_treaties(struct loaddata *loading)
Definition savegame2.c:5387
static void sg_extras_set_bv(bv_extras *extras, char ch, struct extra_type **idx)
Definition savegame2.c:890
static void set_unit_activity_road(struct unit *punit, Road_type_id road)
Definition savegame2.c:584
static Tech_type_id technology_load(struct section_file *file, const char *path, int plrno)
Definition savegame2.c:1362
static enum direction8 char2dir(char dir)
Definition savegame2.c:638
static void sg_load_map_tiles_resources(struct loaddata *loading)
Definition savegame2.c:2376
#define ORDER_OLD_BUILD_CITY
Definition savegame2.c:286
static struct terrain * char2terrain(char ch)
Definition savegame2.c:1339
#define ORDER_OLD_DISBAND
Definition savegame2.c:287
static void sg_load_mapimg(struct loaddata *loading)
Definition savegame2.c:5502
#define ORDER_OLD_HOMECITY
Definition savegame2.c:290
static void sg_special_set_bv(struct tile *ptile, bv_extras *extras, char ch, const enum tile_special_type *idx, bool rivers_overlay)
Definition savegame2.c:1063
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4869
static void sg_load_ruledata(struct loaddata *loading)
Definition savegame2.c:1822
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:923
static void sg_load_player_vision(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4949
static void worklist_load(struct section_file *file, int wlist_max_length, struct worklist *pwl, const char *path,...)
Definition savegame2.c:790
static bool sg_load_player_vision_city(struct loaddata *loading, struct player *plr, struct vision_site *pdcity, const char *citystr)
Definition savegame2.c:5170
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:2403
static void loaddata_destroy(struct loaddata *loading)
Definition savegame2.c:512
static void sg_load_players(struct loaddata *loading)
Definition savegame2.c:2942
#define ORDER_OLD_TRADE_ROUTE
Definition savegame2.c:289
static void sg_load_map_tiles_extras(struct loaddata *loading)
Definition savegame2.c:2297
static void sg_load_sanitycheck(struct loaddata *loading)
Definition savegame2.c:5546
static void sg_load_event_cache(struct loaddata *loading)
Definition savegame2.c:5372
static void sg_load_map_tiles_bases(struct loaddata *loading)
Definition savegame2.c:2313
static void sg_extras_set_dbv(struct dbv *extras, char ch, struct extra_type **idx)
Definition savegame2.c:857
#define ACTIVITY_LAST_SAVEGAME2
Definition savegame2.c:147
static int sg_order_to_action(int order, struct unit *act_unit, struct tile *tgt_tile)
Definition savegame2.c:4166
#define halfbyte_iterate_roads(r, num_roads_types)
Definition savegame2.c:275
void calc_civ_score(struct player *pplayer)
Definition score.c:251
void script_server_state_load(struct section_file *file)
void settings_game_load(struct section_file *file, const char *section)
Definition settings.c:4906
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
bool str_to_int(const char *str, int *pint)
Definition shared.c:515
bool is_base64url(const char *s)
Definition shared.c:321
char scanin(const char **buf, char *delimiters, char *dest, int size)
Definition shared.c:1920
void randomize_base64url_string(char *s, size_t n)
Definition shared.c:343
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
void spaceship_calc_derived(struct player_spaceship *ship)
Definition spacerace.c:46
void spaceship_init(struct player_spaceship *ship)
Definition spaceship.c:96
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
@ SSHIP_LAUNCHED
Definition spaceship.h:85
@ SSHIP_NONE
Definition spaceship.h:84
struct specialist * specialist_by_rule_name(const char *name)
Definition specialist.c:112
Specialist_type_id specialist_index(const struct specialist *sp)
Definition specialist.c:82
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#define DEFAULT_SPECIALIST
Definition specialist.h:43
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
void server_game_init(bool keep_ruleset_value)
Definition srv_main.c:3496
const char * aifill(int amount)
Definition srv_main.c:2505
bool game_was_started(void)
Definition srv_main.c:354
void identity_number_reserve(int id)
Definition srv_main.c:2035
struct server_arguments srvarg
Definition srv_main.c:181
void init_game_seed(void)
Definition srv_main.c:208
void update_nations_with_startpos(void)
Definition srv_main.c:2310
void server_game_free(void)
Definition srv_main.c:3520
bool accept0
Definition diptreaty.h:81
bool accept1
Definition diptreaty.h:81
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:236
int world_peace_start
Definition game.h:238
float turn_change_time
Definition game.h:218
bool vision_reveal_tiles
Definition game.h:200
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:234
struct packet_game_info info
Definition game.h:89
int timeoutcounter
Definition game.h:207
char rulesetdir[MAX_LEN_NAME]
Definition game.h:239
int scoreturn
Definition game.h:225
struct packet_scenario_info scenario
Definition game.h:87
int timeoutint
Definition game.h:203
unsigned revealmap
Definition game.h:177
char orig_game_version[MAX_LEN_NAME]
Definition game.h:221
bool foggedborders
Definition game.h:147
struct civ_game::@31::@35 server
int timeoutincmult
Definition game.h:205
int timeoutinc
Definition game.h:204
int phase_mode_stored
Definition game.h:216
int max_players
Definition game.h:156
int timeoutintinc
Definition game.h:206
bool have_resources
Definition map_types.h:109
struct civ_map::@42::@44 server
bool have_huts
Definition map_types.h:108
enum map_generator generator
Definition map_types.h:99
int changed_to_times
Definition government.h:62
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:116
struct ai_trait * traits
Definition player.h:126
enum barbarian_type barbarian_type
Definition player.h:122
int science_cost
Definition player.h:119
int love[MAX_NUM_PLAYER_SLOTS]
Definition player.h:124
int expand
Definition player.h:118
int fuzzy
Definition player.h:117
enum diplstate_type type
Definition player.h:199
int units_killed
Definition player.h:105
int landarea
Definition player.h:94
int population
Definition player.h:96
int pollution
Definition player.h:99
int wonders
Definition player.h:91
int settledarea
Definition player.h:95
int units_used
Definition player.h:108
int specialists[SP_MAX]
Definition player.h:90
int units_lost
Definition player.h:106
int angry
Definition player.h:89
int techout
Definition player.h:93
int units
Definition player.h:98
int units_built
Definition player.h:104
int content
Definition player.h:87
int happy
Definition player.h:86
int spaceship
Definition player.h:103
int culture
Definition player.h:109
int unhappy
Definition player.h:88
int cities
Definition player.h:97
int literacy
Definition player.h:100
int techs
Definition player.h:92
struct player * extras_owner
Definition maphand.h:35
struct player * owner
Definition maphand.h:34
struct city_list * cities
Definition player.h:281
int bulbs_last_turn
Definition player.h:351
struct player_ai ai_common
Definition player.h:288
bv_plr_flags flags
Definition player.h:292
bool is_male
Definition player.h:257
int wonders[B_LAST]
Definition player.h:305
bool unassigned_ranked
Definition player.h:255
struct government * target_government
Definition player.h:259
char username[MAX_LEN_NAME]
Definition player.h:252
int revolution_finishes
Definition player.h:273
int nturns_idle
Definition player.h:265
struct government * government
Definition player.h:258
struct team * team
Definition player.h:261
int turns_alive
Definition player.h:266
struct unit_list * units
Definition player.h:282
char ranked_username[MAX_LEN_NAME]
Definition player.h:254
int huts
Definition player.h:349
bool is_alive
Definition player.h:268
bv_player real_embassy
Definition player.h:277
struct player_economic economic
Definition player.h:284
struct player_spaceship spaceship
Definition player.h:286
struct attribute_block_s attribute_block
Definition player.h:307
struct player_score score
Definition player.h:283
struct multiplier_value multipliers[MAX_NUM_MULTIPLIERS]
Definition player.h:314
struct nation_type * nation
Definition player.h:260
struct nation_style * style
Definition player.h:279
bool border_vision
Definition player.h:327
bool phase_done
Definition player.h:263
struct player::@70::@72 server
int history
Definition player.h:316
char orig_username[MAX_LEN_NAME]
Definition player.h:347
int last_war_action
Definition player.h:270
bool unassigned_user
Definition player.h:253
const struct tile * tile
char metaserver_addr[256]
Definition srv_main.h:29
char serverid[256]
Definition srv_main.h:49
Definition map.c:40
Definition team.c:40
Definition tile.h:50
int index
Definition tile.h:51
bv_extras extras
Definition tile.h:55
struct unit_list * units
Definition tile.h:58
struct tile * claimer
Definition tile.h:64
enum unit_orders order
Definition unit.h:94
Definition unit.h:140
int length
Definition unit.h:198
int upkeep[O_LAST]
Definition unit.h:150
bool has_orders
Definition unit.h:196
struct unit::@80 orders
enum action_decision action_decision_want
Definition unit.h:205
int battlegroup
Definition unit.h:194
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
int ord_city
Definition unit.h:245
bool moved
Definition unit.h:176
int ord_map
Definition unit.h:244
int index
Definition unit.h:198
struct vision * vision
Definition unit.h:247
bool vigilant
Definition unit.h:200
int hp
Definition unit.h:153
int fuel
Definition unit.h:155
struct extra_type * changed_from_target
Definition unit.h:173
int current_form_turn
Definition unit.h:211
enum direction8 facing
Definition unit.h:144
struct unit::@81::@84 server
struct extra_type * activity_target
Definition unit.h:167
int activity_count
Definition unit.h:165
struct unit_order * list
Definition unit.h:201
enum unit_activity changed_from
Definition unit.h:171
struct player * nationality
Definition unit.h:146
bool repeat
Definition unit.h:199
int homecity
Definition unit.h:148
bool paradropped
Definition unit.h:177
bool done_moving
Definition unit.h:184
int birth_turn
Definition unit.h:210
struct tile * goto_tile
Definition unit.h:157
struct tile * action_decision_tile
Definition unit.h:206
int veteran
Definition unit.h:154
int changed_from_count
Definition unit.h:172
enum server_side_agent ssa_controller
Definition unit.h:175
enum universals_n kind
Definition fc_types.h:880
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:960
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:886
#define sz_strlcpy(dest, src)
Definition support.h:189
#define RETURN_VALUE_AFTER_EXIT(_val_)
Definition support.h:146
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:175
bool team_add_player(struct player *pplayer, struct team *pteam)
Definition team.c:467
struct team * team_new(struct team_slot *tslot)
Definition team.c:317
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
struct advance * advance_by_rule_name(const char *name)
Definition tech.c:200
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define A_FUTURE
Definition tech.h:46
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
#define A_UNKNOWN
Definition tech.h:49
void init_tech(struct research *research, bool update)
Definition techtools.c:1093
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:266
#define T_UNKNOWN
Definition terrain.h:62
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:88
#define terrain_type_iterate_end
Definition terrain.h:272
#define RESOURCE_NONE_IDENTIFIER
Definition terrain.h:52
#define RESOURCE_NULL_IDENTIFIER
Definition terrain.h:51
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:215
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1035
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:1097
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:89
#define tile_worked(_tile)
Definition tile.h:115
#define tile_terrain(_tile)
Definition tile.h:111
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
#define tile_owner(_tile)
Definition tile.h:97
struct goods_type * goods_by_number(Goods_type_id id)
void free_unit_orders(struct unit *punit)
Definition unit.c:1807
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2428
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2499
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:866
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2911
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1662
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2707
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target, enum gen_action trigger_action)
Definition unit.c:1133
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1767
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1285
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1115
#define unit_tile(_pu)
Definition unit.h:397
#define BATTLEGROUP_NONE
Definition unit.h:193
unit_orders
Definition unit.h:38
@ ORDER_ACTION_MOVE
Definition unit.h:46
@ ORDER_ACTIVITY
Definition unit.h:42
@ ORDER_FULL_MP
Definition unit.h:44
@ ORDER_MOVE
Definition unit.h:40
@ ORDER_LAST
Definition unit.h:50
@ ORDER_PERFORM_ACTION
Definition unit.h:48
#define unit_owner(_pu)
Definition unit.h:396
void unit_list_sort_ord_map(struct unit_list *punitlist)
Definition unitlist.c:73
void unit_list_sort_ord_city(struct unit_list *punitlist)
Definition unitlist.c:85
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void resolve_unit_stacks(struct player *pplayer, struct player *aplayer, bool verbose)
Definition unittools.c:1402
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:5001
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1226
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:2613
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:624
#define unit_type_iterate(_p)
Definition unittype.h:859
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:866
void vision_site_size_set(struct vision_site *psite, citizens size)
Definition vision.c:165
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 MAP_NATIVE_WIDTH
#define MAP_INDEX_SIZE
#define MAP_NATIVE_HEIGHT