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