Freeciv-3.1
Loading...
Searching...
No Matches
savegame2.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/*
15 This file includes the definition of a new savegame format introduced with
16 2.3.0. It is defined by the mandatory option '+version2'. The main load
17 function checks if this option is present. If not, the old (pre-2.3.0)
18 loading routines are used.
19 The format version is also saved in the settings section of the savefile, as an
20 integer (savefile.version). The integer is used to determine the version
21 of the savefile.
22
23 Structure of this file:
24
25 - The real work is done by savegame2_load().
26 This function call all submodules (settings, players, etc.)
27
28 - The remaining part of this file is split into several sections:
29 * helper functions
30 * load functions for all submodules (and their subsubmodules)
31
32 - If possible, all functions for load submodules should exit in
33 pairs named sg_load_<submodule>. If one is not
34 needed please add a comment why.
35
36 - The submodules can be further divided as:
37 sg_load_<submodule>_<subsubmodule>
38
39 - If needed (due to static variables in the *.c files) these functions
40 can be located in the corresponding source files (as done for the settings
41 and the event_cache).
42
43 Loading a savegame:
44
45 - The status of the process is saved within the static variable
46 'sg_success'. This variable is set to TRUE within savegame2_load().
47 If you encounter an error use sg_failure_*() to set it to FALSE and
48 return an error message. Furthermore, sg_check_* should be used at the
49 start of each (submodule) function to return if previous functions failed.
50
51 - While the loading process dependencies between different modules exits.
52 They can be handled within the struct loaddata *loading which is used as
53 first argument for all sg_load_*() function. Please indicate the
54 dependencies within the definition of this struct.
55
56*/
57
58#ifdef HAVE_CONFIG_H
59#include <fc_config.h>
60#endif
61
62#include <ctype.h>
63#include <stdarg.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67
68/* utility */
69#include "bitvector.h"
70#include "fcintl.h"
71#include "idex.h"
72#include "log.h"
73#include "mem.h"
74#include "rand.h"
75#include "registry.h"
76#include "shared.h"
77#include "support.h" /* bool type */
78#include "timing.h"
79
80/* common */
81#include "achievements.h"
82#include "ai.h"
83#include "bitvector.h"
84#include "capability.h"
85#include "citizens.h"
86#include "city.h"
87#include "game.h"
88#include "government.h"
89#include "map.h"
90#include "mapimg.h"
91#include "movement.h"
92#include "multipliers.h"
93#include "packets.h"
94#include "research.h"
95#include "rgbcolor.h"
96#include "specialist.h"
97#include "unit.h"
98#include "unitlist.h"
99#include "version.h"
100
101/* server */
102#include "barbarian.h"
103#include "citizenshand.h"
104#include "citytools.h"
105#include "cityturn.h"
106#include "diplhand.h"
107#include "maphand.h"
108#include "meta.h"
109#include "notify.h"
110#include "plrhand.h"
111#include "report.h"
112#include "ruleset.h"
113#include "sanitycheck.h"
114#include "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/*
144 * This loops over the entire map to save data. It collects all the data of
145 * a line using GET_XY_CHAR and then executes the macro SECFILE_INSERT_LINE.
146 *
147 * Parameters:
148 * ptile: current tile within the line (used by GET_XY_CHAR)
149 * GET_XY_CHAR: macro returning the map character for each position
150 * secfile: a secfile struct
151 * secpath, ...: path as used for sprintf() with arguments; the last item
152 * will be the y coordinate
153 * Example:
154 * SAVE_MAP_CHAR(ptile, terrain2char(ptile->terrain), file, "map.t%04d");
155 */
156#define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath, ...) \
157{ \
158 char _line[wld.map.xsize + 1]; \
159 int _nat_x, _nat_y; \
160 \
161 for (_nat_y = 0; _nat_y < wld.map.ysize; _nat_y++) { \
162 for (_nat_x = 0; _nat_x < wld.map.xsize; _nat_x++) { \
163 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
164 fc_assert_action(ptile != NULL, continue); \
165 _line[_nat_x] = (GET_XY_CHAR); \
166 sg_failure_ret(fc_isprint(_line[_nat_x] & 0x7f), \
167 "Trying to write invalid map data at position " \
168 "(%d, %d) for path %s: '%c' (%d)", _nat_x, _nat_y, \
169 secpath, _line[_nat_x], _line[_nat_x]); \
170 } \
171 _line[wld.map.xsize] = '\0'; \
172 secfile_insert_str(secfile, _line, secpath, ## __VA_ARGS__, _nat_y); \
173 } \
174}
175
176/*
177 * This loops over the entire map to load data. It inputs a line of data
178 * using the macro SECFILE_LOOKUP_LINE and then loops using the macro
179 * SET_XY_CHAR to load each char into the map at (map_x, map_y). Internal
180 * variables ch, map_x, map_y, nat_x, and nat_y are allocated within the
181 * macro but definable by the caller.
182 *
183 * Parameters:
184 * ch: a variable to hold a char (data for a single position,
185 * used by SET_XY_CHAR)
186 * ptile: current tile within the line (used by SET_XY_CHAR)
187 * SET_XY_CHAR: macro to load the map character at each (map_x, map_y)
188 * secfile: a secfile struct
189 * secpath, ...: path as used for sprintf() with arguments; the last item
190 * will be the y coordinate
191 * Example:
192 * LOAD_MAP_CHAR(ch, ptile,
193 * map_get_player_tile(ptile, plr)->terrain
194 * = char2terrain(ch), file, "player%d.map_t%04d", plrno);
195 *
196 * Note: some (but not all) of the code this is replacing used to skip over
197 * lines that did not exist. This allowed for backward-compatibility.
198 * We could add another parameter that specified whether it was OK to
199 * skip the data, but there's not really much advantage to exiting
200 * early in this case. Instead, we let any map data type to be empty,
201 * and just print an informative warning message about it.
202 */
203#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath, ...) \
204{ \
205 int _nat_x, _nat_y; \
206 bool _printed_warning = FALSE; \
207 for (_nat_y = 0; _nat_y < wld.map.ysize; _nat_y++) { \
208 const char *_line = secfile_lookup_str(secfile, secpath, \
209 ## __VA_ARGS__, _nat_y); \
210 if (NULL == _line) { \
211 char buf[64]; \
212 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
213 log_verbose("Line not found='%s'", buf); \
214 _printed_warning = TRUE; \
215 continue; \
216 } else if (strlen(_line) != wld.map.xsize) { \
217 char buf[64]; \
218 fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y); \
219 log_verbose("Line too short (expected %d got " SIZE_T_PRINTF \
220 ")='%s'", wld.map.xsize, strlen(_line), buf); \
221 _printed_warning = TRUE; \
222 continue; \
223 } \
224 for (_nat_x = 0; _nat_x < wld.map.xsize; _nat_x++) { \
225 const char ch = _line[_nat_x]; \
226 struct tile *ptile = native_pos_to_tile(&(wld.map), _nat_x, _nat_y); \
227 (SET_XY_CHAR); \
228 } \
229 } \
230 if (_printed_warning) { \
231 /* TRANS: Minor error message. */ \
232 log_sg(_("Saved game contains incomplete map data. This can" \
233 " happen with old saved games, or it may indicate an" \
234 " invalid saved game file. Proceed at your own risk.")); \
235 } \
236}
237
238/* Iterate on the extras half-bytes */
239#define halfbyte_iterate_extras(e, num_extras_types) \
240{ \
241 int e; \
242 for (e = 0; 4 * e < (num_extras_types); e++) {
243
244#define halfbyte_iterate_extras_end \
245 } \
246}
247
248/* Iterate on the specials half-bytes */
249#define halfbyte_iterate_special(s, num_specials_types) \
250{ \
251 enum tile_special_type s; \
252 for (s = 0; 4 * s < (num_specials_types); s++) {
253
254#define halfbyte_iterate_special_end \
255 } \
256}
257
258/* Iterate on the bases half-bytes */
259#define halfbyte_iterate_bases(b, num_bases_types) \
260{ \
261 int b; \
262 for (b = 0; 4 * b < (num_bases_types); b++) {
263
264#define halfbyte_iterate_bases_end \
265 } \
266}
267
268/* Iterate on the roads half-bytes */
269#define halfbyte_iterate_roads(r, num_roads_types) \
270{ \
271 int r; \
272 for (r = 0; 4 * r < (num_roads_types); r++) {
273
274#define halfbyte_iterate_roads_end \
275 } \
276}
277
278#define TOKEN_SIZE 10
279
280#define ORDER_OLD_BUILD_CITY (-1)
281#define ORDER_OLD_DISBAND (-2)
282#define ORDER_OLD_BUILD_WONDER (-3)
283#define ORDER_OLD_TRADE_ROUTE (-4)
284#define ORDER_OLD_HOMECITY (-5)
285
286static struct loaddata *loaddata_new(struct section_file *file);
287static void loaddata_destroy(struct loaddata *loading);
288
289static enum unit_orders char2order(char order);
290static enum direction8 char2dir(char dir);
291static char activity2char(enum unit_activity activity);
292static enum unit_activity char2activity(char activity);
293static int unquote_block(const char *const quoted_, void *dest,
294 int dest_length);
295static void worklist_load(struct section_file *file, int wlist_max_length,
296 struct worklist *pwl, const char *path, ...);
297static void unit_ordering_apply(void);
298static void sg_extras_set(bv_extras *extras, char ch, struct extra_type **idx);
299static void sg_special_set(struct tile *ptile, bv_extras *extras, char ch,
300 const enum tile_special_type *idx,
301 bool rivers_overlay);
302static void sg_bases_set(bv_extras *extras, char ch, struct base_type **idx);
303static void sg_roads_set(bv_extras *extras, char ch, struct road_type **idx);
304static struct extra_type *char2resource(char c);
305static struct terrain *char2terrain(char ch);
306static Tech_type_id technology_load(struct section_file *file,
307 const char *path, int plrno);
308
309static void sg_load_ruleset(struct loaddata *loading);
310static void sg_load_savefile(struct loaddata *loading);
311
312static void sg_load_game(struct loaddata *loading);
313
314static void sg_load_ruledata(struct loaddata *loading);
315
316static void sg_load_random(struct loaddata *loading);
317
318static void sg_load_script(struct loaddata *loading);
319
320static void sg_load_scenario(struct loaddata *loading);
321
322static void sg_load_settings(struct loaddata *loading);
323
324static void sg_load_map(struct loaddata *loading);
325static void sg_load_map_tiles(struct loaddata *loading);
326static void sg_load_map_tiles_extras(struct loaddata *loading);
327static void sg_load_map_tiles_bases(struct loaddata *loading);
328static void sg_load_map_tiles_roads(struct loaddata *loading);
329static void sg_load_map_tiles_specials(struct loaddata *loading,
330 bool rivers_overlay);
331static void sg_load_map_tiles_resources(struct loaddata *loading);
332
333static void sg_load_map_startpos(struct loaddata *loading);
334static void sg_load_map_owner(struct loaddata *loading);
335static void sg_load_map_worked(struct loaddata *loading);
336static void sg_load_map_known(struct loaddata *loading);
337
338static void sg_load_players_basic(struct loaddata *loading);
339static void sg_load_players(struct loaddata *loading);
340static void sg_load_player_main(struct loaddata *loading,
341 struct player *plr);
342static void sg_load_player_cities(struct loaddata *loading,
343 struct player *plr);
344static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
345 struct city *pcity, const char *citystr,
346 int wlist_max_length);
347static void sg_load_player_city_citizens(struct loaddata *loading,
348 struct player *plr,
349 struct city *pcity,
350 const char *citystr);
351static void sg_load_player_units(struct loaddata *loading,
352 struct player *plr);
353static bool sg_load_player_unit(struct loaddata *loading,
354 struct player *plr, struct unit *punit,
355 const char *unitstr);
356static void sg_load_player_units_transport(struct loaddata *loading,
357 struct player *plr);
358static void sg_load_player_attributes(struct loaddata *loading,
359 struct player *plr);
360static void sg_load_player_vision(struct loaddata *loading,
361 struct player *plr);
362static bool sg_load_player_vision_city(struct loaddata *loading,
363 struct player *plr,
364 struct vision_site *pdcity,
365 const char *citystr);
366
367static void sg_load_researches(struct loaddata *loading);
368
369static void sg_load_event_cache(struct loaddata *loading);
370
371static void sg_load_treaties(struct loaddata *loading);
372
373static void sg_load_history(struct loaddata *loading);
374
375static void sg_load_mapimg(struct loaddata *loading);
376
377static void sg_load_sanitycheck(struct loaddata *loading);
378
379
380/* =======================================================================
381 * Basic load / save functions.
382 * ======================================================================= */
383
384/************************************************************************/
387void savegame2_load(struct section_file *file)
388{
389 struct loaddata *loading;
390 bool was_send_city_suppressed, was_send_tile_suppressed;
391
392 /* initialise loading */
393 was_send_city_suppressed = send_city_suppression(TRUE);
394 was_send_tile_suppressed = send_tile_suppression(TRUE);
395 loading = loaddata_new(file);
397
398 /* Load the savegame data. */
399 /* Set up correct ruleset */
400 sg_load_ruleset(loading);
401 /* [compat] */
402 sg_load_compat(loading, SAVEGAME_2);
403 /* [savefile] */
404 sg_load_savefile(loading);
405 /* [game] */
406 sg_load_game(loading);
407 /* [scenario] */
408 sg_load_scenario(loading);
409 /* [random] */
410 sg_load_random(loading);
411 /* [settings] */
412 sg_load_settings(loading);
413 /* [ruledata] */
414 sg_load_ruledata(loading);
415 /* [players] (basic data) */
416 sg_load_players_basic(loading);
417 /* [map]; needs width and height loaded by [settings] */
418 sg_load_map(loading);
419 /* [research] */
420 sg_load_researches(loading);
421 /* [player<i>] */
422 sg_load_players(loading);
423 /* [event_cache] */
424 sg_load_event_cache(loading);
425 /* [treaties] */
426 sg_load_treaties(loading);
427 /* [history] */
428 sg_load_history(loading);
429 /* [mapimg] */
430 sg_load_mapimg(loading);
431 /* [script] -- must come last as may reference game objects */
432 sg_load_script(loading);
433 /* [post_load_compat]; needs the game loaded by [savefile] */
435
436 /* Sanity checks for the loaded game. */
437 sg_load_sanitycheck(loading);
438
439 /* deinitialise loading */
440 loaddata_destroy(loading);
441 send_tile_suppression(was_send_tile_suppressed);
442 send_city_suppression(was_send_city_suppressed);
443
444 if (!sg_success) {
445 log_error("Failure loading savegame!");
446 /* Try to get the server back to a vaguely sane state */
449 load_rulesets(NULL, NULL, FALSE, NULL, TRUE, FALSE, TRUE);
450 }
451}
452
453/************************************************************************/
456static struct loaddata *loaddata_new(struct section_file *file)
457{
458 struct loaddata *loading = calloc(1, sizeof(*loading));
459 loading->file = file;
460 loading->secfile_options = NULL;
461
462 loading->improvement.order = NULL;
463 loading->improvement.size = -1;
464 loading->technology.order = NULL;
465 loading->technology.size = -1;
466 loading->activities.order = NULL;
467 loading->activities.size = -1;
468 loading->trait.order = NULL;
469 loading->trait.size = -1;
470 loading->extra.order = NULL;
471 loading->extra.size = -1;
472 loading->multiplier.order = NULL;
473 loading->multiplier.size = -1;
474 loading->special.order = NULL;
475 loading->special.size = -1;
476 loading->base.order = NULL;
477 loading->base.size = -1;
478 loading->road.order = NULL;
479 loading->road.size = -1;
480 loading->specialist.order = NULL;
481 loading->specialist.size = -1;
482 loading->ds_t.order = NULL;
483 loading->ds_t.size = -1;
484
485 loading->server_state = S_S_INITIAL;
486 loading->rstate = fc_rand_state();
487 loading->worked_tiles = NULL;
488
489 return loading;
490}
491
492/************************************************************************/
495static void loaddata_destroy(struct loaddata *loading)
496{
497 if (loading->improvement.order != NULL) {
498 free(loading->improvement.order);
499 }
500
501 if (loading->technology.order != NULL) {
502 free(loading->technology.order);
503 }
504
505 if (loading->activities.order != NULL) {
506 free(loading->activities.order);
507 }
508
509 if (loading->trait.order != NULL) {
510 free(loading->trait.order);
511 }
512
513 if (loading->extra.order != NULL) {
514 free(loading->extra.order);
515 }
516
517 if (loading->multiplier.order != NULL) {
518 free(loading->multiplier.order);
519 }
520
521 if (loading->special.order != NULL) {
522 free(loading->special.order);
523 }
524
525 if (loading->base.order != NULL) {
526 free(loading->base.order);
527 }
528
529 if (loading->road.order != NULL) {
530 free(loading->road.order);
531 }
532
533 if (loading->specialist.order != NULL) {
534 free(loading->specialist.order);
535 }
536
537 if (loading->ds_t.order != NULL) {
538 free(loading->ds_t.order);
539 }
540
541 if (loading->worked_tiles != NULL) {
542 free(loading->worked_tiles);
543 }
544
545 free(loading);
546}
547
548/* =======================================================================
549 * Helper functions.
550 * ======================================================================= */
551
552/************************************************************************/
555static enum unit_orders char2order(char order)
556{
557 switch (order) {
558 case 'm':
559 case 'M':
560 return ORDER_MOVE;
561 case 'w':
562 case 'W':
563 return ORDER_FULL_MP;
564 case 'b':
565 case 'B':
567 case 'a':
568 case 'A':
569 return ORDER_ACTIVITY;
570 case 'd':
571 case 'D':
572 return ORDER_OLD_DISBAND;
573 case 'u':
574 case 'U':
576 case 't':
577 case 'T':
579 case 'h':
580 case 'H':
581 return ORDER_OLD_HOMECITY;
582 case 'x':
583 case 'X':
584 return ORDER_ACTION_MOVE;
585 }
586
587 /* This can happen if the savegame is invalid. */
588 return ORDER_LAST;
589}
590
591/************************************************************************/
594static enum direction8 char2dir(char dir)
595{
596 /* Numberpad values for the directions. */
597 switch (dir) {
598 case '1':
599 return DIR8_SOUTHWEST;
600 case '2':
601 return DIR8_SOUTH;
602 case '3':
603 return DIR8_SOUTHEAST;
604 case '4':
605 return DIR8_WEST;
606 case '6':
607 return DIR8_EAST;
608 case '7':
609 return DIR8_NORTHWEST;
610 case '8':
611 return DIR8_NORTH;
612 case '9':
613 return DIR8_NORTHEAST;
614 }
615
616 /* This can happen if the savegame is invalid. */
617 return direction8_invalid();
618}
619
620/************************************************************************/
623static char activity2char(enum unit_activity activity)
624{
625 switch (activity) {
626 case ACTIVITY_IDLE:
627 return 'w';
628 case ACTIVITY_POLLUTION:
629 return 'p';
630 case ACTIVITY_OLD_ROAD:
631 return 'r';
632 case ACTIVITY_MINE:
633 return 'm';
634 case ACTIVITY_IRRIGATE:
635 return 'i';
636 case ACTIVITY_FORTIFIED:
637 return 'f';
638 case ACTIVITY_FORTRESS:
639 return 't';
640 case ACTIVITY_SENTRY:
641 return 's';
642 case ACTIVITY_OLD_RAILROAD:
643 return 'l';
644 case ACTIVITY_PILLAGE:
645 return 'e';
646 case ACTIVITY_GOTO:
647 return 'g';
648 case ACTIVITY_EXPLORE:
649 return 'x';
650 case ACTIVITY_TRANSFORM:
651 return 'o';
652 case ACTIVITY_AIRBASE:
653 return 'a';
654 case ACTIVITY_FORTIFYING:
655 return 'y';
656 case ACTIVITY_FALLOUT:
657 return 'u';
658 case ACTIVITY_BASE:
659 return 'b';
660 case ACTIVITY_GEN_ROAD:
661 return 'R';
662 case ACTIVITY_CONVERT:
663 return 'c';
664 case ACTIVITY_UNKNOWN:
665 case ACTIVITY_PATROL_UNUSED:
666 case ACTIVITY_CULTIVATE:
667 case ACTIVITY_PLANT:
668 return '?';
669 case ACTIVITY_LAST:
670 break;
671 }
672
674 return '?';
675}
676
677/************************************************************************/
680static enum unit_activity char2activity(char activity)
681{
682 enum unit_activity a;
683
684 for (a = 0; a < ACTIVITY_LAST; a++) {
685 char achar = activity2char(a);
686
687 if (activity == achar) {
688 return a;
689 }
690 }
691
692 /* This can happen if the savegame is invalid. */
693 return ACTIVITY_LAST;
694}
695
696/************************************************************************/
701static int unquote_block(const char *const quoted_, void *dest,
702 int dest_length)
703{
704 int i, length, parsed, tmp;
705 char *endptr;
706 const char *quoted = quoted_;
707
708 parsed = sscanf(quoted, "%d", &length);
709
710 if (parsed != 1) {
711 log_error(_("Syntax error in attribute block."));
712 return 0;
713 }
714
715 if (length > dest_length) {
716 return 0;
717 }
718
719 quoted = strchr(quoted, ':');
720
721 if (quoted == NULL) {
722 log_error(_("Syntax error in attribute block."));
723 return 0;
724 }
725
726 quoted++;
727
728 for (i = 0; i < length; i++) {
729 tmp = strtol(quoted, &endptr, 16);
730
731 if ((endptr - quoted) != 2
732 || *endptr != ' '
733 || (tmp & 0xff) != tmp) {
734 log_error(_("Syntax error in attribute block."));
735 return 0;
736 }
737
738 ((unsigned char *) dest)[i] = tmp;
739 quoted += 3;
740 }
741
742 return length;
743}
744
745/************************************************************************/
749static void worklist_load(struct section_file *file, int wlist_max_length,
750 struct worklist *pwl, const char *path, ...)
751{
752 int i;
753 const char *kind;
754 const char *name;
755 char path_str[1024];
756 va_list ap;
757
758 /* The first part of the registry path is taken from the varargs to the
759 * function. */
760 va_start(ap, path);
761 fc_vsnprintf(path_str, sizeof(path_str), path, ap);
762 va_end(ap);
763
764 worklist_init(pwl);
766 "%s.wl_length", path_str);
767
768 for (i = 0; i < pwl->length; i++) {
769 kind = secfile_lookup_str(file, "%s.wl_kind%d", path_str, i);
770
771 /* We lookup the production value by name. An invalid entry isn't a
772 * fatal error; we just truncate the worklist. */
773 name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
774 path_str, i);
775 pwl->entries[i] = universal_by_rule_name(kind, name);
776 if (pwl->entries[i].kind == universals_n_invalid()) {
777 log_sg("%s.wl_value%d: unknown \"%s\" \"%s\".", path_str, i, kind,
778 name);
779 pwl->length = i;
780 break;
781 }
782 }
783
784 /* Padding entries */
785 for (; i < wlist_max_length; i++) {
786 (void) secfile_entry_lookup(file, "%s.wl_kind%d", path_str, i);
787 (void) secfile_entry_lookup(file, "%s.wl_value%d", path_str, i);
788 }
789}
790
791/************************************************************************/
795static void unit_ordering_apply(void)
796{
797 players_iterate(pplayer) {
798 city_list_iterate(pplayer->cities, pcity) {
799 unit_list_sort_ord_city(pcity->units_supported);
800 }
803
804 whole_map_iterate(&(wld.map), ptile) {
805 unit_list_sort_ord_map(ptile->units);
807}
808
809/************************************************************************/
816static void sg_extras_set(bv_extras *extras, char ch, struct extra_type **idx)
817{
818 int i, bin;
819 const char *pch = strchr(hex_chars, ch);
820
821 if (!pch || ch == '\0') {
822 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
823 bin = 0;
824 } else {
825 bin = pch - hex_chars;
826 }
827
828 for (i = 0; i < 4; i++) {
829 struct extra_type *pextra = idx[i];
830
831 if (pextra == NULL) {
832 continue;
833 }
834 if ((bin & (1 << i))
835 && (wld.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
836 BV_SET(*extras, extra_index(pextra));
837 }
838 }
839}
840
841/************************************************************************/
848static void sg_special_set(struct tile *ptile, bv_extras *extras, char ch,
849 const enum tile_special_type *idx,
850 bool rivers_overlay)
851{
852 int i, bin;
853 const char *pch = strchr(hex_chars, ch);
854
855 if (!pch || ch == '\0') {
856 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
857 bin = 0;
858 } else {
859 bin = pch - hex_chars;
860 }
861
862 for (i = 0; i < 4; i++) {
863 enum tile_special_type sp = idx[i];
864
865 if (sp == S_LAST) {
866 continue;
867 }
868 if (rivers_overlay && sp != S_OLD_RIVER) {
869 continue;
870 }
871
872 if (sp == S_HUT && !wld.map.server.have_huts) {
873 /* It would be logical to have this in the saving side -
874 * really not saving the huts in the first place, BUT
875 * 1) They have been saved by older versions, so we
876 * have to deal with such savegames.
877 * 2) This makes scenario author less likely to lose
878 * one's work completely after carefully placing huts
879 * and then saving with 'have_huts' disabled. */
880 continue;
881 }
882
883 if (bin & (1 << i)) {
884 if (sp == S_OLD_ROAD) {
885 struct road_type *proad;
886
888 if (proad) {
890 }
891 } else if (sp == S_OLD_RAILROAD) {
892 struct road_type *proad;
893
895 if (proad) {
897 }
898 } else if (sp == S_OLD_RIVER) {
899 struct road_type *proad;
900
902 if (proad) {
904 }
905 } else {
906 struct extra_type *pextra = NULL;
907 enum extra_cause cause = EC_COUNT;
908
909 /* Converting from old hardcoded specials to as sensible extra as we can */
910 switch (sp) {
911 case S_IRRIGATION:
912 case S_FARMLAND:
913 /* If old savegame has both irrigation and farmland, EC_IRRIGATION
914 * gets applied twice, which hopefully has the correct result. */
915 cause = EC_IRRIGATION;
916 break;
917 case S_MINE:
918 cause = EC_MINE;
919 break;
920 case S_POLLUTION:
921 cause = EC_POLLUTION;
922 break;
923 case S_HUT:
924 cause = EC_HUT;
925 break;
926 case S_FALLOUT:
927 cause = EC_FALLOUT;
928 break;
929 default:
931 break;
932 }
933
934 if (cause != EC_COUNT) {
935 struct tile *vtile = tile_virtual_new(ptile);
936 struct terrain *pterr = tile_terrain(vtile);
937 const struct req_context tile_ctxt = { .tile = vtile };
938
939 /* Do not let the extras already set to the real tile mess with setup
940 * of the player tiles if that's what we're doing. */
941 vtile->extras = *extras;
942
943 /* It's ok not to know which player or which unit originally built the extra -
944 * in the rules used when specials were saved these could not have made any
945 * difference. */
946 /* Can't use next_extra_for_tile() as it works for buildable extras only. */
947
948 if ((cause != EC_IRRIGATION || pterr->irrigation_time != 0)
949 && (cause != EC_MINE || pterr->mining_time != 0)
950 && (cause != EC_BASE || pterr->base_time != 0)
951 && (cause != EC_ROAD || pterr->road_time != 0)) {
952 extra_type_by_cause_iterate(cause, candidate) {
953 if (!tile_has_extra(vtile, candidate)) {
954 if ((!is_extra_caused_by(candidate, EC_BASE)
955 || tile_city(vtile) != NULL
956 || extra_base_get(candidate)->border_sq <= 0)
957 && are_reqs_active(&tile_ctxt, tile_owner(vtile),
958 &candidate->reqs,
959 RPT_POSSIBLE)) {
960 pextra = candidate;
961 break;
962 }
963 }
965 }
966
968 }
969
970 if (pextra) {
971 BV_SET(*extras, extra_index(pextra));
972 }
973 }
974 }
975 }
976}
977
978/************************************************************************/
985static void sg_bases_set(bv_extras *extras, char ch, struct base_type **idx)
986{
987 int i, bin;
988 const char *pch = strchr(hex_chars, ch);
989
990 if (!pch || ch == '\0') {
991 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
992 bin = 0;
993 } else {
994 bin = pch - hex_chars;
995 }
996
997 for (i = 0; i < 4; i++) {
998 struct base_type *pbase = idx[i];
999
1000 if (pbase == NULL) {
1001 continue;
1002 }
1003 if (bin & (1 << i)) {
1005 }
1006 }
1007}
1008
1009/************************************************************************/
1016static void sg_roads_set(bv_extras *extras, char ch, struct road_type **idx)
1017{
1018 int i, bin;
1019 const char *pch = strchr(hex_chars, ch);
1020
1021 if (!pch || ch == '\0') {
1022 log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1023 bin = 0;
1024 } else {
1025 bin = pch - hex_chars;
1026 }
1027
1028 for (i = 0; i < 4; i++) {
1029 struct road_type *proad = idx[i];
1030
1031 if (proad == NULL) {
1032 continue;
1033 }
1034 if (bin & (1 << i)) {
1036 }
1037 }
1038}
1039
1040/************************************************************************/
1043static struct extra_type *char2resource(char c)
1044{
1045 /* speed common values */
1047 || c == RESOURCE_NONE_IDENTIFIER) {
1048 return NULL;
1049 }
1050
1051 return resource_by_identifier(c);
1052}
1053
1054/************************************************************************/
1058static struct terrain *char2terrain(char ch)
1059{
1060 /* terrain_by_identifier plus fatal error */
1061 if (ch == TERRAIN_UNKNOWN_IDENTIFIER) {
1062 return T_UNKNOWN;
1063 }
1064 terrain_type_iterate(pterrain) {
1065 if (pterrain->identifier == ch) {
1066 return pterrain;
1067 }
1069
1070 log_fatal("Unknown terrain identifier '%c' in savegame.", ch);
1071
1072 exit(EXIT_FAILURE);
1073
1075}
1076
1077/************************************************************************/
1081 const char *path, int plrno)
1082{
1083 char path_with_name[128];
1084 const char *name;
1085 struct advance *padvance;
1086
1087 fc_snprintf(path_with_name, sizeof(path_with_name),
1088 "%s_name", path);
1089
1090 name = secfile_lookup_str(file, path_with_name, plrno);
1091
1092 if (!name || name[0] == '\0') {
1093 /* Used by researching_saved */
1094 return A_UNKNOWN;
1095 }
1096 if (fc_strcasecmp(name, "A_FUTURE") == 0) {
1097 return A_FUTURE;
1098 }
1099 if (fc_strcasecmp(name, "A_NONE") == 0) {
1100 return A_NONE;
1101 }
1102 if (fc_strcasecmp(name, "A_UNSET") == 0) {
1103 return A_UNSET;
1104 }
1105
1106 padvance = advance_by_rule_name(name);
1107 sg_failure_ret_val(NULL != padvance, A_NONE,
1108 "%s: unknown technology \"%s\".", path_with_name, name);
1109
1110 return advance_number(padvance);
1111}
1112
1113/* =======================================================================
1114 * Load savefile data.
1115 * ======================================================================= */
1116
1117/************************************************************************/
1120static void sg_load_ruleset(struct loaddata *loading)
1121{
1122 const char *ruleset = secfile_lookup_str_default(loading->file,
1124 "savefile.rulesetdir");
1125
1126 /* Load ruleset. */
1128 if (!strcmp("default", game.server.rulesetdir)) {
1129 int version;
1130
1131 version = secfile_lookup_int_default(loading->file, -1, "savefile.version");
1132 if (version >= 30) {
1133 /* Here 'default' really means current default.
1134 * Saving happens with real ruleset name, so savegames containing this
1135 * are special scenarios. */
1137 } else {
1138 /* 'default' is the old name of the classic ruleset */
1139 sz_strlcpy(game.server.rulesetdir, "classic");
1140 }
1141 log_verbose("Savegame specified ruleset '%s'. Really loading '%s'.",
1143 }
1144 if (!load_rulesets(NULL, NULL, FALSE, NULL, TRUE, FALSE, TRUE)) {
1145 /* Failed to load correct ruleset */
1146 sg_failure_ret(FALSE, _("Failed to load ruleset '%s' needed for savegame."),
1147 ruleset);
1148 }
1149}
1150
1151/************************************************************************/
1154static void sg_load_savefile(struct loaddata *loading)
1155{
1156 int i;
1157 const char *terr_name;
1158
1159 /* Check status and return if not OK (sg_success FALSE). */
1160 sg_check_ret();
1161
1162 /* Load savefile options. */
1163 loading->secfile_options
1164 = secfile_lookup_str(loading->file, "savefile.options");
1165
1166 /* We don't need these entries, but read them anyway to avoid
1167 * warnings about unread secfile entries. */
1168 (void) secfile_entry_by_path(loading->file, "savefile.reason");
1169 (void) secfile_entry_by_path(loading->file, "savefile.revision");
1170
1171 /* In case of savegame2.c saves, missing entry means savegame older than support
1172 * for saving last_updated by turn. So this must default to TRUE. */
1174 "savefile.last_updated_as_year");
1175
1176 /* Load improvements. */
1177 loading->improvement.size
1178 = secfile_lookup_int_default(loading->file, 0,
1179 "savefile.improvement_size");
1180 if (loading->improvement.size) {
1181 loading->improvement.order
1182 = secfile_lookup_str_vec(loading->file, &loading->improvement.size,
1183 "savefile.improvement_vector");
1184 sg_failure_ret(loading->improvement.size != 0,
1185 "Failed to load improvement order: %s",
1186 secfile_error());
1187 }
1188
1189 /* Load technologies. */
1190 loading->technology.size
1191 = secfile_lookup_int_default(loading->file, 0,
1192 "savefile.technology_size");
1193 if (loading->technology.size) {
1194 loading->technology.order
1195 = secfile_lookup_str_vec(loading->file, &loading->technology.size,
1196 "savefile.technology_vector");
1197 sg_failure_ret(loading->technology.size != 0,
1198 "Failed to load technology order: %s",
1199 secfile_error());
1200 }
1201
1202 /* Load Activities. */
1203 loading->activities.size
1204 = secfile_lookup_int_default(loading->file, 0,
1205 "savefile.activities_size");
1206 if (loading->activities.size) {
1207 loading->activities.order
1208 = secfile_lookup_str_vec(loading->file, &loading->activities.size,
1209 "savefile.activities_vector");
1210 sg_failure_ret(loading->activities.size != 0,
1211 "Failed to load activity order: %s",
1212 secfile_error());
1213 }
1214
1215 /* Load traits. */
1216 loading->trait.size
1217 = secfile_lookup_int_default(loading->file, 0,
1218 "savefile.trait_size");
1219 if (loading->trait.size) {
1220 loading->trait.order
1221 = secfile_lookup_str_vec(loading->file, &loading->trait.size,
1222 "savefile.trait_vector");
1223 sg_failure_ret(loading->trait.size != 0,
1224 "Failed to load trait order: %s",
1225 secfile_error());
1226 }
1227
1228 /* Load extras. */
1229 loading->extra.size
1230 = secfile_lookup_int_default(loading->file, 0,
1231 "savefile.extras_size");
1232 if (loading->extra.size) {
1233 const char **modname;
1234 size_t nmod;
1235 int j;
1236
1237 modname = secfile_lookup_str_vec(loading->file, &loading->extra.size,
1238 "savefile.extras_vector");
1239 sg_failure_ret(loading->extra.size != 0,
1240 "Failed to load extras order: %s",
1241 secfile_error());
1243 "Number of extras defined by the ruleset (= %d) are "
1244 "lower than the number in the savefile (= %d).",
1245 game.control.num_extra_types, (int)loading->extra.size);
1246 /* make sure that the size of the array is divisible by 4 */
1247 nmod = 4 * ((loading->extra.size + 3) / 4);
1248 loading->extra.order = fc_calloc(nmod, sizeof(*loading->extra.order));
1249 for (j = 0; j < loading->extra.size; j++) {
1250 loading->extra.order[j] = extra_type_by_rule_name(modname[j]);
1251 }
1252 free(modname);
1253 for (; j < nmod; j++) {
1254 loading->extra.order[j] = NULL;
1255 }
1256 }
1257
1258 /* Load multipliers. */
1259 loading->multiplier.size
1260 = secfile_lookup_int_default(loading->file, 0,
1261 "savefile.multipliers_size");
1262 if (loading->multiplier.size) {
1263 const char **modname;
1264 int j;
1265
1266 modname = secfile_lookup_str_vec(loading->file, &loading->multiplier.size,
1267 "savefile.multipliers_vector");
1268 sg_failure_ret(loading->multiplier.size != 0,
1269 "Failed to load multipliers order: %s",
1270 secfile_error());
1271 /* It's OK for the set of multipliers in the savefile to differ
1272 * from those in the ruleset. */
1273 loading->multiplier.order = fc_calloc(loading->multiplier.size,
1274 sizeof(*loading->multiplier.order));
1275 for (j = 0; j < loading->multiplier.size; j++) {
1276 loading->multiplier.order[j] = multiplier_by_rule_name(modname[j]);
1277 if (!loading->multiplier.order[j]) {
1278 log_verbose("Multiplier \"%s\" in savegame but not in ruleset, "
1279 "discarding", modname[j]);
1280 }
1281 }
1282 free(modname);
1283 }
1284
1285 /* Load specials. */
1286 loading->special.size
1287 = secfile_lookup_int_default(loading->file, 0,
1288 "savefile.specials_size");
1289 if (loading->special.size) {
1290 const char **modname;
1291 size_t nmod;
1292 enum tile_special_type j;
1293
1294 modname = secfile_lookup_str_vec(loading->file, &loading->special.size,
1295 "savefile.specials_vector");
1296 sg_failure_ret(loading->special.size != 0,
1297 "Failed to load specials order: %s",
1298 secfile_error());
1299 /* make sure that the size of the array is divisible by 4 */
1300 /* Allocating extra 4 slots, just a couple of bytes,
1301 * in case of special.size being divisible by 4 already is intentional.
1302 * Added complexity would cost those couple of bytes in code size alone,
1303 * and we actually need at least one slot immediately after last valid
1304 * one. That's where S_LAST is (or was in version that saved the game)
1305 * and in some cases S_LAST gets written to savegame, at least as
1306 * activity target special when activity targets some base or road
1307 * instead. By having current S_LAST in that index allows us to map
1308 * that old S_LAST to current S_LAST, just like any real special within
1309 * special.size gets mapped. */
1310 nmod = loading->special.size + (4 - (loading->special.size % 4));
1311 loading->special.order = fc_calloc(nmod,
1312 sizeof(*loading->special.order));
1313 for (j = 0; j < loading->special.size; j++) {
1314 if (!fc_strcasecmp("Road", modname[j])) {
1315 loading->special.order[j] = S_OLD_ROAD;
1316 } else if (!fc_strcasecmp("Railroad", modname[j])) {
1317 loading->special.order[j] = S_OLD_RAILROAD;
1318 } else if (!fc_strcasecmp("River", modname[j])) {
1319 loading->special.order[j] = S_OLD_RIVER;
1320 } else {
1321 loading->special.order[j] = special_by_rule_name(modname[j]);
1322 }
1323 }
1324 free(modname);
1325 for (; j < nmod; j++) {
1326 loading->special.order[j] = S_LAST;
1327 }
1328 }
1329
1330 /* Load bases. */
1331 loading->base.size
1332 = secfile_lookup_int_default(loading->file, 0,
1333 "savefile.bases_size");
1334 if (loading->base.size) {
1335 const char **modname;
1336 size_t nmod;
1337 int j;
1338
1339 modname = secfile_lookup_str_vec(loading->file, &loading->base.size,
1340 "savefile.bases_vector");
1341 sg_failure_ret(loading->base.size != 0,
1342 "Failed to load bases order: %s",
1343 secfile_error());
1344 /* make sure that the size of the array is divisible by 4 */
1345 nmod = 4 * ((loading->base.size + 3) / 4);
1346 loading->base.order = fc_calloc(nmod, sizeof(*loading->base.order));
1347 for (j = 0; j < loading->base.size; j++) {
1348 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1349
1350 sg_failure_ret(pextra != NULL
1351 || game.control.num_base_types >= loading->base.size,
1352 "Unknown base type %s in savefile.",
1353 modname[j]);
1354
1355 if (pextra != NULL) {
1356 loading->base.order[j] = extra_base_get(pextra);
1357 } else {
1358 loading->base.order[j] = NULL;
1359 }
1360 }
1361 free(modname);
1362 for (; j < nmod; j++) {
1363 loading->base.order[j] = NULL;
1364 }
1365 }
1366
1367 /* Load roads. */
1368 loading->road.size
1369 = secfile_lookup_int_default(loading->file, 0,
1370 "savefile.roads_size");
1371 if (loading->road.size) {
1372 const char **modname;
1373 size_t nmod;
1374 int j;
1375
1376 modname = secfile_lookup_str_vec(loading->file, &loading->road.size,
1377 "savefile.roads_vector");
1378 sg_failure_ret(loading->road.size != 0,
1379 "Failed to load roads order: %s",
1380 secfile_error());
1382 "Number of roads defined by the ruleset (= %d) are "
1383 "lower than the number in the savefile (= %d).",
1384 game.control.num_road_types, (int)loading->road.size);
1385 /* make sure that the size of the array is divisible by 4 */
1386 nmod = 4 * ((loading->road.size + 3) / 4);
1387 loading->road.order = fc_calloc(nmod, sizeof(*loading->road.order));
1388 for (j = 0; j < loading->road.size; j++) {
1389 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1390
1391 if (pextra != NULL) {
1392 loading->road.order[j] = extra_road_get(pextra);
1393 } else {
1394 loading->road.order[j] = NULL;
1395 }
1396 }
1397 free(modname);
1398 for (; j < nmod; j++) {
1399 loading->road.order[j] = NULL;
1400 }
1401 }
1402
1403 /* Load specialists. */
1404 loading->specialist.size
1405 = secfile_lookup_int_default(loading->file, 0,
1406 "savefile.specialists_size");
1407 if (loading->specialist.size) {
1408 const char **modname;
1409 size_t nmod;
1410 int j;
1411
1412 modname = secfile_lookup_str_vec(loading->file, &loading->specialist.size,
1413 "savefile.specialists_vector");
1414 sg_failure_ret(loading->specialist.size != 0,
1415 "Failed to load specialists order: %s",
1416 secfile_error());
1418 "Number of specialists defined by the ruleset (= %d) are "
1419 "lower than the number in the savefile (= %d).",
1421 /* make sure that the size of the array is divisible by 4 */
1422 /* That's not really needed with specialists at the moment, but done this way
1423 * for consistency with other types, and to be prepared for the time it needs
1424 * to be this way. */
1425 nmod = 4 * ((loading->specialist.size + 3) / 4);
1426 loading->specialist.order = fc_calloc(nmod, sizeof(*loading->specialist.order));
1427 for (j = 0; j < loading->specialist.size; j++) {
1428 loading->specialist.order[j] = specialist_by_rule_name(modname[j]);
1429 }
1430 free(modname);
1431 for (; j < nmod; j++) {
1432 loading->specialist.order[j] = NULL;
1433 }
1434 }
1435
1436 /* Load diplomatic state type order. */
1437 loading->ds_t.size
1438 = secfile_lookup_int_default(loading->file, 0,
1439 "savefile.diplstate_type_size");
1440
1441 sg_failure_ret(loading->ds_t.size > 0,
1442 "Failed to load diplomatic state type order: %s",
1443 secfile_error());
1444
1445 if (loading->ds_t.size) {
1446 const char **modname;
1447 int j;
1448
1449 modname = secfile_lookup_str_vec(loading->file, &loading->ds_t.size,
1450 "savefile.diplstate_type_vector");
1451
1452 loading->ds_t.order = fc_calloc(loading->ds_t.size,
1453 sizeof(*loading->ds_t.order));
1454
1455 for (j = 0; j < loading->ds_t.size; j++) {
1456 loading->ds_t.order[j] = diplstate_type_by_name(modname[j],
1458 }
1459
1460 free(modname);
1461 }
1462
1463 /* Not used by this freeciv version - for future use */
1464 {
1465 int j;
1466
1467 i = secfile_lookup_int_default(loading->file, 0, "savefile.city_options_size");
1468 for (j = 0; j < i; j++) {
1469 (void) secfile_entry_lookup(loading->file, "savefile.city_options_vector,%d", j);
1470 }
1471 }
1472
1473 terrain_type_iterate(pterr) {
1474 pterr->identifier_load = '\0';
1476
1477 i = 0;
1478 while ((terr_name = secfile_lookup_str_default(loading->file, NULL,
1479 "savefile.terrident%d.name", i)) != NULL) {
1480 struct terrain *pterr = terrain_by_rule_name(terr_name);
1481
1482 if (pterr != NULL) {
1483 const char *iptr = secfile_lookup_str_default(loading->file, NULL,
1484 "savefile.terrident%d.identifier", i);
1485
1486 pterr->identifier_load = *iptr;
1487 } else {
1488 log_error("Identifier for unknown terrain type %s.", terr_name);
1489 }
1490 i++;
1491 }
1492
1493 terrain_type_iterate(pterr) {
1494 terrain_type_iterate(pterr2) {
1495 if (pterr != pterr2 && pterr->identifier_load != '\0') {
1496 sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1497 "%s and %s share a saved identifier",
1498 terrain_rule_name(pterr), terrain_rule_name(pterr2));
1499 }
1502}
1503
1504/* =======================================================================
1505 * Load game status.
1506 * ======================================================================= */
1507
1508/************************************************************************/
1511static void sg_load_ruledata(struct loaddata *loading)
1512{
1513 int i;
1514 const char *name;
1515
1516 /* Check status and return if not OK (sg_success FALSE). */
1517 sg_check_ret();
1518
1519 for (i = 0;
1520 (name = secfile_lookup_str_default(loading->file, NULL,
1521 "ruledata.government%d.name", i));
1522 i++) {
1524
1525 if (gov != NULL) {
1527 "ruledata.government%d.changes", i);
1528 }
1529 }
1530}
1531
1532/************************************************************************/
1535static void sg_load_game(struct loaddata *loading)
1536{
1537 int game_version;
1538 const char *str;
1539 const char *level;
1540 int i;
1541
1542 /* Check status and return if not OK (sg_success FALSE). */
1543 sg_check_ret();
1544
1545 /* Load version. */
1546 game_version
1547 = secfile_lookup_int_default(loading->file, 0, "game.version");
1548 /* We require at least version 2.2.99 */
1549 sg_failure_ret(20299 <= game_version, "Saved game is too old, at least "
1550 "version 2.2.99 required.");
1551
1552 loading->full_version = game_version;
1553
1554 secfile_entry_ignore(loading->file, "scenario.game_version");
1555
1556 /* Load server state. */
1557 str = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
1558 "game.server_state");
1559 loading->server_state = server_states_by_name(str, strcmp);
1560 if (!server_states_is_valid(loading->server_state)) {
1561 /* Don't take any risk! */
1562 loading->server_state = S_S_INITIAL;
1563 }
1564
1567 "game.meta_patches");
1569
1571 /* Do not overwrite this if the user requested a specific metaserver
1572 * from the command line (option --Metaserver). */
1576 "game.meta_server"));
1577 }
1578
1579 if ('\0' == srvarg.serverid[0]) {
1580 /* Do not overwrite this if the user requested a specific metaserver
1581 * from the command line (option --serverid). */
1583 secfile_lookup_str_default(loading->file, "",
1584 "game.serverid"));
1585 }
1586 sz_strlcpy(server.game_identifier,
1587 secfile_lookup_str_default(loading->file, "", "game.id"));
1588 /* We are not checking game_identifier legality just yet.
1589 * That's done when we are sure that rand seed has been initialized,
1590 * so that we can generate new game_identifier, if needed.
1591 * See sq_load_sanitycheck(). */
1592
1593 level = secfile_lookup_str_default(loading->file, NULL,
1594 "game.level");
1595 if (level != NULL) {
1596 if (!fc_strcasecmp("Handicapped", level)) {
1597 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
1598 game.info.skill_level = AI_LEVEL_RESTRICTED;
1599 } else {
1600 game.info.skill_level = ai_level_by_name(level, fc_strcasecmp);
1601 }
1602 } else {
1603 game.info.skill_level = ai_level_invalid();
1604 }
1605
1606 if (!ai_level_is_valid(game.info.skill_level)) {
1610 "game.skill_level"));
1611 }
1614 "game.phase_mode");
1617 "game.phase_mode_stored");
1619 = secfile_lookup_int_default(loading->file, 0,
1620 "game.phase");
1624 "game.scoreturn");
1625
1628 "game.timeoutint");
1631 "game.timeoutintinc");
1634 "game.timeoutinc");
1637 "game.timeoutincmult");
1640 "game.timeoutcounter");
1641
1642 game.info.turn
1643 = secfile_lookup_int_default(loading->file, 0, "game.turn");
1645 "game.year"), "%s", secfile_error());
1647 = secfile_lookup_bool_default(loading->file, FALSE, "game.year_0_hack");
1648
1650 = secfile_lookup_int_default(loading->file, 0, "game.globalwarming");
1652 = secfile_lookup_int_default(loading->file, 0, "game.heating");
1654 = secfile_lookup_int_default(loading->file, 0, "game.warminglevel");
1655
1657 = secfile_lookup_int_default(loading->file, 0, "game.nuclearwinter");
1659 = secfile_lookup_int_default(loading->file, 0, "game.cooling");
1661 = secfile_lookup_int_default(loading->file, 0, "game.coolinglevel");
1662
1663 /* Savegame may have stored random_seed for documentation purposes only,
1664 * but we want to keep it for resaving. */
1665 game.server.seed = secfile_lookup_int_default(loading->file, 0, "game.random_seed");
1666
1667 /* Global advances. */
1668 str = secfile_lookup_str_default(loading->file, NULL,
1669 "game.global_advances");
1670 if (str != NULL) {
1671 sg_failure_ret(strlen(str) == loading->technology.size,
1672 "Invalid length of 'game.global_advances' ("
1673 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
1674 strlen(str), loading->technology.size);
1675 for (i = 0; i < loading->technology.size; i++) {
1676 sg_failure_ret(str[i] == '1' || str[i] == '0',
1677 "Undefined value '%c' within 'game.global_advances'.",
1678 str[i]);
1679 if (str[i] == '1') {
1680 struct advance *padvance =
1682
1683 if (padvance != NULL) {
1685 }
1686 }
1687 }
1688 }
1689
1691 = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
1692
1694 = secfile_lookup_int_default(loading->file, 0, "game.last_turn_change_time") / 100.0;
1695}
1696
1697/* =======================================================================
1698 * Load random status.
1699 * ======================================================================= */
1700
1701/************************************************************************/
1704static void sg_load_random(struct loaddata *loading)
1705{
1706 /* Check status and return if not OK (sg_success FALSE). */
1707 sg_check_ret();
1708
1709 if (secfile_lookup_bool_default(loading->file, FALSE, "random.saved")) {
1710 const char *str;
1711 int i;
1712
1713 /* Since random state was previously saved, save it also when resaving.
1714 * This affects only pre-2.6 scenarios where scenario.save_random
1715 * is not defined.
1716 * - If this is 2.6 or later scenario -> it would have saved random.saved = TRUE
1717 * only if scenario.save_random is already TRUE
1718 *
1719 * Do NOT touch this in case of regular savegame. They always have random.saved
1720 * set, but if one starts to make scenario based on a savegame, we want
1721 * default scenario settings in the beginning (default save_random = FALSE).
1722 */
1725 }
1726
1727 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.j,
1728 "random.index_J"), "%s", secfile_error());
1729 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.k,
1730 "random.index_K"), "%s", secfile_error());
1731 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.x,
1732 "random.index_X"), "%s", secfile_error());
1733
1734 for (i = 0; i < 8; i++) {
1735 str = secfile_lookup_str(loading->file, "random.table%d",i);
1736 sg_failure_ret(NULL != str, "%s", secfile_error());
1737 sscanf(str, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
1738 &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
1739 &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
1740 &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
1741 }
1742 loading->rstate.is_init = TRUE;
1743 fc_rand_set_state(loading->rstate);
1744 } else {
1745 /* No random values - mark the setting. */
1746 (void) secfile_entry_by_path(loading->file, "random.saved");
1747
1748 /* We're loading a game without a seed (which is okay, if it's a scenario).
1749 * We need to generate the game seed now because it will be needed later
1750 * during the load. */
1752 loading->rstate = fc_rand_state();
1753 }
1754}
1755
1756/* =======================================================================
1757 * Load lua script data.
1758 * ======================================================================= */
1759
1760/************************************************************************/
1763static void sg_load_script(struct loaddata *loading)
1764{
1765 /* Check status and return if not OK (sg_success FALSE). */
1766 sg_check_ret();
1767
1769}
1770
1771/* =======================================================================
1772 * Load scenario data.
1773 * ======================================================================= */
1774
1775/************************************************************************/
1778static void sg_load_scenario(struct loaddata *loading)
1779{
1780 const char *buf;
1781 bool lake_flood_default;
1782
1783 /* Check status and return if not OK (sg_success FALSE). */
1784 sg_check_ret();
1785
1786 if (NULL == secfile_section_lookup(loading->file, "scenario")) {
1788
1789 return;
1790 }
1791
1792 /* Default is that when there's scenario section (which we already checked)
1793 * this is a scenario. Only if it explicitly says that it's not, we consider
1794 * this regular savegame */
1795 game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
1796
1797 if (!game.scenario.is_scenario) {
1798 return;
1799 }
1800
1801 buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
1802 if (buf[0] != '\0') {
1804 }
1805
1806 buf = secfile_lookup_str_default(loading->file, "",
1807 "scenario.authors");
1808 if (buf[0] != '\0') {
1810 } else {
1811 game.scenario.authors[0] = '\0';
1812 }
1813
1814 buf = secfile_lookup_str_default(loading->file, "",
1815 "scenario.description");
1816 if (buf[0] != '\0') {
1818 } else {
1819 game.scenario_desc.description[0] = '\0';
1820 }
1821
1823 = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
1825 = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
1828 "scenario.startpos_nations");
1829
1832 "scenario.prevent_new_cities");
1833 if (loading->version < 20599) {
1834 /* Lake flooding may break some old scenarios where rivers made out of
1835 * lake terrains, so play safe there */
1836 lake_flood_default = FALSE;
1837 } else {
1838 /* If lake flooding is a problem for a newer scenario, it could explicitly
1839 * disable it. */
1840 lake_flood_default = TRUE;
1841 }
1843 = secfile_lookup_bool_default(loading->file, lake_flood_default,
1844 "scenario.lake_flooding");
1847 "scenario.handmade");
1850 "scenario.allow_ai_type_fallback");
1852
1853 sg_failure_ret(loading->server_state == S_S_INITIAL
1854 || (loading->server_state == S_S_RUNNING
1855 && game.scenario.players),
1856 "Invalid scenario definition (server state '%s' and "
1857 "players are %s).",
1858 server_states_name(loading->server_state),
1859 game.scenario.players ? "saved" : "not saved");
1860
1861 /* Remove all defined players. They are recreated with the skill level
1862 * defined by the scenario. */
1863 (void) aifill(0);
1864}
1865
1866/* =======================================================================
1867 * Load game settings.
1868 * ======================================================================= */
1869
1870/************************************************************************/
1873static void sg_load_settings(struct loaddata *loading)
1874{
1875 /* Check status and return if not OK (sg_success FALSE). */
1876 sg_check_ret();
1877
1878 settings_game_load(loading->file, "settings");
1879
1880 /* Save current status of fogofwar. */
1882
1883 /* Add all compatibility settings here. */
1884}
1885
1886/* =======================================================================
1887 * Load the main map.
1888 * ======================================================================= */
1889
1890/************************************************************************/
1893static void sg_load_map(struct loaddata *loading)
1894{
1895 /* Check status and return if not OK (sg_success FALSE). */
1896 sg_check_ret();
1897
1898 /* This defaults to TRUE even if map has not been generated. Also,
1899 * old versions have also explicitly saved TRUE even in pre-game.
1900 * We rely on that
1901 * 1) scenario maps have it explicitly right.
1902 * 2) when map is actually generated, it re-initialize this to FALSE. */
1904 = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
1905
1906 /* Savegame may have stored random_seed for documentation purposes only,
1907 * but we want to keep it for resaving. */
1909 = secfile_lookup_int_default(loading->file, 0, "map.random_seed");
1910
1911 if (S_S_INITIAL == loading->server_state
1913 /* Generator MAPGEN_SCENARIO is used;
1914 * this map was done with the map editor. */
1915
1916 /* Load tiles. */
1917 sg_load_map_tiles(loading);
1918 sg_load_map_startpos(loading);
1919
1920 if (loading->version >= 30) {
1921 /* 2.6.0 or newer */
1922 sg_load_map_tiles_extras(loading);
1923 } else {
1924 sg_load_map_tiles_bases(loading);
1925 if (loading->version >= 20) {
1926 /* 2.5.0 or newer */
1927 sg_load_map_tiles_roads(loading);
1928 }
1929 if (has_capability("specials", loading->secfile_options)) {
1930 /* Load specials. */
1932 }
1933 }
1934
1935 /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
1937 if (has_capability("specials", loading->secfile_options)) {
1938 /* Load resources. */
1940 } else if (has_capability("riversoverlay", loading->secfile_options)) {
1941 /* Load only rivers overlay. */
1943 }
1944
1945 /* Nothing more needed for a scenario. */
1946 secfile_entry_ignore(loading->file, "game.save_known");
1947
1948 return;
1949 }
1950
1951 if (S_S_INITIAL == loading->server_state) {
1952 /* Nothing more to do if it is not a scenario but in initial state. */
1953 return;
1954 }
1955
1956 sg_load_map_tiles(loading);
1957 sg_load_map_startpos(loading);
1958 if (loading->version >= 30) {
1959 /* 2.6.0 or newer */
1960 sg_load_map_tiles_extras(loading);
1961 } else {
1962 sg_load_map_tiles_bases(loading);
1963 if (loading->version >= 20) {
1964 /* 2.5.0 or newer */
1965 sg_load_map_tiles_roads(loading);
1966 }
1968 }
1970 sg_load_map_known(loading);
1971 sg_load_map_owner(loading);
1972 sg_load_map_worked(loading);
1973}
1974
1975/************************************************************************/
1978static void sg_load_map_tiles(struct loaddata *loading)
1979{
1980 /* Check status and return if not OK (sg_success FALSE). */
1981 sg_check_ret();
1982
1983 /* Initialize the map for the current topology. 'map.xsize' and
1984 * 'map.ysize' must be set. */
1986
1987 /* Allocate map. */
1989
1990 /* get the terrain type */
1991 LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
1992 "map.t%04d");
1994
1995 /* Check for special tile sprites. */
1996 whole_map_iterate(&(wld.map), ptile) {
1997 const char *spec_sprite;
1998 const char *label;
1999 int nat_x, nat_y;
2000
2002 spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
2003 nat_x, nat_y);
2004 label = secfile_lookup_str_default(loading->file, NULL, "map.label_%d_%d",
2005 nat_x, nat_y);
2006 if (NULL != ptile->spec_sprite) {
2007 ptile->spec_sprite = fc_strdup(spec_sprite);
2008 }
2009 if (label != NULL) {
2010 tile_set_label(ptile, label);
2011 }
2013}
2014
2015/************************************************************************/
2018static void sg_load_map_tiles_extras(struct loaddata *loading)
2019{
2020 /* Check status and return if not OK (sg_success FALSE). */
2021 sg_check_ret();
2022
2023 /* Load extras. */
2024 halfbyte_iterate_extras(j, loading->extra.size) {
2025 LOAD_MAP_CHAR(ch, ptile, sg_extras_set(&ptile->extras, ch, loading->extra.order + 4 * j),
2026 loading->file, "map.e%02d_%04d", j);
2028}
2029
2030/************************************************************************/
2033static void sg_load_map_tiles_bases(struct loaddata *loading)
2034{
2035 /* Check status and return if not OK (sg_success FALSE). */
2036 sg_check_ret();
2037
2038 /* Load bases. */
2039 halfbyte_iterate_bases(j, loading->base.size) {
2040 LOAD_MAP_CHAR(ch, ptile, sg_bases_set(&ptile->extras, ch,
2041 loading->base.order + 4 * j),
2042 loading->file, "map.b%02d_%04d", j);
2044}
2045
2046/************************************************************************/
2049static void sg_load_map_tiles_roads(struct loaddata *loading)
2050{
2051 /* Check status and return if not OK (sg_success FALSE). */
2052 sg_check_ret();
2053
2054 /* Load roads. */
2055 halfbyte_iterate_roads(j, loading->road.size) {
2056 LOAD_MAP_CHAR(ch, ptile, sg_roads_set(&ptile->extras, ch,
2057 loading->road.order + 4 * j),
2058 loading->file, "map.r%02d_%04d", j);
2060}
2061
2062/************************************************************************/
2065static void sg_load_map_tiles_specials(struct loaddata *loading,
2066 bool rivers_overlay)
2067{
2068 /* Check status and return if not OK (sg_success FALSE). */
2069 sg_check_ret();
2070
2071 /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
2072 * from the savegame file.
2073 *
2074 * A scenario may define the terrain of the map but not list the specials
2075 * on it (thus allowing users to control the placement of specials).
2076 * However rivers are a special case and must be included in the map along
2077 * with the scenario. Thus in those cases this function should be called
2078 * to load the river information separate from any other special data.
2079 *
2080 * This does not need to be called from map_load(), because map_load()
2081 * loads the rivers overlay along with the rest of the specials. Call this
2082 * only if you've already called map_load_tiles(), and want to load only
2083 * the rivers overlay but no other specials. Scenarios that encode things
2084 * this way should have the "riversoverlay" capability. */
2086 LOAD_MAP_CHAR(ch, ptile, sg_special_set(ptile, &ptile->extras, ch,
2087 loading->special.order + 4 * j,
2088 rivers_overlay),
2089 loading->file, "map.spe%02d_%04d", j);
2091}
2092
2093/************************************************************************/
2096static void sg_load_map_tiles_resources(struct loaddata *loading)
2097{
2098 /* Check status and return if not OK (sg_success FALSE). */
2099 sg_check_ret();
2100
2101 LOAD_MAP_CHAR(ch, ptile, tile_set_resource(ptile, char2resource(ch)),
2102 loading->file, "map.res%04d");
2103
2104 /* After the resources are loaded, indicate those currently valid. */
2105 whole_map_iterate(&(wld.map), ptile) {
2106 if (NULL == ptile->resource) {
2107 continue;
2108 }
2109
2110 if (ptile->terrain == NULL || !terrain_has_resource(ptile->terrain, ptile->resource)) {
2111 BV_CLR(ptile->extras, extra_index(ptile->resource));
2112 }
2114
2117}
2118
2119/************************************************************************/
2123static void sg_load_map_startpos(struct loaddata *loading)
2124{
2125 struct nation_type *pnation;
2126 struct startpos *psp;
2127 struct tile *ptile;
2128 const char SEPARATOR = '#';
2129 const char *nation_names;
2130 int nat_x, nat_y;
2131 bool exclude;
2132 int i, startpos_count;
2133
2134 /* Check status and return if not OK (sg_success FALSE). */
2135 sg_check_ret();
2136
2137 startpos_count
2138 = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
2139
2140 if (0 == startpos_count) {
2141 /* Nothing to do. */
2142 return;
2143 }
2144
2145 for (i = 0; i < startpos_count; i++) {
2146 if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
2147 || !secfile_lookup_int(loading->file, &nat_y,
2148 "map.startpos%d.y", i)) {
2149 log_sg("Warning: Undefined coordinates for startpos %d", i);
2150 continue;
2151 }
2152
2153 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
2154 if (NULL == ptile) {
2155 log_error("Start position native coordinates (%d, %d) do not exist "
2156 "in this map. Skipping...", nat_x, nat_y);
2157 continue;
2158 }
2159
2160 exclude = secfile_lookup_bool_default(loading->file, FALSE,
2161 "map.startpos%d.exclude", i);
2162
2163 psp = map_startpos_new(ptile);
2164
2165 nation_names = secfile_lookup_str(loading->file,
2166 "map.startpos%d.nations", i);
2167 if (NULL != nation_names && '\0' != nation_names[0]) {
2168 const size_t size = strlen(nation_names) + 1;
2169 char buf[size], *start, *end;
2170
2171 memcpy(buf, nation_names, size);
2172 for (start = buf - 1; NULL != start; start = end) {
2173 start++;
2174 if ((end = strchr(start, SEPARATOR))) {
2175 *end = '\0';
2176 }
2177
2178 pnation = nation_by_rule_name(start);
2179 if (NO_NATION_SELECTED != pnation) {
2180 if (exclude) {
2181 startpos_disallow(psp, pnation);
2182 } else {
2183 startpos_allow(psp, pnation);
2184 }
2185 } else {
2186 log_verbose("Missing nation \"%s\".", start);
2187 }
2188 }
2189 }
2190 }
2191
2192 if (0 < map_startpos_count()
2193 && loading->server_state == S_S_INITIAL
2195 log_verbose("Number of starts (%d) are lower than rules.max_players "
2196 "(%d), lowering rules.max_players.",
2199 }
2200
2201 /* Re-initialize nation availability in light of start positions.
2202 * This has to be after loading [scenario] and [map].startpos and
2203 * before we seek nations for players. */
2205}
2206
2207/************************************************************************/
2210static void sg_load_map_owner(struct loaddata *loading)
2211{
2212 int x, y;
2213 struct player *owner = NULL;
2214 struct tile *claimer = NULL;
2215 struct player *eowner = NULL;
2216
2217 /* Check status and return if not OK (sg_success FALSE). */
2218 sg_check_ret();
2219
2220 if (game.info.is_new_game) {
2221 /* No owner/source information for a new game / scenario. */
2222 return;
2223 }
2224
2225 /* Owner and ownership source are stored as plain numbers */
2226 for (y = 0; y < wld.map.ysize; y++) {
2227 const char *buffer1 = secfile_lookup_str(loading->file,
2228 "map.owner%04d", y);
2229 const char *buffer2 = secfile_lookup_str(loading->file,
2230 "map.source%04d", y);
2231 const char *buffer3 = secfile_lookup_str(loading->file,
2232 "map.eowner%04d", y);
2233 const char *ptr1 = buffer1;
2234 const char *ptr2 = buffer2;
2235 const char *ptr3 = buffer3;
2236
2237 sg_failure_ret(buffer1 != NULL, "%s", secfile_error());
2238 sg_failure_ret(buffer2 != NULL, "%s", secfile_error());
2239 if (loading->version >= 30) {
2240 sg_failure_ret(buffer3 != NULL, "%s", secfile_error());
2241 }
2242
2243 for (x = 0; x < wld.map.xsize; x++) {
2244 char token1[TOKEN_SIZE];
2245 char token2[TOKEN_SIZE];
2246 char token3[TOKEN_SIZE];
2247 int number;
2248 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2249
2250 scanin(&ptr1, ",", token1, sizeof(token1));
2251 sg_failure_ret(token1[0] != '\0',
2252 "Map size not correct (map.owner%d).", y);
2253 if (strcmp(token1, "-") == 0) {
2254 owner = NULL;
2255 } else {
2256 sg_failure_ret(str_to_int(token1, &number),
2257 "Got map owner %s in (%d, %d).", token1, x, y);
2258 owner = player_by_number(number);
2259 }
2260
2261 scanin(&ptr2, ",", token2, sizeof(token2));
2262 sg_failure_ret(token2[0] != '\0',
2263 "Map size not correct (map.source%d).", y);
2264 if (strcmp(token2, "-") == 0) {
2265 claimer = NULL;
2266 } else {
2267 sg_failure_ret(str_to_int(token2, &number),
2268 "Got map source %s in (%d, %d).", token2, x, y);
2269 claimer = index_to_tile(&(wld.map), number);
2270 }
2271
2272 if (loading->version >= 30) {
2273 scanin(&ptr3, ",", token3, sizeof(token3));
2274 sg_failure_ret(token3[0] != '\0',
2275 "Map size not correct (map.eowner%d).", y);
2276 if (strcmp(token3, "-") == 0) {
2277 eowner = NULL;
2278 } else {
2279 sg_failure_ret(str_to_int(token3, &number),
2280 "Got base owner %s in (%d, %d).", token3, x, y);
2281 eowner = player_by_number(number);
2282 }
2283 } else {
2284 eowner = owner;
2285 }
2286
2288 tile_claim_bases(ptile, eowner);
2289 log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
2290 }
2291 }
2292}
2293
2294/************************************************************************/
2297static void sg_load_map_worked(struct loaddata *loading)
2298{
2299 int x, y;
2300
2301 /* Check status and return if not OK (sg_success FALSE). */
2302 sg_check_ret();
2303
2304 sg_failure_ret(loading->worked_tiles == NULL,
2305 "City worked map not loaded!");
2306
2308 sizeof(*loading->worked_tiles));
2309
2310 for (y = 0; y < wld.map.ysize; y++) {
2311 const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
2312 y);
2313 const char *ptr = buffer;
2314
2315 sg_failure_ret(NULL != buffer,
2316 "Savegame corrupt - map line %d not found.", y);
2317 for (x = 0; x < wld.map.xsize; x++) {
2318 char token[TOKEN_SIZE];
2319 int number;
2320 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2321
2322 scanin(&ptr, ",", token, sizeof(token));
2323 sg_failure_ret('\0' != token[0],
2324 "Savegame corrupt - map size not correct.");
2325 if (strcmp(token, "-") == 0) {
2326 number = -1;
2327 } else {
2328 sg_failure_ret(str_to_int(token, &number) && 0 < number,
2329 "Savegame corrupt - got tile worked by city "
2330 "id=%s in (%d, %d).", token, x, y);
2331 }
2332
2333 loading->worked_tiles[ptile->index] = number;
2334 }
2335 }
2336}
2337
2338/************************************************************************/
2341static void sg_load_map_known(struct loaddata *loading)
2342{
2343 /* Check status and return if not OK (sg_success FALSE). */
2344 sg_check_ret();
2345
2346 players_iterate(pplayer) {
2347 /* Allocate player private map here; it is needed in different modules
2348 * besides this one ((i.e. sg_load_player_*()). */
2349 player_map_init(pplayer);
2351
2353 "game.save_known")) {
2354 int lines = player_slot_max_used_number() / 32 + 1;
2355 int j, p, l, i;
2356 unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
2357
2358 for (l = 0; l < lines; l++) {
2359 for (j = 0; j < 8; j++) {
2360 for (i = 0; i < 4; i++) {
2361 /* Only bother trying to load the map for this halfbyte if at least
2362 * one of the corresponding player slots is in use. */
2363 if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
2364 LOAD_MAP_CHAR(ch, ptile,
2365 known[l * MAP_INDEX_SIZE + tile_index(ptile)]
2366 |= ascii_hex2bin(ch, j),
2367 loading->file, "map.k%02d_%04d", l * 8 + j);
2368 break;
2369 }
2370 }
2371 }
2372 }
2373
2374 players_iterate(pplayer) {
2375 dbv_clr_all(&pplayer->tile_known);
2377
2378 /* HACK: we read the known data from hex into 32-bit integers, and
2379 * now we convert it to the known tile data of each player. */
2380 whole_map_iterate(&(wld.map), ptile) {
2381 players_iterate(pplayer) {
2382 p = player_index(pplayer);
2383 l = player_index(pplayer) / 32;
2384
2385 if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
2386 map_set_known(ptile, pplayer);
2387 }
2390
2391 FC_FREE(known);
2392 }
2393}
2394
2395/* =======================================================================
2396 * Load player data.
2397 *
2398 * This is split into two parts as some data can only be loaded if the
2399 * number of players is known and the corresponding player slots are
2400 * defined.
2401 * ======================================================================= */
2402
2403/************************************************************************/
2406static void sg_load_players_basic(struct loaddata *loading)
2407{
2408 int i, k, nplayers;
2409 const char *str;
2410 bool shuffle_loaded = TRUE;
2411
2412 /* Check status and return if not OK (sg_success FALSE). */
2413 sg_check_ret();
2414
2415 if (S_S_INITIAL == loading->server_state
2416 || game.info.is_new_game) {
2417 /* Nothing more to do. */
2418 return;
2419 }
2420
2421 /* Load destroyed wonders: */
2422 str = secfile_lookup_str(loading->file,
2423 "players.destroyed_wonders");
2424 sg_failure_ret(str != NULL, "%s", secfile_error());
2425 sg_failure_ret(strlen(str) == loading->improvement.size,
2426 "Invalid length for 'players.destroyed_wonders' ("
2427 SIZE_T_PRINTF" ~= " SIZE_T_PRINTF ")",
2428 strlen(str), loading->improvement.size);
2429 for (k = 0; k < loading->improvement.size; k++) {
2430 sg_failure_ret(str[k] == '1' || str[k] == '0',
2431 "Undefined value '%c' within "
2432 "'players.destroyed_wonders'.", str[k]);
2433
2434 if (str[k] == '1') {
2435 struct impr_type *pimprove =
2437
2438 if (pimprove) {
2441 }
2442 }
2443 }
2444
2445 server.identity_number
2446 = secfile_lookup_int_default(loading->file, server.identity_number,
2447 "players.identity_number_used");
2448
2449 /* First remove all defined players. */
2450 players_iterate(pplayer) {
2451 server_remove_player(pplayer);
2453
2454 /* Now, load the players from the savefile. */
2455 player_slots_iterate(pslot) {
2456 struct player *pplayer;
2457 struct rgbcolor *prgbcolor = NULL;
2458 int pslot_id = player_slot_index(pslot);
2459
2460 if (NULL == secfile_section_lookup(loading->file, "player%d",
2461 pslot_id)) {
2462 continue;
2463 }
2464
2465 /* Get player AI type. */
2466 str = secfile_lookup_str(loading->file, "player%d.ai_type",
2467 player_slot_index(pslot));
2468 sg_failure_ret(str != NULL, "%s", secfile_error());
2469
2470 /* Get player color */
2471 if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
2472 pslot_id)) {
2473 if (loading->version >= 10 && game_was_started()) {
2474 /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
2475 * as they predate the introduction of configurable player colors. */
2476 log_sg("Game has started, yet player %d has no color defined.",
2477 pslot_id);
2478 /* This will be fixed up later */
2479 } else {
2480 log_verbose("No color defined for player %d.", pslot_id);
2481 /* Colors will be assigned on game start, or at end of savefile
2482 * loading if game has already started */
2483 }
2484 }
2485
2486 /* Create player. */
2487 pplayer = server_create_player(player_slot_index(pslot), str,
2488 prgbcolor,
2491 sg_failure_ret(pplayer != NULL, "Invalid AI type: '%s'!", str);
2492
2493 server_player_init(pplayer, FALSE, FALSE);
2494
2495 /* Free the color definition. */
2496 rgbcolor_destroy(prgbcolor);
2497
2498 /* Multipliers (policies) */
2499
2500 /* First initialise player values with ruleset defaults; this will
2501 * cover any in the ruleset not known when the savefile was created. */
2502 multipliers_iterate(pmul) {
2503 pplayer->multipliers[multiplier_index(pmul)].value
2504 = pplayer->multipliers[multiplier_index(pmul)].target = pmul->def;
2506
2507 /* Now override with any values from the savefile. */
2508 for (k = 0; k < loading->multiplier.size; k++) {
2509 const struct multiplier *pmul = loading->multiplier.order[k];
2510
2511 if (pmul) {
2513 int val =
2514 secfile_lookup_int_default(loading->file, pmul->def,
2515 "player%d.multiplier%d.val",
2516 player_slot_index(pslot), k);
2517 int rval = (((CLIP(pmul->start, val, pmul->stop)
2518 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2519
2520 if (rval != val) {
2521 log_verbose("Player %d had illegal value for multiplier \"%s\": "
2522 "was %d, clamped to %d", pslot_id,
2523 multiplier_rule_name(pmul), val, rval);
2524 }
2525 pplayer->multipliers[idx].value = rval;
2526
2527 val =
2529 pplayer->multipliers[idx].value,
2530 "player%d.multiplier%d.target",
2531 player_slot_index(pslot), k);
2532 rval = (((CLIP(pmul->start, val, pmul->stop)
2533 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2534
2535 if (rval != val) {
2536 log_verbose("Player %d had illegal value for multiplier_target "
2537 "\"%s\": was %d, clamped to %d", pslot_id,
2538 multiplier_rule_name(pmul), val, rval);
2539 }
2540 pplayer->multipliers[idx].target = rval;
2541
2542 /* Never present in savegame2 format */
2543 pplayer->multipliers[idx].changed = 0;
2544 } /* else silently discard multiplier not in current ruleset */
2545 }
2546
2547 /* Just in case savecompat starts adding it in the future. */
2548 pplayer->server.border_vision =
2550 "player%d.border_vision",
2551 player_slot_index(pslot));
2553
2554 /* check number of players */
2555 nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
2556 sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
2557 "(%d) from the loaded game does not match the number of "
2558 "players present (%d).", nplayers, player_count());
2559
2560 /* Load team information. */
2561 players_iterate(pplayer) {
2562 int team;
2563 struct team_slot *tslot = NULL;
2564
2566 "player%d.team_no",
2567 player_number(pplayer))
2568 && (tslot = team_slot_by_number(team)),
2569 "Invalid team definition for player %s (nb %d).",
2570 player_name(pplayer), player_number(pplayer));
2571 /* Should never fail when slot given is not NULL */
2572 team_add_player(pplayer, team_new(tslot));
2574
2575 /* Loading the shuffle list is quite complex. At the time of saving the
2576 * shuffle data is saved as
2577 * shuffled_player_<number> = player_slot_id
2578 * where number is an increasing number and player_slot_id is a number
2579 * between 0 and the maximum number of player slots. Now we have to create
2580 * a list
2581 * shuffler_players[number] = player_slot_id
2582 * where all player slot IDs are used exactly one time. The code below
2583 * handles this ... */
2584 if (secfile_lookup_int_default(loading->file, -1,
2585 "players.shuffled_player_%d", 0) >= 0) {
2586 int slots = player_slot_count();
2587 int plrcount = player_count();
2588 int shuffled_players[slots];
2589 bool shuffled_player_set[slots];
2590
2591 for (i = 0; i < slots; i++) {
2592 /* Array to save used numbers. */
2593 shuffled_player_set[i] = FALSE;
2594 /* List of all player IDs (needed for set_shuffled_players()). It is
2595 * initialised with the value -1 to indicate that no value is set. */
2596 shuffled_players[i] = -1;
2597 }
2598
2599 /* Load shuffled player list. */
2600 for (i = 0; i < plrcount; i++) {
2601 int shuffle
2602 = secfile_lookup_int_default(loading->file, -1,
2603 "players.shuffled_player_%d", i);
2604
2605 if (shuffle == -1) {
2606 log_sg("Missing player shuffle information (index %d) "
2607 "- reshuffle player list!", i);
2608 shuffle_loaded = FALSE;
2609 break;
2610 } else if (shuffled_player_set[shuffle]) {
2611 log_sg("Player shuffle %d used two times "
2612 "- reshuffle player list!", shuffle);
2613 shuffle_loaded = FALSE;
2614 break;
2615 }
2616 /* Set this ID as used. */
2617 shuffled_player_set[shuffle] = TRUE;
2618
2619 /* Save the player ID in the shuffle list. */
2620 shuffled_players[i] = shuffle;
2621 }
2622
2623 if (shuffle_loaded) {
2624 /* Insert missing numbers. */
2625 int shuffle_index = plrcount;
2626
2627 for (i = 0; i < slots; i++) {
2628 if (!shuffled_player_set[i]) {
2629 shuffled_players[shuffle_index++] = i;
2630 }
2631
2632 /* shuffle_index must not grow higher than size of shuffled_players. */
2633 sg_failure_ret(shuffle_index <= slots,
2634 "Invalid player shuffle data!");
2635 }
2636
2637#ifdef FREECIV_DEBUG
2638 log_debug("[load shuffle] player_count() = %d", player_count());
2639 player_slots_iterate(pslot) {
2640 int plrid = player_slot_index(pslot);
2641
2642 log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
2643 plrid, shuffled_players[plrid], plrid,
2644 shuffled_player_set[plrid] ? "is used" : "-");
2646#endif /* FREECIV_DEBUG */
2647
2648 /* Set shuffle list from savegame. */
2649 set_shuffled_players(shuffled_players);
2650 }
2651 }
2652
2653 if (!shuffle_loaded) {
2654 /* No shuffled players included or error loading them, so shuffle them
2655 * (this may include scenarios). */
2657 }
2658}
2659
2660/************************************************************************/
2663static void sg_load_players(struct loaddata *loading)
2664{
2665 /* Check status and return if not OK (sg_success FALSE). */
2666 sg_check_ret();
2667
2668 if (game.info.is_new_game) {
2669 /* Nothing to do. */
2670 return;
2671 }
2672
2673 players_iterate(pplayer) {
2674 sg_load_player_main(loading, pplayer);
2675 sg_load_player_cities(loading, pplayer);
2676 sg_load_player_units(loading, pplayer);
2677 sg_load_player_attributes(loading, pplayer);
2678
2679 /* Check the success of the functions above. */
2680 sg_check_ret();
2681
2682 /* Print out some information */
2683 if (is_ai(pplayer)) {
2684 log_normal(_("%s has been added as %s level AI-controlled player "
2685 "(%s)."), player_name(pplayer),
2686 ai_level_translated_name(pplayer->ai_common.skill_level),
2687 ai_name(pplayer->ai));
2688 } else {
2689 log_normal(_("%s has been added as human player."),
2690 player_name(pplayer));
2691 }
2693
2694 /* Also load the transport status of the units here. It must be a special
2695 * case as all units must be known (unit on an allied transporter). */
2696 players_iterate(pplayer) {
2697 /* Load unit transport status. */
2698 sg_load_player_units_transport(loading, pplayer);
2700
2701 /* Savegame may contain nation assignments that are incompatible with the
2702 * current nationset -- for instance, if it predates the introduction of
2703 * nationsets. Ensure they are compatible, one way or another. */
2705
2706 /* Some players may have invalid nations in the ruleset. Once all players
2707 * are loaded, pick one of the remaining nations for them. */
2708 players_iterate(pplayer) {
2709 if (pplayer->nation == NO_NATION_SELECTED) {
2710 player_set_nation(pplayer, pick_a_nation(NULL, FALSE, TRUE,
2711 NOT_A_BARBARIAN));
2712 /* TRANS: Minor error message: <Leader> ... <Poles>. */
2713 log_sg(_("%s had invalid nation; changing to %s."),
2714 player_name(pplayer), nation_plural_for_player(pplayer));
2715
2716 ai_traits_init(pplayer);
2717 }
2719
2720 /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
2722 players_iterate_alive(aplayer) {
2723 if (pplayers_allied(plr, aplayer)) {
2724 enum dipl_reason can_ally = pplayer_can_make_treaty(plr, aplayer,
2725 DS_ALLIANCE);
2726
2727 if (can_ally == DIPL_ALLIANCE_PROBLEM_US
2728 || can_ally == DIPL_ALLIANCE_PROBLEM_THEM) {
2729 log_sg("Illegal alliance structure detected: "
2730 "%s alliance to %s reduced to peace treaty.",
2733 player_diplstate_get(plr, aplayer)->type = DS_PEACE;
2734 player_diplstate_get(aplayer, plr)->type = DS_PEACE;
2735 }
2736 }
2739
2740 /* Update cached city illness. This can depend on trade routes,
2741 * so can't be calculated until all players have been loaded. */
2742 if (game.info.illness_on) {
2743 cities_iterate(pcity) {
2744 pcity->server.illness
2745 = city_illness_calc(pcity, NULL, NULL,
2746 &(pcity->illness_trade), NULL);
2748 }
2749
2750 /* Update all city information. This must come after all cities are
2751 * loaded (in player_load) but before player (dumb) cities are loaded
2752 * in player_load_vision(). */
2753 players_iterate(plr) {
2754 city_list_iterate(plr->cities, pcity) {
2755 city_refresh(pcity);
2756 sanity_check_city(pcity);
2757 CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
2760
2761 /* Since the cities must be placed on the map to put them on the
2762 player map we do this afterwards */
2763 players_iterate(pplayer) {
2764 sg_load_player_vision(loading, pplayer);
2765 /* Check the success of the function above. */
2766 sg_check_ret();
2768
2769 /* Check shared vision. */
2770 players_iterate(pplayer) {
2771 BV_CLR_ALL(pplayer->gives_shared_vision);
2772 BV_CLR_ALL(pplayer->server.really_gives_vision);
2774
2775 /* Set up shared vision... */
2776 players_iterate(pplayer) {
2777 int plr1 = player_index(pplayer);
2778
2779 players_iterate(pplayer2) {
2780 int plr2 = player_index(pplayer2);
2781
2783 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
2784 give_shared_vision(pplayer, pplayer2);
2785 }
2788
2789 /* ...and check it */
2790 players_iterate(pplayer1) {
2791 players_iterate(pplayer2) {
2792 /* TODO: Is there a good reason player is not marked as
2793 * giving shared vision to themselves -> really_gives_vision()
2794 * returning FALSE when pplayer1 == pplayer2 */
2795 if (pplayer1 != pplayer2
2796 && players_on_same_team(pplayer1, pplayer2)) {
2797 if (!really_gives_vision(pplayer1, pplayer2)) {
2798 sg_regr(3000900,
2799 _("%s did not give shared vision to team member %s."),
2800 player_name(pplayer1), player_name(pplayer2));
2801 give_shared_vision(pplayer1, pplayer2);
2802 }
2803 if (!really_gives_vision(pplayer2, pplayer1)) {
2804 sg_regr(3000900,
2805 _("%s did not give shared vision to team member %s."),
2806 player_name(pplayer2), player_name(pplayer1));
2807 give_shared_vision(pplayer2, pplayer1);
2808 }
2809 }
2812
2815
2816 /* All vision is ready; this calls city_thaw_workers_queue(). */
2818
2819 /* Make sure everything is consistent. */
2820 players_iterate(pplayer) {
2821 unit_list_iterate(pplayer->units, punit) {
2823 struct tile *ptile = unit_tile(punit);
2824
2825 log_sg("%s doing illegal activity in savegame!",
2827 log_sg("Activity: %s, Target: %s, Tile: (%d, %d), Terrain: %s",
2828 unit_activity_name(punit->activity),
2831 : "missing",
2832 TILE_XY(ptile), terrain_rule_name(tile_terrain(ptile)));
2833 punit->activity = ACTIVITY_IDLE;
2834 }
2837
2838 cities_iterate(pcity) {
2839 city_refresh(pcity);
2840 city_thaw_workers(pcity); /* may auto_arrange_workers() */
2842
2843 /* Player colors are always needed once game has started. Pre-2.4 savegames
2844 * lack them. This cannot be in compatibility conversion layer as we need
2845 * all the player data available to be able to assign best colors. */
2846 if (game_was_started()) {
2848 }
2849}
2850
2851/************************************************************************/
2854static void sg_load_player_main(struct loaddata *loading,
2855 struct player *plr)
2856{
2857 const char **slist;
2858 int i, plrno = player_number(plr);
2859 const char *str;
2860 struct government *gov;
2861 const char *level;
2862 const char *barb_str;
2863 size_t nval;
2864
2865 /* Check status and return if not OK (sg_success FALSE). */
2866 sg_check_ret();
2867
2868 /* Basic player data. */
2869 str = secfile_lookup_str(loading->file, "player%d.name", plrno);
2870 sg_failure_ret(str != NULL, "%s", secfile_error());
2872 sz_strlcpy(plr->username,
2873 secfile_lookup_str_default(loading->file, "",
2874 "player%d.username", plrno));
2876 "player%d.unassigned_user", plrno),
2877 "%s", secfile_error());
2879 secfile_lookup_str_default(loading->file, "",
2880 "player%d.orig_username",
2881 plrno));
2883 secfile_lookup_str_default(loading->file, "",
2884 "player%d.ranked_username",
2885 plrno));
2887 "player%d.unassigned_ranked", plrno),
2888 "%s", secfile_error());
2889 str = secfile_lookup_str_default(loading->file, "",
2890 "player%d.delegation_username",
2891 plrno);
2892 /* Defaults to no delegation. */
2893 if (strlen(str)) {
2895 }
2896
2897 /* Player flags */
2898 BV_CLR_ALL(plr->flags);
2899 slist = secfile_lookup_str_vec(loading->file, &nval, "player%d.flags", plrno);
2900 for (i = 0; i < nval; i++) {
2901 const char *sval = slist[i];
2902 enum plr_flag_id fid = plr_flag_id_by_name(sval, fc_strcasecmp);
2903
2904 sg_failure_ret(plr_flag_id_is_valid(fid), "Invalid player flag \"%s\".", sval);
2905
2906 BV_SET(plr->flags, fid);
2907 }
2908 free(slist);
2909
2910 /* Nation */
2911 str = secfile_lookup_str(loading->file, "player%d.nation", plrno);
2913 if (plr->nation != NULL) {
2914 ai_traits_init(plr);
2915 }
2916
2917 /* Government */
2918 str = secfile_lookup_str(loading->file, "player%d.government_name",
2919 plrno);
2921 sg_failure_ret(gov != NULL, "Player%d: unsupported government \"%s\".",
2922 plrno, str);
2923 plr->government = gov;
2924
2925 /* Target government */
2926 str = secfile_lookup_str(loading->file,
2927 "player%d.target_government_name", plrno);
2928 if (str != NULL) {
2930 } else {
2931 plr->target_government = NULL;
2932 }
2934 = secfile_lookup_int_default(loading->file, -1,
2935 "player%d.revolution_finishes", plrno);
2936
2938 &plr->server.got_first_city,
2939 "player%d.got_first_city", plrno),
2940 "%s", secfile_error());
2941
2942 /* Load diplomatic data (diplstate + embassy + vision).
2943 * Shared vision is loaded in sg_load_players(). */
2945 players_iterate(pplayer) {
2946 char buf[32];
2947 int unconverted;
2948 struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
2949 i = player_index(pplayer);
2950
2951 /* load diplomatic status */
2952 fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
2953
2954 unconverted =
2955 secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
2956 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
2957 /* Look up what state the unconverted number represents. */
2958 ds->type = loading->ds_t.order[unconverted];
2959 } else {
2960 log_sg("No valid diplomatic state type between players %d and %d",
2961 plrno, i);
2962
2963 ds->type = DS_WAR;
2964 }
2965
2966 unconverted =
2967 secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
2968 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
2969 /* Look up what state the unconverted number represents. */
2970 ds->max_state = loading->ds_t.order[unconverted];
2971 } else {
2972 log_sg("No valid diplomatic max_state between players %d and %d",
2973 plrno, i);
2974
2975 ds->max_state = DS_WAR;
2976 }
2977
2978 ds->first_contact_turn =
2979 secfile_lookup_int_default(loading->file, 0,
2980 "%s.first_contact_turn", buf);
2981 ds->turns_left =
2982 secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
2984 secfile_lookup_int_default(loading->file, 0,
2985 "%s.has_reason_to_cancel", buf);
2986 ds->contact_turns_left =
2987 secfile_lookup_int_default(loading->file, 0,
2988 "%s.contact_turns_left", buf);
2989
2990 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
2991 buf)) {
2992 BV_SET(plr->real_embassy, i);
2993 }
2994 /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
2995 * must be known. */
2997
2998 /* load ai data */
2999 players_iterate(aplayer) {
3000 char buf[32];
3001
3002 fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
3003 player_index(aplayer));
3004
3005 plr->ai_common.love[player_index(aplayer)] =
3006 secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
3007 CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
3009
3010 CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
3011
3012 /* Some sane defaults */
3013 plr->ai_common.fuzzy = 0;
3014 plr->ai_common.expand = 100;
3015 plr->ai_common.science_cost = 100;
3016
3017
3018 level = secfile_lookup_str_default(loading->file, NULL,
3019 "player%d.ai.level", plrno);
3020 if (level != NULL) {
3021 if (!fc_strcasecmp("Handicapped", level)) {
3022 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
3023 plr->ai_common.skill_level = AI_LEVEL_RESTRICTED;
3024 } else {
3025 plr->ai_common.skill_level = ai_level_by_name(level, fc_strcasecmp);
3026 }
3027 } else {
3028 plr->ai_common.skill_level = ai_level_invalid();
3029 }
3030
3031 if (!ai_level_is_valid(plr->ai_common.skill_level)) {
3035 "player%d.ai.skill_level",
3036 plrno));
3037 }
3038
3039 barb_str = secfile_lookup_str_default(loading->file, "None",
3040 "player%d.ai.barb_type", plrno);
3041 plr->ai_common.barbarian_type = barbarian_type_by_name(barb_str, fc_strcasecmp);
3042
3043 if (!barbarian_type_is_valid(plr->ai_common.barbarian_type)) {
3044 log_sg("Player%d: Invalid barbarian type \"%s\". "
3045 "Changed to \"None\".", plrno, barb_str);
3046 plr->ai_common.barbarian_type = NOT_A_BARBARIAN;
3047 }
3048
3049 if (is_barbarian(plr)) {
3050 server.nbarbarians++;
3051 }
3052
3053 if (is_ai(plr)) {
3055 CALL_PLR_AI_FUNC(gained_control, plr, plr);
3056 }
3057
3058 /* Load nation style. */
3059 {
3060 struct nation_style *style;
3061
3062 str = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
3063
3064 /* Handle pre-2.6 savegames */
3065 if (str == NULL) {
3066 str = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
3067 plrno);
3068 }
3069
3070 sg_failure_ret(str != NULL, "%s", secfile_error());
3071 style = style_by_rule_name(str);
3072 if (style == NULL) {
3073 style = style_by_number(0);
3074 log_sg("Player%d: unsupported city_style_name \"%s\". "
3075 "Changed to \"%s\".", plrno, str, style_rule_name(style));
3076 }
3077 plr->style = style;
3078 }
3079
3081 "player%d.idle_turns", plrno),
3082 "%s", secfile_error());
3084 "player%d.is_male", plrno);
3086 "player%d.is_alive", plrno),
3087 "%s", secfile_error());
3089 "player%d.turns_alive", plrno),
3090 "%s", secfile_error());
3092 "player%d.last_war", plrno),
3093 "%s", secfile_error());
3095 "player%d.phase_done", plrno);
3097 "player%d.gold", plrno),
3098 "%s", secfile_error());
3100 "player%d.rates.tax", plrno),
3101 "%s", secfile_error());
3103 "player%d.rates.science", plrno),
3104 "%s", secfile_error());
3106 "player%d.rates.luxury", plrno),
3107 "%s", secfile_error());
3108 plr->server.bulbs_last_turn =
3109 secfile_lookup_int_default(loading->file, 0,
3110 "player%d.research.bulbs_last_turn", plrno);
3111
3112 /* Traits */
3113 if (plr->nation) {
3114 for (i = 0; i < loading->trait.size; i++) {
3115 enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
3116
3117 if (trait_is_valid(tr)) {
3118 int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
3119 plrno, i);
3120
3121 if (val != -1) {
3122 plr->ai_common.traits[tr].val = val;
3123 }
3124
3125 sg_failure_ret(secfile_lookup_int(loading->file, &val,
3126 "player%d.trait%d.mod", plrno, i),
3127 "%s", secfile_error());
3128 plr->ai_common.traits[tr].mod = val;
3129 }
3130 }
3131 }
3132
3133 /* Achievements */
3134 {
3135 int count;
3136
3137 count = secfile_lookup_int_default(loading->file, -1,
3138 "player%d.achievement_count", plrno);
3139
3140 if (count > 0) {
3141 for (i = 0; i < count; i++) {
3142 const char *name;
3143 struct achievement *pach;
3144 bool first;
3145
3146 name = secfile_lookup_str(loading->file,
3147 "player%d.achievement%d.name", plrno, i);
3149
3150 sg_failure_ret(pach != NULL,
3151 "Unknown achievement \"%s\".", name);
3152
3154 "player%d.achievement%d.first",
3155 plrno, i),
3156 "achievement error: %s", secfile_error());
3157
3158 sg_failure_ret(pach->first == NULL || !first,
3159 "Multiple players listed as first to get achievement \"%s\".",
3160 name);
3161
3162 BV_SET(pach->achievers, player_index(plr));
3163
3164 if (first) {
3165 pach->first = plr;
3166 }
3167 }
3168 }
3169 }
3170
3171 /* Player score. */
3172 plr->score.happy =
3173 secfile_lookup_int_default(loading->file, 0,
3174 "score%d.happy", plrno);
3175 plr->score.content =
3176 secfile_lookup_int_default(loading->file, 0,
3177 "score%d.content", plrno);
3178 plr->score.unhappy =
3179 secfile_lookup_int_default(loading->file, 0,
3180 "score%d.unhappy", plrno);
3181 plr->score.angry =
3182 secfile_lookup_int_default(loading->file, 0,
3183 "score%d.angry", plrno);
3184
3185 /* Make sure that the score about specialists in current ruleset that
3186 * were not present at saving time are set to zero. */
3188 plr->score.specialists[sp] = 0;
3190
3191 for (i = 0; i < loading->specialist.size; i++) {
3193 = secfile_lookup_int_default(loading->file, 0,
3194 "score%d.specialists%d", plrno, i);
3195 }
3196
3197 plr->score.wonders =
3198 secfile_lookup_int_default(loading->file, 0,
3199 "score%d.wonders", plrno);
3200 plr->score.techs =
3201 secfile_lookup_int_default(loading->file, 0,
3202 "score%d.techs", plrno);
3203 plr->score.techout =
3204 secfile_lookup_int_default(loading->file, 0,
3205 "score%d.techout", plrno);
3206 plr->score.landarea =
3207 secfile_lookup_int_default(loading->file, 0,
3208 "score%d.landarea", plrno);
3209 plr->score.settledarea =
3210 secfile_lookup_int_default(loading->file, 0,
3211 "score%d.settledarea", plrno);
3212 plr->score.population =
3213 secfile_lookup_int_default(loading->file, 0,
3214 "score%d.population", plrno);
3215 plr->score.cities =
3216 secfile_lookup_int_default(loading->file, 0,
3217 "score%d.cities", plrno);
3218 plr->score.units =
3219 secfile_lookup_int_default(loading->file, 0,
3220 "score%d.units", plrno);
3221 plr->score.pollution =
3222 secfile_lookup_int_default(loading->file, 0,
3223 "score%d.pollution", plrno);
3224 plr->score.literacy =
3225 secfile_lookup_int_default(loading->file, 0,
3226 "score%d.literacy", plrno);
3227 plr->score.bnp =
3228 secfile_lookup_int_default(loading->file, 0,
3229 "score%d.bnp", plrno);
3230 plr->score.mfg =
3231 secfile_lookup_int_default(loading->file, 0,
3232 "score%d.mfg", plrno);
3233 plr->score.spaceship =
3234 secfile_lookup_int_default(loading->file, 0,
3235 "score%d.spaceship", plrno);
3236 plr->score.units_built =
3237 secfile_lookup_int_default(loading->file, 0,
3238 "score%d.units_built", plrno);
3239 plr->score.units_killed =
3240 secfile_lookup_int_default(loading->file, 0,
3241 "score%d.units_killed", plrno);
3242 plr->score.units_lost =
3243 secfile_lookup_int_default(loading->file, 0,
3244 "score%d.units_lost", plrno);
3245 plr->score.culture =
3246 secfile_lookup_int_default(loading->file, 0,
3247 "score%d.culture", plrno);
3248 plr->score.game =
3249 secfile_lookup_int_default(loading->file, 0,
3250 "score%d.total", plrno);
3251
3252 /* Load space ship data. */
3253 {
3254 struct player_spaceship *ship = &plr->spaceship;
3255 char prefix[32];
3256 const char *st;
3257 int ei;
3258
3259 fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
3260 spaceship_init(ship);
3262 &ei,
3263 "%s.state", prefix),
3264 "%s", secfile_error());
3265 ship->state = ei;
3266
3267 if (ship->state != SSHIP_NONE) {
3269 "%s.structurals", prefix),
3270 "%s", secfile_error());
3272 "%s.components", prefix),
3273 "%s", secfile_error());
3275 "%s.modules", prefix),
3276 "%s", secfile_error());
3277 sg_failure_ret(secfile_lookup_int(loading->file, &ship->fuel,
3278 "%s.fuel", prefix),
3279 "%s", secfile_error());
3281 "%s.propulsion", prefix),
3282 "%s", secfile_error());
3284 "%s.habitation", prefix),
3285 "%s", secfile_error());
3287 "%s.life_support", prefix),
3288 "%s", secfile_error());
3290 "%s.solar_panels", prefix),
3291 "%s", secfile_error());
3292
3293 st = secfile_lookup_str(loading->file, "%s.structure", prefix);
3294 sg_failure_ret(st != NULL, "%s", secfile_error())
3295 for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
3296 sg_failure_ret(st[i] == '1' || st[i] == '0',
3297 "Undefined value '%c' within '%s.structure'.", st[i],
3298 prefix)
3299
3300 if (!(st[i] == '0')) {
3301 BV_SET(ship->structure, i);
3302 }
3303 }
3304 if (ship->state >= SSHIP_LAUNCHED) {
3306 "%s.launch_year", prefix),
3307 "%s", secfile_error());
3308 }
3310 }
3311 }
3312
3313 /* Load lost wonder data. */
3314 str = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
3315 /* If not present, probably an old savegame; nothing to be done */
3316 if (str != NULL) {
3317 int k;
3318
3319 sg_failure_ret(strlen(str) == loading->improvement.size,
3320 "Invalid length for 'player%d.lost_wonders' ("
3321 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ")",
3322 plrno, strlen(str), loading->improvement.size);
3323 for (k = 0; k < loading->improvement.size; k++) {
3324 sg_failure_ret(str[k] == '1' || str[k] == '0',
3325 "Undefined value '%c' within "
3326 "'player%d.lost_wonders'.", plrno, str[k]);
3327
3328 if (str[k] == '1') {
3329 struct impr_type *pimprove =
3331
3332 if (pimprove) {
3333 plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
3334 }
3335 }
3336 }
3337 }
3338
3339 plr->history =
3340 secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
3341 plr->server.huts =
3342 secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
3343}
3344
3345/************************************************************************/
3348static void sg_load_player_cities(struct loaddata *loading,
3349 struct player *plr)
3350{
3351 int ncities, i, plrno = player_number(plr);
3352 bool tasks_handled;
3353 int wlist_max_length = 0;
3354
3355 /* Check status and return if not OK (sg_success FALSE). */
3356 sg_check_ret();
3357
3358 sg_failure_ret(secfile_lookup_int(loading->file, &ncities,
3359 "player%d.ncities", plrno),
3360 "%s", secfile_error());
3361
3362 if (!plr->is_alive && ncities > 0) {
3363 log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
3364 ncities = 0;
3365 }
3366
3367 if (!plr->server.got_first_city && ncities > 0) {
3368 /* Probably barbarians in an old savegame; fix up */
3369 plr->server.got_first_city = TRUE;
3370 }
3371
3372 /* Find longest worklist */
3373 for (i = 0; i < ncities; i++) {
3374 int wl_length = secfile_lookup_int_default(loading->file, 0,
3375 "player%d.c%d.wl_length",
3376 plrno, i);
3377
3378 wlist_max_length = MAX(wlist_max_length, wl_length);
3379 }
3380
3381 /* Load all cities of the player. */
3382 for (i = 0; i < ncities; i++) {
3383 char buf[32];
3384 struct city *pcity;
3385
3386 fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
3387
3388 /* Create a dummy city. */
3389 pcity = create_city_virtual(plr, NULL, buf);
3390 adv_city_alloc(pcity);
3391 if (!sg_load_player_city(loading, plr, pcity, buf, wlist_max_length)) {
3392 adv_city_free(pcity);
3393 destroy_city_virtual(pcity);
3394 sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
3395 }
3396
3398 idex_register_city(&wld, pcity);
3399
3400 /* Load the information about the nationality of citizens. This is done
3401 * here because the city sanity check called by citizens_update() requires
3402 * that the city is registered. */
3403 sg_load_player_city_citizens(loading, plr, pcity, buf);
3404
3405 /* After everything is loaded, but before vision. */
3406 map_claim_ownership(city_tile(pcity), plr, city_tile(pcity), TRUE);
3407
3408 /* adding the city contribution to fog-of-war */
3409 pcity->server.vision = vision_new(plr, city_tile(pcity));
3411 city_refresh_vision(pcity);
3412
3413 city_list_append(plr->cities, pcity);
3414 }
3415
3416 tasks_handled = FALSE;
3417 for (i = 0; !tasks_handled; i++) {
3418 int city_id;
3419 struct city *pcity = NULL;
3420
3421 city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
3422 plrno, i);
3423
3424 if (city_id != -1) {
3425 pcity = player_city_by_number(plr, city_id);
3426 }
3427
3428 if (pcity != NULL) {
3429 const char *str;
3430 int nat_x, nat_y;
3431 struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
3432
3433 nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
3434 nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
3435
3436 ptask->ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3437
3438 str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
3439 ptask->act = unit_activity_by_name(str, fc_strcasecmp);
3440
3441 sg_failure_ret(unit_activity_is_valid(ptask->act),
3442 "Unknown workertask activity %s", str);
3443
3444 str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
3445
3446 if (strcmp("-", str)) {
3448
3449 sg_failure_ret(ptask->tgt != NULL,
3450 "Unknown workertask target %s", str);
3451 } else {
3452 ptask->tgt = NULL;
3453 }
3454
3455 ptask->want = secfile_lookup_int_default(loading->file, 1,
3456 "player%d.task%d.want", plrno, i);
3457
3458 worker_task_list_append(pcity->task_reqs, ptask);
3459 } else {
3460 tasks_handled = TRUE;
3461 }
3462 }
3463}
3464
3465/************************************************************************/
3468static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
3469 struct city *pcity, const char *citystr,
3470 int wlist_max_length)
3471{
3472 struct player *past;
3473 const char *kind, *name, *str;
3474 int id, i, repair, sp_count = 0, workers = 0, value;
3475 int nat_x, nat_y;
3476 citizens size;
3477 const char *stylename;
3478 const struct civ_map *nmap = &(wld.map);
3479
3480 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", citystr),
3481 FALSE, "%s", secfile_error());
3482 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", citystr),
3483 FALSE, "%s", secfile_error());
3484 pcity->tile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3485 sg_warn_ret_val(NULL != pcity->tile, FALSE,
3486 "%s has invalid center tile (%d, %d)",
3487 citystr, nat_x, nat_y);
3488 sg_warn_ret_val(NULL == tile_city(pcity->tile), FALSE,
3489 "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
3490
3491 /* Instead of dying, use 'citystr' string for damaged name. */
3492 city_name_set(pcity, secfile_lookup_str_default(loading->file, citystr,
3493 "%s.name", citystr));
3494
3495 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->id, "%s.id",
3496 citystr), FALSE, "%s", secfile_error());
3497
3498 id = secfile_lookup_int_default(loading->file, player_number(plr),
3499 "%s.original", citystr);
3500 past = player_by_number(id);
3501 if (NULL != past) {
3502 pcity->original = past;
3503 }
3504
3505 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
3506 citystr), FALSE, "%s", secfile_error());
3507 size = (citizens)value; /* set the correct type */
3508 sg_warn_ret_val(value == (int)size, FALSE,
3509 "Invalid city size: %d, set to %d", value, size);
3510 city_size_set(pcity, size);
3511
3512 for (i = 0; i < loading->specialist.size; i++) {
3513 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
3514 citystr, i),
3515 FALSE, "%s", secfile_error());
3516 pcity->specialists[specialist_index(loading->specialist.order[i])]
3517 = (citizens)value;
3518 sp_count += value;
3519 }
3520
3521 for (i = 0; i < MAX_TRADE_ROUTES; i++) {
3522 int partner = secfile_lookup_int_default(loading->file, 0,
3523 "%s.traderoute%d", citystr, i);
3524
3525 if (partner != 0) {
3526 struct trade_route *proute = fc_malloc(sizeof(struct trade_route));
3527
3528 proute->partner = partner;
3529 proute->dir = RDIR_BIDIRECTIONAL;
3530 proute->goods = goods_by_number(0); /* First good */
3531
3532 trade_route_list_append(pcity->routes, proute);
3533 }
3534 }
3535
3537 "%s.food_stock", citystr),
3538 FALSE, "%s", secfile_error());
3540 "%s.shield_stock", citystr),
3541 FALSE, "%s", secfile_error());
3542 pcity->history =
3543 secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
3544
3545 pcity->airlift =
3546 secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
3547 pcity->was_happy =
3548 secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
3549 citystr);
3550
3551 pcity->turn_plague =
3552 secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
3553
3555 "%s.anarchy", citystr),
3556 FALSE, "%s", secfile_error());
3557 pcity->rapture =
3558 secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
3559 pcity->steal =
3560 secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
3561
3562 /* before did_buy for undocumented hack */
3563 pcity->turn_founded =
3564 secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
3565 citystr);
3566 sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
3567 citystr), FALSE, "%s", secfile_error());
3568 pcity->did_buy = (i != 0);
3569 if (i == -1 && pcity->turn_founded == -2) {
3570 /* undocumented hack */
3571 pcity->turn_founded = game.info.turn;
3572 }
3573
3574 pcity->did_sell =
3575 secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
3576
3578 "%s.turn_last_built", citystr),
3579 FALSE, "%s", secfile_error());
3580
3581 kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
3582 citystr);
3583 name = secfile_lookup_str(loading->file, "%s.currently_building_name",
3584 citystr);
3585 pcity->production = universal_by_rule_name(kind, name);
3586 sg_warn_ret_val(pcity->production.kind != universals_n_invalid(), FALSE,
3587 "%s.currently_building: unknown \"%s\" \"%s\".",
3588 citystr, kind, name);
3589
3590 kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
3591 citystr);
3592 name = secfile_lookup_str(loading->file, "%s.changed_from_name",
3593 citystr);
3595 sg_warn_ret_val(pcity->changed_from.kind != universals_n_invalid(), FALSE,
3596 "%s.changed_from: unknown \"%s\" \"%s\".",
3597 citystr, kind, name);
3598
3599 pcity->before_change_shields =
3601 "%s.before_change_shields", citystr);
3602 pcity->caravan_shields =
3603 secfile_lookup_int_default(loading->file, 0,
3604 "%s.caravan_shields", citystr);
3605 pcity->disbanded_shields =
3606 secfile_lookup_int_default(loading->file, 0,
3607 "%s.disbanded_shields", citystr);
3609 secfile_lookup_int_default(loading->file, 0,
3610 "%s.last_turns_shield_surplus",
3611 citystr);
3612
3613 stylename = secfile_lookup_str_default(loading->file, NULL,
3614 "%s.style", citystr);
3615 if (stylename != NULL) {
3616 pcity->style = city_style_by_rule_name(stylename);
3617 } else {
3618 pcity->style = 0;
3619 }
3620 if (pcity->style < 0) {
3621 pcity->style = city_style(pcity);
3622 }
3623
3624 pcity->server.synced = FALSE; /* Must re-sync with clients */
3625
3626 /* Initialise list of city improvements. */
3627 for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
3628 pcity->built[i].turn = I_NEVER;
3629 }
3630
3631 /* Load city improvements. */
3632 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
3633 sg_warn_ret_val(str != NULL, FALSE, "%s", secfile_error());
3634 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
3635 "Invalid length of '%s.improvements' ("
3636 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
3637 citystr, strlen(str), loading->improvement.size);
3638 for (i = 0; i < loading->improvement.size; i++) {
3639 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
3640 "Undefined value '%c' within '%s.improvements'.",
3641 str[i], citystr)
3642
3643 if (str[i] == '1') {
3644 struct impr_type *pimprove =
3646
3647 if (pimprove) {
3648 city_add_improvement(pcity, pimprove);
3649 }
3650 }
3651 }
3652
3653 sg_failure_ret_val(loading->worked_tiles != NULL, FALSE,
3654 "No worked tiles map defined.");
3655
3656 city_freeze_workers(pcity);
3657
3658 /* Load new savegame with variable (squared) city radius and worked
3659 * tiles map */
3660
3661 int radius_sq
3662 = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
3663 citystr);
3664 city_map_radius_sq_set(pcity, radius_sq);
3665
3666 city_tile_iterate(nmap, CITY_MAP_MAX_RADIUS_SQ, city_tile(pcity), ptile) {
3667 if (loading->worked_tiles[ptile->index] == pcity->id) {
3668 if (sq_map_distance(ptile, pcity->tile) > radius_sq) {
3669 log_sg("[%s] '%s' (%d, %d) has worker outside current radius "
3670 "at (%d, %d); repairing", citystr, city_name_get(pcity),
3671 TILE_XY(pcity->tile), TILE_XY(ptile));
3673 sp_count++;
3674 } else {
3675 tile_set_worked(ptile, pcity);
3676 workers++;
3677 }
3678
3679#ifdef FREECIV_DEBUG
3680 /* Set this tile to unused; a check for not reset tiles is
3681 * included in game_load_internal() */
3682 loading->worked_tiles[ptile->index] = -1;
3683#endif /* FREECIV_DEBUG */
3684 }
3686
3687 if (tile_worked(city_tile(pcity)) != pcity) {
3688 struct city *pwork = tile_worked(city_tile(pcity));
3689
3690 if (NULL != pwork) {
3691 log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
3692 "(%d,%d) [%d]; repairing", citystr, city_name_get(pcity),
3693 TILE_XY(city_tile(pcity)), city_size_get(pcity), city_name_get(pwork),
3694 TILE_XY(city_tile(pwork)), city_size_get(pwork));
3695
3696 tile_set_worked(city_tile(pcity), NULL); /* remove tile from pwork */
3698 auto_arrange_workers(pwork);
3699 } else {
3700 log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing",
3701 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)),
3702 city_size_get(pcity));
3703 }
3704
3705 /* repair pcity */
3706 tile_set_worked(city_tile(pcity), pcity);
3707 city_repair_size(pcity, -1);
3708 }
3709
3710 repair = city_size_get(pcity) - sp_count - (workers - FREE_WORKED_TILES);
3711 if (0 != repair) {
3712 log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
3713 "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
3714 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)), city_size_get(pcity),
3715 workers, FREE_WORKED_TILES, sp_count);
3716
3717 /* repair pcity */
3718 city_repair_size(pcity, repair);
3719 }
3720
3721 /* worklist_init() done in create_city_virtual() */
3722 worklist_load(loading->file, wlist_max_length, &pcity->worklist, "%s", citystr);
3723
3724 /* Load city options. */
3725 BV_CLR_ALL(pcity->city_options);
3726 for (i = 0; i < CITYO_LAST; i++) {
3727 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
3728 citystr, i)) {
3729 BV_SET(pcity->city_options, i);
3730 }
3731 }
3732
3733 CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
3734
3735 return TRUE;
3736}
3737
3738/************************************************************************/
3741static void sg_load_player_city_citizens(struct loaddata *loading,
3742 struct player *plr,
3743 struct city *pcity,
3744 const char *citystr)
3745{
3747 citizens size;
3748
3749 citizens_init(pcity);
3750 player_slots_iterate(pslot) {
3751 int nationality;
3752
3754 "%s.citizen%d", citystr,
3755 player_slot_index(pslot));
3756 if (nationality > 0 && !player_slot_is_used(pslot)) {
3757 log_sg("Citizens of an invalid nation for %s (player slot %d)!",
3758 city_name_get(pcity), player_slot_index(pslot));
3759 continue;
3760 }
3761
3762 if (nationality != -1 && player_slot_is_used(pslot)) {
3764 "Invalid value for citizens of player %d in %s: %d.",
3766 citizens_nation_set(pcity, pslot, nationality);
3767 }
3769 /* Sanity check. */
3770 size = citizens_count(pcity);
3771 if (size != city_size_get(pcity)) {
3772 if (size != 0) {
3773 /* size == 0 can be result from the fact that ruleset had no
3774 * nationality enabled at saving time, so no citizens at all
3775 * were saved. But something more serious must be going on if
3776 * citizens have been saved partially - if some of them are there. */
3777 log_sg("City size and number of citizens does not match in %s "
3778 "(%d != %d)! Repairing ...", city_name_get(pcity),
3779 city_size_get(pcity), size);
3780 }
3781 citizens_update(pcity, NULL);
3782 }
3783 }
3784}
3785
3786/************************************************************************/
3789static void sg_load_player_units(struct loaddata *loading,
3790 struct player *plr)
3791{
3792 int nunits, i, plrno = player_number(plr);
3793
3794 /* Check status and return if not OK (sg_success FALSE). */
3795 sg_check_ret();
3796
3797 sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
3798 "player%d.nunits", plrno),
3799 "%s", secfile_error());
3800 if (!plr->is_alive && nunits > 0) {
3801 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
3802 nunits = 0; /* Some old savegames may be buggy. */
3803 }
3804
3805 for (i = 0; i < nunits; i++) {
3806 struct unit *punit;
3807 struct city *pcity;
3808 const char *name;
3809 char buf[32];
3810 struct unit_type *type;
3811 struct tile *ptile;
3812
3813 fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
3814
3815 name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
3817 sg_failure_ret(type != NULL, "%s: unknown unit type \"%s\".", buf, name);
3818
3819 /* Create a dummy unit. */
3820 punit = unit_virtual_create(plr, NULL, type, 0);
3821 if (!sg_load_player_unit(loading, plr, punit, buf)) {
3823 sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
3824 }
3825
3828
3829 if ((pcity = game_city_by_number(punit->homecity))) {
3830 unit_list_prepend(pcity->units_supported, punit);
3831 } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
3832 log_sg("%s: bad home city %d.", buf, punit->homecity);
3834 }
3835
3836 ptile = unit_tile(punit);
3837
3838 /* allocate the unit's contribution to fog of war */
3841 /* NOTE: There used to be some map_set_known calls here. These were
3842 * unneeded since unfogging the tile when the unit sees it will
3843 * automatically reveal that tile. */
3844
3845 unit_list_append(plr->units, punit);
3846 unit_list_prepend(unit_tile(punit)->units, punit);
3847
3848 /* Claim ownership of fortress? */
3849 if ((extra_owner(ptile) == NULL
3850 || pplayers_at_war(extra_owner(ptile), plr))
3852 tile_claim_bases(ptile, plr);
3853 }
3854 }
3855}
3856
3857/************************************************************************/
3867static int sg_order_to_action(int order, struct unit *act_unit,
3868 struct tile *tgt_tile)
3869{
3870 switch (order) {
3872 if (tile_city(tgt_tile)
3873 && city_owner(tile_city(tgt_tile)) == unit_owner(act_unit)) {
3874 /* The player's cities are loaded right before their units. It wasn't
3875 * possible for rulesets to allow joining foreign cities before 3.0.
3876 * This means that a converted build city order only can be a Join
3877 * City order if it targets a domestic city. */
3878 return ACTION_JOIN_CITY;
3879 } else {
3880 /* Assume that the intention was to found a new city. */
3881 return ACTION_FOUND_CITY;
3882 }
3884 /* Maps one to one with each other. */
3885 return ACTION_HELP_WONDER;
3887 /* Maps one to one with each other. */
3888 return ACTION_TRADE_ROUTE;
3889 case ORDER_OLD_DISBAND:
3890 /* Added to the order system in the same commit as Help Wonder. Assume
3891 * that anyone that intended to order Help Wonder used Help Wonder. */
3892 /* Could in theory be intended as an order to disband in the field. Why
3893 * would the player give a unit an order to go to a non city location
3894 * and disband there? Assume the intention was to recover production
3895 * until a non recovering disband order is found. */
3896 return ACTION_DISBAND_UNIT_RECOVER;
3897 case ORDER_OLD_HOMECITY:
3898 return ACTION_HOME_CITY;
3899 }
3900
3901 /* The order hasn't been replaced by an action. */
3902 return ACTION_NONE;
3903}
3904
3905/************************************************************************/
3908static bool sg_load_player_unit(struct loaddata *loading,
3909 struct player *plr, struct unit *punit,
3910 const char *unitstr)
3911{
3912 enum unit_activity activity;
3913 int nat_x, nat_y;
3914 enum tile_special_type target;
3915 struct extra_type *pextra = NULL;
3916 struct base_type *pbase = NULL;
3917 struct road_type *proad = NULL;
3918 struct tile *ptile;
3919 int extra_id;
3920 int base_id;
3921 int road_id;
3922 int ei;
3923 const char *facing_str;
3924 enum tile_special_type cfspe;
3925 int natnbr;
3926 bool ai_controlled;
3927
3928 sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->id, "%s.id",
3929 unitstr), FALSE, "%s", secfile_error());
3930 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", unitstr),
3931 FALSE, "%s", secfile_error());
3932 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", unitstr),
3933 FALSE, "%s", secfile_error());
3934
3935 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3936 sg_warn_ret_val(NULL != ptile, FALSE, "%s invalid tile (%d, %d)",
3937 unitstr, nat_x, nat_y);
3938 unit_tile_set(punit, ptile);
3939
3940 facing_str
3941 = secfile_lookup_str_default(loading->file, "x",
3942 "%s.facing", unitstr);
3943 if (facing_str[0] != 'x') {
3944 /* We don't touch punit->facing if savegame does not contain that
3945 * information. Initial orientation set by unit_virtual_create()
3946 * is as good as any. */
3947 enum direction8 facing = char2dir(facing_str[0]);
3948
3949 if (direction8_is_valid(facing)) {
3950 punit->facing = facing;
3951 } else {
3952 log_error("Illegal unit orientation '%s'", facing_str);
3953 }
3954 }
3955
3956 /* If savegame has unit nationality, it doesn't hurt to
3957 * internally set it even if nationality rules are disabled. */
3958 natnbr = secfile_lookup_int_default(loading->file,
3959 player_number(plr),
3960 "%s.nationality", unitstr);
3961
3963 if (punit->nationality == NULL) {
3964 punit->nationality = plr;
3965 }
3966
3968 "%s.homecity", unitstr), FALSE,
3969 "%s", secfile_error());
3971 "%s.moves", unitstr), FALSE,
3972 "%s", secfile_error());
3974 "%s.fuel", unitstr), FALSE,
3975 "%s", secfile_error());
3977 "%s.activity", unitstr), FALSE,
3978 "%s", secfile_error());
3979 activity = unit_activity_by_name(loading->activities.order[ei],
3981
3984 "%s.born", unitstr);
3985
3986 extra_id = secfile_lookup_int_default(loading->file, -2,
3987 "%s.activity_tgt", unitstr);
3988
3989 if (extra_id != -2) {
3990 if (extra_id >= 0 && extra_id < loading->extra.size) {
3991 pextra = loading->extra.order[extra_id];
3992 set_unit_activity_targeted(punit, activity, pextra);
3993 } else if (activity == ACTIVITY_IRRIGATE) {
3995 EC_IRRIGATION,
3997 punit);
3998 if (tgt != NULL) {
3999 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
4000 } else {
4001 set_unit_activity(punit, ACTIVITY_CULTIVATE);
4002 }
4003 } else if (activity == ACTIVITY_MINE) {
4005 EC_MINE,
4007 punit);
4008 if (tgt != NULL) {
4009 set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
4010 } else {
4011 set_unit_activity(punit, ACTIVITY_PLANT);
4012 }
4013 } else {
4014 set_unit_activity(punit, activity);
4015 }
4016 } else {
4017 /* extra_id == -2 -> activity_tgt not set */
4018 base_id = secfile_lookup_int_default(loading->file, -1,
4019 "%s.activity_base", unitstr);
4020 if (base_id >= 0 && base_id < loading->base.size) {
4021 pbase = loading->base.order[base_id];
4022 }
4023 road_id = secfile_lookup_int_default(loading->file, -1,
4024 "%s.activity_road", unitstr);
4025 if (road_id >= 0 && road_id < loading->road.size) {
4026 proad = loading->road.order[road_id];
4027 }
4028
4029 {
4030 int tgt_no = secfile_lookup_int_default(loading->file,
4031 loading->special.size /* S_LAST */,
4032 "%s.activity_target", unitstr);
4033 if (tgt_no >= 0 && tgt_no < loading->special.size) {
4034 target = loading->special.order[tgt_no];
4035 } else {
4036 target = S_LAST;
4037 }
4038 }
4039
4040 if (target == S_OLD_ROAD) {
4041 target = S_LAST;
4043 } else if (target == S_OLD_RAILROAD) {
4044 target = S_LAST;
4046 }
4047
4048 if (activity == ACTIVITY_OLD_ROAD) {
4049 activity = ACTIVITY_GEN_ROAD;
4051 } else if (activity == ACTIVITY_OLD_RAILROAD) {
4052 activity = ACTIVITY_GEN_ROAD;
4054 }
4055
4056 /* We need changed_from == ACTIVITY_IDLE by now so that
4057 * set_unit_activity() and friends don't spuriously restore activity
4058 * points -- unit should have been created this way */
4059 fc_assert(punit->changed_from == ACTIVITY_IDLE);
4060
4061 if (activity == ACTIVITY_BASE) {
4062 if (pbase) {
4064 } else {
4065 log_sg("Cannot find base %d for %s to build",
4066 base_id, unit_rule_name(punit));
4067 set_unit_activity(punit, ACTIVITY_IDLE);
4068 }
4069 } else if (activity == ACTIVITY_GEN_ROAD) {
4070 if (proad) {
4072 } else {
4073 log_sg("Cannot find road %d for %s to build",
4074 road_id, unit_rule_name(punit));
4075 set_unit_activity(punit, ACTIVITY_IDLE);
4076 }
4077 } else if (activity == ACTIVITY_PILLAGE) {
4078 struct extra_type *a_target;
4079
4080 if (target != S_LAST) {
4081 a_target = special_extra_get(target);
4082 } else if (pbase != NULL) {
4083 a_target = base_extra_get(pbase);
4084 } else if (proad != NULL) {
4085 a_target = road_extra_get(proad);
4086 } else {
4087 a_target = NULL;
4088 }
4089 /* An out-of-range base number is seen with old savegames. We take
4090 * it as indicating undirected pillaging. We will assign pillage
4091 * targets before play starts. */
4092 set_unit_activity_targeted(punit, activity, a_target);
4093 } else if (activity == ACTIVITY_IRRIGATE) {
4095 EC_IRRIGATION,
4097 punit);
4098 if (tgt != NULL) {
4099 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
4100 } else {
4101 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, NULL);
4102 }
4103 } else if (activity == ACTIVITY_MINE) {
4105 EC_MINE,
4107 punit);
4108 if (tgt != NULL) {
4109 set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
4110 } else {
4111 set_unit_activity_targeted(punit, ACTIVITY_MINE, NULL);
4112 }
4113 } else if (activity == ACTIVITY_POLLUTION) {
4115 ERM_CLEANPOLLUTION,
4117 punit);
4118 if (tgt != NULL) {
4119 set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, tgt);
4120 } else {
4121 set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, NULL);
4122 }
4123 } else if (activity == ACTIVITY_FALLOUT) {
4125 ERM_CLEANFALLOUT,
4127 punit);
4128 if (tgt != NULL) {
4129 set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, tgt);
4130 } else {
4131 set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, NULL);
4132 }
4133 } else {
4134 set_unit_activity_targeted(punit, activity, NULL);
4135 }
4136 } /* activity_tgt == NULL */
4137
4139 "%s.activity_count", unitstr), FALSE,
4140 "%s", secfile_error());
4141
4143 secfile_lookup_int_default(loading->file, ACTIVITY_IDLE,
4144 "%s.changed_from", unitstr);
4145
4146 extra_id = secfile_lookup_int_default(loading->file, -2,
4147 "%s.changed_from_tgt", unitstr);
4148
4149 if (extra_id != -2) {
4150 if (extra_id >= 0 && extra_id < loading->extra.size) {
4151 punit->changed_from_target = loading->extra.order[extra_id];
4152 } else {
4153 punit->changed_from_target = NULL;
4154 }
4155 } else {
4156 /* extra_id == -2 -> changed_from_tgt not set */
4157
4158 cfspe =
4160 "%s.changed_from_target", unitstr);
4161 base_id =
4162 secfile_lookup_int_default(loading->file, -1,
4163 "%s.changed_from_base", unitstr);
4164 road_id =
4165 secfile_lookup_int_default(loading->file, -1,
4166 "%s.changed_from_road", unitstr);
4167
4168 if (road_id == -1) {
4169 if (cfspe == S_OLD_ROAD) {
4171 if (proad) {
4172 road_id = road_number(proad);
4173 }
4174 } else if (cfspe == S_OLD_RAILROAD) {
4176 if (proad) {
4177 road_id = road_number(proad);
4178 }
4179 }
4180 }
4181
4182 if (base_id >= 0 && base_id < loading->base.size) {
4183 punit->changed_from_target = base_extra_get(loading->base.order[base_id]);
4184 } else if (road_id >= 0 && road_id < loading->road.size) {
4185 punit->changed_from_target = road_extra_get(loading->road.order[road_id]);
4186 } else if (cfspe != S_LAST) {
4188 } else {
4189 punit->changed_from_target = NULL;
4190 }
4191
4192 if (punit->changed_from == ACTIVITY_IRRIGATE) {
4194 EC_IRRIGATION,
4196 punit);
4197 if (tgt != NULL) {
4199 } else {
4200 punit->changed_from_target = NULL;
4201 }
4202 } else if (punit->changed_from == ACTIVITY_MINE) {
4204 EC_MINE,
4206 punit);
4207 if (tgt != NULL) {
4209 } else {
4210 punit->changed_from_target = NULL;
4211 }
4212 } else if (punit->changed_from == ACTIVITY_POLLUTION) {
4214 ERM_CLEANPOLLUTION,
4216 punit);
4217 if (tgt != NULL) {
4219 } else {
4220 punit->changed_from_target = NULL;
4221 }
4222 } else if (punit->changed_from == ACTIVITY_FALLOUT) {
4224 ERM_CLEANFALLOUT,
4226 punit);
4227 if (tgt != NULL) {
4229 } else {
4230 punit->changed_from_target = NULL;
4231 }
4232 }
4233 }
4234
4236 secfile_lookup_int_default(loading->file, 0,
4237 "%s.changed_from_count", unitstr);
4238
4239 /* Special case: for a long time, we accidentally incremented
4240 * activity_count while a unit was sentried, so it could increase
4241 * without bound (bug #20641) and be saved in old savefiles.
4242 * We zero it to prevent potential trouble overflowing the range
4243 * in network packets, etc. */
4244 if (activity == ACTIVITY_SENTRY) {
4245 punit->activity_count = 0;
4246 }
4247 if (punit->changed_from == ACTIVITY_SENTRY) {
4249 }
4250
4251 punit->veteran
4252 = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
4253 {
4254 /* Protect against change in veteran system in ruleset */
4255 const int levels = utype_veteran_levels(unit_type_get(punit));
4256 if (punit->veteran >= levels) {
4257 fc_assert(levels >= 1);
4258 punit->veteran = levels - 1;
4259 }
4260 }
4263 "%s.done_moving", unitstr);
4266 "%s.battlegroup", unitstr);
4267
4269 "%s.go", unitstr)) {
4270 int gnat_x, gnat_y;
4271
4272 sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_x,
4273 "%s.goto_x", unitstr), FALSE,
4274 "%s", secfile_error());
4275 sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_y,
4276 "%s.goto_y", unitstr), FALSE,
4277 "%s", secfile_error());
4278
4279 punit->goto_tile = native_pos_to_tile(&(wld.map), gnat_x, gnat_y);
4280 } else {
4281 punit->goto_tile = NULL;
4282
4283 if (punit->activity == ACTIVITY_GOTO) {
4284 /* goto_tile should never be NULL with ACTIVITY_GOTO */
4285 log_sg("Unit %d on goto without goto_tile. Aborting goto.",
4286 punit->id);
4287 punit->activity = ACTIVITY_IDLE;
4288 }
4289
4290 /* These variables are not used but needed for saving the unit table.
4291 * Load them to prevent unused variables errors. */
4292 (void) secfile_entry_lookup(loading->file, "%s.goto_x", unitstr);
4293 (void) secfile_entry_lookup(loading->file, "%s.goto_y", unitstr);
4294 }
4295
4296 /* Load AI data of the unit. */
4297 CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
4298
4300 &ai_controlled,
4301 "%s.ai", unitstr), FALSE,
4302 "%s", secfile_error());
4303 if (ai_controlled) {
4304 /* Autosettler and Autoexplore are separated by
4305 * compat_post_load_030100() when set to SSA_AUTOSETTLER */
4306 punit->ssa_controller = SSA_AUTOSETTLER;
4307 } else {
4308 punit->ssa_controller = SSA_NONE;
4309 }
4311 "%s.hp", unitstr), FALSE,
4312 "%s", secfile_error());
4313
4315 = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
4317 = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
4318 punit->moved
4319 = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
4322 "%s.paradropped", unitstr);
4323
4324 /* The transport status (punit->transported_by) is loaded in
4325 * sg_player_units_transport(). */
4326
4327 /* Initialize upkeep values: these are hopefully initialized
4328 * elsewhere before use (specifically, in city_support(); but
4329 * fixme: check whether always correctly initialized?).
4330 * Below is mainly for units which don't have homecity --
4331 * otherwise these don't get initialized (and AI calculations
4332 * etc may use junk values). */
4336
4339 ACT_DEC_NOTHING, action_decision,
4340 "%s.action_decision_want", unitstr);
4341
4342 if (punit->action_decision_want != ACT_DEC_NOTHING) {
4343 /* Load the tile to act against. */
4344 int adwt_x, adwt_y;
4345
4346 if (secfile_lookup_int(loading->file, &adwt_x,
4347 "%s.action_decision_tile_x", unitstr)
4348 && secfile_lookup_int(loading->file, &adwt_y,
4349 "%s.action_decision_tile_y", unitstr)) {
4351 adwt_x, adwt_y);
4352 } else {
4353 punit->action_decision_want = ACT_DEC_NOTHING;
4355 log_sg("Bad action_decision_tile for unit %d", punit->id);
4356 }
4357 } else {
4358 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_x", unitstr);
4359 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_y", unitstr);
4361 }
4362
4363 /* Load the unit orders */
4364 {
4365 int len = secfile_lookup_int_default(loading->file, 0,
4366 "%s.orders_length", unitstr);
4367
4368 if (len > 0) {
4369 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
4370 const char *tgt_unitstr;
4371 const char *base_unitstr = NULL;
4372 const char *road_unitstr = NULL;
4375 int j;
4376
4377 punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
4380 = secfile_lookup_int_default(loading->file, 0,
4381 "%s.orders_index", unitstr);
4384 "%s.orders_repeat", unitstr);
4387 "%s.orders_vigilant", unitstr);
4388
4389 orders_unitstr
4390 = secfile_lookup_str_default(loading->file, "",
4391 "%s.orders_list", unitstr);
4392 dir_unitstr
4393 = secfile_lookup_str_default(loading->file, "",
4394 "%s.dir_list", unitstr);
4395 act_unitstr
4396 = secfile_lookup_str_default(loading->file, "",
4397 "%s.activity_list", unitstr);
4398 tgt_unitstr
4399 = secfile_lookup_str_default(loading->file, NULL, "%s.tgt_list", unitstr);
4400
4401 if (tgt_unitstr == NULL) {
4402 base_unitstr
4403 = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
4404 road_unitstr
4405 = secfile_lookup_str_default(loading->file, NULL, "%s.road_list", unitstr);
4406 }
4407
4409
4410 for (j = 0; j < len; j++) {
4411 struct unit_order *order = &punit->orders.list[j];
4412
4413 if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
4414 || act_unitstr[j] == '\0') {
4415 log_sg("Invalid unit orders.");
4417 break;
4418 }
4419 order->order = char2order(orders_unitstr[j]);
4420 order->dir = char2dir(dir_unitstr[j]);
4421 order->activity = char2activity(act_unitstr[j]);
4422 /* Target, if needed, is set in compat_post_load_030100() */
4423 order->target = NO_TARGET;
4424 order->sub_target = NO_TARGET;
4425
4426 if (order->order == ORDER_LAST
4427 || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
4428 || (order->order == ORDER_ACTION_MOVE
4429 && !direction8_is_valid(order->dir))
4430 || (order->order == ORDER_ACTIVITY
4431 && order->activity == ACTIVITY_LAST)) {
4432 /* An invalid order. Just drop the orders for this unit. */
4433 free(punit->orders.list);
4434 punit->orders.list = NULL;
4435 punit->orders.length = 0;
4437 punit->goto_tile = NULL;
4438 break;
4439 }
4440
4441 /* The order may have been replaced by the perform action order */
4442 order->action = sg_order_to_action(order->order, punit,
4443 punit->goto_tile);
4444 if (order->action != ACTION_NONE) {
4445 /* The order was converted by order_to_action */
4446 order->order = ORDER_PERFORM_ACTION;
4447 }
4448
4449 if (tgt_unitstr) {
4450 if (tgt_unitstr[j] != '?') {
4451 extra_id = char2num(tgt_unitstr[j]);
4452
4453 if (extra_id < 0 || extra_id >= loading->extra.size) {
4454 log_sg("Cannot find extra %d for %s to build",
4455 extra_id, unit_rule_name(punit));
4456 order->sub_target = EXTRA_NONE;
4457 } else {
4458 order->sub_target = extra_id;
4459 }
4460 } else {
4461 order->sub_target = EXTRA_NONE;
4462 }
4463 } else {
4464 /* In pre-2.6 savegames, base_list and road_list were only saved
4465 * for those activities (and not e.g. pillaging) */
4466 if (base_unitstr && base_unitstr[j] != '?'
4467 && order->activity == ACTIVITY_BASE) {
4468 base_id = char2num(base_unitstr[j]);
4469
4470 if (base_id < 0 || base_id >= loading->base.size) {
4471 log_sg("Cannot find base %d for %s to build",
4472 base_id, unit_rule_name(punit));
4473 base_id = base_number(get_base_by_gui_type(BASE_GUI_FORTRESS,
4474 NULL, NULL));
4475 }
4476
4477 order->sub_target
4479 } else if (road_unitstr && road_unitstr[j] != '?'
4480 && order->activity == ACTIVITY_GEN_ROAD) {
4481 road_id = char2num(road_unitstr[j]);
4482
4483 if (road_id < 0 || road_id >= loading->road.size) {
4484 log_sg("Cannot find road %d for %s to build",
4485 road_id, unit_rule_name(punit));
4486 road_id = 0;
4487 }
4488
4489 order->sub_target
4491 } else {
4492 order->sub_target = EXTRA_NONE;
4493 }
4494
4495 if (order->activity == ACTIVITY_OLD_ROAD) {
4496 order->activity = ACTIVITY_GEN_ROAD;
4497 order->sub_target
4499 } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
4500 order->activity = ACTIVITY_GEN_ROAD;
4501 order->sub_target
4503 }
4504 }
4505 }
4506 } else {
4507 /* Never nullify goto_tile for a unit that is in active goto. */
4508 if (punit->activity != ACTIVITY_GOTO) {
4509 punit->goto_tile = NULL;
4510 }
4511
4513 punit->orders.list = NULL;
4514 punit->orders.length = 0;
4515
4516 (void) secfile_entry_lookup(loading->file, "%s.orders_index", unitstr);
4517 (void) secfile_entry_lookup(loading->file, "%s.orders_repeat", unitstr);
4518 (void) secfile_entry_lookup(loading->file, "%s.orders_vigilant", unitstr);
4519 (void) secfile_entry_lookup(loading->file, "%s.orders_list", unitstr);
4520 (void) secfile_entry_lookup(loading->file, "%s.dir_list", unitstr);
4521 (void) secfile_entry_lookup(loading->file, "%s.activity_list", unitstr);
4522 (void) secfile_entry_lookup(loading->file, "%s.tgt_list", unitstr);
4523 }
4524 }
4525
4526 return TRUE;
4527}
4528
4529/************************************************************************/
4533static void sg_load_player_units_transport(struct loaddata *loading,
4534 struct player *plr)
4535{
4536 int nunits, i, plrno = player_number(plr);
4537
4538 /* Check status and return if not OK (sg_success FALSE). */
4539 sg_check_ret();
4540
4541 /* Recheck the number of units for the player. This is a copied from
4542 * sg_load_player_units(). */
4543 sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
4544 "player%d.nunits", plrno),
4545 "%s", secfile_error());
4546 if (!plr->is_alive && nunits > 0) {
4547 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4548 nunits = 0; /* Some old savegames may be buggy. */
4549 }
4550
4551 for (i = 0; i < nunits; i++) {
4552 int id_unit, id_trans;
4553 struct unit *punit, *ptrans;
4554
4555 id_unit = secfile_lookup_int_default(loading->file, -1,
4556 "player%d.u%d.id",
4557 plrno, i);
4558 punit = player_unit_by_number(plr, id_unit);
4559 fc_assert_action(punit != NULL, continue);
4560
4561 id_trans = secfile_lookup_int_default(loading->file, -1,
4562 "player%d.u%d.transported_by",
4563 plrno, i);
4564 if (id_trans == -1) {
4565 /* Not transported. */
4566 continue;
4567 }
4568
4569 ptrans = game_unit_by_number(id_trans);
4570 fc_assert_action(id_trans == -1 || ptrans != NULL, continue);
4571
4572 if (ptrans) {
4573#ifndef FREECIV_NDEBUG
4574 bool load_success =
4575#endif
4576 unit_transport_load(punit, ptrans, TRUE);
4577
4578 fc_assert_action(load_success, continue);
4579 }
4580 }
4581}
4582
4583/************************************************************************/
4586static void sg_load_player_attributes(struct loaddata *loading,
4587 struct player *plr)
4588{
4589 int plrno = player_number(plr);
4590
4591 /* Check status and return if not OK (sg_success FALSE). */
4592 sg_check_ret();
4593
4594 /* Toss any existing attribute_block (should not exist) */
4595 if (plr->attribute_block.data) {
4596 free(plr->attribute_block.data);
4597 plr->attribute_block.data = NULL;
4598 }
4599
4600 /* This is a big heap of opaque data for the client, check everything! */
4602 loading->file, 0, "player%d.attribute_v2_block_length", plrno);
4603
4604 if (0 > plr->attribute_block.length) {
4605 log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
4606 plr->attribute_block.length);
4607 plr->attribute_block.length = 0;
4608 } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
4609 log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
4611 plr->attribute_block.length = 0;
4612 } else if (0 < plr->attribute_block.length) {
4613 int part_nr, parts;
4614 int quoted_length;
4615 char *quoted;
4616#ifndef FREECIV_NDEBUG
4617 size_t actual_length;
4618#endif
4619
4621 secfile_lookup_int(loading->file, &quoted_length,
4622 "player%d.attribute_v2_block_length_quoted",
4623 plrno), "%s", secfile_error());
4625 secfile_lookup_int(loading->file, &parts,
4626 "player%d.attribute_v2_block_parts", plrno),
4627 "%s", secfile_error());
4628
4629 quoted = fc_malloc(quoted_length + 1);
4630 quoted[0] = '\0';
4632 for (part_nr = 0; part_nr < parts; part_nr++) {
4633 const char *current =
4634 secfile_lookup_str(loading->file,
4635 "player%d.attribute_v2_block_data.part%d",
4636 plrno, part_nr);
4637 if (!current) {
4638 log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
4639 break;
4640 }
4641 log_debug("attribute_v2_block_length_quoted=%d"
4642 " have=" SIZE_T_PRINTF " part=" SIZE_T_PRINTF,
4643 quoted_length, strlen(quoted), strlen(current));
4644 fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
4645 strcat(quoted, current);
4646 }
4647 fc_assert_msg(quoted_length == strlen(quoted),
4648 "attribute_v2_block_length_quoted=%d"
4649 " actual=" SIZE_T_PRINTF,
4650 quoted_length, strlen(quoted));
4651
4652#ifndef FREECIV_NDEBUG
4653 actual_length =
4654#endif
4655 unquote_block(quoted,
4656 plr->attribute_block.data,
4657 plr->attribute_block.length);
4658 fc_assert(actual_length == plr->attribute_block.length);
4659 free(quoted);
4660 }
4661}
4662
4663/************************************************************************/
4666static void sg_load_player_vision(struct loaddata *loading,
4667 struct player *plr)
4668{
4669 int plrno = player_number(plr);
4670 int total_ncities =
4671 secfile_lookup_int_default(loading->file, -1,
4672 "player%d.dc_total", plrno);
4673 int i;
4674 bool someone_alive = FALSE;
4675
4676 /* Check status and return if not OK (sg_success FALSE). */
4677 sg_check_ret();
4678
4679 if (game.server.revealmap & REVEAL_MAP_DEAD) {
4680 player_list_iterate(team_members(plr->team), pteam_member) {
4681 if (pteam_member->is_alive) {
4682 someone_alive = TRUE;
4683 break;
4684 }
4686
4687 if (!someone_alive) {
4688 /* Reveal all for completely dead teams. */
4690 }
4691 }
4692
4693 if (!plr->is_alive
4694 || -1 == total_ncities
4695 || !game.info.fogofwar
4697 "game.save_private_map")) {
4698 /* We have:
4699 * - a dead player;
4700 * - fogged cities are not saved for any reason;
4701 * - a savegame with fog of war turned off;
4702 * - or game.save_private_map is not set to FALSE in the scenario /
4703 * savegame. The players private knowledge is set to be what they could
4704 * see without fog of war. */
4705 whole_map_iterate(&(wld.map), ptile) {
4706 if (map_is_known(ptile, plr)) {
4707 struct city *pcity = tile_city(ptile);
4708
4709 update_player_tile_last_seen(plr, ptile);
4710 update_player_tile_knowledge(plr, ptile);
4711
4712 if (NULL != pcity) {
4713 update_dumb_city(plr, pcity);
4714 }
4715 }
4717
4718 /* Nothing more to do; */
4719 return;
4720 }
4721
4722 /* Load player map (terrain). */
4723 LOAD_MAP_CHAR(ch, ptile,
4724 map_get_player_tile(ptile, plr)->terrain
4725 = char2terrain(ch), loading->file,
4726 "player%d.map_t%04d", plrno);
4727
4728 /* Load player map (resources). */
4729 LOAD_MAP_CHAR(ch, ptile,
4730 map_get_player_tile(ptile, plr)->resource
4731 = char2resource(ch), loading->file,
4732 "player%d.map_res%04d", plrno);
4733
4734 if (loading->version >= 30) {
4735 /* 2.6.0 or newer */
4736
4737 /* Load player map (extras). */
4738 halfbyte_iterate_extras(j, loading->extra.size) {
4739 LOAD_MAP_CHAR(ch, ptile,
4741 ch, loading->extra.order + 4 * j),
4742 loading->file, "player%d.map_e%02d_%04d", plrno, j);
4744 } else {
4745 /* Load player map (specials). */
4747 LOAD_MAP_CHAR(ch, ptile,
4748 sg_special_set(ptile, &map_get_player_tile(ptile, plr)->extras,
4749 ch, loading->special.order + 4 * j, FALSE),
4750 loading->file, "player%d.map_spe%02d_%04d", plrno, j);
4752
4753 /* Load player map (bases). */
4754 halfbyte_iterate_bases(j, loading->base.size) {
4755 LOAD_MAP_CHAR(ch, ptile,
4757 ch, loading->base.order + 4 * j),
4758 loading->file, "player%d.map_b%02d_%04d", plrno, j);
4760
4761 /* Load player map (roads). */
4762 if (loading->version >= 20) {
4763 /* 2.5.0 or newer */
4764 halfbyte_iterate_roads(j, loading->road.size) {
4765 LOAD_MAP_CHAR(ch, ptile,
4767 ch, loading->road.order + 4 * j),
4768 loading->file, "player%d.map_r%02d_%04d", plrno, j);
4770 }
4771 }
4772
4774 /* Load player map (border). */
4775 int x, y;
4776
4777 for (y = 0; y < wld.map.ysize; y++) {
4778 const char *buffer
4779 = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
4780 plrno, y);
4781 const char *buffer2
4782 = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
4783 plrno, y);
4784 const char *ptr = buffer;
4785 const char *ptr2 = buffer2;
4786
4787 sg_failure_ret(NULL != buffer,
4788 "Savegame corrupt - map line %d not found.", y);
4789 for (x = 0; x < wld.map.xsize; x++) {
4790 char token[TOKEN_SIZE];
4791 char token2[TOKEN_SIZE];
4792 int number;
4793 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
4794
4795 scanin(&ptr, ",", token, sizeof(token));
4796 sg_failure_ret('\0' != token[0],
4797 "Savegame corrupt - map size not correct.");
4798 if (strcmp(token, "-") == 0) {
4799 map_get_player_tile(ptile, plr)->owner = NULL;
4800 } else {
4801 sg_failure_ret(str_to_int(token, &number),
4802 "Savegame corrupt - got tile owner=%s in (%d, %d).",
4803 token, x, y);
4804 map_get_player_tile(ptile, plr)->owner = player_by_number(number);
4805 }
4806
4807 if (loading->version >= 30) {
4808 scanin(&ptr2, ",", token2, sizeof(token2));
4809 sg_failure_ret('\0' != token2[0],
4810 "Savegame corrupt - map size not correct.");
4811 if (strcmp(token2, "-") == 0) {
4812 map_get_player_tile(ptile, plr)->extras_owner = NULL;
4813 } else {
4814 sg_failure_ret(str_to_int(token2, &number),
4815 "Savegame corrupt - got extras owner=%s in (%d, %d).",
4816 token, x, y);
4817 map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
4818 }
4819 } else {
4821 = map_get_player_tile(ptile, plr)->owner;
4822 }
4823 }
4824 }
4825 }
4826
4827 /* Load player map (update time). */
4828 for (i = 0; i < 4; i++) {
4829 /* put 4-bit segments of 16-bit "updated" field */
4830 if (i == 0) {
4831 LOAD_MAP_CHAR(ch, ptile,
4832 map_get_player_tile(ptile, plr)->last_updated
4833 = ascii_hex2bin(ch, i),
4834 loading->file, "player%d.map_u%02d_%04d", plrno, i);
4835 } else {
4836 LOAD_MAP_CHAR(ch, ptile,
4837 map_get_player_tile(ptile, plr)->last_updated
4838 |= ascii_hex2bin(ch, i),
4839 loading->file, "player%d.map_u%02d_%04d", plrno, i);
4840 }
4841 }
4842
4843 /* Load player map known cities. */
4844 for (i = 0; i < total_ncities; i++) {
4845 struct vision_site *pdcity;
4846 char buf[32];
4847 fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
4848
4849 pdcity = vision_site_new(0, NULL, NULL);
4850 if (sg_load_player_vision_city(loading, plr, pdcity, buf)) {
4852 pdcity);
4854 } else {
4855 /* Error loading the data. */
4856 log_sg("Skipping seen city %d for player %d.", i, plrno);
4857 if (pdcity != NULL) {
4858 vision_site_destroy(pdcity);
4859 }
4860 }
4861 }
4862
4863 /* Repair inconsistent player maps. */
4864 whole_map_iterate(&(wld.map), ptile) {
4865 if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
4866 struct city *pcity = tile_city(ptile);
4867
4868 update_player_tile_knowledge(plr, ptile);
4869 reality_check_city(plr, ptile);
4870
4871 if (NULL != pcity) {
4872 update_dumb_city(plr, pcity);
4873 }
4874 } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
4875 /* Non fogged borders aren't loaded. See hrm Bug #879084 */
4876 struct player_tile *plrtile = map_get_player_tile(ptile, plr);
4877
4878 plrtile->owner = tile_owner(ptile);
4879 }
4881}
4882
4883/************************************************************************/
4886static bool sg_load_player_vision_city(struct loaddata *loading,
4887 struct player *plr,
4888 struct vision_site *pdcity,
4889 const char *citystr)
4890{
4891 const char *str;
4892 int i, id, size;
4893 citizens city_size;
4894 int nat_x, nat_y;
4895 const char *stylename;
4896 const char *vname;
4897
4898 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x",
4899 citystr),
4900 FALSE, "%s", secfile_error());
4901 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y",
4902 citystr),
4903 FALSE, "%s", secfile_error());
4904 pdcity->location = native_pos_to_tile(&(wld.map), nat_x, nat_y);
4905 sg_warn_ret_val(NULL != pdcity->location, FALSE,
4906 "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
4907
4908 sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
4909 citystr),
4910 FALSE, "%s", secfile_error());
4911 pdcity->owner = player_by_number(id);
4912 sg_warn_ret_val(NULL != pdcity->owner, FALSE,
4913 "%s has invalid owner (%d); skipping.", citystr, id);
4914
4916 "%s.id", citystr),
4917 FALSE, "%s", secfile_error());
4918 sg_warn_ret_val(IDENTITY_NUMBER_ZERO < pdcity->identity, FALSE,
4919 "%s has invalid id (%d); skipping.", citystr, id);
4920
4922 "%s.size", citystr),
4923 FALSE, "%s", secfile_error());
4924 city_size = (citizens)size; /* set the correct type */
4925 sg_warn_ret_val(size == (int)city_size, FALSE,
4926 "Invalid city size: %d; set to %d.", size, city_size);
4927 vision_site_size_set(pdcity, city_size);
4928
4929 /* Initialise list of improvements */
4930 BV_CLR_ALL(pdcity->improvements);
4931 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
4932 sg_warn_ret_val(str != NULL, FALSE, "%s", secfile_error());
4933 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
4934 "Invalid length of '%s.improvements' ("
4935 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
4936 citystr, strlen(str), loading->improvement.size);
4937 for (i = 0; i < loading->improvement.size; i++) {
4938 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
4939 "Undefined value '%c' within '%s.improvements'.",
4940 str[i], citystr)
4941
4942 if (str[i] == '1') {
4943 struct impr_type *pimprove =
4945
4946 if (pimprove) {
4947 BV_SET(pdcity->improvements, improvement_index(pimprove));
4948 }
4949 }
4950 }
4951
4952 vname = secfile_lookup_str_default(loading->file, NULL,
4953 "%s.name", citystr);
4954
4955 if (vname != NULL) {
4956 pdcity->name = fc_strdup(vname);
4957 }
4958
4959 pdcity->occupied = secfile_lookup_bool_default(loading->file, FALSE,
4960 "%s.occupied", citystr);
4961 pdcity->walls = secfile_lookup_bool_default(loading->file, FALSE,
4962 "%s.walls", citystr);
4963 pdcity->happy = secfile_lookup_bool_default(loading->file, FALSE,
4964 "%s.happy", citystr);
4965 pdcity->unhappy = secfile_lookup_bool_default(loading->file, FALSE,
4966 "%s.unhappy", citystr);
4967 stylename = secfile_lookup_str_default(loading->file, NULL,
4968 "%s.style", citystr);
4969 if (stylename != NULL) {
4970 pdcity->style = city_style_by_rule_name(stylename);
4971 } else {
4972 pdcity->style = 0;
4973 }
4974 if (pdcity->style < 0) {
4975 pdcity->style = 0;
4976 }
4977
4978 pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
4979 "%s.city_image", citystr);
4980
4981 pdcity->capital = CAPITAL_NOT;
4982
4983 return TRUE;
4984}
4985
4986/* =======================================================================
4987 * Load the researches.
4988 * ======================================================================= */
4989
4990/************************************************************************/
4993static void sg_load_researches(struct loaddata *loading)
4994{
4995 struct research *presearch;
4996 int count;
4997 int number;
4998 const char *str;
4999 int i, j;
5000
5001 /* Check status and return if not OK (sg_success FALSE). */
5002 sg_check_ret();
5003
5004 /* Initialize all researches. */
5005 researches_iterate(pinitres) {
5006 init_tech(pinitres, FALSE);
5008
5009 /* May be unsaved (e.g. scenario case). */
5010 count = secfile_lookup_int_default(loading->file, 0, "research.count");
5011 for (i = 0; i < count; i++) {
5012 sg_failure_ret(secfile_lookup_int(loading->file, &number,
5013 "research.r%d.number", i),
5014 "%s", secfile_error());
5015 presearch = research_by_number(number);
5016 sg_failure_ret(presearch != NULL,
5017 "Invalid research number %d in 'research.r%d.number'",
5018 number, i);
5019
5020 presearch->tech_goal = technology_load(loading->file,
5021 "research.r%d.goal", i);
5023 &presearch->techs_researched,
5024 "research.r%d.techs", i),
5025 "%s", secfile_error());
5027 &presearch->future_tech,
5028 "research.r%d.futuretech", i),
5029 "%s", secfile_error());
5031 &presearch->bulbs_researched,
5032 "research.r%d.bulbs", i),
5033 "%s", secfile_error());
5035 &presearch->bulbs_researching_saved,
5036 "research.r%d.bulbs_before", i),
5037 "%s", secfile_error());
5038 presearch->researching_saved = technology_load(loading->file,
5039 "research.r%d.saved", i);
5040 presearch->researching = technology_load(loading->file,
5041 "research.r%d.now", i);
5043 &presearch->got_tech,
5044 "research.r%d.got_tech", i),
5045 "%s", secfile_error());
5046
5047 str = secfile_lookup_str(loading->file, "research.r%d.done", i);
5048 sg_failure_ret(str != NULL, "%s", secfile_error());
5049 sg_failure_ret(strlen(str) == loading->technology.size,
5050 "Invalid length of 'research.r%d.done' ("
5051 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5052 i, strlen(str), loading->technology.size);
5053 for (j = 0; j < loading->technology.size; j++) {
5054 sg_failure_ret(str[j] == '1' || str[j] == '0',
5055 "Undefined value '%c' within 'research.r%d.done'.",
5056 str[j], i);
5057
5058 if (str[j] == '1') {
5059 struct advance *padvance =
5061
5062 if (padvance) {
5063 research_invention_set(presearch, advance_number(padvance),
5064 TECH_KNOWN);
5065 }
5066 }
5067 }
5068 }
5069
5070 /* In case of tech_leakage, we can update research only after all the
5071 * researches have been loaded */
5072 researches_iterate(pupres) {
5073 research_update(pupres);
5075}
5076
5077/* =======================================================================
5078 * Load the event cache. Should be the last thing to do.
5079 * ======================================================================= */
5080
5081/************************************************************************/
5084static void sg_load_event_cache(struct loaddata *loading)
5085{
5086 /* Check status and return if not OK (sg_success FALSE). */
5087 sg_check_ret();
5088
5089 event_cache_load(loading->file, "event_cache");
5090}
5091
5092/* =======================================================================
5093 * Load the open treaties
5094 * ======================================================================= */
5095
5096/************************************************************************/
5099static void sg_load_treaties(struct loaddata *loading)
5100{
5101 int tidx;
5102 const char *plr0;
5103 struct treaty_list *treaties = get_all_treaties();
5104
5105 /* Check status and return if not OK (sg_success FALSE). */
5106 sg_check_ret();
5107
5108 for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, NULL,
5109 "treaty%d.plr0", tidx)) != NULL ;
5110 tidx++) {
5111 const char *plr1;
5112 const char *ct;
5113 int cidx;
5114 struct player *p0, *p1;
5115
5116 plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
5117
5118 p0 = player_by_name(plr0);
5119 p1 = player_by_name(plr1);
5120
5121 if (p0 == NULL || p1 == NULL) {
5122 log_error("Treaty between unknown players %s and %s", plr0, plr1);
5123 } else {
5124 struct Treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
5125
5126 init_treaty(ptreaty, p0, p1);
5127 treaty_list_prepend(treaties, ptreaty);
5128
5129 for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, NULL,
5130 "treaty%d.clause%d.type",
5131 tidx, cidx)) != NULL ;
5132 cidx++ ) {
5133 enum clause_type type = clause_type_by_name(ct, fc_strcasecmp);
5134 const char *plrx;
5135
5136 if (!clause_type_is_valid(type)) {
5137 log_error("Invalid clause type \"%s\"", ct);
5138 } else {
5139 struct player *pgiver = NULL;
5140
5141 plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
5142 tidx, cidx);
5143
5144 if (!fc_strcasecmp(plrx, plr0)) {
5145 pgiver = p0;
5146 } else if (!fc_strcasecmp(plrx, plr1)) {
5147 pgiver = p1;
5148 } else {
5149 log_error("Clause giver %s is not participant of the treaty"
5150 "between %s and %s", plrx, plr0, plr1);
5151 }
5152
5153 if (pgiver != NULL) {
5154 int value;
5155
5156 value = secfile_lookup_int_default(loading->file, 0,
5157 "treaty%d.clause%d.value",
5158 tidx, cidx);
5159
5160 add_clause(ptreaty, pgiver, type, value, NULL);
5161 }
5162 }
5163 }
5164
5165 /* These must be after clauses have been added so that acceptance
5166 * does not get cleared by what seems like changes to the treaty. */
5167 ptreaty->accept0 = secfile_lookup_bool_default(loading->file, FALSE,
5168 "treaty%d.accept0", tidx);
5169 ptreaty->accept1 = secfile_lookup_bool_default(loading->file, FALSE,
5170 "treaty%d.accept1", tidx);
5171 }
5172 }
5173}
5174
5175/* =======================================================================
5176 * Load the history report
5177 * ======================================================================= */
5178
5179/************************************************************************/
5182static void sg_load_history(struct loaddata *loading)
5183{
5184 struct history_report *hist = history_report_get();
5185 int turn;
5186
5187 /* Check status and return if not OK (sg_success FALSE). */
5188 sg_check_ret();
5189
5190 turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
5191
5192 if (turn != -2) {
5193 hist->turn = turn;
5194 }
5195
5196 if (turn + 1 >= game.info.turn) {
5197 const char *str;
5198
5199 str = secfile_lookup_str(loading->file, "history.title");
5200 sg_failure_ret(str != NULL, "%s", secfile_error());
5201 sz_strlcpy(hist->title, str);
5202 str = secfile_lookup_str(loading->file, "history.body");
5203 sg_failure_ret(str != NULL, "%s", secfile_error());
5204 sz_strlcpy(hist->body, str);
5205 }
5206}
5207
5208/* =======================================================================
5209 * Load the mapimg definitions.
5210 * ======================================================================= */
5211
5212/************************************************************************/
5215static void sg_load_mapimg(struct loaddata *loading)
5216{
5217 int mapdef_count, i;
5218
5219 /* Check status and return if not OK (sg_success FALSE). */
5220 sg_check_ret();
5221
5222 /* Clear all defined map images. */
5223 while (mapimg_count() > 0) {
5224 mapimg_delete(0);
5225 }
5226
5227 mapdef_count = secfile_lookup_int_default(loading->file, 0,
5228 "mapimg.count");
5229 log_verbose("Saved map image definitions: %d.", mapdef_count);
5230
5231 if (0 >= mapdef_count) {
5232 return;
5233 }
5234
5235 for (i = 0; i < mapdef_count; i++) {
5236 const char *p;
5237
5238 p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
5239 if (NULL == p) {
5240 log_verbose("[Mapimg %4d] Missing definition.", i);
5241 continue;
5242 }
5243
5244 if (!mapimg_define(p, FALSE)) {
5245 log_error("Invalid map image definition %4d: %s.", i, p);
5246 }
5247
5248 log_verbose("Mapimg %4d loaded.", i);
5249 }
5250}
5251
5252/* =======================================================================
5253 * Sanity checks for loading a game.
5254 * ======================================================================= */
5255
5256/************************************************************************/
5259static void sg_load_sanitycheck(struct loaddata *loading)
5260{
5261 int players;
5262
5263 /* Check status and return if not OK (sg_success FALSE). */
5264 sg_check_ret();
5265
5266 if (game.info.is_new_game) {
5267 /* Nothing to do for new games (or not started scenarios). */
5268 return;
5269 }
5270
5271 /* Old savegames may have maxplayers lower than current player count,
5272 * fix. */
5273 players = normal_player_count();
5274 if (game.server.max_players < players) {
5275 log_verbose("Max players lower than current players, fixing");
5276 game.server.max_players = players;
5277 }
5278
5279 /* Fix ferrying sanity */
5280 players_iterate(pplayer) {
5281 unit_list_iterate_safe(pplayer->units, punit) {
5284 log_sg("Removing %s unferried %s in %s at (%d, %d)",
5290 }
5293
5294 /* Fix stacking issues. We don't rely on the savegame preserving
5295 * alliance invariants (old savegames often did not) so if there are any
5296 * unallied units on the same tile we just bounce them. */
5297 players_iterate(pplayer) {
5298 players_iterate(aplayer) {
5299 resolve_unit_stacks(pplayer, aplayer, TRUE);
5302
5303 /* Recalculate the potential buildings for each city. Has caused some
5304 * problems with game random state.
5305 * This also changes the game state if you save the game directly after
5306 * loading it and compare the results. */
5307 players_iterate(pplayer) {
5308 /* Building advisor needs data phase open in order to work */
5309 adv_data_phase_init(pplayer, FALSE);
5310 building_advisor(pplayer);
5311 /* Close data phase again so it can be opened again when game starts. */
5312 adv_data_phase_done(pplayer);
5314
5315 /* Prevent a buggy or intentionally crafted save game from crashing
5316 * Freeciv. See hrm Bug #887748 */
5317 players_iterate(pplayer) {
5318 city_list_iterate(pplayer->cities, pcity) {
5319 worker_task_list_iterate(pcity->task_reqs, ptask) {
5320 if (!worker_task_is_sane(ptask)) {
5321 log_error("[city id: %d] Bad worker task %d.",
5322 pcity->id, ptask->act);
5323 worker_task_list_remove(pcity->task_reqs, ptask);
5324 free(ptask);
5325 ptask = NULL;
5326 }
5330
5331 /* Check worked tiles map */
5332#ifdef FREECIV_DEBUG
5333 if (loading->worked_tiles != NULL) {
5334 /* check the entire map for unused worked tiles */
5335 whole_map_iterate(&(wld.map), ptile) {
5336 if (loading->worked_tiles[ptile->index] != -1) {
5337 log_error("[city id: %d] Unused worked tile at (%d, %d).",
5338 loading->worked_tiles[ptile->index], TILE_XY(ptile));
5339 }
5341 }
5342#endif /* FREECIV_DEBUG */
5343
5344 /* Check researching technologies and goals. */
5345 researches_iterate(presearch) {
5346 int techs;
5347
5348 if (presearch->researching != A_UNSET
5349 && !is_future_tech(presearch->researching)
5350 && (valid_advance_by_number(presearch->researching) == NULL
5351 || (research_invention_state(presearch, presearch->researching)
5352 != TECH_PREREQS_KNOWN))) {
5353 log_sg(_("%s had invalid researching technology."),
5354 research_name_translation(presearch));
5355 presearch->researching = A_UNSET;
5356 }
5357 if (presearch->tech_goal != A_UNSET
5358 && !is_future_tech(presearch->tech_goal)
5359 && (valid_advance_by_number(presearch->tech_goal) == NULL
5360 || !research_invention_reachable(presearch, presearch->tech_goal)
5361 || (research_invention_state(presearch, presearch->tech_goal)
5362 == TECH_KNOWN))) {
5363 log_sg(_("%s had invalid technology goal."),
5364 research_name_translation(presearch));
5365 presearch->tech_goal = A_UNSET;
5366 }
5367
5369
5370 if (presearch->techs_researched != techs) {
5371 sg_regr(3000300,
5372 _("%s had finished researches count wrong."),
5373 research_name_translation(presearch));
5374 presearch->techs_researched = techs;
5375 }
5377
5378 players_iterate(pplayer) {
5379 unit_list_iterate_safe(pplayer->units, punit) {
5380 if (punit->has_orders
5382 punit->orders.list)) {
5383 log_sg("Invalid unit orders for unit %d.", punit->id);
5385 }
5388
5389 /* Check max rates (rules may have changed since saving) */
5390 players_iterate(pplayer) {
5393
5394 if (0 == strlen(server.game_identifier)
5395 || !is_base64url(server.game_identifier)) {
5396 /* This uses fc_rand(), so random state has to be initialized before. */
5397 randomize_base64url_string(server.game_identifier,
5398 sizeof(server.game_identifier));
5399 }
5400
5401 /* Check if some player has more than one of some UTYF_UNIQUE unit type */
5402 players_iterate(pplayer) {
5403 int unique_count[U_LAST];
5404
5405 memset(unique_count, 0, sizeof(unique_count));
5406
5407 unit_list_iterate(pplayer->units, punit) {
5408 unique_count[utype_index(unit_type_get(punit))]++;
5410
5411 unit_type_iterate(ut) {
5412 if (unique_count[utype_index(ut)] > 1 && utype_has_flag(ut, UTYF_UNIQUE)) {
5413 log_sg(_("%s has multiple units of type %s though it should be possible "
5414 "to have only one."),
5415 player_name(pplayer), utype_name_translation(ut));
5416 }
5419
5420 /* Restore game random state, just in case various initialization code
5421 * inexplicably altered the previously existing state. */
5422 if (!game.info.is_new_game) {
5423 fc_rand_set_state(loading->rstate);
5424
5425 if (loading->version < 30) {
5426 /* For older savegames we have to recalculate the score with current data,
5427 * instead of using beginning-of-turn saved scores. */
5428 players_iterate(pplayer) {
5429 calc_civ_score(pplayer);
5431 }
5432 }
5433
5434 /* At the end do the default sanity checks. */
5435 sanity_check();
5436}
struct achievement * achievement_by_rule_name(const char *name)
#define ACTION_NONE
Definition actions.h:295
void building_advisor(struct player *pplayer)
bool adv_data_phase_init(struct player *pplayer, bool is_new_phase)
Definition advdata.c:262
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:553
const char * ai_name(const struct ai_type *ai)
Definition ai.c:329
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:384
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:374
void ai_traits_init(struct player *pplayer)
Definition aitraits.c:32
#define str
Definition astring.c:76
Base_type_id base_number(const struct base_type *pbase)
Definition base.c:92
struct extra_type * base_extra_get(const struct base_type *pbase)
Definition base.c:101
struct base_type * get_base_by_gui_type(enum base_gui_type type, const struct unit *punit, const struct tile *ptile)
Definition base.c:139
struct base_type * base_by_number(const Base_type_id id)
Definition base.c:76
void dbv_clr_all(struct dbv *pdbv)
Definition bitvector.c:179
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_CLR(bv, bit)
Definition bitvector.h:86
bool has_capability(const char *cap, const char *capstr)
Definition capability.c:77
void citizens_nation_set(struct city *pcity, const struct player_slot *pslot, citizens count)
Definition citizens.c:145
citizens citizens_count(const struct city *pcity)
Definition citizens.c:162
void citizens_init(struct city *pcity)
Definition citizens.c:32
void citizens_update(struct city *pcity, struct player *plr)
void city_map_radius_sq_set(struct city *pcity, int radius_sq)
Definition city.c:143
void city_name_set(struct city *pcity, const char *new_name)
Definition city.c:1123
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3343
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2772
void city_size_set(struct city *pcity, citizens size)
Definition city.c:1158
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3270
void destroy_city_virtual(struct city *pcity)
Definition city.c:3419
int city_style_by_rule_name(const char *s)
Definition city.c:1711
#define cities_iterate_end
Definition city.h:497
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
#define cities_iterate(pcity)
Definition city.h:492
#define CITY_MAP_MAX_RADIUS_SQ
Definition city.h:78
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
#define output_type_iterate(output)
Definition city.h:821
#define city_owner(_pcity_)
Definition city.h:543
#define FREE_WORKED_TILES
Definition city.h:858
#define MAX_CITY_SIZE
Definition city.h:98
#define city_list_iterate_end
Definition city.h:490
#define I_NEVER
Definition city.h:239
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:222
#define city_tile_iterate_end
Definition city.h:230
#define output_type_iterate_end
Definition city.h:827
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2683
bool send_city_suppression(bool now)
Definition citytools.c:2143
static void void city_freeze_workers(struct city *pcity)
Definition citytools.c:135
void city_thaw_workers(struct city *pcity)
Definition citytools.c:145
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2751
void city_refresh_vision(struct city *pcity)
Definition citytools.c:3338
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:369
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:897
bool city_refresh(struct city *pcity)
Definition cityturn.c:161
static char * ruleset
Definition civmanual.c:206
char * techs
Definition comments.c:30
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:2819
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2840
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Definition difficulty.c:39
static struct treaty_list * treaties
Definition diplhand.c:58
struct treaty_list * get_all_treaties(void)
Definition diplhand.c:986
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Definition diptreaty.c:96
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val, struct player *client_player)
Definition diptreaty.c:142
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:740
struct extra_type * extra_type_by_rule_name(const char *name)
Definition extras.c:204
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1068
int extra_number(const struct extra_type *pextra)
Definition extras.c:153
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:765
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:195
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_index(_e_)
Definition extras.h:177
#define EXTRA_NONE
Definition extras.h:82
#define extra_base_get(_e_)
Definition extras.h:184
#define extra_road_get(_e_)
Definition extras.h:185
#define extra_type_by_cause_iterate_end
Definition extras.h:315
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:309
#define NO_TARGET
Definition fc_types.h:324
#define MAX_TRADE_ROUTES
Definition fc_types.h:1111
@ ROCO_RAILROAD
Definition fc_types.h:1105
@ ROCO_RIVER
Definition fc_types.h:1105
@ ROCO_ROAD
Definition fc_types.h:1105
int Tech_type_id
Definition fc_types.h:347
unsigned char citizens
Definition fc_types.h:358
@ RPT_POSSIBLE
Definition fc_types.h:585
int Multiplier_type_id
Definition fc_types.h:356
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:82
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
void initialize_globals(void)
Definition game.c:663
struct city * game_city_by_number(int id)
Definition game.c:102
#define GAME_DEFAULT_TIMEOUTINTINC
Definition game.h:576
#define GAME_DEFAULT_SCORETURN
Definition game.h:560
#define GAME_DEFAULT_TIMEOUTINT
Definition game.h:575
#define GAME_DEFAULT_TIMEOUTINCMULT
Definition game.h:578
#define GAME_DEFAULT_TIMEOUTINC
Definition game.h:577
#define GAME_DEFAULT_RULESETDIR
Definition game.h:654
#define GAME_DEFAULT_TIMEOUTCOUNTER
Definition game.h:580
#define GAME_DEFAULT_PHASE_MODE
Definition game.h:595
#define GAME_HARDCODED_DEFAULT_SKILL_LEVEL
Definition game.h:676
struct government * government_by_rule_name(const char *name)
Definition government.c:54
struct city * owner
Definition citydlg.c:219
GType type
Definition repodlgs.c:1312
void idex_register_unit(struct world *iworld, struct unit *punit)
Definition idex.c:81
void idex_register_city(struct world *iworld, struct city *pcity)
Definition idex.c:66
Impr_type_id improvement_index(const struct impr_type *pimprove)
struct impr_type * improvement_by_rule_name(const char *name)
#define WONDER_DESTROYED
#define WONDER_LOST
void adv_city_free(struct city *pcity)
Definition infracache.c:501
void adv_city_alloc(struct city *pcity)
Definition infracache.c:488
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define log_fatal(message,...)
Definition log.h:100
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1463
#define nat_x
#define nat_y
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:639
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1669
void map_init_topology(struct civ_map *nmap)
Definition map.c:301
void main_map_allocate(void)
Definition map.c:517
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
int map_startpos_count(void)
Definition map.c:1656
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:441
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1446
#define MAP_INDEX_SIZE
Definition map.h:131
#define whole_map_iterate(_map, _tile)
Definition map.h:539
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:151
#define whole_map_iterate_end
Definition map.h:548
@ MAPGEN_SCENARIO
Definition map_types.h:47
void assign_continent_numbers(void)
void player_map_init(struct player *pplayer)
Definition maphand.c:1202
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1455
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2191
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:886
bool send_tile_suppression(bool now)
Definition maphand.c:472
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:342
void map_know_and_see_all(struct player *pplayer)
Definition maphand.c:1177
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1386
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2204
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1159
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:900
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1140
void map_calculate_borders(void)
Definition maphand.c:2357
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1620
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1370
bool mapimg_define(const char *maparg, bool check)
Definition mapimg.c:768
bool mapimg_delete(int id)
Definition mapimg.c:1203
int mapimg_count(void)
Definition mapimg.c:572
#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:171
const char * default_meta_patches_string(void)
Definition meta.c:82
#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:336
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:137
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
struct nation_type * nation_by_rule_name(const char *name)
Definition nation.c:120
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:177
#define NO_NATION_SELECTED
Definition nation.h:29
void event_cache_load(struct section_file *file, const char *section)
Definition notify.c:783
int parts
Definition packhand.c:130
char * lines
Definition packhand.c:129
int len
Definition packhand.c:125
bool player_slot_is_used(const struct player_slot *pslot)
Definition player.c:441
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
struct player * player_by_number(const int player_id)
Definition player.c:840
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1452
int player_count(void)
Definition player.c:808
int player_slot_count(void)
Definition player.c:411
struct player_slot * player_slot_by_number(int player_id)
Definition player.c:456
int player_number(const struct player *pplayer)
Definition player.c:828
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Definition player.c:153
const char * player_name(const struct player *pplayer)
Definition player.c:886
int player_slot_max_used_number(void)
Definition player.c:469
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
int player_slot_index(const struct player_slot *pslot)
Definition player.c:419
struct player * player_by_name(const char *name)
Definition player.c:872
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1179
int player_index(const struct player *pplayer)
Definition player.c:820
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Definition player.c:852
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:317
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
struct player_slot * slots
Definition player.c:50
#define players_iterate_end
Definition player.h:535
dipl_reason
Definition player.h:194
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition player.h:196
@ DIPL_ALLIANCE_PROBLEM_US
Definition player.h:196
#define players_iterate(_pplayer)
Definition player.h:530
#define MAX_ATTRIBUTE_BLOCK
Definition player.h:225
#define player_list_iterate(playerlist, pplayer)
Definition player.h:553
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define player_slots_iterate(_pslot)
Definition player.h:521
#define is_ai(plr)
Definition player.h:234
#define player_list_iterate_end
Definition player.h:555
#define players_iterate_alive_end
Definition player.h:545
#define player_slots_iterate_end
Definition player.h:525
#define players_iterate_alive(_pplayer)
Definition player.h:540
void server_player_set_name(struct player *pplayer, const char *name)
Definition plrhand.c:2098
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Definition plrhand.c:1724
int normal_player_count(void)
Definition plrhand.c:3035
void player_limit_to_max_rates(struct player *pplayer)
Definition plrhand.c:1887
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:2283
void set_shuffled_players(int *shuffled_players)
Definition plrhand.c:2233
void player_delegation_set(struct player *pplayer, const char *username)
Definition plrhand.c:3081
void shuffle_players(void)
Definition plrhand.c:2208
void server_remove_player(struct player *pplayer)
Definition plrhand.c:1773
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Definition plrhand.c:1451
void assign_player_colors(void)
Definition plrhand.c:1564
void fit_nationset_to_players(void)
Definition plrhand.c:2489
RANDOM_STATE fc_rand_state(void)
Definition rand.c:175
void fc_rand_set_state(RANDOM_STATE state)
Definition rand.c:196
const char * secfile_error(void)
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
struct section * secfile_section_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
#define secfile_lookup_enum_default(secfile, defval, specenum_type, path,...)
#define secfile_entry_ignore(_sfile_, _fmt_,...)
struct history_report * history_report_get(void)
Definition report.c:1689
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
struct universal universal_by_rule_name(const char *kind, const char *value)
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c:665
const char * research_name_translation(const struct research *presearch)
Definition research.c:154
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:634
struct research * research_by_number(int number)
Definition research.c:116
int recalculate_techs_researched(const struct research *presearch)
Definition research.c:1318
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
void research_update(struct research *presearch)
Definition research.c:499
#define researches_iterate(_presearch)
Definition research.h:157
#define researches_iterate_end
Definition research.h:160
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Definition rgbcolor.c:74
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, char *path,...)
Definition rgbcolor.c:90
struct extra_type * road_extra_get(const struct road_type *proad)
Definition road.c:42
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
struct road_type * road_by_number(Road_type_id id)
Definition road.c:58
struct road_type * road_by_compat_special(enum road_compat compat)
Definition road.c:160
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Definition ruleset.c:9231
#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:300
void set_unit_activity_road(struct unit *punit, Road_type_id road)
int char2num(char ch)
Definition savecompat.c:245
void sg_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:132
enum ai_level ai_level_convert(int old_level)
void set_unit_activity_base(struct unit *punit, Base_type_id base)
int ascii_hex2bin(char ch, int halfbyte)
Definition savecompat.c:221
struct extra_type * special_extra_get(int spe)
Definition savecompat.c:286
enum tile_special_type special_by_rule_name(const char *name)
Definition savecompat.c:260
void sg_load_post_load_compat(struct loaddata *loading, enum sgf_version format_class)
Definition savecompat.c:177
const char * special_rule_name(enum tile_special_type type)
Definition savecompat.c:276
#define sg_check_ret(...)
Definition savecompat.h:141
#define sg_warn(condition, message,...)
Definition savecompat.h:151
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:196
#define sg_failure_ret_val(condition, _val, message,...)
Definition savecompat.h:175
#define sg_failure_ret(condition, message,...)
Definition savecompat.h:168
#define sg_regr(fixversion, message,...)
Definition savecompat.h:184
@ SAVEGAME_2
Definition savecompat.h:27
#define log_sg
Definition savecompat.h:137
#define sg_warn_ret_val(condition, _val, message,...)
Definition savecompat.h:162
static void unit_ordering_apply(void)
Definition savegame2.c:795
static void sg_load_players_basic(struct loaddata *loading)
Definition savegame2.c:2406
static struct loaddata * loaddata_new(struct section_file *file)
Definition savegame2.c:456
static void sg_load_map_known(struct loaddata *loading)
Definition savegame2.c:2341
#define halfbyte_iterate_roads_end
Definition savegame2.c:274
static struct extra_type * char2resource(char c)
Definition savegame2.c:1043
static void sg_load_map_owner(struct loaddata *loading)
Definition savegame2.c:2210
static void sg_extras_set(bv_extras *extras, char ch, struct extra_type **idx)
Definition savegame2.c:816
bool sg_success
Definition savecompat.c:32
static void sg_bases_set(bv_extras *extras, char ch, struct base_type **idx)
Definition savegame2.c:985
#define halfbyte_iterate_extras_end
Definition savegame2.c:244
static void sg_load_map_tiles_roads(struct loaddata *loading)
Definition savegame2.c:2049
#define halfbyte_iterate_extras(e, num_extras_types)
Definition savegame2.c:239
static void sg_load_map(struct loaddata *loading)
Definition savegame2.c:1893
static enum unit_orders char2order(char order)
Definition savegame2.c:555
static int unquote_block(const char *const quoted_, void *dest, int dest_length)
Definition savegame2.c:701
#define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath,...)
Definition savegame2.c:203
static void sg_load_player_city_citizens(struct loaddata *loading, struct player *plr, struct city *pcity, const char *citystr)
Definition savegame2.c:3741
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3348
static void sg_load_map_tiles(struct loaddata *loading)
Definition savegame2.c:1978
static char activity2char(enum unit_activity activity)
Definition savegame2.c:623
static void sg_load_savefile(struct loaddata *loading)
Definition savegame2.c:1154
static enum unit_activity char2activity(char activity)
Definition savegame2.c:680
static bool sg_load_player_unit(struct loaddata *loading, struct player *plr, struct unit *punit, const char *unitstr)
Definition savegame2.c:3908
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:3468
static void sg_load_settings(struct loaddata *loading)
Definition savegame2.c:1873
static void sg_load_player_units(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3789
#define halfbyte_iterate_special(s, num_specials_types)
Definition savegame2.c:249
void savegame2_load(struct section_file *file)
Definition savegame2.c:387
static void sg_load_researches(struct loaddata *loading)
Definition savegame2.c:4993
#define halfbyte_iterate_bases_end
Definition savegame2.c:264
static void sg_load_map_worked(struct loaddata *loading)
Definition savegame2.c:2297
static void sg_load_random(struct loaddata *loading)
Definition savegame2.c:1704
#define halfbyte_iterate_special_end
Definition savegame2.c:254
#define halfbyte_iterate_bases(b, num_bases_types)
Definition savegame2.c:259
static void sg_load_player_units_transport(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4533
static void sg_load_history(struct loaddata *loading)
Definition savegame2.c:5182
#define ORDER_OLD_BUILD_WONDER
Definition savegame2.c:282
static void sg_load_map_tiles_specials(struct loaddata *loading, bool rivers_overlay)
Definition savegame2.c:2065
#define TOKEN_SIZE
Definition savegame2.c:278
static void sg_load_script(struct loaddata *loading)
Definition savegame2.c:1763
static void sg_load_scenario(struct loaddata *loading)
Definition savegame2.c:1778
static void sg_load_ruleset(struct loaddata *loading)
Definition savegame2.c:1120
static void sg_load_game(struct loaddata *loading)
Definition savegame2.c:1535
static void sg_load_player_main(struct loaddata *loading, struct player *plr)
Definition savegame2.c:2854
static void sg_load_treaties(struct loaddata *loading)
Definition savegame2.c:5099
static void sg_roads_set(bv_extras *extras, char ch, struct road_type **idx)
Definition savegame2.c:1016
static Tech_type_id technology_load(struct section_file *file, const char *path, int plrno)
Definition savegame2.c:1080
static enum direction8 char2dir(char dir)
Definition savegame2.c:594
static void sg_load_map_tiles_resources(struct loaddata *loading)
Definition savegame2.c:2096
#define ORDER_OLD_BUILD_CITY
Definition savegame2.c:280
static struct terrain * char2terrain(char ch)
Definition savegame2.c:1058
#define ORDER_OLD_DISBAND
Definition savegame2.c:281
static void sg_load_mapimg(struct loaddata *loading)
Definition savegame2.c:5215
#define ORDER_OLD_HOMECITY
Definition savegame2.c:284
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4586
static void sg_load_ruledata(struct loaddata *loading)
Definition savegame2.c:1511
static void sg_load_player_vision(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4666
static void worklist_load(struct section_file *file, int wlist_max_length, struct worklist *pwl, const char *path,...)
Definition savegame2.c:749
static bool sg_load_player_vision_city(struct loaddata *loading, struct player *plr, struct vision_site *pdcity, const char *citystr)
Definition savegame2.c:4886
static void sg_load_map_startpos(struct loaddata *loading)
Definition savegame2.c:2123
static void loaddata_destroy(struct loaddata *loading)
Definition savegame2.c:495
static void sg_load_players(struct loaddata *loading)
Definition savegame2.c:2663
#define ORDER_OLD_TRADE_ROUTE
Definition savegame2.c:283
static void sg_load_map_tiles_extras(struct loaddata *loading)
Definition savegame2.c:2018
static void sg_load_sanitycheck(struct loaddata *loading)
Definition savegame2.c:5259
static void sg_load_event_cache(struct loaddata *loading)
Definition savegame2.c:5084
static void sg_load_map_tiles_bases(struct loaddata *loading)
Definition savegame2.c:2033
static void sg_special_set(struct tile *ptile, bv_extras *extras, char ch, const enum tile_special_type *idx, bool rivers_overlay)
Definition savegame2.c:848
static int sg_order_to_action(int order, struct unit *act_unit, struct tile *tgt_tile)
Definition savegame2.c:3867
#define halfbyte_iterate_roads(r, num_roads_types)
Definition savegame2.c:269
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:4648
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
bool str_to_int(const char *str, int *pint)
Definition shared.c:512
bool is_base64url(const char *s)
Definition shared.c:317
char scanin(const char **buf, char *delimiters, char *dest, int size)
Definition shared.c:1912
void randomize_base64url_string(char *s, size_t n)
Definition shared.c:338
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MAX(x, y)
Definition shared.h:54
void spaceship_calc_derived(struct player_spaceship *ship)
Definition spacerace.c:45
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
void server_game_init(bool keep_ruleset_value)
Definition srv_main.c:3382
const char * aifill(int amount)
Definition srv_main.c:2395
bool game_was_started(void)
Definition srv_main.c:339
void identity_number_reserve(int id)
Definition srv_main.c:1926
struct server_arguments srvarg
Definition srv_main.c:173
void init_game_seed(void)
Definition srv_main.c:200
void update_nations_with_startpos(void)
Definition srv_main.c:2200
void server_game_free(void)
Definition srv_main.c:3406
int x
Definition rand.h:30
RANDOM_TYPE v[56]
Definition rand.h:29
int k
Definition rand.h:30
bool is_init
Definition rand.h:31
int j
Definition rand.h:30
bool accept0
Definition diptreaty.h:78
bool accept1
Definition diptreaty.h:78
struct player * first
bv_player achievers
int val
Definition traits.h:38
int mod
Definition traits.h:39
int turn
Definition city.h:238
Definition city.h:309
struct worker_task_list * task_reqs
Definition city.h:395
int turn_last_built
Definition city.h:373
int food_stock
Definition city.h:354
struct built_status built[B_LAST]
Definition city.h:380
struct player * original
Definition city.h:313
int history
Definition city.h:393
bool did_sell
Definition city.h:367
int id
Definition city.h:315
int last_turns_shield_surplus
Definition city.h:378
int disbanded_shields
Definition city.h:377
int turn_plague
Definition city.h:361
bv_city_options city_options
Definition city.h:389
bool was_happy
Definition city.h:368
int turn_founded
Definition city.h:372
int airlift
Definition city.h:365
int caravan_shields
Definition city.h:376
bool did_buy
Definition city.h:366
struct trade_route_list * routes
Definition city.h:332
int anarchy
Definition city.h:370
struct worklist worklist
Definition city.h:387
struct universal production
Definition city.h:382
citizens * nationality
Definition city.h:329
int steal
Definition city.h:397
int before_change_shields
Definition city.h:375
int style
Definition city.h:316
bool synced
Definition city.h:431
citizens specialists[SP_MAX]
Definition city.h:324
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
struct vision * vision
Definition city.h:438
struct city::@17::@19 server
struct universal changed_from
Definition city.h:385
struct unit_list * units_supported
Definition city.h:391
int rapture
Definition city.h:371
bool last_updated_year
Definition game.h:234
struct civ_game::@30::@34 server
float turn_change_time
Definition game.h:217
bool vision_reveal_tiles
Definition game.h:199
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:232
struct packet_game_info info
Definition game.h:89
int timeoutcounter
Definition game.h:206
char rulesetdir[MAX_LEN_NAME]
Definition game.h:236
int scoreturn
Definition game.h:223
randseed seed
Definition game.h:225
struct packet_scenario_info scenario
Definition game.h:87
int timeoutint
Definition game.h:202
unsigned revealmap
Definition game.h:176
bool foggedborders
Definition game.h:146
int timeoutincmult
Definition game.h:204
int timeoutinc
Definition game.h:203
int phase_mode_stored
Definition game.h:215
int max_players
Definition game.h:155
int timeoutintinc
Definition game.h:205
int xsize
Definition map_types.h:77
randseed seed
Definition map_types.h:89
int ysize
Definition map_types.h:77
bool have_resources
Definition map_types.h:107
struct civ_map::@41::@43 server
bool have_huts
Definition map_types.h:106
enum map_generator generator
Definition map_types.h:95
int changed_to_times
Definition government.h:61
char title[REPORT_TITLESIZE]
Definition report.h:27
char body[REPORT_BODYSIZE]
Definition report.h:28
const char * secfile_options
Definition savecompat.h:49
int version
Definition savecompat.h:50
RANDOM_STATE rstate
Definition savecompat.h:131
struct loaddata::@107 road
struct loaddata::@106 base
struct loaddata::@104 multiplier
int full_version
Definition savecompat.h:51
size_t size
Definition savecompat.h:56
struct loaddata::@109 ds_t
struct loaddata::@105 special
enum server_states server_state
Definition savecompat.h:128
struct loaddata::@100 technology
struct loaddata::@108 specialist
const char ** order
Definition savecompat.h:55
struct loaddata::@101 activities
struct loaddata::@102 trait
struct loaddata::@99 improvement
int * worked_tiles
Definition savecompat.h:134
struct loaddata::@103 extra
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:122
struct ai_trait * traits
Definition player.h:132
enum barbarian_type barbarian_type
Definition player.h:128
int science_cost
Definition player.h:125
int love[MAX_NUM_PLAYER_SLOTS]
Definition player.h:130
int expand
Definition player.h:124
int fuzzy
Definition player.h:123
char contact_turns_left
Definition player.h:206
int first_contact_turn
Definition player.h:203
enum diplstate_type max_state
Definition player.h:202
enum diplstate_type type
Definition player.h:201
char has_reason_to_cancel
Definition player.h:205
int units_killed
Definition player.h:112
int landarea
Definition player.h:101
int population
Definition player.h:103
int pollution
Definition player.h:106
int wonders
Definition player.h:98
int settledarea
Definition player.h:102
int specialists[SP_MAX]
Definition player.h:97
int units_lost
Definition player.h:113
int angry
Definition player.h:96
int techout
Definition player.h:100
int units_built
Definition player.h:111
int content
Definition player.h:94
int happy
Definition player.h:93
int spaceship
Definition player.h:110
int culture
Definition player.h:115
int unhappy
Definition player.h:95
int literacy
Definition player.h:107
int techs
Definition player.h:99
bv_spaceship_structure structure
Definition spaceship.h:100
enum spaceship_state state
Definition spaceship.h:108
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
bool got_first_city
Definition player.h:320
int wonders[B_LAST]
Definition player.h:301
bool unassigned_ranked
Definition player.h:255
struct government * target_government
Definition player.h:259
char username[MAX_LEN_NAME]
Definition player.h:252
int revolution_finishes
Definition player.h:273
int nturns_idle
Definition player.h:265
struct government * government
Definition player.h:258
struct team * team
Definition player.h:261
int turns_alive
Definition player.h:266
struct unit_list * units
Definition player.h:282
char ranked_username[MAX_LEN_NAME]
Definition player.h:254
int huts
Definition player.h:349
bool is_alive
Definition player.h:268
bv_player real_embassy
Definition player.h:277
struct player_economic economic
Definition player.h:284
struct player_spaceship spaceship
Definition player.h:286
struct attribute_block_s attribute_block
Definition player.h:303
struct player_score score
Definition player.h:283
struct multiplier_value multipliers[MAX_NUM_MULTIPLIERS]
Definition player.h:310
struct nation_type * nation
Definition player.h:260
struct nation_style * style
Definition player.h:279
bool border_vision
Definition player.h:327
bool phase_done
Definition player.h:263
struct player::@69::@71 server
int history
Definition player.h:312
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
Tech_type_id researching
Definition research.h:52
int future_tech
Definition research.h:42
Tech_type_id tech_goal
Definition research.h:85
int bulbs_researching_saved
Definition research.h:63
Tech_type_id researching_saved
Definition research.h:62
bool got_tech
Definition research.h:67
int techs_researched
Definition research.h:42
int bulbs_researched
Definition research.h:53
char metaserver_addr[256]
Definition srv_main.h:29
char serverid[256]
Definition srv_main.h:49
Definition map.c:41
Definition team.c:40
int road_time
Definition terrain.h:201
int mining_time
Definition terrain.h:213
char identifier_load
Definition terrain.h:185
int irrigation_time
Definition terrain.h:210
int base_time
Definition terrain.h:200
Definition tile.h:49
int index
Definition tile.h:50
bv_extras extras
Definition tile.h:54
struct unit_list * units
Definition tile.h:57
struct tile * claimer
Definition tile.h:63
enum route_direction dir
Definition traderoutes.h:86
struct goods_type * goods
Definition traderoutes.h:87
enum unit_orders order
Definition unit.h:93
Definition unit.h:138
int length
Definition unit.h:195
int upkeep[O_LAST]
Definition unit.h:148
bool has_orders
Definition unit.h:193
enum action_decision action_decision_want
Definition unit.h:202
int battlegroup
Definition unit.h:191
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
int ord_city
Definition unit.h:240
bool moved
Definition unit.h:173
int ord_map
Definition unit.h:239
int index
Definition unit.h:195
struct vision * vision
Definition unit.h:242
bool vigilant
Definition unit.h:197
int hp
Definition unit.h:151
struct unit::@79 orders
int fuel
Definition unit.h:153
struct extra_type * changed_from_target
Definition unit.h:170
enum direction8 facing
Definition unit.h:142
struct extra_type * activity_target
Definition unit.h:164
int activity_count
Definition unit.h:162
struct unit_order * list
Definition unit.h:198
enum unit_activity changed_from
Definition unit.h:168
struct player * nationality
Definition unit.h:144
bool repeat
Definition unit.h:196
struct unit::@80::@83 server
int homecity
Definition unit.h:146
bool paradropped
Definition unit.h:174
bool done_moving
Definition unit.h:181
int birth_turn
Definition unit.h:235
struct tile * goto_tile
Definition unit.h:155
struct tile * action_decision_tile
Definition unit.h:203
int veteran
Definition unit.h:152
int changed_from_count
Definition unit.h:169
enum server_side_agent ssa_controller
Definition unit.h:172
enum universals_n kind
Definition fc_types.h:758
char * name
Definition vision.h:109
bool happy
Definition vision.h:118
bv_imprs improvements
Definition vision.h:124
struct tile * location
Definition vision.h:110
int identity
Definition vision.h:113
int walls
Definition vision.h:117
int style
Definition vision.h:120
bool unhappy
Definition vision.h:119
struct player * owner
Definition vision.h:111
int city_image
Definition vision.h:121
bool occupied
Definition vision.h:116
enum capital_type capital
Definition vision.h:122
enum unit_activity act
Definition workertask.h:23
struct tile * ptile
Definition workertask.h:22
struct extra_type * tgt
Definition workertask.h:24
struct universal entries[MAX_LEN_WORKLIST]
Definition worklist.h:30
int length
Definition worklist.h:29
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:969
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:896
#define sz_strlcpy(dest, src)
Definition support.h:167
#define RETURN_VALUE_AFTER_EXIT(_val_)
Definition support.h:121
#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:1070
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:174
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:235
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Definition terrain.c:243
#define terrain_type_iterate(_p)
Definition terrain.h:358
#define T_UNKNOWN
Definition terrain.h:57
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:188
#define terrain_type_iterate_end
Definition terrain.h:364
#define RESOURCE_NONE_IDENTIFIER
Definition terrain.h:47
#define RESOURCE_NULL_IDENTIFIER
Definition terrain.h:46
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:209
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1018
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:966
bool tile_set_label(struct tile *ptile, const char *label)
Definition tile.c:1080
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Definition tile.c:343
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:87
#define tile_worked(_tile)
Definition tile.h:117
#define tile_terrain(_tile)
Definition tile.h:113
#define TILE_XY(ptile)
Definition tile.h:42
#define tile_has_extra(ptile, pextra)
Definition tile.h:150
#define tile_owner(_tile)
Definition tile.h:95
struct goods_type * goods_by_number(Goods_type_id id)
void free_unit_orders(struct unit *punit)
Definition unit.c:1761
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2362
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1115
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2433
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:853
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1132
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1625
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2640
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1721
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1289
#define unit_tile(_pu)
Definition unit.h:395
#define BATTLEGROUP_NONE
Definition unit.h:190
unit_orders
Definition unit.h:37
@ ORDER_ACTION_MOVE
Definition unit.h:45
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_FULL_MP
Definition unit.h:43
@ ORDER_MOVE
Definition unit.h:39
@ ORDER_LAST
Definition unit.h:49
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_owner(_pu)
Definition unit.h:394
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:1415
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:4853
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1242
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:1819
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2673
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:1612
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define unit_type_iterate(_p)
Definition unittype.h:841
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:848
void vision_site_size_set(struct vision_site *psite, citizens size)
Definition vision.c:165
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Definition vision.c:33
bool vision_reveal_tiles(struct vision *vision, bool reveal_tiles)
Definition vision.c:62
struct vision_site * vision_site_new(int identity, struct tile *location, struct player *owner)
Definition vision.c:86
void vision_site_destroy(struct vision_site *psite)
Definition vision.c:74
bool worker_task_is_sane(struct worker_task *ptask)
Definition workertask.c:40
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35
void worklist_init(struct worklist *pwl)
Definition worklist.c:38