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