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/************************************************************************/
1082 const char *path, int plrno)
1083{
1084 char path_with_name[128];
1085 const char *name;
1086 struct advance *padvance;
1087
1088 fc_snprintf(path_with_name, sizeof(path_with_name),
1089 "%s_name", path);
1090
1091 name = secfile_lookup_str(file, path_with_name, plrno);
1092
1093 if (!name || name[0] == '\0') {
1094 /* used by researching_saved */
1095 return A_UNKNOWN;
1096 }
1097 if (fc_strcasecmp(name, "A_FUTURE") == 0) {
1098 return A_FUTURE;
1099 }
1100 if (fc_strcasecmp(name, "A_NONE") == 0) {
1101 return A_NONE;
1102 }
1103 if (fc_strcasecmp(name, "A_UNSET") == 0) {
1104 return A_UNSET;
1105 }
1106
1107 padvance = advance_by_rule_name(name);
1108 sg_failure_ret_val(NULL != padvance, A_NONE,
1109 "%s: unknown technology \"%s\".", path_with_name, name);
1110
1111 return advance_number(padvance);
1112}
1113
1114/* =======================================================================
1115 * Load savefile data.
1116 * ======================================================================= */
1117
1118/************************************************************************/
1121static void sg_load_ruleset(struct loaddata *loading)
1122{
1123 const char *ruleset = secfile_lookup_str_default(loading->file,
1125 "savefile.rulesetdir");
1126
1127 /* Load ruleset. */
1129 if (!strcmp("default", game.server.rulesetdir)) {
1130 int version;
1131
1132 version = secfile_lookup_int_default(loading->file, -1, "savefile.version");
1133 if (version >= 30) {
1134 /* Here 'default' really means current default.
1135 * Saving happens with real ruleset name, so savegames containing this
1136 * are special scenarios. */
1138 } else {
1139 /* 'default' is the old name of the classic ruleset */
1140 sz_strlcpy(game.server.rulesetdir, "classic");
1141 }
1142 log_verbose("Savegame specified ruleset '%s'. Really loading '%s'.",
1144 }
1145 if (!load_rulesets(NULL, NULL, FALSE, NULL, TRUE, FALSE, TRUE)) {
1146 /* Failed to load correct ruleset */
1147 sg_failure_ret(FALSE, _("Failed to load ruleset '%s' needed for savegame."),
1148 ruleset);
1149 }
1150}
1151
1152/************************************************************************/
1155static void sg_load_savefile(struct loaddata *loading)
1156{
1157 int i;
1158 const char *terr_name;
1159
1160 /* Check status and return if not OK (sg_success FALSE). */
1161 sg_check_ret();
1162
1163 /* Load savefile options. */
1164 loading->secfile_options
1165 = secfile_lookup_str(loading->file, "savefile.options");
1166
1167 /* We don't need these entries, but read them anyway to avoid
1168 * warnings about unread secfile entries. */
1169 (void) secfile_entry_by_path(loading->file, "savefile.reason");
1170 (void) secfile_entry_by_path(loading->file, "savefile.revision");
1171
1172 /* In case of savegame2.c saves, missing entry means savegame older than support
1173 * for saving last_updated by turn. So this must default to TRUE. */
1175 "savefile.last_updated_as_year");
1176
1177 /* Load improvements. */
1178 loading->improvement.size
1179 = secfile_lookup_int_default(loading->file, 0,
1180 "savefile.improvement_size");
1181 if (loading->improvement.size) {
1182 loading->improvement.order
1183 = secfile_lookup_str_vec(loading->file, &loading->improvement.size,
1184 "savefile.improvement_vector");
1185 sg_failure_ret(loading->improvement.size != 0,
1186 "Failed to load improvement order: %s",
1187 secfile_error());
1188 }
1189
1190 /* Load technologies. */
1191 loading->technology.size
1192 = secfile_lookup_int_default(loading->file, 0,
1193 "savefile.technology_size");
1194 if (loading->technology.size) {
1195 loading->technology.order
1196 = secfile_lookup_str_vec(loading->file, &loading->technology.size,
1197 "savefile.technology_vector");
1198 sg_failure_ret(loading->technology.size != 0,
1199 "Failed to load technology order: %s",
1200 secfile_error());
1201 }
1202
1203 /* Load Activities. */
1204 loading->activities.size
1205 = secfile_lookup_int_default(loading->file, 0,
1206 "savefile.activities_size");
1207 if (loading->activities.size) {
1208 loading->activities.order
1209 = secfile_lookup_str_vec(loading->file, &loading->activities.size,
1210 "savefile.activities_vector");
1211 sg_failure_ret(loading->activities.size != 0,
1212 "Failed to load activity order: %s",
1213 secfile_error());
1214 }
1215
1216 /* Load traits. */
1217 loading->trait.size
1218 = secfile_lookup_int_default(loading->file, 0,
1219 "savefile.trait_size");
1220 if (loading->trait.size) {
1221 loading->trait.order
1222 = secfile_lookup_str_vec(loading->file, &loading->trait.size,
1223 "savefile.trait_vector");
1224 sg_failure_ret(loading->trait.size != 0,
1225 "Failed to load trait order: %s",
1226 secfile_error());
1227 }
1228
1229 /* Load extras. */
1230 loading->extra.size
1231 = secfile_lookup_int_default(loading->file, 0,
1232 "savefile.extras_size");
1233 if (loading->extra.size) {
1234 const char **modname;
1235 size_t nmod;
1236 int j;
1237
1238 modname = secfile_lookup_str_vec(loading->file, &loading->extra.size,
1239 "savefile.extras_vector");
1240 sg_failure_ret(loading->extra.size != 0,
1241 "Failed to load extras order: %s",
1242 secfile_error());
1244 "Number of extras defined by the ruleset (= %d) are "
1245 "lower than the number in the savefile (= %d).",
1246 game.control.num_extra_types, (int)loading->extra.size);
1247 /* make sure that the size of the array is divisible by 4 */
1248 nmod = 4 * ((loading->extra.size + 3) / 4);
1249 loading->extra.order = fc_calloc(nmod, sizeof(*loading->extra.order));
1250 for (j = 0; j < loading->extra.size; j++) {
1251 loading->extra.order[j] = extra_type_by_rule_name(modname[j]);
1252 }
1253 free(modname);
1254 for (; j < nmod; j++) {
1255 loading->extra.order[j] = NULL;
1256 }
1257 }
1258
1259 /* Load multipliers. */
1260 loading->multiplier.size
1261 = secfile_lookup_int_default(loading->file, 0,
1262 "savefile.multipliers_size");
1263 if (loading->multiplier.size) {
1264 const char **modname;
1265 int j;
1266
1267 modname = secfile_lookup_str_vec(loading->file, &loading->multiplier.size,
1268 "savefile.multipliers_vector");
1269 sg_failure_ret(loading->multiplier.size != 0,
1270 "Failed to load multipliers order: %s",
1271 secfile_error());
1272 /* It's OK for the set of multipliers in the savefile to differ
1273 * from those in the ruleset. */
1274 loading->multiplier.order = fc_calloc(loading->multiplier.size,
1275 sizeof(*loading->multiplier.order));
1276 for (j = 0; j < loading->multiplier.size; j++) {
1277 loading->multiplier.order[j] = multiplier_by_rule_name(modname[j]);
1278 if (!loading->multiplier.order[j]) {
1279 log_verbose("Multiplier \"%s\" in savegame but not in ruleset, "
1280 "discarding", modname[j]);
1281 }
1282 }
1283 free(modname);
1284 }
1285
1286 /* Load specials. */
1287 loading->special.size
1288 = secfile_lookup_int_default(loading->file, 0,
1289 "savefile.specials_size");
1290 if (loading->special.size) {
1291 const char **modname;
1292 size_t nmod;
1293 enum tile_special_type j;
1294
1295 modname = secfile_lookup_str_vec(loading->file, &loading->special.size,
1296 "savefile.specials_vector");
1297 sg_failure_ret(loading->special.size != 0,
1298 "Failed to load specials order: %s",
1299 secfile_error());
1300 /* make sure that the size of the array is divisible by 4 */
1301 /* Allocating extra 4 slots, just a couple of bytes,
1302 * in case of special.size being divisible by 4 already is intentional.
1303 * Added complexity would cost those couple of bytes in code size alone,
1304 * and we actually need at least one slot immediately after last valid
1305 * one. That's where S_LAST is (or was in version that saved the game)
1306 * and in some cases S_LAST gets written to savegame, at least as
1307 * activity target special when activity targets some base or road
1308 * instead. By having current S_LAST in that index allows us to map
1309 * that old S_LAST to current S_LAST, just like any real special within
1310 * special.size gets mapped. */
1311 nmod = loading->special.size + (4 - (loading->special.size % 4));
1312 loading->special.order = fc_calloc(nmod,
1313 sizeof(*loading->special.order));
1314 for (j = 0; j < loading->special.size; j++) {
1315 if (!fc_strcasecmp("Road", modname[j])) {
1316 loading->special.order[j] = S_OLD_ROAD;
1317 } else if (!fc_strcasecmp("Railroad", modname[j])) {
1318 loading->special.order[j] = S_OLD_RAILROAD;
1319 } else if (!fc_strcasecmp("River", modname[j])) {
1320 loading->special.order[j] = S_OLD_RIVER;
1321 } else {
1322 loading->special.order[j] = special_by_rule_name(modname[j]);
1323 }
1324 }
1325 free(modname);
1326 for (; j < nmod; j++) {
1327 loading->special.order[j] = S_LAST;
1328 }
1329 }
1330
1331 /* Load bases. */
1332 loading->base.size
1333 = secfile_lookup_int_default(loading->file, 0,
1334 "savefile.bases_size");
1335 if (loading->base.size) {
1336 const char **modname;
1337 size_t nmod;
1338 int j;
1339
1340 modname = secfile_lookup_str_vec(loading->file, &loading->base.size,
1341 "savefile.bases_vector");
1342 sg_failure_ret(loading->base.size != 0,
1343 "Failed to load bases order: %s",
1344 secfile_error());
1345 /* make sure that the size of the array is divisible by 4 */
1346 nmod = 4 * ((loading->base.size + 3) / 4);
1347 loading->base.order = fc_calloc(nmod, sizeof(*loading->base.order));
1348 for (j = 0; j < loading->base.size; j++) {
1349 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1350
1351 sg_failure_ret(pextra != NULL
1352 || game.control.num_base_types >= loading->base.size,
1353 "Unknown base type %s in savefile.",
1354 modname[j]);
1355
1356 if (pextra != NULL) {
1357 loading->base.order[j] = extra_base_get(pextra);
1358 } else {
1359 loading->base.order[j] = NULL;
1360 }
1361 }
1362 free(modname);
1363 for (; j < nmod; j++) {
1364 loading->base.order[j] = NULL;
1365 }
1366 }
1367
1368 /* Load roads. */
1369 loading->road.size
1370 = secfile_lookup_int_default(loading->file, 0,
1371 "savefile.roads_size");
1372 if (loading->road.size) {
1373 const char **modname;
1374 size_t nmod;
1375 int j;
1376
1377 modname = secfile_lookup_str_vec(loading->file, &loading->road.size,
1378 "savefile.roads_vector");
1379 sg_failure_ret(loading->road.size != 0,
1380 "Failed to load roads order: %s",
1381 secfile_error());
1383 "Number of roads defined by the ruleset (= %d) are "
1384 "lower than the number in the savefile (= %d).",
1385 game.control.num_road_types, (int)loading->road.size);
1386 /* make sure that the size of the array is divisible by 4 */
1387 nmod = 4 * ((loading->road.size + 3) / 4);
1388 loading->road.order = fc_calloc(nmod, sizeof(*loading->road.order));
1389 for (j = 0; j < loading->road.size; j++) {
1390 struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1391
1392 if (pextra != NULL) {
1393 loading->road.order[j] = extra_road_get(pextra);
1394 } else {
1395 loading->road.order[j] = NULL;
1396 }
1397 }
1398 free(modname);
1399 for (; j < nmod; j++) {
1400 loading->road.order[j] = NULL;
1401 }
1402 }
1403
1404 /* Load specialists. */
1405 loading->specialist.size
1406 = secfile_lookup_int_default(loading->file, 0,
1407 "savefile.specialists_size");
1408 if (loading->specialist.size) {
1409 const char **modname;
1410 size_t nmod;
1411 int j;
1412
1413 modname = secfile_lookup_str_vec(loading->file, &loading->specialist.size,
1414 "savefile.specialists_vector");
1415 sg_failure_ret(loading->specialist.size != 0,
1416 "Failed to load specialists order: %s",
1417 secfile_error());
1419 "Number of specialists defined by the ruleset (= %d) are "
1420 "lower than the number in the savefile (= %d).",
1422 /* make sure that the size of the array is divisible by 4 */
1423 /* That's not really needed with specialists at the moment, but done this way
1424 * for consistency with other types, and to be prepared for the time it needs
1425 * to be this way. */
1426 nmod = 4 * ((loading->specialist.size + 3) / 4);
1427 loading->specialist.order = fc_calloc(nmod, sizeof(*loading->specialist.order));
1428 for (j = 0; j < loading->specialist.size; j++) {
1429 loading->specialist.order[j] = specialist_by_rule_name(modname[j]);
1430 }
1431 free(modname);
1432 for (; j < nmod; j++) {
1433 loading->specialist.order[j] = NULL;
1434 }
1435 }
1436
1437 /* Load diplomatic state type order. */
1438 loading->ds_t.size
1439 = secfile_lookup_int_default(loading->file, 0,
1440 "savefile.diplstate_type_size");
1441
1442 sg_failure_ret(loading->ds_t.size > 0,
1443 "Failed to load diplomatic state type order: %s",
1444 secfile_error());
1445
1446 if (loading->ds_t.size) {
1447 const char **modname;
1448 int j;
1449
1450 modname = secfile_lookup_str_vec(loading->file, &loading->ds_t.size,
1451 "savefile.diplstate_type_vector");
1452
1453 loading->ds_t.order = fc_calloc(loading->ds_t.size,
1454 sizeof(*loading->ds_t.order));
1455
1456 for (j = 0; j < loading->ds_t.size; j++) {
1457 loading->ds_t.order[j] = diplstate_type_by_name(modname[j],
1459 }
1460
1461 free(modname);
1462 }
1463
1464 /* Not used by this freeciv version - for future use */
1465 {
1466 int j;
1467
1468 i = secfile_lookup_int_default(loading->file, 0, "savefile.city_options_size");
1469 for (j = 0; j < i; j++) {
1470 (void) secfile_entry_lookup(loading->file, "savefile.city_options_vector,%d", j);
1471 }
1472 }
1473
1474 terrain_type_iterate(pterr) {
1475 pterr->identifier_load = '\0';
1477
1478 i = 0;
1479 while ((terr_name = secfile_lookup_str_default(loading->file, NULL,
1480 "savefile.terrident%d.name", i)) != NULL) {
1481 struct terrain *pterr = terrain_by_rule_name(terr_name);
1482
1483 if (pterr != NULL) {
1484 const char *iptr = secfile_lookup_str_default(loading->file, NULL,
1485 "savefile.terrident%d.identifier", i);
1486
1487 pterr->identifier_load = *iptr;
1488 } else {
1489 log_error("Identifier for unknown terrain type %s.", terr_name);
1490 }
1491 i++;
1492 }
1493
1494 terrain_type_iterate(pterr) {
1495 terrain_type_iterate(pterr2) {
1496 if (pterr != pterr2 && pterr->identifier_load != '\0') {
1497 sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1498 "%s and %s share a saved identifier",
1499 terrain_rule_name(pterr), terrain_rule_name(pterr2));
1500 }
1503}
1504
1505/* =======================================================================
1506 * Load game status.
1507 * ======================================================================= */
1508
1509/************************************************************************/
1512static void sg_load_ruledata(struct loaddata *loading)
1513{
1514 int i;
1515 const char *name;
1516
1517 /* Check status and return if not OK (sg_success FALSE). */
1518 sg_check_ret();
1519
1520 for (i = 0;
1521 (name = secfile_lookup_str_default(loading->file, NULL,
1522 "ruledata.government%d.name", i));
1523 i++) {
1525
1526 if (gov != NULL) {
1528 "ruledata.government%d.changes", i);
1529 }
1530 }
1531}
1532
1533/************************************************************************/
1536static void sg_load_game(struct loaddata *loading)
1537{
1538 int game_version;
1539 const char *str;
1540 const char *level;
1541 int i;
1542
1543 /* Check status and return if not OK (sg_success FALSE). */
1544 sg_check_ret();
1545
1546 /* Load version. */
1547 game_version
1548 = secfile_lookup_int_default(loading->file, 0, "game.version");
1549 /* We require at least version 2.2.99 */
1550 sg_failure_ret(20299 <= game_version, "Saved game is too old, at least "
1551 "version 2.2.99 required.");
1552
1553 loading->full_version = game_version;
1554
1555 /* Load server state. */
1556 str = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
1557 "game.server_state");
1558 loading->server_state = server_states_by_name(str, strcmp);
1559 if (!server_states_is_valid(loading->server_state)) {
1560 /* Don't take any risk! */
1561 loading->server_state = S_S_INITIAL;
1562 }
1563
1566 "game.meta_patches");
1568
1570 /* Do not overwrite this if the user requested a specific metaserver
1571 * from the command line (option --Metaserver). */
1575 "game.meta_server"));
1576 }
1577
1578 if ('\0' == srvarg.serverid[0]) {
1579 /* Do not overwrite this if the user requested a specific metaserver
1580 * from the command line (option --serverid). */
1582 secfile_lookup_str_default(loading->file, "",
1583 "game.serverid"));
1584 }
1585 sz_strlcpy(server.game_identifier,
1586 secfile_lookup_str_default(loading->file, "", "game.id"));
1587 /* We are not checking game_identifier legality just yet.
1588 * That's done when we are sure that rand seed has been initialized,
1589 * so that we can generate new game_identifier, if needed.
1590 * See sq_load_sanitycheck(). */
1591
1592 level = secfile_lookup_str_default(loading->file, NULL,
1593 "game.level");
1594 if (level != NULL) {
1595 if (!fc_strcasecmp("Handicapped", level)) {
1596 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
1597 game.info.skill_level = AI_LEVEL_RESTRICTED;
1598 } else {
1599 game.info.skill_level = ai_level_by_name(level, fc_strcasecmp);
1600 }
1601 } else {
1602 game.info.skill_level = ai_level_invalid();
1603 }
1604
1605 if (!ai_level_is_valid(game.info.skill_level)) {
1609 "game.skill_level"));
1610 }
1613 "game.phase_mode");
1616 "game.phase_mode_stored");
1618 = secfile_lookup_int_default(loading->file, 0,
1619 "game.phase");
1623 "game.scoreturn");
1624
1627 "game.timeoutint");
1630 "game.timeoutintinc");
1633 "game.timeoutinc");
1636 "game.timeoutincmult");
1639 "game.timeoutcounter");
1640
1641 game.info.turn
1642 = secfile_lookup_int_default(loading->file, 0, "game.turn");
1644 "game.year"), "%s", secfile_error());
1646 = secfile_lookup_bool_default(loading->file, FALSE, "game.year_0_hack");
1647
1649 = secfile_lookup_int_default(loading->file, 0, "game.globalwarming");
1651 = secfile_lookup_int_default(loading->file, 0, "game.heating");
1653 = secfile_lookup_int_default(loading->file, 0, "game.warminglevel");
1654
1656 = secfile_lookup_int_default(loading->file, 0, "game.nuclearwinter");
1658 = secfile_lookup_int_default(loading->file, 0, "game.cooling");
1660 = secfile_lookup_int_default(loading->file, 0, "game.coolinglevel");
1661
1662 /* Global advances. */
1663 str = secfile_lookup_str_default(loading->file, NULL,
1664 "game.global_advances");
1665 if (str != NULL) {
1666 sg_failure_ret(strlen(str) == loading->technology.size,
1667 "Invalid length of 'game.global_advances' ("
1668 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
1669 strlen(str), loading->technology.size);
1670 for (i = 0; i < loading->technology.size; i++) {
1671 sg_failure_ret(str[i] == '1' || str[i] == '0',
1672 "Undefined value '%c' within 'game.global_advances'.",
1673 str[i]);
1674 if (str[i] == '1') {
1675 struct advance *padvance =
1677
1678 if (padvance != NULL) {
1680 }
1681 }
1682 }
1683 }
1684
1686 = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
1687
1689 = secfile_lookup_int_default(loading->file, 0, "game.last_turn_change_time") / 100.0;
1690}
1691
1692/* =======================================================================
1693 * Load random status.
1694 * ======================================================================= */
1695
1696/************************************************************************/
1699static void sg_load_random(struct loaddata *loading)
1700{
1701 /* Check status and return if not OK (sg_success FALSE). */
1702 sg_check_ret();
1703
1704 if (secfile_lookup_bool_default(loading->file, FALSE, "random.saved")) {
1705 const char *str;
1706 int i;
1707
1708 /* Since random state was previously saved, save it also when resaving.
1709 * This affects only pre-2.6 scenarios where scenario.save_random
1710 * is not defined.
1711 * - If this is 2.6 or later scenario -> it would have saved random.saved = TRUE
1712 * only if scenario.save_random is already TRUE
1713 *
1714 * Do NOT touch this in case of regular savegame. They always have random.saved
1715 * set, but if one starts to make scenario based on a savegame, we want
1716 * default scenario settings in the beginning (default save_random = FALSE).
1717 */
1720 }
1721
1722 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.j,
1723 "random.index_J"), "%s", secfile_error());
1724 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.k,
1725 "random.index_K"), "%s", secfile_error());
1726 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.x,
1727 "random.index_X"), "%s", secfile_error());
1728
1729 for (i = 0; i < 8; i++) {
1730 str = secfile_lookup_str(loading->file, "random.table%d",i);
1731 sg_failure_ret(NULL != str, "%s", secfile_error());
1732 sscanf(str, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
1733 &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
1734 &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
1735 &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
1736 }
1737 loading->rstate.is_init = TRUE;
1738 fc_rand_set_state(loading->rstate);
1739 } else {
1740 /* No random values - mark the setting. */
1741 (void) secfile_entry_by_path(loading->file, "random.saved");
1742
1743 /* We're loading a game without a seed (which is okay, if it's a scenario).
1744 * We need to generate the game seed now because it will be needed later
1745 * during the load. */
1747 loading->rstate = fc_rand_state();
1748 }
1749}
1750
1751/* =======================================================================
1752 * Load lua script data.
1753 * ======================================================================= */
1754
1755/************************************************************************/
1758static void sg_load_script(struct loaddata *loading)
1759{
1760 /* Check status and return if not OK (sg_success FALSE). */
1761 sg_check_ret();
1762
1764}
1765
1766/* =======================================================================
1767 * Load scenario data.
1768 * ======================================================================= */
1769
1770/************************************************************************/
1773static void sg_load_scenario(struct loaddata *loading)
1774{
1775 const char *buf;
1776 bool lake_flood_default;
1777
1778 /* Check status and return if not OK (sg_success FALSE). */
1779 sg_check_ret();
1780
1781 if (NULL == secfile_section_lookup(loading->file, "scenario")) {
1783
1784 return;
1785 }
1786
1787 /* Default is that when there's scenario section (which we already checked)
1788 * this is a scenario. Only if it explicitly says that it's not, we consider
1789 * this regular savegame */
1790 game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
1791
1792 if (!game.scenario.is_scenario) {
1793 return;
1794 }
1795
1796 buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
1797 if (buf[0] != '\0') {
1799 }
1800
1801 buf = secfile_lookup_str_default(loading->file, "",
1802 "scenario.authors");
1803 if (buf[0] != '\0') {
1805 } else {
1806 game.scenario.authors[0] = '\0';
1807 }
1808
1809 buf = secfile_lookup_str_default(loading->file, "",
1810 "scenario.description");
1811 if (buf[0] != '\0') {
1813 } else {
1814 game.scenario_desc.description[0] = '\0';
1815 }
1816
1818 = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
1820 = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
1823 "scenario.startpos_nations");
1824
1827 "scenario.prevent_new_cities");
1828 if (loading->version < 20599) {
1829 /* Lake flooding may break some old scenarios where rivers made out of
1830 * lake terrains, so play safe there */
1831 lake_flood_default = FALSE;
1832 } else {
1833 /* If lake flooding is a problem for a newer scenario, it could explicitly
1834 * disable it. */
1835 lake_flood_default = TRUE;
1836 }
1838 = secfile_lookup_bool_default(loading->file, lake_flood_default,
1839 "scenario.lake_flooding");
1842 "scenario.handmade");
1845 "scenario.allow_ai_type_fallback");
1847
1848 sg_failure_ret(loading->server_state == S_S_INITIAL
1849 || (loading->server_state == S_S_RUNNING
1850 && game.scenario.players),
1851 "Invalid scenario definition (server state '%s' and "
1852 "players are %s).",
1853 server_states_name(loading->server_state),
1854 game.scenario.players ? "saved" : "not saved");
1855
1856 /* Remove all defined players. They are recreated with the skill level
1857 * defined by the scenario. */
1858 (void) aifill(0);
1859}
1860
1861/* =======================================================================
1862 * Load game settings.
1863 * ======================================================================= */
1864
1865/************************************************************************/
1868static void sg_load_settings(struct loaddata *loading)
1869{
1870 /* Check status and return if not OK (sg_success FALSE). */
1871 sg_check_ret();
1872
1873 settings_game_load(loading->file, "settings");
1874
1875 /* Save current status of fogofwar. */
1877
1878 /* Add all compatibility settings here. */
1879}
1880
1881/* =======================================================================
1882 * Load the main map.
1883 * ======================================================================= */
1884
1885/************************************************************************/
1888static void sg_load_map(struct loaddata *loading)
1889{
1890 /* Check status and return if not OK (sg_success FALSE). */
1891 sg_check_ret();
1892
1893 /* This defaults to TRUE even if map has not been generated. Also,
1894 * old versions have also explicitly saved TRUE even in pre-game.
1895 * We rely on that
1896 * 1) scenario maps have it explicitly right.
1897 * 2) when map is actually generated, it re-initialize this to FALSE. */
1899 = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
1900
1901 if (S_S_INITIAL == loading->server_state
1903 /* Generator MAPGEN_SCENARIO is used;
1904 * this map was done with the map editor. */
1905
1906 /* Load tiles. */
1907 sg_load_map_tiles(loading);
1908 sg_load_map_startpos(loading);
1909
1910 if (loading->version >= 30) {
1911 /* 2.6.0 or newer */
1912 sg_load_map_tiles_extras(loading);
1913 } else {
1914 sg_load_map_tiles_bases(loading);
1915 if (loading->version >= 20) {
1916 /* 2.5.0 or newer */
1917 sg_load_map_tiles_roads(loading);
1918 }
1919 if (has_capability("specials", loading->secfile_options)) {
1920 /* Load specials. */
1922 }
1923 }
1924
1925 /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
1927 if (has_capability("specials", loading->secfile_options)) {
1928 /* Load resources. */
1930 } else if (has_capability("riversoverlay", loading->secfile_options)) {
1931 /* Load only rivers overlay. */
1933 }
1934
1935 /* Nothing more needed for a scenario. */
1936 return;
1937 }
1938
1939 if (S_S_INITIAL == loading->server_state) {
1940 /* Nothing more to do if it is not a scenario but in initial state. */
1941 return;
1942 }
1943
1944 sg_load_map_tiles(loading);
1945 sg_load_map_startpos(loading);
1946 if (loading->version >= 30) {
1947 /* 2.6.0 or newer */
1948 sg_load_map_tiles_extras(loading);
1949 } else {
1950 sg_load_map_tiles_bases(loading);
1951 if (loading->version >= 20) {
1952 /* 2.5.0 or newer */
1953 sg_load_map_tiles_roads(loading);
1954 }
1956 }
1958 sg_load_map_known(loading);
1959 sg_load_map_owner(loading);
1960 sg_load_map_worked(loading);
1961}
1962
1963/************************************************************************/
1966static void sg_load_map_tiles(struct loaddata *loading)
1967{
1968 /* Check status and return if not OK (sg_success FALSE). */
1969 sg_check_ret();
1970
1971 /* Initialize the map for the current topology. 'map.xsize' and
1972 * 'map.ysize' must be set. */
1974
1975 /* Allocate map. */
1977
1978 /* get the terrain type */
1979 LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
1980 "map.t%04d");
1982
1983 /* Check for special tile sprites. */
1984 whole_map_iterate(&(wld.map), ptile) {
1985 const char *spec_sprite;
1986 const char *label;
1987 int nat_x, nat_y;
1988
1990 spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
1991 nat_x, nat_y);
1992 label = secfile_lookup_str_default(loading->file, NULL, "map.label_%d_%d",
1993 nat_x, nat_y);
1994 if (NULL != ptile->spec_sprite) {
1995 ptile->spec_sprite = fc_strdup(spec_sprite);
1996 }
1997 if (label != NULL) {
1998 tile_set_label(ptile, label);
1999 }
2001}
2002
2003/************************************************************************/
2006static void sg_load_map_tiles_extras(struct loaddata *loading)
2007{
2008 /* Check status and return if not OK (sg_success FALSE). */
2009 sg_check_ret();
2010
2011 /* Load extras. */
2012 halfbyte_iterate_extras(j, loading->extra.size) {
2013 LOAD_MAP_CHAR(ch, ptile, sg_extras_set(&ptile->extras, ch, loading->extra.order + 4 * j),
2014 loading->file, "map.e%02d_%04d", j);
2016}
2017
2018/************************************************************************/
2021static void sg_load_map_tiles_bases(struct loaddata *loading)
2022{
2023 /* Check status and return if not OK (sg_success FALSE). */
2024 sg_check_ret();
2025
2026 /* Load bases. */
2027 halfbyte_iterate_bases(j, loading->base.size) {
2028 LOAD_MAP_CHAR(ch, ptile, sg_bases_set(&ptile->extras, ch,
2029 loading->base.order + 4 * j),
2030 loading->file, "map.b%02d_%04d", j);
2032}
2033
2034/************************************************************************/
2037static void sg_load_map_tiles_roads(struct loaddata *loading)
2038{
2039 /* Check status and return if not OK (sg_success FALSE). */
2040 sg_check_ret();
2041
2042 /* Load roads. */
2043 halfbyte_iterate_roads(j, loading->road.size) {
2044 LOAD_MAP_CHAR(ch, ptile, sg_roads_set(&ptile->extras, ch,
2045 loading->road.order + 4 * j),
2046 loading->file, "map.r%02d_%04d", j);
2048}
2049
2050/************************************************************************/
2053static void sg_load_map_tiles_specials(struct loaddata *loading,
2054 bool rivers_overlay)
2055{
2056 /* Check status and return if not OK (sg_success FALSE). */
2057 sg_check_ret();
2058
2059 /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
2060 * from the savegame file.
2061 *
2062 * A scenario may define the terrain of the map but not list the specials
2063 * on it (thus allowing users to control the placement of specials).
2064 * However rivers are a special case and must be included in the map along
2065 * with the scenario. Thus in those cases this function should be called
2066 * to load the river information separate from any other special data.
2067 *
2068 * This does not need to be called from map_load(), because map_load()
2069 * loads the rivers overlay along with the rest of the specials. Call this
2070 * only if you've already called map_load_tiles(), and want to load only
2071 * the rivers overlay but no other specials. Scenarios that encode things
2072 * this way should have the "riversoverlay" capability. */
2074 LOAD_MAP_CHAR(ch, ptile, sg_special_set(ptile, &ptile->extras, ch,
2075 loading->special.order + 4 * j,
2076 rivers_overlay),
2077 loading->file, "map.spe%02d_%04d", j);
2079}
2080
2081/************************************************************************/
2084static void sg_load_map_tiles_resources(struct loaddata *loading)
2085{
2086 /* Check status and return if not OK (sg_success FALSE). */
2087 sg_check_ret();
2088
2089 LOAD_MAP_CHAR(ch, ptile, tile_set_resource(ptile, char2resource(ch)),
2090 loading->file, "map.res%04d");
2091
2092 /* After the resources are loaded, indicate those currently valid. */
2093 whole_map_iterate(&(wld.map), ptile) {
2094 if (NULL == ptile->resource) {
2095 continue;
2096 }
2097
2098 if (ptile->terrain == NULL || !terrain_has_resource(ptile->terrain, ptile->resource)) {
2099 BV_CLR(ptile->extras, extra_index(ptile->resource));
2100 }
2102
2105}
2106
2107/************************************************************************/
2111static void sg_load_map_startpos(struct loaddata *loading)
2112{
2113 struct nation_type *pnation;
2114 struct startpos *psp;
2115 struct tile *ptile;
2116 const char SEPARATOR = '#';
2117 const char *nation_names;
2118 int nat_x, nat_y;
2119 bool exclude;
2120 int i, startpos_count;
2121
2122 /* Check status and return if not OK (sg_success FALSE). */
2123 sg_check_ret();
2124
2125 startpos_count
2126 = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
2127
2128 if (0 == startpos_count) {
2129 /* Nothing to do. */
2130 return;
2131 }
2132
2133 for (i = 0; i < startpos_count; i++) {
2134 if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
2135 || !secfile_lookup_int(loading->file, &nat_y,
2136 "map.startpos%d.y", i)) {
2137 log_sg("Warning: Undefined coordinates for startpos %d", i);
2138 continue;
2139 }
2140
2141 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
2142 if (NULL == ptile) {
2143 log_error("Start position native coordinates (%d, %d) do not exist "
2144 "in this map. Skipping...", nat_x, nat_y);
2145 continue;
2146 }
2147
2148 exclude = secfile_lookup_bool_default(loading->file, FALSE,
2149 "map.startpos%d.exclude", i);
2150
2151 psp = map_startpos_new(ptile);
2152
2153 nation_names = secfile_lookup_str(loading->file,
2154 "map.startpos%d.nations", i);
2155 if (NULL != nation_names && '\0' != nation_names[0]) {
2156 const size_t size = strlen(nation_names) + 1;
2157 char buf[size], *start, *end;
2158
2159 memcpy(buf, nation_names, size);
2160 for (start = buf - 1; NULL != start; start = end) {
2161 start++;
2162 if ((end = strchr(start, SEPARATOR))) {
2163 *end = '\0';
2164 }
2165
2166 pnation = nation_by_rule_name(start);
2167 if (NO_NATION_SELECTED != pnation) {
2168 if (exclude) {
2169 startpos_disallow(psp, pnation);
2170 } else {
2171 startpos_allow(psp, pnation);
2172 }
2173 } else {
2174 log_verbose("Missing nation \"%s\".", start);
2175 }
2176 }
2177 }
2178 }
2179
2180 if (0 < map_startpos_count()
2181 && loading->server_state == S_S_INITIAL
2183 log_verbose("Number of starts (%d) are lower than rules.max_players "
2184 "(%d), lowering rules.max_players.",
2187 }
2188
2189 /* Re-initialize nation availability in light of start positions.
2190 * This has to be after loading [scenario] and [map].startpos and
2191 * before we seek nations for players. */
2193}
2194
2195/************************************************************************/
2198static void sg_load_map_owner(struct loaddata *loading)
2199{
2200 int x, y;
2201 struct player *owner = NULL;
2202 struct tile *claimer = NULL;
2203 struct player *eowner = NULL;
2204
2205 /* Check status and return if not OK (sg_success FALSE). */
2206 sg_check_ret();
2207
2208 if (game.info.is_new_game) {
2209 /* No owner/source information for a new game / scenario. */
2210 return;
2211 }
2212
2213 /* Owner and ownership source are stored as plain numbers */
2214 for (y = 0; y < wld.map.ysize; y++) {
2215 const char *buffer1 = secfile_lookup_str(loading->file,
2216 "map.owner%04d", y);
2217 const char *buffer2 = secfile_lookup_str(loading->file,
2218 "map.source%04d", y);
2219 const char *buffer3 = secfile_lookup_str(loading->file,
2220 "map.eowner%04d", y);
2221 const char *ptr1 = buffer1;
2222 const char *ptr2 = buffer2;
2223 const char *ptr3 = buffer3;
2224
2225 sg_failure_ret(buffer1 != NULL, "%s", secfile_error());
2226 sg_failure_ret(buffer2 != NULL, "%s", secfile_error());
2227 if (loading->version >= 30) {
2228 sg_failure_ret(buffer3 != NULL, "%s", secfile_error());
2229 }
2230
2231 for (x = 0; x < wld.map.xsize; x++) {
2232 char token1[TOKEN_SIZE];
2233 char token2[TOKEN_SIZE];
2234 char token3[TOKEN_SIZE];
2235 int number;
2236 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2237
2238 scanin(&ptr1, ",", token1, sizeof(token1));
2239 sg_failure_ret(token1[0] != '\0',
2240 "Map size not correct (map.owner%d).", y);
2241 if (strcmp(token1, "-") == 0) {
2242 owner = NULL;
2243 } else {
2244 sg_failure_ret(str_to_int(token1, &number),
2245 "Got map owner %s in (%d, %d).", token1, x, y);
2246 owner = player_by_number(number);
2247 }
2248
2249 scanin(&ptr2, ",", token2, sizeof(token2));
2250 sg_failure_ret(token2[0] != '\0',
2251 "Map size not correct (map.source%d).", y);
2252 if (strcmp(token2, "-") == 0) {
2253 claimer = NULL;
2254 } else {
2255 sg_failure_ret(str_to_int(token2, &number),
2256 "Got map source %s in (%d, %d).", token2, x, y);
2257 claimer = index_to_tile(&(wld.map), number);
2258 }
2259
2260 if (loading->version >= 30) {
2261 scanin(&ptr3, ",", token3, sizeof(token3));
2262 sg_failure_ret(token3[0] != '\0',
2263 "Map size not correct (map.eowner%d).", y);
2264 if (strcmp(token3, "-") == 0) {
2265 eowner = NULL;
2266 } else {
2267 sg_failure_ret(str_to_int(token3, &number),
2268 "Got base owner %s in (%d, %d).", token3, x, y);
2269 eowner = player_by_number(number);
2270 }
2271 } else {
2272 eowner = owner;
2273 }
2274
2276 tile_claim_bases(ptile, eowner);
2277 log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
2278 }
2279 }
2280}
2281
2282/************************************************************************/
2285static void sg_load_map_worked(struct loaddata *loading)
2286{
2287 int x, y;
2288
2289 /* Check status and return if not OK (sg_success FALSE). */
2290 sg_check_ret();
2291
2292 sg_failure_ret(loading->worked_tiles == NULL,
2293 "City worked map not loaded!");
2294
2296 sizeof(*loading->worked_tiles));
2297
2298 for (y = 0; y < wld.map.ysize; y++) {
2299 const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
2300 y);
2301 const char *ptr = buffer;
2302
2303 sg_failure_ret(NULL != buffer,
2304 "Savegame corrupt - map line %d not found.", y);
2305 for (x = 0; x < wld.map.xsize; x++) {
2306 char token[TOKEN_SIZE];
2307 int number;
2308 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2309
2310 scanin(&ptr, ",", token, sizeof(token));
2311 sg_failure_ret('\0' != token[0],
2312 "Savegame corrupt - map size not correct.");
2313 if (strcmp(token, "-") == 0) {
2314 number = -1;
2315 } else {
2316 sg_failure_ret(str_to_int(token, &number) && 0 < number,
2317 "Savegame corrupt - got tile worked by city "
2318 "id=%s in (%d, %d).", token, x, y);
2319 }
2320
2321 loading->worked_tiles[ptile->index] = number;
2322 }
2323 }
2324}
2325
2326/************************************************************************/
2329static void sg_load_map_known(struct loaddata *loading)
2330{
2331 /* Check status and return if not OK (sg_success FALSE). */
2332 sg_check_ret();
2333
2334 players_iterate(pplayer) {
2335 /* Allocate player private map here; it is needed in different modules
2336 * besides this one ((i.e. sg_load_player_*()). */
2337 player_map_init(pplayer);
2339
2341 "game.save_known")) {
2342 int lines = player_slot_max_used_number()/32 + 1, j, p, l, i;
2343 unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
2344
2345 for (l = 0; l < lines; l++) {
2346 for (j = 0; j < 8; j++) {
2347 for (i = 0; i < 4; i++) {
2348 /* Only bother trying to load the map for this halfbyte if at least
2349 * one of the corresponding player slots is in use. */
2350 if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
2351 LOAD_MAP_CHAR(ch, ptile,
2352 known[l * MAP_INDEX_SIZE + tile_index(ptile)]
2353 |= ascii_hex2bin(ch, j),
2354 loading->file, "map.k%02d_%04d", l * 8 + j);
2355 break;
2356 }
2357 }
2358 }
2359 }
2360
2361 players_iterate(pplayer) {
2362 dbv_clr_all(&pplayer->tile_known);
2364
2365 /* HACK: we read the known data from hex into 32-bit integers, and
2366 * now we convert it to the known tile data of each player. */
2367 whole_map_iterate(&(wld.map), ptile) {
2368 players_iterate(pplayer) {
2369 p = player_index(pplayer);
2370 l = player_index(pplayer) / 32;
2371
2372 if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
2373 map_set_known(ptile, pplayer);
2374 }
2377
2378 FC_FREE(known);
2379 }
2380}
2381
2382/* =======================================================================
2383 * Load player data.
2384 *
2385 * This is splitted into two parts as some data can only be loaded if the
2386 * number of players is known and the corresponding player slots are
2387 * defined.
2388 * ======================================================================= */
2389
2390/************************************************************************/
2393static void sg_load_players_basic(struct loaddata *loading)
2394{
2395 int i, k, nplayers;
2396 const char *str;
2397 bool shuffle_loaded = TRUE;
2398
2399 /* Check status and return if not OK (sg_success FALSE). */
2400 sg_check_ret();
2401
2402 if (S_S_INITIAL == loading->server_state
2403 || game.info.is_new_game) {
2404 /* Nothing more to do. */
2405 return;
2406 }
2407
2408 /* Load destroyed wonders: */
2409 str = secfile_lookup_str(loading->file,
2410 "players.destroyed_wonders");
2411 sg_failure_ret(str != NULL, "%s", secfile_error());
2412 sg_failure_ret(strlen(str) == loading->improvement.size,
2413 "Invalid length for 'players.destroyed_wonders' ("
2414 SIZE_T_PRINTF" ~= " SIZE_T_PRINTF ")",
2415 strlen(str), loading->improvement.size);
2416 for (k = 0; k < loading->improvement.size; k++) {
2417 sg_failure_ret(str[k] == '1' || str[k] == '0',
2418 "Undefined value '%c' within "
2419 "'players.destroyed_wonders'.", str[k]);
2420
2421 if (str[k] == '1') {
2422 struct impr_type *pimprove =
2424
2425 if (pimprove) {
2428 }
2429 }
2430 }
2431
2432 server.identity_number
2433 = secfile_lookup_int_default(loading->file, server.identity_number,
2434 "players.identity_number_used");
2435
2436 /* First remove all defined players. */
2437 players_iterate(pplayer) {
2438 server_remove_player(pplayer);
2440
2441 /* Now, load the players from the savefile. */
2442 player_slots_iterate(pslot) {
2443 struct player *pplayer;
2444 struct rgbcolor *prgbcolor = NULL;
2445 int pslot_id = player_slot_index(pslot);
2446
2447 if (NULL == secfile_section_lookup(loading->file, "player%d",
2448 pslot_id)) {
2449 continue;
2450 }
2451
2452 /* Get player AI type. */
2453 str = secfile_lookup_str(loading->file, "player%d.ai_type",
2454 player_slot_index(pslot));
2455 sg_failure_ret(str != NULL, "%s", secfile_error());
2456
2457 /* Get player color */
2458 if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
2459 pslot_id)) {
2460 if (loading->version >= 10 && game_was_started()) {
2461 /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
2462 * as they predate the introduction of configurable player colors. */
2463 log_sg("Game has started, yet player %d has no color defined.",
2464 pslot_id);
2465 /* This will be fixed up later */
2466 } else {
2467 log_verbose("No color defined for player %d.", pslot_id);
2468 /* Colors will be assigned on game start, or at end of savefile
2469 * loading if game has already started */
2470 }
2471 }
2472
2473 /* Create player. */
2474 pplayer = server_create_player(player_slot_index(pslot), str,
2475 prgbcolor,
2478 sg_failure_ret(pplayer != NULL, "Invalid AI type: '%s'!", str);
2479
2480 server_player_init(pplayer, FALSE, FALSE);
2481
2482 /* Free the color definition. */
2483 rgbcolor_destroy(prgbcolor);
2484
2485 /* Multipliers (policies) */
2486
2487 /* First initialise player values with ruleset defaults; this will
2488 * cover any in the ruleset not known when the savefile was created. */
2489 multipliers_iterate(pmul) {
2490 pplayer->multipliers[multiplier_index(pmul)].value
2491 = pplayer->multipliers[multiplier_index(pmul)].target = pmul->def;
2493
2494 /* Now override with any values from the savefile. */
2495 for (k = 0; k < loading->multiplier.size; k++) {
2496 const struct multiplier *pmul = loading->multiplier.order[k];
2497
2498 if (pmul) {
2500 int val =
2501 secfile_lookup_int_default(loading->file, pmul->def,
2502 "player%d.multiplier%d.val",
2503 player_slot_index(pslot), k);
2504 int rval = (((CLIP(pmul->start, val, pmul->stop)
2505 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2506
2507 if (rval != val) {
2508 log_verbose("Player %d had illegal value for multiplier \"%s\": "
2509 "was %d, clamped to %d", pslot_id,
2510 multiplier_rule_name(pmul), val, rval);
2511 }
2512 pplayer->multipliers[idx].value = rval;
2513
2514 val =
2516 pplayer->multipliers[idx].value,
2517 "player%d.multiplier%d.target",
2518 player_slot_index(pslot), k);
2519 rval = (((CLIP(pmul->start, val, pmul->stop)
2520 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2521
2522 if (rval != val) {
2523 log_verbose("Player %d had illegal value for multiplier_target "
2524 "\"%s\": was %d, clamped to %d", pslot_id,
2525 multiplier_rule_name(pmul), val, rval);
2526 }
2527 pplayer->multipliers[idx].target = rval;
2528
2529 /* Never present in savegame2 format */
2530 pplayer->multipliers[idx].changed = 0;
2531 } /* else silently discard multiplier not in current ruleset */
2532 }
2533
2534 /* Just in case savecompat starts adding it in the future. */
2535 pplayer->server.border_vision =
2537 "player%d.border_vision",
2538 player_slot_index(pslot));
2540
2541 /* check number of players */
2542 nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
2543 sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
2544 "(%d) from the loaded game does not match the number of "
2545 "players present (%d).", nplayers, player_count());
2546
2547 /* Load team informations. */
2548 players_iterate(pplayer) {
2549 int team;
2550 struct team_slot *tslot = NULL;
2551
2553 "player%d.team_no",
2554 player_number(pplayer))
2555 && (tslot = team_slot_by_number(team)),
2556 "Invalid team definition for player %s (nb %d).",
2557 player_name(pplayer), player_number(pplayer));
2558 /* Should never fail when slot given is not NULL */
2559 team_add_player(pplayer, team_new(tslot));
2561
2562 /* Loading the shuffle list is quite complex. At the time of saving the
2563 * shuffle data is saved as
2564 * shuffled_player_<number> = player_slot_id
2565 * where number is an increasing number and player_slot_id is a number
2566 * between 0 and the maximum number of player slots. Now we have to create
2567 * a list
2568 * shuffler_players[number] = player_slot_id
2569 * where all player slot IDs are used exactly one time. The code below
2570 * handles this ... */
2571 if (secfile_lookup_int_default(loading->file, -1,
2572 "players.shuffled_player_%d", 0) >= 0) {
2573 int slots = player_slot_count();
2574 int plrcount = player_count();
2575 int shuffled_players[slots];
2576 bool shuffled_player_set[slots];
2577
2578 for (i = 0; i < slots; i++) {
2579 /* Array to save used numbers. */
2580 shuffled_player_set[i] = FALSE;
2581 /* List of all player IDs (needed for set_shuffled_players()). It is
2582 * initialised with the value -1 to indicate that no value is set. */
2583 shuffled_players[i] = -1;
2584 }
2585
2586 /* Load shuffled player list. */
2587 for (i = 0; i < plrcount; i++) {
2588 int shuffle
2589 = secfile_lookup_int_default(loading->file, -1,
2590 "players.shuffled_player_%d", i);
2591
2592 if (shuffle == -1) {
2593 log_sg("Missing player shuffle information (index %d) "
2594 "- reshuffle player list!", i);
2595 shuffle_loaded = FALSE;
2596 break;
2597 } else if (shuffled_player_set[shuffle]) {
2598 log_sg("Player shuffle %d used two times "
2599 "- reshuffle player list!", shuffle);
2600 shuffle_loaded = FALSE;
2601 break;
2602 }
2603 /* Set this ID as used. */
2604 shuffled_player_set[shuffle] = TRUE;
2605
2606 /* Save the player ID in the shuffle list. */
2607 shuffled_players[i] = shuffle;
2608 }
2609
2610 if (shuffle_loaded) {
2611 /* Insert missing numbers. */
2612 int shuffle_index = plrcount;
2613
2614 for (i = 0; i < slots; i++) {
2615 if (!shuffled_player_set[i]) {
2616 shuffled_players[shuffle_index++] = i;
2617 }
2618
2619 /* shuffle_index must not grow higher than size of shuffled_players. */
2620 sg_failure_ret(shuffle_index <= slots,
2621 "Invalid player shuffle data!");
2622 }
2623
2624#ifdef FREECIV_DEBUG
2625 log_debug("[load shuffle] player_count() = %d", player_count());
2626 player_slots_iterate(pslot) {
2627 int plrid = player_slot_index(pslot);
2628
2629 log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
2630 plrid, shuffled_players[plrid], plrid,
2631 shuffled_player_set[plrid] ? "is used" : "-");
2633#endif /* FREECIV_DEBUG */
2634
2635 /* Set shuffle list from savegame. */
2636 set_shuffled_players(shuffled_players);
2637 }
2638 }
2639
2640 if (!shuffle_loaded) {
2641 /* No shuffled players included or error loading them, so shuffle them
2642 * (this may include scenarios). */
2644 }
2645}
2646
2647/************************************************************************/
2650static void sg_load_players(struct loaddata *loading)
2651{
2652 /* Check status and return if not OK (sg_success FALSE). */
2653 sg_check_ret();
2654
2655 if (game.info.is_new_game) {
2656 /* Nothing to do. */
2657 return;
2658 }
2659
2660 players_iterate(pplayer) {
2661 sg_load_player_main(loading, pplayer);
2662 sg_load_player_cities(loading, pplayer);
2663 sg_load_player_units(loading, pplayer);
2664 sg_load_player_attributes(loading, pplayer);
2665
2666 /* Check the success of the functions above. */
2667 sg_check_ret();
2668
2669 /* print out some informations */
2670 if (is_ai(pplayer)) {
2671 log_normal(_("%s has been added as %s level AI-controlled player "
2672 "(%s)."), player_name(pplayer),
2673 ai_level_translated_name(pplayer->ai_common.skill_level),
2674 ai_name(pplayer->ai));
2675 } else {
2676 log_normal(_("%s has been added as human player."),
2677 player_name(pplayer));
2678 }
2680
2681 /* Also load the transport status of the units here. It must be a special
2682 * case as all units must be known (unit on an allied transporter). */
2683 players_iterate(pplayer) {
2684 /* Load unit transport status. */
2685 sg_load_player_units_transport(loading, pplayer);
2687
2688 /* Savegame may contain nation assignments that are incompatible with the
2689 * current nationset -- for instance, if it predates the introduction of
2690 * nationsets. Ensure they are compatible, one way or another. */
2692
2693 /* Some players may have invalid nations in the ruleset. Once all players
2694 * are loaded, pick one of the remaining nations for them. */
2695 players_iterate(pplayer) {
2696 if (pplayer->nation == NO_NATION_SELECTED) {
2697 player_set_nation(pplayer, pick_a_nation(NULL, FALSE, TRUE,
2698 NOT_A_BARBARIAN));
2699 /* TRANS: Minor error message: <Leader> ... <Poles>. */
2700 log_sg(_("%s had invalid nation; changing to %s."),
2701 player_name(pplayer), nation_plural_for_player(pplayer));
2702
2703 ai_traits_init(pplayer);
2704 }
2706
2707 /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
2709 players_iterate_alive(aplayer) {
2710 if (pplayers_allied(plr, aplayer)) {
2711 enum dipl_reason can_ally = pplayer_can_make_treaty(plr, aplayer,
2712 DS_ALLIANCE);
2713
2714 if (can_ally == DIPL_ALLIANCE_PROBLEM_US
2715 || can_ally == DIPL_ALLIANCE_PROBLEM_THEM) {
2716 log_sg("Illegal alliance structure detected: "
2717 "%s alliance to %s reduced to peace treaty.",
2720 player_diplstate_get(plr, aplayer)->type = DS_PEACE;
2721 player_diplstate_get(aplayer, plr)->type = DS_PEACE;
2722 }
2723 }
2726
2727 /* Update cached city illness. This can depend on trade routes,
2728 * so can't be calculated until all players have been loaded. */
2729 if (game.info.illness_on) {
2730 cities_iterate(pcity) {
2731 pcity->server.illness
2732 = city_illness_calc(pcity, NULL, NULL,
2733 &(pcity->illness_trade), NULL);
2735 }
2736
2737 /* Update all city information. This must come after all cities are
2738 * loaded (in player_load) but before player (dumb) cities are loaded
2739 * in player_load_vision(). */
2740 players_iterate(plr) {
2741 city_list_iterate(plr->cities, pcity) {
2742 city_refresh(pcity);
2743 sanity_check_city(pcity);
2744 CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
2747
2748 /* Since the cities must be placed on the map to put them on the
2749 player map we do this afterwards */
2750 players_iterate(pplayer) {
2751 sg_load_player_vision(loading, pplayer);
2752 /* Check the success of the function above. */
2753 sg_check_ret();
2755
2756 /* Check shared vision. */
2757 players_iterate(pplayer) {
2758 BV_CLR_ALL(pplayer->gives_shared_vision);
2759 BV_CLR_ALL(pplayer->server.really_gives_vision);
2761
2762 /* Set up shared vision... */
2763 players_iterate(pplayer) {
2764 int plr1 = player_index(pplayer);
2765
2766 players_iterate(pplayer2) {
2767 int plr2 = player_index(pplayer2);
2768
2770 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
2771 give_shared_vision(pplayer, pplayer2);
2772 }
2775
2776 /* ...and check it */
2777 players_iterate(pplayer1) {
2778 players_iterate(pplayer2) {
2779 /* TODO: Is there a good reason player is not marked as
2780 * giving shared vision to themselves -> really_gives_vision()
2781 * returning FALSE when pplayer1 == pplayer2 */
2782 if (pplayer1 != pplayer2
2783 && players_on_same_team(pplayer1, pplayer2)) {
2784 if (!really_gives_vision(pplayer1, pplayer2)) {
2785 sg_regr(3000900,
2786 _("%s did not give shared vision to team member %s."),
2787 player_name(pplayer1), player_name(pplayer2));
2788 give_shared_vision(pplayer1, pplayer2);
2789 }
2790 if (!really_gives_vision(pplayer2, pplayer1)) {
2791 sg_regr(3000900,
2792 _("%s did not give shared vision to team member %s."),
2793 player_name(pplayer2), player_name(pplayer1));
2794 give_shared_vision(pplayer2, pplayer1);
2795 }
2796 }
2799
2802
2803 /* All vision is ready; this calls city_thaw_workers_queue(). */
2805
2806 /* Make sure everything is consistent. */
2807 players_iterate(pplayer) {
2808 unit_list_iterate(pplayer->units, punit) {
2810 struct tile *ptile = unit_tile(punit);
2811
2812 log_sg("%s doing illegal activity in savegame!",
2814 log_sg("Activity: %s, Target: %s, Tile: (%d, %d), Terrain: %s",
2815 unit_activity_name(punit->activity),
2818 : "missing",
2819 TILE_XY(ptile), terrain_rule_name(tile_terrain(ptile)));
2820 punit->activity = ACTIVITY_IDLE;
2821 }
2824
2825 cities_iterate(pcity) {
2826 city_refresh(pcity);
2827 city_thaw_workers(pcity); /* may auto_arrange_workers() */
2829
2830 /* Player colors are always needed once game has started. Pre-2.4 savegames
2831 * lack them. This cannot be in compatibility conversion layer as we need
2832 * all the player data available to be able to assign best colors. */
2833 if (game_was_started()) {
2835 }
2836}
2837
2838/************************************************************************/
2841static void sg_load_player_main(struct loaddata *loading,
2842 struct player *plr)
2843{
2844 const char **slist;
2845 int i, plrno = player_number(plr);
2846 const char *str;
2847 struct government *gov;
2848 const char *level;
2849 const char *barb_str;
2850 size_t nval;
2851
2852 /* Check status and return if not OK (sg_success FALSE). */
2853 sg_check_ret();
2854
2855 /* Basic player data. */
2856 str = secfile_lookup_str(loading->file, "player%d.name", plrno);
2857 sg_failure_ret(str != NULL, "%s", secfile_error());
2859 sz_strlcpy(plr->username,
2860 secfile_lookup_str_default(loading->file, "",
2861 "player%d.username", plrno));
2863 "player%d.unassigned_user", plrno),
2864 "%s", secfile_error());
2866 secfile_lookup_str_default(loading->file, "",
2867 "player%d.orig_username",
2868 plrno));
2870 secfile_lookup_str_default(loading->file, "",
2871 "player%d.ranked_username",
2872 plrno));
2874 "player%d.unassigned_ranked", plrno),
2875 "%s", secfile_error());
2876 str = secfile_lookup_str_default(loading->file, "",
2877 "player%d.delegation_username",
2878 plrno);
2879 /* Defaults to no delegation. */
2880 if (strlen(str)) {
2882 }
2883
2884 /* Player flags */
2885 BV_CLR_ALL(plr->flags);
2886 slist = secfile_lookup_str_vec(loading->file, &nval, "player%d.flags", plrno);
2887 for (i = 0; i < nval; i++) {
2888 const char *sval = slist[i];
2889 enum plr_flag_id fid = plr_flag_id_by_name(sval, fc_strcasecmp);
2890
2891 sg_failure_ret(plr_flag_id_is_valid(fid), "Invalid player flag \"%s\".", sval);
2892
2893 BV_SET(plr->flags, fid);
2894 }
2895 free(slist);
2896
2897 /* Nation */
2898 str = secfile_lookup_str(loading->file, "player%d.nation", plrno);
2900 if (plr->nation != NULL) {
2901 ai_traits_init(plr);
2902 }
2903
2904 /* Government */
2905 str = secfile_lookup_str(loading->file, "player%d.government_name",
2906 plrno);
2908 sg_failure_ret(gov != NULL, "Player%d: unsupported government \"%s\".",
2909 plrno, str);
2910 plr->government = gov;
2911
2912 /* Target government */
2913 str = secfile_lookup_str(loading->file,
2914 "player%d.target_government_name", plrno);
2915 if (str != NULL) {
2917 } else {
2918 plr->target_government = NULL;
2919 }
2921 = secfile_lookup_int_default(loading->file, -1,
2922 "player%d.revolution_finishes", plrno);
2923
2925 &plr->server.got_first_city,
2926 "player%d.got_first_city", plrno),
2927 "%s", secfile_error());
2928
2929 /* Load diplomatic data (diplstate + embassy + vision).
2930 * Shared vision is loaded in sg_load_players(). */
2932 players_iterate(pplayer) {
2933 char buf[32];
2934 int unconverted;
2935 struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
2936 i = player_index(pplayer);
2937
2938 /* load diplomatic status */
2939 fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
2940
2941 unconverted =
2942 secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
2943 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
2944 /* Look up what state the unconverted number represents. */
2945 ds->type = loading->ds_t.order[unconverted];
2946 } else {
2947 log_sg("No valid diplomatic state type between players %d and %d",
2948 plrno, i);
2949
2950 ds->type = DS_WAR;
2951 }
2952
2953 unconverted =
2954 secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
2955 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
2956 /* Look up what state the unconverted number represents. */
2957 ds->max_state = loading->ds_t.order[unconverted];
2958 } else {
2959 log_sg("No valid diplomatic max_state between players %d and %d",
2960 plrno, i);
2961
2962 ds->max_state = DS_WAR;
2963 }
2964
2965 ds->first_contact_turn =
2966 secfile_lookup_int_default(loading->file, 0,
2967 "%s.first_contact_turn", buf);
2968 ds->turns_left =
2969 secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
2971 secfile_lookup_int_default(loading->file, 0,
2972 "%s.has_reason_to_cancel", buf);
2973 ds->contact_turns_left =
2974 secfile_lookup_int_default(loading->file, 0,
2975 "%s.contact_turns_left", buf);
2976
2977 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
2978 buf)) {
2979 BV_SET(plr->real_embassy, i);
2980 }
2981 /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
2982 * must be known. */
2984
2985 /* load ai data */
2986 players_iterate(aplayer) {
2987 char buf[32];
2988
2989 fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
2990 player_index(aplayer));
2991
2992 plr->ai_common.love[player_index(aplayer)] =
2993 secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
2994 CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
2996
2997 CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
2998
2999 /* Some sane defaults */
3000 plr->ai_common.fuzzy = 0;
3001 plr->ai_common.expand = 100;
3002 plr->ai_common.science_cost = 100;
3003
3004
3005 level = secfile_lookup_str_default(loading->file, NULL,
3006 "player%d.ai.level", plrno);
3007 if (level != NULL) {
3008 if (!fc_strcasecmp("Handicapped", level)) {
3009 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
3010 plr->ai_common.skill_level = AI_LEVEL_RESTRICTED;
3011 } else {
3012 plr->ai_common.skill_level = ai_level_by_name(level, fc_strcasecmp);
3013 }
3014 } else {
3015 plr->ai_common.skill_level = ai_level_invalid();
3016 }
3017
3018 if (!ai_level_is_valid(plr->ai_common.skill_level)) {
3022 "player%d.ai.skill_level",
3023 plrno));
3024 }
3025
3026 barb_str = secfile_lookup_str_default(loading->file, "None",
3027 "player%d.ai.barb_type", plrno);
3028 plr->ai_common.barbarian_type = barbarian_type_by_name(barb_str, fc_strcasecmp);
3029
3030 if (!barbarian_type_is_valid(plr->ai_common.barbarian_type)) {
3031 log_sg("Player%d: Invalid barbarian type \"%s\". "
3032 "Changed to \"None\".", plrno, barb_str);
3033 plr->ai_common.barbarian_type = NOT_A_BARBARIAN;
3034 }
3035
3036 if (is_barbarian(plr)) {
3037 server.nbarbarians++;
3038 }
3039
3040 if (is_ai(plr)) {
3042 CALL_PLR_AI_FUNC(gained_control, plr, plr);
3043 }
3044
3045 /* Load nation style. */
3046 {
3047 struct nation_style *style;
3048
3049 str = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
3050
3051 /* Handle pre-2.6 savegames */
3052 if (str == NULL) {
3053 str = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
3054 plrno);
3055 }
3056
3057 sg_failure_ret(str != NULL, "%s", secfile_error());
3058 style = style_by_rule_name(str);
3059 if (style == NULL) {
3060 style = style_by_number(0);
3061 log_sg("Player%d: unsupported city_style_name \"%s\". "
3062 "Changed to \"%s\".", plrno, str, style_rule_name(style));
3063 }
3064 plr->style = style;
3065 }
3066
3068 "player%d.idle_turns", plrno),
3069 "%s", secfile_error());
3071 "player%d.is_male", plrno);
3073 "player%d.is_alive", plrno),
3074 "%s", secfile_error());
3076 "player%d.turns_alive", plrno),
3077 "%s", secfile_error());
3079 "player%d.last_war", plrno),
3080 "%s", secfile_error());
3082 "player%d.phase_done", plrno);
3084 "player%d.gold", plrno),
3085 "%s", secfile_error());
3087 "player%d.rates.tax", plrno),
3088 "%s", secfile_error());
3090 "player%d.rates.science", plrno),
3091 "%s", secfile_error());
3093 "player%d.rates.luxury", plrno),
3094 "%s", secfile_error());
3095 plr->server.bulbs_last_turn =
3096 secfile_lookup_int_default(loading->file, 0,
3097 "player%d.research.bulbs_last_turn", plrno);
3098
3099 /* Traits */
3100 if (plr->nation) {
3101 for (i = 0; i < loading->trait.size; i++) {
3102 enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
3103
3104 if (trait_is_valid(tr)) {
3105 int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
3106 plrno, i);
3107
3108 if (val != -1) {
3109 plr->ai_common.traits[tr].val = val;
3110 }
3111
3112 sg_failure_ret(secfile_lookup_int(loading->file, &val,
3113 "player%d.trait%d.mod", plrno, i),
3114 "%s", secfile_error());
3115 plr->ai_common.traits[tr].mod = val;
3116 }
3117 }
3118 }
3119
3120 /* Achievements */
3121 {
3122 int count;
3123
3124 count = secfile_lookup_int_default(loading->file, -1,
3125 "player%d.achievement_count", plrno);
3126
3127 if (count > 0) {
3128 for (i = 0; i < count; i++) {
3129 const char *name;
3130 struct achievement *pach;
3131 bool first;
3132
3133 name = secfile_lookup_str(loading->file,
3134 "player%d.achievement%d.name", plrno, i);
3136
3137 sg_failure_ret(pach != NULL,
3138 "Unknown achievement \"%s\".", name);
3139
3141 "player%d.achievement%d.first",
3142 plrno, i),
3143 "achievement error: %s", secfile_error());
3144
3145 sg_failure_ret(pach->first == NULL || !first,
3146 "Multiple players listed as first to get achievement \"%s\".",
3147 name);
3148
3149 BV_SET(pach->achievers, player_index(plr));
3150
3151 if (first) {
3152 pach->first = plr;
3153 }
3154 }
3155 }
3156 }
3157
3158 /* Player score. */
3159 plr->score.happy =
3160 secfile_lookup_int_default(loading->file, 0,
3161 "score%d.happy", plrno);
3162 plr->score.content =
3163 secfile_lookup_int_default(loading->file, 0,
3164 "score%d.content", plrno);
3165 plr->score.unhappy =
3166 secfile_lookup_int_default(loading->file, 0,
3167 "score%d.unhappy", plrno);
3168 plr->score.angry =
3169 secfile_lookup_int_default(loading->file, 0,
3170 "score%d.angry", plrno);
3171
3172 /* Make sure that the score about specialists in current ruleset that
3173 * were not present at saving time are set to zero. */
3175 plr->score.specialists[sp] = 0;
3177
3178 for (i = 0; i < loading->specialist.size; i++) {
3180 = secfile_lookup_int_default(loading->file, 0,
3181 "score%d.specialists%d", plrno, i);
3182 }
3183
3184 plr->score.wonders =
3185 secfile_lookup_int_default(loading->file, 0,
3186 "score%d.wonders", plrno);
3187 plr->score.techs =
3188 secfile_lookup_int_default(loading->file, 0,
3189 "score%d.techs", plrno);
3190 plr->score.techout =
3191 secfile_lookup_int_default(loading->file, 0,
3192 "score%d.techout", plrno);
3193 plr->score.landarea =
3194 secfile_lookup_int_default(loading->file, 0,
3195 "score%d.landarea", plrno);
3196 plr->score.settledarea =
3197 secfile_lookup_int_default(loading->file, 0,
3198 "score%d.settledarea", plrno);
3199 plr->score.population =
3200 secfile_lookup_int_default(loading->file, 0,
3201 "score%d.population", plrno);
3202 plr->score.cities =
3203 secfile_lookup_int_default(loading->file, 0,
3204 "score%d.cities", plrno);
3205 plr->score.units =
3206 secfile_lookup_int_default(loading->file, 0,
3207 "score%d.units", plrno);
3208 plr->score.pollution =
3209 secfile_lookup_int_default(loading->file, 0,
3210 "score%d.pollution", plrno);
3211 plr->score.literacy =
3212 secfile_lookup_int_default(loading->file, 0,
3213 "score%d.literacy", plrno);
3214 plr->score.bnp =
3215 secfile_lookup_int_default(loading->file, 0,
3216 "score%d.bnp", plrno);
3217 plr->score.mfg =
3218 secfile_lookup_int_default(loading->file, 0,
3219 "score%d.mfg", plrno);
3220 plr->score.spaceship =
3221 secfile_lookup_int_default(loading->file, 0,
3222 "score%d.spaceship", plrno);
3223 plr->score.units_built =
3224 secfile_lookup_int_default(loading->file, 0,
3225 "score%d.units_built", plrno);
3226 plr->score.units_killed =
3227 secfile_lookup_int_default(loading->file, 0,
3228 "score%d.units_killed", plrno);
3229 plr->score.units_lost =
3230 secfile_lookup_int_default(loading->file, 0,
3231 "score%d.units_lost", plrno);
3232 plr->score.culture =
3233 secfile_lookup_int_default(loading->file, 0,
3234 "score%d.culture", plrno);
3235 plr->score.game =
3236 secfile_lookup_int_default(loading->file, 0,
3237 "score%d.total", plrno);
3238
3239 /* Load space ship data. */
3240 {
3241 struct player_spaceship *ship = &plr->spaceship;
3242 char prefix[32];
3243 const char *st;
3244 int ei;
3245
3246 fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
3247 spaceship_init(ship);
3249 &ei,
3250 "%s.state", prefix),
3251 "%s", secfile_error());
3252 ship->state = ei;
3253
3254 if (ship->state != SSHIP_NONE) {
3256 "%s.structurals", prefix),
3257 "%s", secfile_error());
3259 "%s.components", prefix),
3260 "%s", secfile_error());
3262 "%s.modules", prefix),
3263 "%s", secfile_error());
3264 sg_failure_ret(secfile_lookup_int(loading->file, &ship->fuel,
3265 "%s.fuel", prefix),
3266 "%s", secfile_error());
3268 "%s.propulsion", prefix),
3269 "%s", secfile_error());
3271 "%s.habitation", prefix),
3272 "%s", secfile_error());
3274 "%s.life_support", prefix),
3275 "%s", secfile_error());
3277 "%s.solar_panels", prefix),
3278 "%s", secfile_error());
3279
3280 st = secfile_lookup_str(loading->file, "%s.structure", prefix);
3281 sg_failure_ret(st != NULL, "%s", secfile_error())
3282 for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
3283 sg_failure_ret(st[i] == '1' || st[i] == '0',
3284 "Undefined value '%c' within '%s.structure'.", st[i],
3285 prefix)
3286
3287 if (!(st[i] == '0')) {
3288 BV_SET(ship->structure, i);
3289 }
3290 }
3291 if (ship->state >= SSHIP_LAUNCHED) {
3293 "%s.launch_year", prefix),
3294 "%s", secfile_error());
3295 }
3297 }
3298 }
3299
3300 /* Load lost wonder data. */
3301 str = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
3302 /* If not present, probably an old savegame; nothing to be done */
3303 if (str != NULL) {
3304 int k;
3305
3306 sg_failure_ret(strlen(str) == loading->improvement.size,
3307 "Invalid length for 'player%d.lost_wonders' ("
3308 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ")",
3309 plrno, strlen(str), loading->improvement.size);
3310 for (k = 0; k < loading->improvement.size; k++) {
3311 sg_failure_ret(str[k] == '1' || str[k] == '0',
3312 "Undefined value '%c' within "
3313 "'player%d.lost_wonders'.", plrno, str[k]);
3314
3315 if (str[k] == '1') {
3316 struct impr_type *pimprove =
3318
3319 if (pimprove) {
3320 plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
3321 }
3322 }
3323 }
3324 }
3325
3326 plr->history =
3327 secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
3328 plr->server.huts =
3329 secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
3330}
3331
3332/************************************************************************/
3335static void sg_load_player_cities(struct loaddata *loading,
3336 struct player *plr)
3337{
3338 int ncities, i, plrno = player_number(plr);
3339 bool tasks_handled;
3340 int wlist_max_length = 0;
3341
3342 /* Check status and return if not OK (sg_success FALSE). */
3343 sg_check_ret();
3344
3345 sg_failure_ret(secfile_lookup_int(loading->file, &ncities,
3346 "player%d.ncities", plrno),
3347 "%s", secfile_error());
3348
3349 if (!plr->is_alive && ncities > 0) {
3350 log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
3351 ncities = 0;
3352 }
3353
3354 if (!plr->server.got_first_city && ncities > 0) {
3355 /* Probably barbarians in an old savegame; fix up */
3356 plr->server.got_first_city = TRUE;
3357 }
3358
3359 /* Find longest worklist */
3360 for (i = 0; i < ncities; i++) {
3361 int wl_length = secfile_lookup_int_default(loading->file, 0,
3362 "player%d.c%d.wl_length",
3363 plrno, i);
3364
3365 wlist_max_length = MAX(wlist_max_length, wl_length);
3366 }
3367
3368 /* Load all cities of the player. */
3369 for (i = 0; i < ncities; i++) {
3370 char buf[32];
3371 struct city *pcity;
3372
3373 fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
3374
3375 /* Create a dummy city. */
3376 pcity = create_city_virtual(plr, NULL, buf);
3377 adv_city_alloc(pcity);
3378 if (!sg_load_player_city(loading, plr, pcity, buf, wlist_max_length)) {
3379 adv_city_free(pcity);
3380 destroy_city_virtual(pcity);
3381 sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
3382 }
3383
3385 idex_register_city(&wld, pcity);
3386
3387 /* Load the information about the nationality of citizens. This is done
3388 * here because the city sanity check called by citizens_update() requires
3389 * that the city is registered. */
3390 sg_load_player_city_citizens(loading, plr, pcity, buf);
3391
3392 /* After everything is loaded, but before vision. */
3393 map_claim_ownership(city_tile(pcity), plr, city_tile(pcity), TRUE);
3394
3395 /* adding the city contribution to fog-of-war */
3396 pcity->server.vision = vision_new(plr, city_tile(pcity));
3398 city_refresh_vision(pcity);
3399
3400 city_list_append(plr->cities, pcity);
3401 }
3402
3403 tasks_handled = FALSE;
3404 for (i = 0; !tasks_handled; i++) {
3405 int city_id;
3406 struct city *pcity = NULL;
3407
3408 city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
3409 plrno, i);
3410
3411 if (city_id != -1) {
3412 pcity = player_city_by_number(plr, city_id);
3413 }
3414
3415 if (pcity != NULL) {
3416 const char *str;
3417 int nat_x, nat_y;
3418 struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
3419
3420 nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
3421 nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
3422
3423 ptask->ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3424
3425 str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
3426 ptask->act = unit_activity_by_name(str, fc_strcasecmp);
3427
3428 sg_failure_ret(unit_activity_is_valid(ptask->act),
3429 "Unknown workertask activity %s", str);
3430
3431 str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
3432
3433 if (strcmp("-", str)) {
3435
3436 sg_failure_ret(ptask->tgt != NULL,
3437 "Unknown workertask target %s", str);
3438 } else {
3439 ptask->tgt = NULL;
3440 }
3441
3442 ptask->want = secfile_lookup_int_default(loading->file, 1,
3443 "player%d.task%d.want", plrno, i);
3444
3445 worker_task_list_append(pcity->task_reqs, ptask);
3446 } else {
3447 tasks_handled = TRUE;
3448 }
3449 }
3450}
3451
3452/************************************************************************/
3455static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
3456 struct city *pcity, const char *citystr,
3457 int wlist_max_length)
3458{
3459 struct player *past;
3460 const char *kind, *name, *str;
3461 int id, i, repair, sp_count = 0, workers = 0, value;
3462 int nat_x, nat_y;
3463 citizens size;
3464 const char *stylename;
3465 const struct civ_map *nmap = &(wld.map);
3466
3467 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", citystr),
3468 FALSE, "%s", secfile_error());
3469 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", citystr),
3470 FALSE, "%s", secfile_error());
3471 pcity->tile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3472 sg_warn_ret_val(NULL != pcity->tile, FALSE,
3473 "%s has invalid center tile (%d, %d)",
3474 citystr, nat_x, nat_y);
3475 sg_warn_ret_val(NULL == tile_city(pcity->tile), FALSE,
3476 "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
3477
3478 /* Instead of dying, use 'citystr' string for damaged name. */
3479 city_name_set(pcity, secfile_lookup_str_default(loading->file, citystr,
3480 "%s.name", citystr));
3481
3482 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->id, "%s.id",
3483 citystr), FALSE, "%s", secfile_error());
3484
3485 id = secfile_lookup_int_default(loading->file, player_number(plr),
3486 "%s.original", citystr);
3487 past = player_by_number(id);
3488 if (NULL != past) {
3489 pcity->original = past;
3490 }
3491
3492 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
3493 citystr), FALSE, "%s", secfile_error());
3494 size = (citizens)value; /* set the correct type */
3495 sg_warn_ret_val(value == (int)size, FALSE,
3496 "Invalid city size: %d, set to %d", value, size);
3497 city_size_set(pcity, size);
3498
3499 for (i = 0; i < loading->specialist.size; i++) {
3500 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
3501 citystr, i),
3502 FALSE, "%s", secfile_error());
3503 pcity->specialists[specialist_index(loading->specialist.order[i])]
3504 = (citizens)value;
3505 sp_count += value;
3506 }
3507
3508 for (i = 0; i < MAX_TRADE_ROUTES; i++) {
3509 int partner = secfile_lookup_int_default(loading->file, 0,
3510 "%s.traderoute%d", citystr, i);
3511
3512 if (partner != 0) {
3513 struct trade_route *proute = fc_malloc(sizeof(struct trade_route));
3514
3515 proute->partner = partner;
3516 proute->dir = RDIR_BIDIRECTIONAL;
3517 proute->goods = goods_by_number(0); /* First good */
3518
3519 trade_route_list_append(pcity->routes, proute);
3520 }
3521 }
3522
3524 "%s.food_stock", citystr),
3525 FALSE, "%s", secfile_error());
3527 "%s.shield_stock", citystr),
3528 FALSE, "%s", secfile_error());
3529 pcity->history =
3530 secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
3531
3532 pcity->airlift =
3533 secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
3534 pcity->was_happy =
3535 secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
3536 citystr);
3537
3538 pcity->turn_plague =
3539 secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
3540
3542 "%s.anarchy", citystr),
3543 FALSE, "%s", secfile_error());
3544 pcity->rapture =
3545 secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
3546 pcity->steal =
3547 secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
3548
3549 /* before did_buy for undocumented hack */
3550 pcity->turn_founded =
3551 secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
3552 citystr);
3553 sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
3554 citystr), FALSE, "%s", secfile_error());
3555 pcity->did_buy = (i != 0);
3556 if (i == -1 && pcity->turn_founded == -2) {
3557 /* undocumented hack */
3558 pcity->turn_founded = game.info.turn;
3559 }
3560
3561 pcity->did_sell =
3562 secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
3563
3565 "%s.turn_last_built", citystr),
3566 FALSE, "%s", secfile_error());
3567
3568 kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
3569 citystr);
3570 name = secfile_lookup_str(loading->file, "%s.currently_building_name",
3571 citystr);
3572 pcity->production = universal_by_rule_name(kind, name);
3573 sg_warn_ret_val(pcity->production.kind != universals_n_invalid(), FALSE,
3574 "%s.currently_building: unknown \"%s\" \"%s\".",
3575 citystr, kind, name);
3576
3577 kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
3578 citystr);
3579 name = secfile_lookup_str(loading->file, "%s.changed_from_name",
3580 citystr);
3582 sg_warn_ret_val(pcity->changed_from.kind != universals_n_invalid(), FALSE,
3583 "%s.changed_from: unknown \"%s\" \"%s\".",
3584 citystr, kind, name);
3585
3586 pcity->before_change_shields =
3588 "%s.before_change_shields", citystr);
3589 pcity->caravan_shields =
3590 secfile_lookup_int_default(loading->file, 0,
3591 "%s.caravan_shields", citystr);
3592 pcity->disbanded_shields =
3593 secfile_lookup_int_default(loading->file, 0,
3594 "%s.disbanded_shields", citystr);
3596 secfile_lookup_int_default(loading->file, 0,
3597 "%s.last_turns_shield_surplus",
3598 citystr);
3599
3600 stylename = secfile_lookup_str_default(loading->file, NULL,
3601 "%s.style", citystr);
3602 if (stylename != NULL) {
3603 pcity->style = city_style_by_rule_name(stylename);
3604 } else {
3605 pcity->style = 0;
3606 }
3607 if (pcity->style < 0) {
3608 pcity->style = city_style(pcity);
3609 }
3610
3611 pcity->server.synced = FALSE; /* Must re-sync with clients */
3612
3613 /* Initialise list of city improvements. */
3614 for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
3615 pcity->built[i].turn = I_NEVER;
3616 }
3617
3618 /* Load city improvements. */
3619 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
3620 sg_warn_ret_val(str != NULL, FALSE, "%s", secfile_error());
3621 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
3622 "Invalid length of '%s.improvements' ("
3623 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
3624 citystr, strlen(str), loading->improvement.size);
3625 for (i = 0; i < loading->improvement.size; i++) {
3626 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
3627 "Undefined value '%c' within '%s.improvements'.",
3628 str[i], citystr)
3629
3630 if (str[i] == '1') {
3631 struct impr_type *pimprove =
3633
3634 if (pimprove) {
3635 city_add_improvement(pcity, pimprove);
3636 }
3637 }
3638 }
3639
3640 sg_failure_ret_val(loading->worked_tiles != NULL, FALSE,
3641 "No worked tiles map defined.");
3642
3643 city_freeze_workers(pcity);
3644
3645 /* Load new savegame with variable (squared) city radius and worked
3646 * tiles map */
3647
3648 int radius_sq
3649 = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
3650 citystr);
3651 city_map_radius_sq_set(pcity, radius_sq);
3652
3653 city_tile_iterate(nmap, CITY_MAP_MAX_RADIUS_SQ, city_tile(pcity), ptile) {
3654 if (loading->worked_tiles[ptile->index] == pcity->id) {
3655 if (sq_map_distance(ptile, pcity->tile) > radius_sq) {
3656 log_sg("[%s] '%s' (%d, %d) has worker outside current radius "
3657 "at (%d, %d); repairing", citystr, city_name_get(pcity),
3658 TILE_XY(pcity->tile), TILE_XY(ptile));
3660 sp_count++;
3661 } else {
3662 tile_set_worked(ptile, pcity);
3663 workers++;
3664 }
3665
3666#ifdef FREECIV_DEBUG
3667 /* Set this tile to unused; a check for not resetted tiles is
3668 * included in game_load_internal() */
3669 loading->worked_tiles[ptile->index] = -1;
3670#endif /* FREECIV_DEBUG */
3671 }
3673
3674 if (tile_worked(city_tile(pcity)) != pcity) {
3675 struct city *pwork = tile_worked(city_tile(pcity));
3676
3677 if (NULL != pwork) {
3678 log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
3679 "(%d,%d) [%d]; repairing", citystr, city_name_get(pcity),
3680 TILE_XY(city_tile(pcity)), city_size_get(pcity), city_name_get(pwork),
3681 TILE_XY(city_tile(pwork)), city_size_get(pwork));
3682
3683 tile_set_worked(city_tile(pcity), NULL); /* remove tile from pwork */
3685 auto_arrange_workers(pwork);
3686 } else {
3687 log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing",
3688 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)),
3689 city_size_get(pcity));
3690 }
3691
3692 /* repair pcity */
3693 tile_set_worked(city_tile(pcity), pcity);
3694 city_repair_size(pcity, -1);
3695 }
3696
3697 repair = city_size_get(pcity) - sp_count - (workers - FREE_WORKED_TILES);
3698 if (0 != repair) {
3699 log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
3700 "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
3701 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)), city_size_get(pcity),
3702 workers, FREE_WORKED_TILES, sp_count);
3703
3704 /* repair pcity */
3705 city_repair_size(pcity, repair);
3706 }
3707
3708 /* worklist_init() done in create_city_virtual() */
3709 worklist_load(loading->file, wlist_max_length, &pcity->worklist, "%s", citystr);
3710
3711 /* Load city options. */
3712 BV_CLR_ALL(pcity->city_options);
3713 for (i = 0; i < CITYO_LAST; i++) {
3714 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
3715 citystr, i)) {
3716 BV_SET(pcity->city_options, i);
3717 }
3718 }
3719
3720 CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
3721
3722 return TRUE;
3723}
3724
3725/************************************************************************/
3728static void sg_load_player_city_citizens(struct loaddata *loading,
3729 struct player *plr,
3730 struct city *pcity,
3731 const char *citystr)
3732{
3734 citizens size;
3735
3736 citizens_init(pcity);
3737 player_slots_iterate(pslot) {
3738 int nationality;
3739
3741 "%s.citizen%d", citystr,
3742 player_slot_index(pslot));
3743 if (nationality > 0 && !player_slot_is_used(pslot)) {
3744 log_sg("Citizens of an invalid nation for %s (player slot %d)!",
3745 city_name_get(pcity), player_slot_index(pslot));
3746 continue;
3747 }
3748
3749 if (nationality != -1 && player_slot_is_used(pslot)) {
3751 "Invalid value for citizens of player %d in %s: %d.",
3753 citizens_nation_set(pcity, pslot, nationality);
3754 }
3756 /* Sanity check. */
3757 size = citizens_count(pcity);
3758 if (size != city_size_get(pcity)) {
3759 if (size != 0) {
3760 /* size == 0 can be result from the fact that ruleset had no
3761 * nationality enabled at saving time, so no citizens at all
3762 * were saved. But something more serious must be going on if
3763 * citizens have been saved partially - if some of them are there. */
3764 log_sg("City size and number of citizens does not match in %s "
3765 "(%d != %d)! Repairing ...", city_name_get(pcity),
3766 city_size_get(pcity), size);
3767 }
3768 citizens_update(pcity, NULL);
3769 }
3770 }
3771}
3772
3773/************************************************************************/
3776static void sg_load_player_units(struct loaddata *loading,
3777 struct player *plr)
3778{
3779 int nunits, i, plrno = player_number(plr);
3780
3781 /* Check status and return if not OK (sg_success FALSE). */
3782 sg_check_ret();
3783
3784 sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
3785 "player%d.nunits", plrno),
3786 "%s", secfile_error());
3787 if (!plr->is_alive && nunits > 0) {
3788 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
3789 nunits = 0; /* Some old savegames may be buggy. */
3790 }
3791
3792 for (i = 0; i < nunits; i++) {
3793 struct unit *punit;
3794 struct city *pcity;
3795 const char *name;
3796 char buf[32];
3797 struct unit_type *type;
3798 struct tile *ptile;
3799
3800 fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
3801
3802 name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
3804 sg_failure_ret(type != NULL, "%s: unknown unit type \"%s\".", buf, name);
3805
3806 /* Create a dummy unit. */
3807 punit = unit_virtual_create(plr, NULL, type, 0);
3808 if (!sg_load_player_unit(loading, plr, punit, buf)) {
3810 sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
3811 }
3812
3815
3816 if ((pcity = game_city_by_number(punit->homecity))) {
3817 unit_list_prepend(pcity->units_supported, punit);
3818 } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
3819 log_sg("%s: bad home city %d.", buf, punit->homecity);
3821 }
3822
3823 ptile = unit_tile(punit);
3824
3825 /* allocate the unit's contribution to fog of war */
3828 /* NOTE: There used to be some map_set_known calls here. These were
3829 * unneeded since unfogging the tile when the unit sees it will
3830 * automatically reveal that tile. */
3831
3832 unit_list_append(plr->units, punit);
3833 unit_list_prepend(unit_tile(punit)->units, punit);
3834
3835 /* Claim ownership of fortress? */
3836 if ((extra_owner(ptile) == NULL
3837 || pplayers_at_war(extra_owner(ptile), plr))
3839 tile_claim_bases(ptile, plr);
3840 }
3841 }
3842}
3843
3844/************************************************************************/
3854static int sg_order_to_action(int order, struct unit *act_unit,
3855 struct tile *tgt_tile)
3856{
3857 switch (order) {
3859 if (tile_city(tgt_tile)
3860 && city_owner(tile_city(tgt_tile)) == unit_owner(act_unit)) {
3861 /* The player's cities are loaded right before their units. It wasn't
3862 * possible for rulesets to allow joining foreign cities before 3.0.
3863 * This means that a converted build city order only can be a Join
3864 * City order if it targets a domestic city. */
3865 return ACTION_JOIN_CITY;
3866 } else {
3867 /* Assume that the intention was to found a new city. */
3868 return ACTION_FOUND_CITY;
3869 }
3871 /* Maps one to one with each other. */
3872 return ACTION_HELP_WONDER;
3874 /* Maps one to one with each other. */
3875 return ACTION_TRADE_ROUTE;
3876 case ORDER_OLD_DISBAND:
3877 /* Added to the order system in the same commit as Help Wonder. Assume
3878 * that anyone that intended to order Help Wonder used Help Wonder. */
3879 /* Could in theory be intended as an order to disband in the field. Why
3880 * would the player give a unit an order to go to a non city location
3881 * and disband there? Assume the intention was to recover production
3882 * until a non recovering disband order is found. */
3883 return ACTION_DISBAND_UNIT_RECOVER;
3884 case ORDER_OLD_HOMECITY:
3885 return ACTION_HOME_CITY;
3886 }
3887
3888 /* The order hasn't been replaced by an action. */
3889 return ACTION_NONE;
3890}
3891
3892/************************************************************************/
3895static bool sg_load_player_unit(struct loaddata *loading,
3896 struct player *plr, struct unit *punit,
3897 const char *unitstr)
3898{
3899 enum unit_activity activity;
3900 int nat_x, nat_y;
3901 enum tile_special_type target;
3902 struct extra_type *pextra = NULL;
3903 struct base_type *pbase = NULL;
3904 struct road_type *proad = NULL;
3905 struct tile *ptile;
3906 int extra_id;
3907 int base_id;
3908 int road_id;
3909 int ei;
3910 const char *facing_str;
3911 enum tile_special_type cfspe;
3912 int natnbr;
3913 bool ai_controlled;
3914
3915 sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->id, "%s.id",
3916 unitstr), FALSE, "%s", secfile_error());
3917 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", unitstr),
3918 FALSE, "%s", secfile_error());
3919 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", unitstr),
3920 FALSE, "%s", secfile_error());
3921
3922 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3923 sg_warn_ret_val(NULL != ptile, FALSE, "%s invalid tile (%d, %d)",
3924 unitstr, nat_x, nat_y);
3925 unit_tile_set(punit, ptile);
3926
3927 facing_str
3928 = secfile_lookup_str_default(loading->file, "x",
3929 "%s.facing", unitstr);
3930 if (facing_str[0] != 'x') {
3931 /* We don't touch punit->facing if savegame does not contain that
3932 * information. Initial orientation set by unit_virtual_create()
3933 * is as good as any. */
3934 enum direction8 facing = char2dir(facing_str[0]);
3935
3936 if (direction8_is_valid(facing)) {
3937 punit->facing = facing;
3938 } else {
3939 log_error("Illegal unit orientation '%s'", facing_str);
3940 }
3941 }
3942
3943 /* If savegame has unit nationality, it doesn't hurt to
3944 * internally set it even if nationality rules are disabled. */
3945 natnbr = secfile_lookup_int_default(loading->file,
3946 player_number(plr),
3947 "%s.nationality", unitstr);
3948
3950 if (punit->nationality == NULL) {
3951 punit->nationality = plr;
3952 }
3953
3955 "%s.homecity", unitstr), FALSE,
3956 "%s", secfile_error());
3958 "%s.moves", unitstr), FALSE,
3959 "%s", secfile_error());
3961 "%s.fuel", unitstr), FALSE,
3962 "%s", secfile_error());
3964 "%s.activity", unitstr), FALSE,
3965 "%s", secfile_error());
3966 activity = unit_activity_by_name(loading->activities.order[ei],
3968
3971 "%s.born", unitstr);
3972
3973 extra_id = secfile_lookup_int_default(loading->file, -2,
3974 "%s.activity_tgt", unitstr);
3975
3976 if (extra_id != -2) {
3977 if (extra_id >= 0 && extra_id < loading->extra.size) {
3978 pextra = loading->extra.order[extra_id];
3979 set_unit_activity_targeted(punit, activity, pextra);
3980 } else if (activity == ACTIVITY_IRRIGATE) {
3982 EC_IRRIGATION,
3984 punit);
3985 if (tgt != NULL) {
3986 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
3987 } else {
3988 set_unit_activity(punit, ACTIVITY_CULTIVATE);
3989 }
3990 } else if (activity == ACTIVITY_MINE) {
3992 EC_MINE,
3994 punit);
3995 if (tgt != NULL) {
3996 set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
3997 } else {
3998 set_unit_activity(punit, ACTIVITY_PLANT);
3999 }
4000 } else {
4001 set_unit_activity(punit, activity);
4002 }
4003 } else {
4004 /* extra_id == -2 -> activity_tgt not set */
4005 base_id = secfile_lookup_int_default(loading->file, -1,
4006 "%s.activity_base", unitstr);
4007 if (base_id >= 0 && base_id < loading->base.size) {
4008 pbase = loading->base.order[base_id];
4009 }
4010 road_id = secfile_lookup_int_default(loading->file, -1,
4011 "%s.activity_road", unitstr);
4012 if (road_id >= 0 && road_id < loading->road.size) {
4013 proad = loading->road.order[road_id];
4014 }
4015
4016 {
4017 int tgt_no = secfile_lookup_int_default(loading->file,
4018 loading->special.size /* S_LAST */,
4019 "%s.activity_target", unitstr);
4020 if (tgt_no >= 0 && tgt_no < loading->special.size) {
4021 target = loading->special.order[tgt_no];
4022 } else {
4023 target = S_LAST;
4024 }
4025 }
4026
4027 if (target == S_OLD_ROAD) {
4028 target = S_LAST;
4030 } else if (target == S_OLD_RAILROAD) {
4031 target = S_LAST;
4033 }
4034
4035 if (activity == ACTIVITY_OLD_ROAD) {
4036 activity = ACTIVITY_GEN_ROAD;
4038 } else if (activity == ACTIVITY_OLD_RAILROAD) {
4039 activity = ACTIVITY_GEN_ROAD;
4041 }
4042
4043 /* We need changed_from == ACTIVITY_IDLE by now so that
4044 * set_unit_activity() and friends don't spuriously restore activity
4045 * points -- unit should have been created this way */
4046 fc_assert(punit->changed_from == ACTIVITY_IDLE);
4047
4048 if (activity == ACTIVITY_BASE) {
4049 if (pbase) {
4051 } else {
4052 log_sg("Cannot find base %d for %s to build",
4053 base_id, unit_rule_name(punit));
4054 set_unit_activity(punit, ACTIVITY_IDLE);
4055 }
4056 } else if (activity == ACTIVITY_GEN_ROAD) {
4057 if (proad) {
4059 } else {
4060 log_sg("Cannot find road %d for %s to build",
4061 road_id, unit_rule_name(punit));
4062 set_unit_activity(punit, ACTIVITY_IDLE);
4063 }
4064 } else if (activity == ACTIVITY_PILLAGE) {
4065 struct extra_type *a_target;
4066
4067 if (target != S_LAST) {
4068 a_target = special_extra_get(target);
4069 } else if (pbase != NULL) {
4070 a_target = base_extra_get(pbase);
4071 } else if (proad != NULL) {
4072 a_target = road_extra_get(proad);
4073 } else {
4074 a_target = NULL;
4075 }
4076 /* An out-of-range base number is seen with old savegames. We take
4077 * it as indicating undirected pillaging. We will assign pillage
4078 * targets before play starts. */
4079 set_unit_activity_targeted(punit, activity, a_target);
4080 } else if (activity == ACTIVITY_IRRIGATE) {
4082 EC_IRRIGATION,
4084 punit);
4085 if (tgt != NULL) {
4086 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
4087 } else {
4088 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, NULL);
4089 }
4090 } else if (activity == ACTIVITY_MINE) {
4092 EC_MINE,
4094 punit);
4095 if (tgt != NULL) {
4096 set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
4097 } else {
4098 set_unit_activity_targeted(punit, ACTIVITY_MINE, NULL);
4099 }
4100 } else if (activity == ACTIVITY_POLLUTION) {
4102 ERM_CLEANPOLLUTION,
4104 punit);
4105 if (tgt != NULL) {
4106 set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, tgt);
4107 } else {
4108 set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, NULL);
4109 }
4110 } else if (activity == ACTIVITY_FALLOUT) {
4112 ERM_CLEANFALLOUT,
4114 punit);
4115 if (tgt != NULL) {
4116 set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, tgt);
4117 } else {
4118 set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, NULL);
4119 }
4120 } else {
4121 set_unit_activity_targeted(punit, activity, NULL);
4122 }
4123 } /* activity_tgt == NULL */
4124
4126 "%s.activity_count", unitstr), FALSE,
4127 "%s", secfile_error());
4128
4130 secfile_lookup_int_default(loading->file, ACTIVITY_IDLE,
4131 "%s.changed_from", unitstr);
4132
4133 extra_id = secfile_lookup_int_default(loading->file, -2,
4134 "%s.changed_from_tgt", unitstr);
4135
4136 if (extra_id != -2) {
4137 if (extra_id >= 0 && extra_id < loading->extra.size) {
4138 punit->changed_from_target = loading->extra.order[extra_id];
4139 } else {
4140 punit->changed_from_target = NULL;
4141 }
4142 } else {
4143 /* extra_id == -2 -> changed_from_tgt not set */
4144
4145 cfspe =
4147 "%s.changed_from_target", unitstr);
4148 base_id =
4149 secfile_lookup_int_default(loading->file, -1,
4150 "%s.changed_from_base", unitstr);
4151 road_id =
4152 secfile_lookup_int_default(loading->file, -1,
4153 "%s.changed_from_road", unitstr);
4154
4155 if (road_id == -1) {
4156 if (cfspe == S_OLD_ROAD) {
4158 if (proad) {
4159 road_id = road_number(proad);
4160 }
4161 } else if (cfspe == S_OLD_RAILROAD) {
4163 if (proad) {
4164 road_id = road_number(proad);
4165 }
4166 }
4167 }
4168
4169 if (base_id >= 0 && base_id < loading->base.size) {
4170 punit->changed_from_target = base_extra_get(loading->base.order[base_id]);
4171 } else if (road_id >= 0 && road_id < loading->road.size) {
4172 punit->changed_from_target = road_extra_get(loading->road.order[road_id]);
4173 } else if (cfspe != S_LAST) {
4175 } else {
4176 punit->changed_from_target = NULL;
4177 }
4178
4179 if (punit->changed_from == ACTIVITY_IRRIGATE) {
4181 EC_IRRIGATION,
4183 punit);
4184 if (tgt != NULL) {
4186 } else {
4187 punit->changed_from_target = NULL;
4188 }
4189 } else if (punit->changed_from == ACTIVITY_MINE) {
4191 EC_MINE,
4193 punit);
4194 if (tgt != NULL) {
4196 } else {
4197 punit->changed_from_target = NULL;
4198 }
4199 } else if (punit->changed_from == ACTIVITY_POLLUTION) {
4201 ERM_CLEANPOLLUTION,
4203 punit);
4204 if (tgt != NULL) {
4206 } else {
4207 punit->changed_from_target = NULL;
4208 }
4209 } else if (punit->changed_from == ACTIVITY_FALLOUT) {
4211 ERM_CLEANFALLOUT,
4213 punit);
4214 if (tgt != NULL) {
4216 } else {
4217 punit->changed_from_target = NULL;
4218 }
4219 }
4220 }
4221
4223 secfile_lookup_int_default(loading->file, 0,
4224 "%s.changed_from_count", unitstr);
4225
4226 /* Special case: for a long time, we accidentally incremented
4227 * activity_count while a unit was sentried, so it could increase
4228 * without bound (bug #20641) and be saved in old savefiles.
4229 * We zero it to prevent potential trouble overflowing the range
4230 * in network packets, etc. */
4231 if (activity == ACTIVITY_SENTRY) {
4232 punit->activity_count = 0;
4233 }
4234 if (punit->changed_from == ACTIVITY_SENTRY) {
4236 }
4237
4238 punit->veteran
4239 = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
4240 {
4241 /* Protect against change in veteran system in ruleset */
4242 const int levels = utype_veteran_levels(unit_type_get(punit));
4243 if (punit->veteran >= levels) {
4244 fc_assert(levels >= 1);
4245 punit->veteran = levels - 1;
4246 }
4247 }
4250 "%s.done_moving", unitstr);
4253 "%s.battlegroup", unitstr);
4254
4256 "%s.go", unitstr)) {
4257 int gnat_x, gnat_y;
4258
4259 sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_x,
4260 "%s.goto_x", unitstr), FALSE,
4261 "%s", secfile_error());
4262 sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_y,
4263 "%s.goto_y", unitstr), FALSE,
4264 "%s", secfile_error());
4265
4266 punit->goto_tile = native_pos_to_tile(&(wld.map), gnat_x, gnat_y);
4267 } else {
4268 punit->goto_tile = NULL;
4269
4270 /* These variables are not used but needed for saving the unit table.
4271 * Load them to prevent unused variables errors. */
4272 (void) secfile_entry_lookup(loading->file, "%s.goto_x", unitstr);
4273 (void) secfile_entry_lookup(loading->file, "%s.goto_y", unitstr);
4274 }
4275
4276 /* Load AI data of the unit. */
4277 CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
4278
4280 &ai_controlled,
4281 "%s.ai", unitstr), FALSE,
4282 "%s", secfile_error());
4283 if (ai_controlled) {
4284 /* Autosettler and Autoexplore are separated by
4285 * compat_post_load_030100() when set to SSA_AUTOSETTLER */
4286 punit->ssa_controller = SSA_AUTOSETTLER;
4287 } else {
4288 punit->ssa_controller = SSA_NONE;
4289 }
4291 "%s.hp", unitstr), FALSE,
4292 "%s", secfile_error());
4293
4295 = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
4297 = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
4298 punit->moved
4299 = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
4302 "%s.paradropped", unitstr);
4303
4304 /* The transport status (punit->transported_by) is loaded in
4305 * sg_player_units_transport(). */
4306
4307 /* Initialize upkeep values: these are hopefully initialized
4308 * elsewhere before use (specifically, in city_support(); but
4309 * fixme: check whether always correctly initialized?).
4310 * Below is mainly for units which don't have homecity --
4311 * otherwise these don't get initialized (and AI calculations
4312 * etc may use junk values). */
4316
4319 ACT_DEC_NOTHING, action_decision,
4320 "%s.action_decision_want", unitstr);
4321
4322 if (punit->action_decision_want != ACT_DEC_NOTHING) {
4323 /* Load the tile to act against. */
4324 int adwt_x, adwt_y;
4325
4326 if (secfile_lookup_int(loading->file, &adwt_x,
4327 "%s.action_decision_tile_x", unitstr)
4328 && secfile_lookup_int(loading->file, &adwt_y,
4329 "%s.action_decision_tile_y", unitstr)) {
4331 adwt_x, adwt_y);
4332 } else {
4333 punit->action_decision_want = ACT_DEC_NOTHING;
4335 log_sg("Bad action_decision_tile for unit %d", punit->id);
4336 }
4337 } else {
4338 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_x", unitstr);
4339 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_y", unitstr);
4341 }
4342
4343 /* Load the unit orders */
4344 {
4345 int len = secfile_lookup_int_default(loading->file, 0,
4346 "%s.orders_length", unitstr);
4347
4348 if (len > 0) {
4349 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
4350 const char *tgt_unitstr;
4351 const char *base_unitstr = NULL;
4352 const char *road_unitstr = NULL;
4355 int j;
4356
4357 punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
4360 = secfile_lookup_int_default(loading->file, 0,
4361 "%s.orders_index", unitstr);
4364 "%s.orders_repeat", unitstr);
4367 "%s.orders_vigilant", unitstr);
4368
4369 orders_unitstr
4370 = secfile_lookup_str_default(loading->file, "",
4371 "%s.orders_list", unitstr);
4372 dir_unitstr
4373 = secfile_lookup_str_default(loading->file, "",
4374 "%s.dir_list", unitstr);
4375 act_unitstr
4376 = secfile_lookup_str_default(loading->file, "",
4377 "%s.activity_list", unitstr);
4378 tgt_unitstr
4379 = secfile_lookup_str_default(loading->file, NULL, "%s.tgt_list", unitstr);
4380
4381 if (tgt_unitstr == NULL) {
4382 base_unitstr
4383 = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
4384 road_unitstr
4385 = secfile_lookup_str_default(loading->file, NULL, "%s.road_list", unitstr);
4386 }
4387
4389
4390 for (j = 0; j < len; j++) {
4391 struct unit_order *order = &punit->orders.list[j];
4392
4393 if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
4394 || act_unitstr[j] == '\0') {
4395 log_sg("Invalid unit orders.");
4397 break;
4398 }
4399 order->order = char2order(orders_unitstr[j]);
4400 order->dir = char2dir(dir_unitstr[j]);
4401 order->activity = char2activity(act_unitstr[j]);
4402 /* Target, if needed, is set in compat_post_load_030100() */
4403 order->target = NO_TARGET;
4404 order->sub_target = NO_TARGET;
4405
4406 if (order->order == ORDER_LAST
4407 || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
4408 || (order->order == ORDER_ACTION_MOVE
4409 && !direction8_is_valid(order->dir))
4410 || (order->order == ORDER_ACTIVITY
4411 && order->activity == ACTIVITY_LAST)) {
4412 /* An invalid order. Just drop the orders for this unit. */
4413 free(punit->orders.list);
4414 punit->orders.list = NULL;
4416 break;
4417 }
4418
4419 /* The order may have been replaced by the perform action order */
4420 order->action = sg_order_to_action(order->order, punit,
4421 punit->goto_tile);
4422 if (order->action != ACTION_NONE) {
4423 /* The order was converted by order_to_action */
4424 order->order = ORDER_PERFORM_ACTION;
4425 }
4426
4427 if (tgt_unitstr) {
4428 if (tgt_unitstr[j] != '?') {
4429 extra_id = char2num(tgt_unitstr[j]);
4430
4431 if (extra_id < 0 || extra_id >= loading->extra.size) {
4432 log_sg("Cannot find extra %d for %s to build",
4433 extra_id, unit_rule_name(punit));
4434 order->sub_target = EXTRA_NONE;
4435 } else {
4436 order->sub_target = extra_id;
4437 }
4438 } else {
4439 order->sub_target = EXTRA_NONE;
4440 }
4441 } else {
4442 /* In pre-2.6 savegames, base_list and road_list were only saved
4443 * for those activities (and not e.g. pillaging) */
4444 if (base_unitstr && base_unitstr[j] != '?'
4445 && order->activity == ACTIVITY_BASE) {
4446 base_id = char2num(base_unitstr[j]);
4447
4448 if (base_id < 0 || base_id >= loading->base.size) {
4449 log_sg("Cannot find base %d for %s to build",
4450 base_id, unit_rule_name(punit));
4451 base_id = base_number(get_base_by_gui_type(BASE_GUI_FORTRESS,
4452 NULL, NULL));
4453 }
4454
4455 order->sub_target
4457 } else if (road_unitstr && road_unitstr[j] != '?'
4458 && order->activity == ACTIVITY_GEN_ROAD) {
4459 road_id = char2num(road_unitstr[j]);
4460
4461 if (road_id < 0 || road_id >= loading->road.size) {
4462 log_sg("Cannot find road %d for %s to build",
4463 road_id, unit_rule_name(punit));
4464 road_id = 0;
4465 }
4466
4467 order->sub_target
4469 } else {
4470 order->sub_target = EXTRA_NONE;
4471 }
4472
4473 if (order->activity == ACTIVITY_OLD_ROAD) {
4474 order->activity = ACTIVITY_GEN_ROAD;
4475 order->sub_target
4477 } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
4478 order->activity = ACTIVITY_GEN_ROAD;
4479 order->sub_target
4481 }
4482 }
4483 }
4484 } else {
4486 punit->orders.list = NULL;
4487
4488 (void) secfile_entry_lookup(loading->file, "%s.orders_index", unitstr);
4489 (void) secfile_entry_lookup(loading->file, "%s.orders_repeat", unitstr);
4490 (void) secfile_entry_lookup(loading->file, "%s.orders_vigilant", unitstr);
4491 (void) secfile_entry_lookup(loading->file, "%s.orders_list", unitstr);
4492 (void) secfile_entry_lookup(loading->file, "%s.dir_list", unitstr);
4493 (void) secfile_entry_lookup(loading->file, "%s.activity_list", unitstr);
4494 (void) secfile_entry_lookup(loading->file, "%s.tgt_list", unitstr);
4495 }
4496 }
4497
4498 return TRUE;
4499}
4500
4501/************************************************************************/
4505static void sg_load_player_units_transport(struct loaddata *loading,
4506 struct player *plr)
4507{
4508 int nunits, i, plrno = player_number(plr);
4509
4510 /* Check status and return if not OK (sg_success FALSE). */
4511 sg_check_ret();
4512
4513 /* Recheck the number of units for the player. This is a copied from
4514 * sg_load_player_units(). */
4515 sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
4516 "player%d.nunits", plrno),
4517 "%s", secfile_error());
4518 if (!plr->is_alive && nunits > 0) {
4519 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4520 nunits = 0; /* Some old savegames may be buggy. */
4521 }
4522
4523 for (i = 0; i < nunits; i++) {
4524 int id_unit, id_trans;
4525 struct unit *punit, *ptrans;
4526
4527 id_unit = secfile_lookup_int_default(loading->file, -1,
4528 "player%d.u%d.id",
4529 plrno, i);
4530 punit = player_unit_by_number(plr, id_unit);
4531 fc_assert_action(punit != NULL, continue);
4532
4533 id_trans = secfile_lookup_int_default(loading->file, -1,
4534 "player%d.u%d.transported_by",
4535 plrno, i);
4536 if (id_trans == -1) {
4537 /* Not transported. */
4538 continue;
4539 }
4540
4541 ptrans = game_unit_by_number(id_trans);
4542 fc_assert_action(id_trans == -1 || ptrans != NULL, continue);
4543
4544 if (ptrans) {
4545#ifndef FREECIV_NDEBUG
4546 bool load_success =
4547#endif
4548 unit_transport_load(punit, ptrans, TRUE);
4549
4550 fc_assert_action(load_success, continue);
4551 }
4552 }
4553}
4554
4555/************************************************************************/
4558static void sg_load_player_attributes(struct loaddata *loading,
4559 struct player *plr)
4560{
4561 int plrno = player_number(plr);
4562
4563 /* Check status and return if not OK (sg_success FALSE). */
4564 sg_check_ret();
4565
4566 /* Toss any existing attribute_block (should not exist) */
4567 if (plr->attribute_block.data) {
4568 free(plr->attribute_block.data);
4569 plr->attribute_block.data = NULL;
4570 }
4571
4572 /* This is a big heap of opaque data for the client, check everything! */
4574 loading->file, 0, "player%d.attribute_v2_block_length", plrno);
4575
4576 if (0 > plr->attribute_block.length) {
4577 log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
4578 plr->attribute_block.length);
4579 plr->attribute_block.length = 0;
4580 } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
4581 log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
4583 plr->attribute_block.length = 0;
4584 } else if (0 < plr->attribute_block.length) {
4585 int part_nr, parts;
4586 int quoted_length;
4587 char *quoted;
4588#ifndef FREECIV_NDEBUG
4589 size_t actual_length;
4590#endif
4591
4593 secfile_lookup_int(loading->file, &quoted_length,
4594 "player%d.attribute_v2_block_length_quoted",
4595 plrno), "%s", secfile_error());
4597 secfile_lookup_int(loading->file, &parts,
4598 "player%d.attribute_v2_block_parts", plrno),
4599 "%s", secfile_error());
4600
4601 quoted = fc_malloc(quoted_length + 1);
4602 quoted[0] = '\0';
4604 for (part_nr = 0; part_nr < parts; part_nr++) {
4605 const char *current =
4606 secfile_lookup_str(loading->file,
4607 "player%d.attribute_v2_block_data.part%d",
4608 plrno, part_nr);
4609 if (!current) {
4610 log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
4611 break;
4612 }
4613 log_debug("attribute_v2_block_length_quoted=%d"
4614 " have=" SIZE_T_PRINTF " part=" SIZE_T_PRINTF,
4615 quoted_length, strlen(quoted), strlen(current));
4616 fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
4617 strcat(quoted, current);
4618 }
4619 fc_assert_msg(quoted_length == strlen(quoted),
4620 "attribute_v2_block_length_quoted=%d"
4621 " actual=" SIZE_T_PRINTF,
4622 quoted_length, strlen(quoted));
4623
4624#ifndef FREECIV_NDEBUG
4625 actual_length =
4626#endif
4627 unquote_block(quoted,
4628 plr->attribute_block.data,
4629 plr->attribute_block.length);
4630 fc_assert(actual_length == plr->attribute_block.length);
4631 free(quoted);
4632 }
4633}
4634
4635/************************************************************************/
4638static void sg_load_player_vision(struct loaddata *loading,
4639 struct player *plr)
4640{
4641 int plrno = player_number(plr);
4642 int total_ncities =
4643 secfile_lookup_int_default(loading->file, -1,
4644 "player%d.dc_total", plrno);
4645 int i;
4646 bool someone_alive = FALSE;
4647
4648 /* Check status and return if not OK (sg_success FALSE). */
4649 sg_check_ret();
4650
4651 if (game.server.revealmap & REVEAL_MAP_DEAD) {
4652 player_list_iterate(team_members(plr->team), pteam_member) {
4653 if (pteam_member->is_alive) {
4654 someone_alive = TRUE;
4655 break;
4656 }
4658
4659 if (!someone_alive) {
4660 /* Reveal all for completely dead teams. */
4662 }
4663 }
4664
4665 if (!plr->is_alive
4666 || -1 == total_ncities
4667 || !game.info.fogofwar
4669 "game.save_private_map")) {
4670 /* We have:
4671 * - a dead player;
4672 * - fogged cities are not saved for any reason;
4673 * - a savegame with fog of war turned off;
4674 * - or game.save_private_map is not set to FALSE in the scenario /
4675 * savegame. The players private knowledge is set to be what they could
4676 * see without fog of war. */
4677 whole_map_iterate(&(wld.map), ptile) {
4678 if (map_is_known(ptile, plr)) {
4679 struct city *pcity = tile_city(ptile);
4680
4681 update_player_tile_last_seen(plr, ptile);
4682 update_player_tile_knowledge(plr, ptile);
4683
4684 if (NULL != pcity) {
4685 update_dumb_city(plr, pcity);
4686 }
4687 }
4689
4690 /* Nothing more to do; */
4691 return;
4692 }
4693
4694 /* Load player map (terrain). */
4695 LOAD_MAP_CHAR(ch, ptile,
4696 map_get_player_tile(ptile, plr)->terrain
4697 = char2terrain(ch), loading->file,
4698 "player%d.map_t%04d", plrno);
4699
4700 /* Load player map (resources). */
4701 LOAD_MAP_CHAR(ch, ptile,
4702 map_get_player_tile(ptile, plr)->resource
4703 = char2resource(ch), loading->file,
4704 "player%d.map_res%04d", plrno);
4705
4706 if (loading->version >= 30) {
4707 /* 2.6.0 or newer */
4708
4709 /* Load player map (extras). */
4710 halfbyte_iterate_extras(j, loading->extra.size) {
4711 LOAD_MAP_CHAR(ch, ptile,
4713 ch, loading->extra.order + 4 * j),
4714 loading->file, "player%d.map_e%02d_%04d", plrno, j);
4716 } else {
4717 /* Load player map (specials). */
4719 LOAD_MAP_CHAR(ch, ptile,
4720 sg_special_set(ptile, &map_get_player_tile(ptile, plr)->extras,
4721 ch, loading->special.order + 4 * j, FALSE),
4722 loading->file, "player%d.map_spe%02d_%04d", plrno, j);
4724
4725 /* Load player map (bases). */
4726 halfbyte_iterate_bases(j, loading->base.size) {
4727 LOAD_MAP_CHAR(ch, ptile,
4729 ch, loading->base.order + 4 * j),
4730 loading->file, "player%d.map_b%02d_%04d", plrno, j);
4732
4733 /* Load player map (roads). */
4734 if (loading->version >= 20) {
4735 /* 2.5.0 or newer */
4736 halfbyte_iterate_roads(j, loading->road.size) {
4737 LOAD_MAP_CHAR(ch, ptile,
4739 ch, loading->road.order + 4 * j),
4740 loading->file, "player%d.map_r%02d_%04d", plrno, j);
4742 }
4743 }
4744
4746 /* Load player map (border). */
4747 int x, y;
4748
4749 for (y = 0; y < wld.map.ysize; y++) {
4750 const char *buffer
4751 = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
4752 plrno, y);
4753 const char *buffer2
4754 = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
4755 plrno, y);
4756 const char *ptr = buffer;
4757 const char *ptr2 = buffer2;
4758
4759 sg_failure_ret(NULL != buffer,
4760 "Savegame corrupt - map line %d not found.", y);
4761 for (x = 0; x < wld.map.xsize; x++) {
4762 char token[TOKEN_SIZE];
4763 char token2[TOKEN_SIZE];
4764 int number;
4765 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
4766
4767 scanin(&ptr, ",", token, sizeof(token));
4768 sg_failure_ret('\0' != token[0],
4769 "Savegame corrupt - map size not correct.");
4770 if (strcmp(token, "-") == 0) {
4771 map_get_player_tile(ptile, plr)->owner = NULL;
4772 } else {
4773 sg_failure_ret(str_to_int(token, &number),
4774 "Savegame corrupt - got tile owner=%s in (%d, %d).",
4775 token, x, y);
4776 map_get_player_tile(ptile, plr)->owner = player_by_number(number);
4777 }
4778
4779 if (loading->version >= 30) {
4780 scanin(&ptr2, ",", token2, sizeof(token2));
4781 sg_failure_ret('\0' != token2[0],
4782 "Savegame corrupt - map size not correct.");
4783 if (strcmp(token2, "-") == 0) {
4784 map_get_player_tile(ptile, plr)->extras_owner = NULL;
4785 } else {
4786 sg_failure_ret(str_to_int(token2, &number),
4787 "Savegame corrupt - got extras owner=%s in (%d, %d).",
4788 token, x, y);
4789 map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
4790 }
4791 } else {
4793 = map_get_player_tile(ptile, plr)->owner;
4794 }
4795 }
4796 }
4797 }
4798
4799 /* Load player map (update time). */
4800 for (i = 0; i < 4; i++) {
4801 /* put 4-bit segments of 16-bit "updated" field */
4802 if (i == 0) {
4803 LOAD_MAP_CHAR(ch, ptile,
4804 map_get_player_tile(ptile, plr)->last_updated
4805 = ascii_hex2bin(ch, i),
4806 loading->file, "player%d.map_u%02d_%04d", plrno, i);
4807 } else {
4808 LOAD_MAP_CHAR(ch, ptile,
4809 map_get_player_tile(ptile, plr)->last_updated
4810 |= ascii_hex2bin(ch, i),
4811 loading->file, "player%d.map_u%02d_%04d", plrno, i);
4812 }
4813 }
4814
4815 /* Load player map known cities. */
4816 for (i = 0; i < total_ncities; i++) {
4817 struct vision_site *pdcity;
4818 char buf[32];
4819 fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
4820
4821 pdcity = vision_site_new(0, NULL, NULL);
4822 if (sg_load_player_vision_city(loading, plr, pdcity, buf)) {
4824 pdcity);
4826 } else {
4827 /* Error loading the data. */
4828 log_sg("Skipping seen city %d for player %d.", i, plrno);
4829 if (pdcity != NULL) {
4830 vision_site_destroy(pdcity);
4831 }
4832 }
4833 }
4834
4835 /* Repair inconsistent player maps. */
4836 whole_map_iterate(&(wld.map), ptile) {
4837 if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
4838 struct city *pcity = tile_city(ptile);
4839
4840 update_player_tile_knowledge(plr, ptile);
4841 reality_check_city(plr, ptile);
4842
4843 if (NULL != pcity) {
4844 update_dumb_city(plr, pcity);
4845 }
4846 } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
4847 /* Non fogged borders aren't loaded. See hrm Bug #879084 */
4848 struct player_tile *plrtile = map_get_player_tile(ptile, plr);
4849
4850 plrtile->owner = tile_owner(ptile);
4851 }
4853}
4854
4855/************************************************************************/
4858static bool sg_load_player_vision_city(struct loaddata *loading,
4859 struct player *plr,
4860 struct vision_site *pdcity,
4861 const char *citystr)
4862{
4863 const char *str;
4864 int i, id, size;
4865 citizens city_size;
4866 int nat_x, nat_y;
4867 const char *stylename;
4868 const char *vname;
4869
4870 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x",
4871 citystr),
4872 FALSE, "%s", secfile_error());
4873 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y",
4874 citystr),
4875 FALSE, "%s", secfile_error());
4876 pdcity->location = native_pos_to_tile(&(wld.map), nat_x, nat_y);
4877 sg_warn_ret_val(NULL != pdcity->location, FALSE,
4878 "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
4879
4880 sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
4881 citystr),
4882 FALSE, "%s", secfile_error());
4883 pdcity->owner = player_by_number(id);
4884 sg_warn_ret_val(NULL != pdcity->owner, FALSE,
4885 "%s has invalid owner (%d); skipping.", citystr, id);
4886
4888 "%s.id", citystr),
4889 FALSE, "%s", secfile_error());
4890 sg_warn_ret_val(IDENTITY_NUMBER_ZERO < pdcity->identity, FALSE,
4891 "%s has invalid id (%d); skipping.", citystr, id);
4892
4894 "%s.size", citystr),
4895 FALSE, "%s", secfile_error());
4896 city_size = (citizens)size; /* set the correct type */
4897 sg_warn_ret_val(size == (int)city_size, FALSE,
4898 "Invalid city size: %d; set to %d.", size, city_size);
4899 vision_site_size_set(pdcity, city_size);
4900
4901 /* Initialise list of improvements */
4902 BV_CLR_ALL(pdcity->improvements);
4903 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
4904 sg_warn_ret_val(str != NULL, FALSE, "%s", secfile_error());
4905 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
4906 "Invalid length of '%s.improvements' ("
4907 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
4908 citystr, strlen(str), loading->improvement.size);
4909 for (i = 0; i < loading->improvement.size; i++) {
4910 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
4911 "Undefined value '%c' within '%s.improvements'.",
4912 str[i], citystr)
4913
4914 if (str[i] == '1') {
4915 struct impr_type *pimprove =
4917
4918 if (pimprove) {
4919 BV_SET(pdcity->improvements, improvement_index(pimprove));
4920 }
4921 }
4922 }
4923
4924 vname = secfile_lookup_str_default(loading->file, NULL,
4925 "%s.name", citystr);
4926
4927 if (vname != NULL) {
4928 pdcity->name = fc_strdup(vname);
4929 }
4930
4931 pdcity->occupied = secfile_lookup_bool_default(loading->file, FALSE,
4932 "%s.occupied", citystr);
4933 pdcity->walls = secfile_lookup_bool_default(loading->file, FALSE,
4934 "%s.walls", citystr);
4935 pdcity->happy = secfile_lookup_bool_default(loading->file, FALSE,
4936 "%s.happy", citystr);
4937 pdcity->unhappy = secfile_lookup_bool_default(loading->file, FALSE,
4938 "%s.unhappy", citystr);
4939 stylename = secfile_lookup_str_default(loading->file, NULL,
4940 "%s.style", citystr);
4941 if (stylename != NULL) {
4942 pdcity->style = city_style_by_rule_name(stylename);
4943 } else {
4944 pdcity->style = 0;
4945 }
4946 if (pdcity->style < 0) {
4947 pdcity->style = 0;
4948 }
4949
4950 pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
4951 "%s.city_image", citystr);
4952
4953 pdcity->capital = CAPITAL_NOT;
4954
4955 return TRUE;
4956}
4957
4958/* =======================================================================
4959 * Load the researches.
4960 * ======================================================================= */
4961
4962/************************************************************************/
4965static void sg_load_researches(struct loaddata *loading)
4966{
4967 struct research *presearch;
4968 int count;
4969 int number;
4970 const char *str;
4971 int i, j;
4972
4973 /* Check status and return if not OK (sg_success FALSE). */
4974 sg_check_ret();
4975
4976 /* Initialize all researches. */
4977 researches_iterate(pinitres) {
4978 init_tech(pinitres, FALSE);
4980
4981 /* May be unsaved (e.g. scenario case). */
4982 count = secfile_lookup_int_default(loading->file, 0, "research.count");
4983 for (i = 0; i < count; i++) {
4984 sg_failure_ret(secfile_lookup_int(loading->file, &number,
4985 "research.r%d.number", i),
4986 "%s", secfile_error());
4987 presearch = research_by_number(number);
4988 sg_failure_ret(presearch != NULL,
4989 "Invalid research number %d in 'research.r%d.number'",
4990 number, i);
4991
4992 presearch->tech_goal = technology_load(loading->file,
4993 "research.r%d.goal", i);
4995 &presearch->techs_researched,
4996 "research.r%d.techs", i),
4997 "%s", secfile_error());
4999 &presearch->future_tech,
5000 "research.r%d.futuretech", i),
5001 "%s", secfile_error());
5003 &presearch->bulbs_researched,
5004 "research.r%d.bulbs", i),
5005 "%s", secfile_error());
5007 &presearch->bulbs_researching_saved,
5008 "research.r%d.bulbs_before", i),
5009 "%s", secfile_error());
5010 presearch->researching_saved = technology_load(loading->file,
5011 "research.r%d.saved", i);
5012 presearch->researching = technology_load(loading->file,
5013 "research.r%d.now", i);
5015 &presearch->got_tech,
5016 "research.r%d.got_tech", i),
5017 "%s", secfile_error());
5018
5019 str = secfile_lookup_str(loading->file, "research.r%d.done", i);
5020 sg_failure_ret(str != NULL, "%s", secfile_error());
5021 sg_failure_ret(strlen(str) == loading->technology.size,
5022 "Invalid length of 'research.r%d.done' ("
5023 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5024 i, strlen(str), loading->technology.size);
5025 for (j = 0; j < loading->technology.size; j++) {
5026 sg_failure_ret(str[j] == '1' || str[j] == '0',
5027 "Undefined value '%c' within 'research.r%d.done'.",
5028 str[j], i);
5029
5030 if (str[j] == '1') {
5031 struct advance *padvance =
5033
5034 if (padvance) {
5035 research_invention_set(presearch, advance_number(padvance),
5036 TECH_KNOWN);
5037 }
5038 }
5039 }
5040 }
5041
5042 /* In case of tech_leakage, we can update research only after all the
5043 * researches have been loaded */
5044 researches_iterate(pupres) {
5045 research_update(pupres);
5047}
5048
5049/* =======================================================================
5050 * Load the event cache. Should be the last thing to do.
5051 * ======================================================================= */
5052
5053/************************************************************************/
5056static void sg_load_event_cache(struct loaddata *loading)
5057{
5058 /* Check status and return if not OK (sg_success FALSE). */
5059 sg_check_ret();
5060
5061 event_cache_load(loading->file, "event_cache");
5062}
5063
5064/* =======================================================================
5065 * Load the open treaties
5066 * ======================================================================= */
5067
5068/************************************************************************/
5071static void sg_load_treaties(struct loaddata *loading)
5072{
5073 int tidx;
5074 const char *plr0;
5075 struct treaty_list *treaties = get_all_treaties();
5076
5077 /* Check status and return if not OK (sg_success FALSE). */
5078 sg_check_ret();
5079
5080 for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, NULL,
5081 "treaty%d.plr0", tidx)) != NULL ;
5082 tidx++) {
5083 const char *plr1;
5084 const char *ct;
5085 int cidx;
5086 struct player *p0, *p1;
5087
5088 plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
5089
5090 p0 = player_by_name(plr0);
5091 p1 = player_by_name(plr1);
5092
5093 if (p0 == NULL || p1 == NULL) {
5094 log_error("Treaty between unknown players %s and %s", plr0, plr1);
5095 } else {
5096 struct Treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
5097
5098 init_treaty(ptreaty, p0, p1);
5099 treaty_list_prepend(treaties, ptreaty);
5100
5101 for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, NULL,
5102 "treaty%d.clause%d.type",
5103 tidx, cidx)) != NULL ;
5104 cidx++ ) {
5105 enum clause_type type = clause_type_by_name(ct, fc_strcasecmp);
5106 const char *plrx;
5107
5108 if (!clause_type_is_valid(type)) {
5109 log_error("Invalid clause type \"%s\"", ct);
5110 } else {
5111 struct player *pgiver = NULL;
5112
5113 plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
5114 tidx, cidx);
5115
5116 if (!fc_strcasecmp(plrx, plr0)) {
5117 pgiver = p0;
5118 } else if (!fc_strcasecmp(plrx, plr1)) {
5119 pgiver = p1;
5120 } else {
5121 log_error("Clause giver %s is not participant of the treaty"
5122 "between %s and %s", plrx, plr0, plr1);
5123 }
5124
5125 if (pgiver != NULL) {
5126 int value;
5127
5128 value = secfile_lookup_int_default(loading->file, 0,
5129 "treaty%d.clause%d.value",
5130 tidx, cidx);
5131
5132 add_clause(ptreaty, pgiver, type, value, NULL);
5133 }
5134 }
5135 }
5136
5137 /* These must be after clauses have been added so that acceptance
5138 * does not get cleared by what seems like changes to the treaty. */
5139 ptreaty->accept0 = secfile_lookup_bool_default(loading->file, FALSE,
5140 "treaty%d.accept0", tidx);
5141 ptreaty->accept1 = secfile_lookup_bool_default(loading->file, FALSE,
5142 "treaty%d.accept1", tidx);
5143 }
5144 }
5145}
5146
5147/* =======================================================================
5148 * Load the history report
5149 * ======================================================================= */
5150
5151/************************************************************************/
5154static void sg_load_history(struct loaddata *loading)
5155{
5156 struct history_report *hist = history_report_get();
5157 int turn;
5158
5159 /* Check status and return if not OK (sg_success FALSE). */
5160 sg_check_ret();
5161
5162 turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
5163
5164 if (turn != -2) {
5165 hist->turn = turn;
5166 }
5167
5168 if (turn + 1 >= game.info.turn) {
5169 const char *str;
5170
5171 str = secfile_lookup_str(loading->file, "history.title");
5172 sg_failure_ret(str != NULL, "%s", secfile_error());
5173 sz_strlcpy(hist->title, str);
5174 str = secfile_lookup_str(loading->file, "history.body");
5175 sg_failure_ret(str != NULL, "%s", secfile_error());
5176 sz_strlcpy(hist->body, str);
5177 }
5178}
5179
5180/* =======================================================================
5181 * Load the mapimg definitions.
5182 * ======================================================================= */
5183
5184/************************************************************************/
5187static void sg_load_mapimg(struct loaddata *loading)
5188{
5189 int mapdef_count, i;
5190
5191 /* Check status and return if not OK (sg_success FALSE). */
5192 sg_check_ret();
5193
5194 /* Clear all defined map images. */
5195 while (mapimg_count() > 0) {
5196 mapimg_delete(0);
5197 }
5198
5199 mapdef_count = secfile_lookup_int_default(loading->file, 0,
5200 "mapimg.count");
5201 log_verbose("Saved map image definitions: %d.", mapdef_count);
5202
5203 if (0 >= mapdef_count) {
5204 return;
5205 }
5206
5207 for (i = 0; i < mapdef_count; i++) {
5208 const char *p;
5209
5210 p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
5211 if (NULL == p) {
5212 log_verbose("[Mapimg %4d] Missing definition.", i);
5213 continue;
5214 }
5215
5216 if (!mapimg_define(p, FALSE)) {
5217 log_error("Invalid map image definition %4d: %s.", i, p);
5218 }
5219
5220 log_verbose("Mapimg %4d loaded.", i);
5221 }
5222}
5223
5224/* =======================================================================
5225 * Sanity checks for loading a game.
5226 * ======================================================================= */
5227
5228/************************************************************************/
5231static void sg_load_sanitycheck(struct loaddata *loading)
5232{
5233 int players;
5234
5235 /* Check status and return if not OK (sg_success FALSE). */
5236 sg_check_ret();
5237
5238 if (game.info.is_new_game) {
5239 /* Nothing to do for new games (or not started scenarios). */
5240 return;
5241 }
5242
5243 /* Old savegames may have maxplayers lower than current player count,
5244 * fix. */
5245 players = normal_player_count();
5246 if (game.server.max_players < players) {
5247 log_verbose("Max players lower than current players, fixing");
5248 game.server.max_players = players;
5249 }
5250
5251 /* Fix ferrying sanity */
5252 players_iterate(pplayer) {
5253 unit_list_iterate_safe(pplayer->units, punit) {
5256 log_sg("Removing %s unferried %s in %s at (%d, %d)",
5262 }
5265
5266 /* Fix stacking issues. We don't rely on the savegame preserving
5267 * alliance invariants (old savegames often did not) so if there are any
5268 * unallied units on the same tile we just bounce them. */
5269 players_iterate(pplayer) {
5270 players_iterate(aplayer) {
5271 resolve_unit_stacks(pplayer, aplayer, TRUE);
5274
5275 /* Recalculate the potential buildings for each city. Has caused some
5276 * problems with game random state.
5277 * This also changes the game state if you save the game directly after
5278 * loading it and compare the results. */
5279 players_iterate(pplayer) {
5280 /* Building advisor needs data phase open in order to work */
5281 adv_data_phase_init(pplayer, FALSE);
5282 building_advisor(pplayer);
5283 /* Close data phase again so it can be opened again when game starts. */
5284 adv_data_phase_done(pplayer);
5286
5287 /* Prevent a buggy or intentionally crafted save game from crashing
5288 * Freeciv. See hrm Bug #887748 */
5289 players_iterate(pplayer) {
5290 city_list_iterate(pplayer->cities, pcity) {
5291 worker_task_list_iterate(pcity->task_reqs, ptask) {
5292 if (!worker_task_is_sane(ptask)) {
5293 log_error("[city id: %d] Bad worker task %d.",
5294 pcity->id, ptask->act);
5295 worker_task_list_remove(pcity->task_reqs, ptask);
5296 free(ptask);
5297 ptask = NULL;
5298 }
5302
5303 /* Check worked tiles map */
5304#ifdef FREECIV_DEBUG
5305 if (loading->worked_tiles != NULL) {
5306 /* check the entire map for unused worked tiles */
5307 whole_map_iterate(&(wld.map), ptile) {
5308 if (loading->worked_tiles[ptile->index] != -1) {
5309 log_error("[city id: %d] Unused worked tile at (%d, %d).",
5310 loading->worked_tiles[ptile->index], TILE_XY(ptile));
5311 }
5313 }
5314#endif /* FREECIV_DEBUG */
5315
5316 /* Check researching technologies and goals. */
5317 researches_iterate(presearch) {
5318 int techs;
5319
5320 if (presearch->researching != A_UNSET
5321 && !is_future_tech(presearch->researching)
5322 && (valid_advance_by_number(presearch->researching) == NULL
5323 || (research_invention_state(presearch, presearch->researching)
5324 != TECH_PREREQS_KNOWN))) {
5325 log_sg(_("%s had invalid researching technology."),
5326 research_name_translation(presearch));
5327 presearch->researching = A_UNSET;
5328 }
5329 if (presearch->tech_goal != A_UNSET
5330 && !is_future_tech(presearch->tech_goal)
5331 && (valid_advance_by_number(presearch->tech_goal) == NULL
5332 || !research_invention_reachable(presearch, presearch->tech_goal)
5333 || (research_invention_state(presearch, presearch->tech_goal)
5334 == TECH_KNOWN))) {
5335 log_sg(_("%s had invalid technology goal."),
5336 research_name_translation(presearch));
5337 presearch->tech_goal = A_UNSET;
5338 }
5339
5341
5342 if (presearch->techs_researched != techs) {
5343 sg_regr(3000300,
5344 _("%s had finished researches count wrong."),
5345 research_name_translation(presearch));
5346 presearch->techs_researched = techs;
5347 }
5349
5350 players_iterate(pplayer) {
5351 unit_list_iterate_safe(pplayer->units, punit) {
5353 punit->orders.list)) {
5354 log_sg("Invalid unit orders for unit %d.", punit->id);
5356 }
5359
5360 /* Check max rates (rules may have changed since saving) */
5361 players_iterate(pplayer) {
5364
5365 if (0 == strlen(server.game_identifier)
5366 || !is_base64url(server.game_identifier)) {
5367 /* This uses fc_rand(), so random state has to be initialized before. */
5368 randomize_base64url_string(server.game_identifier,
5369 sizeof(server.game_identifier));
5370 }
5371
5372 /* Check if some player has more than one of some UTYF_UNIQUE unit type */
5373 players_iterate(pplayer) {
5374 int unique_count[U_LAST];
5375
5376 memset(unique_count, 0, sizeof(unique_count));
5377
5378 unit_list_iterate(pplayer->units, punit) {
5379 unique_count[utype_index(unit_type_get(punit))]++;
5381
5382 unit_type_iterate(ut) {
5383 if (unique_count[utype_index(ut)] > 1 && utype_has_flag(ut, UTYF_UNIQUE)) {
5384 log_sg(_("%s has multiple units of type %s though it should be possible "
5385 "to have only one."),
5386 player_name(pplayer), utype_name_translation(ut));
5387 }
5390
5391 /* Restore game random state, just in case various initialization code
5392 * inexplicably altered the previously existing state. */
5393 if (!game.info.is_new_game) {
5394 fc_rand_set_state(loading->rstate);
5395
5396 if (loading->version < 30) {
5397 /* For older savegames we have to recalculate the score with current data,
5398 * instead of using beginning-of-turn saved scores. */
5399 players_iterate(pplayer) {
5400 calc_civ_score(pplayer);
5402 }
5403 }
5404
5405 /* At the end do the default sanity checks. */
5406 sanity_check();
5407}
struct achievement * achievement_by_rule_name(const char *name)
#define ACTION_NONE
Definition actions.h:293
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:1119
const char * city_name_get(const struct city *pcity)
Definition city.c:1111
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3339
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2769
void city_size_set(struct city *pcity, citizens size)
Definition city.c:1154
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3266
void destroy_city_virtual(struct city *pcity)
Definition city.c:3415
int city_style_by_rule_name(const char *s)
Definition city.c:1707
#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:812
#define city_owner(_pcity_)
Definition city.h:543
#define FREE_WORKED_TILES
Definition city.h:849
#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:818
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2676
bool send_city_suppression(bool now)
Definition citytools.c:2136
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:2744
void city_refresh_vision(struct city *pcity)
Definition citytools.c:3331
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:368
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:896
bool city_refresh(struct city *pcity)
Definition cityturn.c:161
static char * ruleset
Definition civmanual.c:202
char * techs
Definition comments.c:29
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:2818
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2839
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 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
void map_init_topology(void)
Definition map.c:301
#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:304
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:784
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:2097
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Definition plrhand.c:1723
int normal_player_count(void)
Definition plrhand.c:3034
void player_limit_to_max_rates(struct player *pplayer)
Definition plrhand.c:1886
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:2282
void set_shuffled_players(int *shuffled_players)
Definition plrhand.c:2232
void player_delegation_set(struct player *pplayer, const char *username)
Definition plrhand.c:3080
void shuffle_players(void)
Definition plrhand.c:2207
void server_remove_player(struct player *pplayer)
Definition plrhand.c:1772
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Definition plrhand.c:1450
void assign_player_colors(void)
Definition plrhand.c:1563
void fit_nationset_to_players(void)
Definition plrhand.c:2488
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,...)
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:9246
#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:2393
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:2329
#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:2198
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:2037
#define halfbyte_iterate_extras(e, num_extras_types)
Definition savegame2.c:239
static void sg_load_map(struct loaddata *loading)
Definition savegame2.c:1888
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:3728
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3335
static void sg_load_map_tiles(struct loaddata *loading)
Definition savegame2.c:1966
static char activity2char(enum unit_activity activity)
Definition savegame2.c:623
static void sg_load_savefile(struct loaddata *loading)
Definition savegame2.c:1155
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:3895
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:3455
static void sg_load_settings(struct loaddata *loading)
Definition savegame2.c:1868
static void sg_load_player_units(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3776
#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:4965
#define halfbyte_iterate_bases_end
Definition savegame2.c:264
static void sg_load_map_worked(struct loaddata *loading)
Definition savegame2.c:2285
static void sg_load_random(struct loaddata *loading)
Definition savegame2.c:1699
#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:4505
static void sg_load_history(struct loaddata *loading)
Definition savegame2.c:5154
#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:2053
#define TOKEN_SIZE
Definition savegame2.c:278
static void sg_load_script(struct loaddata *loading)
Definition savegame2.c:1758
static void sg_load_scenario(struct loaddata *loading)
Definition savegame2.c:1773
static void sg_load_ruleset(struct loaddata *loading)
Definition savegame2.c:1121
static void sg_load_game(struct loaddata *loading)
Definition savegame2.c:1536
static void sg_load_player_main(struct loaddata *loading, struct player *plr)
Definition savegame2.c:2841
static void sg_load_treaties(struct loaddata *loading)
Definition savegame2.c:5071
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:1081
static enum direction8 char2dir(char dir)
Definition savegame2.c:594
static void sg_load_map_tiles_resources(struct loaddata *loading)
Definition savegame2.c:2084
#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:5187
#define ORDER_OLD_HOMECITY
Definition savegame2.c:284
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4558
static void sg_load_ruledata(struct loaddata *loading)
Definition savegame2.c:1512
static void sg_load_player_vision(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4638
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:4858
static void sg_load_map_startpos(struct loaddata *loading)
Definition savegame2.c:2111
static void loaddata_destroy(struct loaddata *loading)
Definition savegame2.c:495
static void sg_load_players(struct loaddata *loading)
Definition savegame2.c:2650
#define ORDER_OLD_TRADE_ROUTE
Definition savegame2.c:283
static void sg_load_map_tiles_extras(struct loaddata *loading)
Definition savegame2.c:2006
static void sg_load_sanitycheck(struct loaddata *loading)
Definition savegame2.c:5231
static void sg_load_event_cache(struct loaddata *loading)
Definition savegame2.c:5056
static void sg_load_map_tiles_bases(struct loaddata *loading)
Definition savegame2.c:2021
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:3854
#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:1909
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
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
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:60
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:110
bool happy
Definition vision.h:119
bv_imprs improvements
Definition vision.h:125
struct tile * location
Definition vision.h:111
int identity
Definition vision.h:114
int walls
Definition vision.h:118
int style
Definition vision.h:121
bool unhappy
Definition vision.h:120
struct player * owner
Definition vision.h:112
int city_image
Definition vision.h:122
bool occupied
Definition vision.h:117
enum capital_type capital
Definition vision.h:123
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:161
#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:1069
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:113
#define tile_terrain(_tile)
Definition tile.h:109
#define TILE_XY(ptile)
Definition tile.h:42
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
#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:1755
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2356
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1108
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2427
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:846
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1125
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1619
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2634
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1715
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1282
#define unit_tile(_pu)
Definition unit.h:388
#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:387
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:1418
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:4852
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1245
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:2661
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:838
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:845
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