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 secfile_entry_ignore(loading->file, "scenario.game_version");
1556
1557 /* Load server state. */
1558 str = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
1559 "game.server_state");
1560 loading->server_state = server_states_by_name(str, strcmp);
1561 if (!server_states_is_valid(loading->server_state)) {
1562 /* Don't take any risk! */
1563 loading->server_state = S_S_INITIAL;
1564 }
1565
1568 "game.meta_patches");
1570
1572 /* Do not overwrite this if the user requested a specific metaserver
1573 * from the command line (option --Metaserver). */
1577 "game.meta_server"));
1578 }
1579
1580 if ('\0' == srvarg.serverid[0]) {
1581 /* Do not overwrite this if the user requested a specific metaserver
1582 * from the command line (option --serverid). */
1584 secfile_lookup_str_default(loading->file, "",
1585 "game.serverid"));
1586 }
1587 sz_strlcpy(server.game_identifier,
1588 secfile_lookup_str_default(loading->file, "", "game.id"));
1589 /* We are not checking game_identifier legality just yet.
1590 * That's done when we are sure that rand seed has been initialized,
1591 * so that we can generate new game_identifier, if needed.
1592 * See sq_load_sanitycheck(). */
1593
1594 level = secfile_lookup_str_default(loading->file, NULL,
1595 "game.level");
1596 if (level != NULL) {
1597 if (!fc_strcasecmp("Handicapped", level)) {
1598 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
1599 game.info.skill_level = AI_LEVEL_RESTRICTED;
1600 } else {
1601 game.info.skill_level = ai_level_by_name(level, fc_strcasecmp);
1602 }
1603 } else {
1604 game.info.skill_level = ai_level_invalid();
1605 }
1606
1607 if (!ai_level_is_valid(game.info.skill_level)) {
1611 "game.skill_level"));
1612 }
1615 "game.phase_mode");
1618 "game.phase_mode_stored");
1620 = secfile_lookup_int_default(loading->file, 0,
1621 "game.phase");
1625 "game.scoreturn");
1626
1629 "game.timeoutint");
1632 "game.timeoutintinc");
1635 "game.timeoutinc");
1638 "game.timeoutincmult");
1641 "game.timeoutcounter");
1642
1643 game.info.turn
1644 = secfile_lookup_int_default(loading->file, 0, "game.turn");
1646 "game.year"), "%s", secfile_error());
1648 = secfile_lookup_bool_default(loading->file, FALSE, "game.year_0_hack");
1649
1651 = secfile_lookup_int_default(loading->file, 0, "game.globalwarming");
1653 = secfile_lookup_int_default(loading->file, 0, "game.heating");
1655 = secfile_lookup_int_default(loading->file, 0, "game.warminglevel");
1656
1658 = secfile_lookup_int_default(loading->file, 0, "game.nuclearwinter");
1660 = secfile_lookup_int_default(loading->file, 0, "game.cooling");
1662 = secfile_lookup_int_default(loading->file, 0, "game.coolinglevel");
1663
1664 /* Savegame may have stored random_seed for documentation purposes only,
1665 * but we want to keep it for resaving. */
1666 game.server.seed = secfile_lookup_int_default(loading->file, 0, "game.random_seed");
1667
1668 /* Global advances. */
1669 str = secfile_lookup_str_default(loading->file, NULL,
1670 "game.global_advances");
1671 if (str != NULL) {
1672 sg_failure_ret(strlen(str) == loading->technology.size,
1673 "Invalid length of 'game.global_advances' ("
1674 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
1675 strlen(str), loading->technology.size);
1676 for (i = 0; i < loading->technology.size; i++) {
1677 sg_failure_ret(str[i] == '1' || str[i] == '0',
1678 "Undefined value '%c' within 'game.global_advances'.",
1679 str[i]);
1680 if (str[i] == '1') {
1681 struct advance *padvance =
1683
1684 if (padvance != NULL) {
1686 }
1687 }
1688 }
1689 }
1690
1692 = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
1693
1695 = secfile_lookup_int_default(loading->file, 0, "game.last_turn_change_time") / 100.0;
1696}
1697
1698/* =======================================================================
1699 * Load random status.
1700 * ======================================================================= */
1701
1702/************************************************************************/
1705static void sg_load_random(struct loaddata *loading)
1706{
1707 /* Check status and return if not OK (sg_success FALSE). */
1708 sg_check_ret();
1709
1710 if (secfile_lookup_bool_default(loading->file, FALSE, "random.saved")) {
1711 const char *str;
1712 int i;
1713
1714 /* Since random state was previously saved, save it also when resaving.
1715 * This affects only pre-2.6 scenarios where scenario.save_random
1716 * is not defined.
1717 * - If this is 2.6 or later scenario -> it would have saved random.saved = TRUE
1718 * only if scenario.save_random is already TRUE
1719 *
1720 * Do NOT touch this in case of regular savegame. They always have random.saved
1721 * set, but if one starts to make scenario based on a savegame, we want
1722 * default scenario settings in the beginning (default save_random = FALSE).
1723 */
1726 }
1727
1728 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.j,
1729 "random.index_J"), "%s", secfile_error());
1730 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.k,
1731 "random.index_K"), "%s", secfile_error());
1732 sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.x,
1733 "random.index_X"), "%s", secfile_error());
1734
1735 for (i = 0; i < 8; i++) {
1736 str = secfile_lookup_str(loading->file, "random.table%d",i);
1737 sg_failure_ret(NULL != str, "%s", secfile_error());
1738 sscanf(str, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
1739 &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
1740 &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
1741 &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
1742 }
1743 loading->rstate.is_init = TRUE;
1744 fc_rand_set_state(loading->rstate);
1745 } else {
1746 /* No random values - mark the setting. */
1747 (void) secfile_entry_by_path(loading->file, "random.saved");
1748
1749 /* We're loading a game without a seed (which is okay, if it's a scenario).
1750 * We need to generate the game seed now because it will be needed later
1751 * during the load. */
1753 loading->rstate = fc_rand_state();
1754 }
1755}
1756
1757/* =======================================================================
1758 * Load lua script data.
1759 * ======================================================================= */
1760
1761/************************************************************************/
1764static void sg_load_script(struct loaddata *loading)
1765{
1766 /* Check status and return if not OK (sg_success FALSE). */
1767 sg_check_ret();
1768
1770}
1771
1772/* =======================================================================
1773 * Load scenario data.
1774 * ======================================================================= */
1775
1776/************************************************************************/
1779static void sg_load_scenario(struct loaddata *loading)
1780{
1781 const char *buf;
1782 bool lake_flood_default;
1783
1784 /* Check status and return if not OK (sg_success FALSE). */
1785 sg_check_ret();
1786
1787 if (NULL == secfile_section_lookup(loading->file, "scenario")) {
1789
1790 return;
1791 }
1792
1793 /* Default is that when there's scenario section (which we already checked)
1794 * this is a scenario. Only if it explicitly says that it's not, we consider
1795 * this regular savegame */
1796 game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
1797
1798 if (!game.scenario.is_scenario) {
1799 return;
1800 }
1801
1802 buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
1803 if (buf[0] != '\0') {
1805 }
1806
1807 buf = secfile_lookup_str_default(loading->file, "",
1808 "scenario.authors");
1809 if (buf[0] != '\0') {
1811 } else {
1812 game.scenario.authors[0] = '\0';
1813 }
1814
1815 buf = secfile_lookup_str_default(loading->file, "",
1816 "scenario.description");
1817 if (buf[0] != '\0') {
1819 } else {
1820 game.scenario_desc.description[0] = '\0';
1821 }
1822
1824 = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
1826 = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
1829 "scenario.startpos_nations");
1830
1833 "scenario.prevent_new_cities");
1834 if (loading->version < 20599) {
1835 /* Lake flooding may break some old scenarios where rivers made out of
1836 * lake terrains, so play safe there */
1837 lake_flood_default = FALSE;
1838 } else {
1839 /* If lake flooding is a problem for a newer scenario, it could explicitly
1840 * disable it. */
1841 lake_flood_default = TRUE;
1842 }
1844 = secfile_lookup_bool_default(loading->file, lake_flood_default,
1845 "scenario.lake_flooding");
1848 "scenario.handmade");
1851 "scenario.allow_ai_type_fallback");
1853
1854 sg_failure_ret(loading->server_state == S_S_INITIAL
1855 || (loading->server_state == S_S_RUNNING
1856 && game.scenario.players),
1857 "Invalid scenario definition (server state '%s' and "
1858 "players are %s).",
1859 server_states_name(loading->server_state),
1860 game.scenario.players ? "saved" : "not saved");
1861
1862 /* Remove all defined players. They are recreated with the skill level
1863 * defined by the scenario. */
1864 (void) aifill(0);
1865}
1866
1867/* =======================================================================
1868 * Load game settings.
1869 * ======================================================================= */
1870
1871/************************************************************************/
1874static void sg_load_settings(struct loaddata *loading)
1875{
1876 /* Check status and return if not OK (sg_success FALSE). */
1877 sg_check_ret();
1878
1879 settings_game_load(loading->file, "settings");
1880
1881 /* Save current status of fogofwar. */
1883
1884 /* Add all compatibility settings here. */
1885}
1886
1887/* =======================================================================
1888 * Load the main map.
1889 * ======================================================================= */
1890
1891/************************************************************************/
1894static void sg_load_map(struct loaddata *loading)
1895{
1896 /* Check status and return if not OK (sg_success FALSE). */
1897 sg_check_ret();
1898
1899 /* This defaults to TRUE even if map has not been generated. Also,
1900 * old versions have also explicitly saved TRUE even in pre-game.
1901 * We rely on that
1902 * 1) scenario maps have it explicitly right.
1903 * 2) when map is actually generated, it re-initialize this to FALSE. */
1905 = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
1906
1907 /* Savegame may have stored random_seed for documentation purposes only,
1908 * but we want to keep it for resaving. */
1910 = secfile_lookup_int_default(loading->file, 0, "map.random_seed");
1911
1912 if (S_S_INITIAL == loading->server_state
1914 /* Generator MAPGEN_SCENARIO is used;
1915 * this map was done with the map editor. */
1916
1917 /* Load tiles. */
1918 sg_load_map_tiles(loading);
1919 sg_load_map_startpos(loading);
1920
1921 if (loading->version >= 30) {
1922 /* 2.6.0 or newer */
1923 sg_load_map_tiles_extras(loading);
1924 } else {
1925 sg_load_map_tiles_bases(loading);
1926 if (loading->version >= 20) {
1927 /* 2.5.0 or newer */
1928 sg_load_map_tiles_roads(loading);
1929 }
1930 if (has_capability("specials", loading->secfile_options)) {
1931 /* Load specials. */
1933 }
1934 }
1935
1936 /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
1938 if (has_capability("specials", loading->secfile_options)) {
1939 /* Load resources. */
1941 } else if (has_capability("riversoverlay", loading->secfile_options)) {
1942 /* Load only rivers overlay. */
1944 }
1945
1946 /* Nothing more needed for a scenario. */
1947 secfile_entry_ignore(loading->file, "game.save_known");
1948
1949 return;
1950 }
1951
1952 if (S_S_INITIAL == loading->server_state) {
1953 /* Nothing more to do if it is not a scenario but in initial state. */
1954 return;
1955 }
1956
1957 sg_load_map_tiles(loading);
1958 sg_load_map_startpos(loading);
1959 if (loading->version >= 30) {
1960 /* 2.6.0 or newer */
1961 sg_load_map_tiles_extras(loading);
1962 } else {
1963 sg_load_map_tiles_bases(loading);
1964 if (loading->version >= 20) {
1965 /* 2.5.0 or newer */
1966 sg_load_map_tiles_roads(loading);
1967 }
1969 }
1971 sg_load_map_known(loading);
1972 sg_load_map_owner(loading);
1973 sg_load_map_worked(loading);
1974}
1975
1976/************************************************************************/
1979static void sg_load_map_tiles(struct loaddata *loading)
1980{
1981 /* Check status and return if not OK (sg_success FALSE). */
1982 sg_check_ret();
1983
1984 /* Initialize the map for the current topology. 'map.xsize' and
1985 * 'map.ysize' must be set. */
1987
1988 /* Allocate map. */
1990
1991 /* get the terrain type */
1992 LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
1993 "map.t%04d");
1995
1996 /* Check for special tile sprites. */
1997 whole_map_iterate(&(wld.map), ptile) {
1998 const char *spec_sprite;
1999 const char *label;
2000 int nat_x, nat_y;
2001
2003 spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
2004 nat_x, nat_y);
2005 label = secfile_lookup_str_default(loading->file, NULL, "map.label_%d_%d",
2006 nat_x, nat_y);
2007 if (NULL != ptile->spec_sprite) {
2008 ptile->spec_sprite = fc_strdup(spec_sprite);
2009 }
2010 if (label != NULL) {
2011 tile_set_label(ptile, label);
2012 }
2014}
2015
2016/************************************************************************/
2019static void sg_load_map_tiles_extras(struct loaddata *loading)
2020{
2021 /* Check status and return if not OK (sg_success FALSE). */
2022 sg_check_ret();
2023
2024 /* Load extras. */
2025 halfbyte_iterate_extras(j, loading->extra.size) {
2026 LOAD_MAP_CHAR(ch, ptile, sg_extras_set(&ptile->extras, ch, loading->extra.order + 4 * j),
2027 loading->file, "map.e%02d_%04d", j);
2029}
2030
2031/************************************************************************/
2034static void sg_load_map_tiles_bases(struct loaddata *loading)
2035{
2036 /* Check status and return if not OK (sg_success FALSE). */
2037 sg_check_ret();
2038
2039 /* Load bases. */
2040 halfbyte_iterate_bases(j, loading->base.size) {
2041 LOAD_MAP_CHAR(ch, ptile, sg_bases_set(&ptile->extras, ch,
2042 loading->base.order + 4 * j),
2043 loading->file, "map.b%02d_%04d", j);
2045}
2046
2047/************************************************************************/
2050static void sg_load_map_tiles_roads(struct loaddata *loading)
2051{
2052 /* Check status and return if not OK (sg_success FALSE). */
2053 sg_check_ret();
2054
2055 /* Load roads. */
2056 halfbyte_iterate_roads(j, loading->road.size) {
2057 LOAD_MAP_CHAR(ch, ptile, sg_roads_set(&ptile->extras, ch,
2058 loading->road.order + 4 * j),
2059 loading->file, "map.r%02d_%04d", j);
2061}
2062
2063/************************************************************************/
2066static void sg_load_map_tiles_specials(struct loaddata *loading,
2067 bool rivers_overlay)
2068{
2069 /* Check status and return if not OK (sg_success FALSE). */
2070 sg_check_ret();
2071
2072 /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
2073 * from the savegame file.
2074 *
2075 * A scenario may define the terrain of the map but not list the specials
2076 * on it (thus allowing users to control the placement of specials).
2077 * However rivers are a special case and must be included in the map along
2078 * with the scenario. Thus in those cases this function should be called
2079 * to load the river information separate from any other special data.
2080 *
2081 * This does not need to be called from map_load(), because map_load()
2082 * loads the rivers overlay along with the rest of the specials. Call this
2083 * only if you've already called map_load_tiles(), and want to load only
2084 * the rivers overlay but no other specials. Scenarios that encode things
2085 * this way should have the "riversoverlay" capability. */
2087 LOAD_MAP_CHAR(ch, ptile, sg_special_set(ptile, &ptile->extras, ch,
2088 loading->special.order + 4 * j,
2089 rivers_overlay),
2090 loading->file, "map.spe%02d_%04d", j);
2092}
2093
2094/************************************************************************/
2097static void sg_load_map_tiles_resources(struct loaddata *loading)
2098{
2099 /* Check status and return if not OK (sg_success FALSE). */
2100 sg_check_ret();
2101
2102 LOAD_MAP_CHAR(ch, ptile, tile_set_resource(ptile, char2resource(ch)),
2103 loading->file, "map.res%04d");
2104
2105 /* After the resources are loaded, indicate those currently valid. */
2106 whole_map_iterate(&(wld.map), ptile) {
2107 if (NULL == ptile->resource) {
2108 continue;
2109 }
2110
2111 if (ptile->terrain == NULL || !terrain_has_resource(ptile->terrain, ptile->resource)) {
2112 BV_CLR(ptile->extras, extra_index(ptile->resource));
2113 }
2115
2118}
2119
2120/************************************************************************/
2124static void sg_load_map_startpos(struct loaddata *loading)
2125{
2126 struct nation_type *pnation;
2127 struct startpos *psp;
2128 struct tile *ptile;
2129 const char SEPARATOR = '#';
2130 const char *nation_names;
2131 int nat_x, nat_y;
2132 bool exclude;
2133 int i, startpos_count;
2134
2135 /* Check status and return if not OK (sg_success FALSE). */
2136 sg_check_ret();
2137
2138 startpos_count
2139 = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
2140
2141 if (0 == startpos_count) {
2142 /* Nothing to do. */
2143 return;
2144 }
2145
2146 for (i = 0; i < startpos_count; i++) {
2147 if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
2148 || !secfile_lookup_int(loading->file, &nat_y,
2149 "map.startpos%d.y", i)) {
2150 log_sg("Warning: Undefined coordinates for startpos %d", i);
2151 continue;
2152 }
2153
2154 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
2155 if (NULL == ptile) {
2156 log_error("Start position native coordinates (%d, %d) do not exist "
2157 "in this map. Skipping...", nat_x, nat_y);
2158 continue;
2159 }
2160
2161 exclude = secfile_lookup_bool_default(loading->file, FALSE,
2162 "map.startpos%d.exclude", i);
2163
2164 psp = map_startpos_new(ptile);
2165
2166 nation_names = secfile_lookup_str(loading->file,
2167 "map.startpos%d.nations", i);
2168 if (NULL != nation_names && '\0' != nation_names[0]) {
2169 const size_t size = strlen(nation_names) + 1;
2170 char buf[size], *start, *end;
2171
2172 memcpy(buf, nation_names, size);
2173 for (start = buf - 1; NULL != start; start = end) {
2174 start++;
2175 if ((end = strchr(start, SEPARATOR))) {
2176 *end = '\0';
2177 }
2178
2179 pnation = nation_by_rule_name(start);
2180 if (NO_NATION_SELECTED != pnation) {
2181 if (exclude) {
2182 startpos_disallow(psp, pnation);
2183 } else {
2184 startpos_allow(psp, pnation);
2185 }
2186 } else {
2187 log_verbose("Missing nation \"%s\".", start);
2188 }
2189 }
2190 }
2191 }
2192
2193 if (0 < map_startpos_count()
2194 && loading->server_state == S_S_INITIAL
2196 log_verbose("Number of starts (%d) are lower than rules.max_players "
2197 "(%d), lowering rules.max_players.",
2200 }
2201
2202 /* Re-initialize nation availability in light of start positions.
2203 * This has to be after loading [scenario] and [map].startpos and
2204 * before we seek nations for players. */
2206}
2207
2208/************************************************************************/
2211static void sg_load_map_owner(struct loaddata *loading)
2212{
2213 int x, y;
2214 struct player *owner = NULL;
2215 struct tile *claimer = NULL;
2216 struct player *eowner = NULL;
2217
2218 /* Check status and return if not OK (sg_success FALSE). */
2219 sg_check_ret();
2220
2221 if (game.info.is_new_game) {
2222 /* No owner/source information for a new game / scenario. */
2223 return;
2224 }
2225
2226 /* Owner and ownership source are stored as plain numbers */
2227 for (y = 0; y < wld.map.ysize; y++) {
2228 const char *buffer1 = secfile_lookup_str(loading->file,
2229 "map.owner%04d", y);
2230 const char *buffer2 = secfile_lookup_str(loading->file,
2231 "map.source%04d", y);
2232 const char *buffer3 = secfile_lookup_str(loading->file,
2233 "map.eowner%04d", y);
2234 const char *ptr1 = buffer1;
2235 const char *ptr2 = buffer2;
2236 const char *ptr3 = buffer3;
2237
2238 sg_failure_ret(buffer1 != NULL, "%s", secfile_error());
2239 sg_failure_ret(buffer2 != NULL, "%s", secfile_error());
2240 if (loading->version >= 30) {
2241 sg_failure_ret(buffer3 != NULL, "%s", secfile_error());
2242 }
2243
2244 for (x = 0; x < wld.map.xsize; x++) {
2245 char token1[TOKEN_SIZE];
2246 char token2[TOKEN_SIZE];
2247 char token3[TOKEN_SIZE];
2248 int number;
2249 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2250
2251 scanin(&ptr1, ",", token1, sizeof(token1));
2252 sg_failure_ret(token1[0] != '\0',
2253 "Map size not correct (map.owner%d).", y);
2254 if (strcmp(token1, "-") == 0) {
2255 owner = NULL;
2256 } else {
2257 sg_failure_ret(str_to_int(token1, &number),
2258 "Got map owner %s in (%d, %d).", token1, x, y);
2259 owner = player_by_number(number);
2260 }
2261
2262 scanin(&ptr2, ",", token2, sizeof(token2));
2263 sg_failure_ret(token2[0] != '\0',
2264 "Map size not correct (map.source%d).", y);
2265 if (strcmp(token2, "-") == 0) {
2266 claimer = NULL;
2267 } else {
2268 sg_failure_ret(str_to_int(token2, &number),
2269 "Got map source %s in (%d, %d).", token2, x, y);
2270 claimer = index_to_tile(&(wld.map), number);
2271 }
2272
2273 if (loading->version >= 30) {
2274 scanin(&ptr3, ",", token3, sizeof(token3));
2275 sg_failure_ret(token3[0] != '\0',
2276 "Map size not correct (map.eowner%d).", y);
2277 if (strcmp(token3, "-") == 0) {
2278 eowner = NULL;
2279 } else {
2280 sg_failure_ret(str_to_int(token3, &number),
2281 "Got base owner %s in (%d, %d).", token3, x, y);
2282 eowner = player_by_number(number);
2283 }
2284 } else {
2285 eowner = owner;
2286 }
2287
2289 tile_claim_bases(ptile, eowner);
2290 log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
2291 }
2292 }
2293}
2294
2295/************************************************************************/
2298static void sg_load_map_worked(struct loaddata *loading)
2299{
2300 int x, y;
2301
2302 /* Check status and return if not OK (sg_success FALSE). */
2303 sg_check_ret();
2304
2305 sg_failure_ret(loading->worked_tiles == NULL,
2306 "City worked map not loaded!");
2307
2309 sizeof(*loading->worked_tiles));
2310
2311 for (y = 0; y < wld.map.ysize; y++) {
2312 const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
2313 y);
2314 const char *ptr = buffer;
2315
2316 sg_failure_ret(NULL != buffer,
2317 "Savegame corrupt - map line %d not found.", y);
2318 for (x = 0; x < wld.map.xsize; x++) {
2319 char token[TOKEN_SIZE];
2320 int number;
2321 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
2322
2323 scanin(&ptr, ",", token, sizeof(token));
2324 sg_failure_ret('\0' != token[0],
2325 "Savegame corrupt - map size not correct.");
2326 if (strcmp(token, "-") == 0) {
2327 number = -1;
2328 } else {
2329 sg_failure_ret(str_to_int(token, &number) && 0 < number,
2330 "Savegame corrupt - got tile worked by city "
2331 "id=%s in (%d, %d).", token, x, y);
2332 }
2333
2334 loading->worked_tiles[ptile->index] = number;
2335 }
2336 }
2337}
2338
2339/************************************************************************/
2342static void sg_load_map_known(struct loaddata *loading)
2343{
2344 /* Check status and return if not OK (sg_success FALSE). */
2345 sg_check_ret();
2346
2347 players_iterate(pplayer) {
2348 /* Allocate player private map here; it is needed in different modules
2349 * besides this one ((i.e. sg_load_player_*()). */
2350 player_map_init(pplayer);
2352
2354 "game.save_known")) {
2355 int lines = player_slot_max_used_number() / 32 + 1;
2356 int j, p, l, i;
2357 unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
2358
2359 for (l = 0; l < lines; l++) {
2360 for (j = 0; j < 8; j++) {
2361 for (i = 0; i < 4; i++) {
2362 /* Only bother trying to load the map for this halfbyte if at least
2363 * one of the corresponding player slots is in use. */
2364 if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
2365 LOAD_MAP_CHAR(ch, ptile,
2366 known[l * MAP_INDEX_SIZE + tile_index(ptile)]
2367 |= ascii_hex2bin(ch, j),
2368 loading->file, "map.k%02d_%04d", l * 8 + j);
2369 break;
2370 }
2371 }
2372 }
2373 }
2374
2375 players_iterate(pplayer) {
2376 dbv_clr_all(&pplayer->tile_known);
2378
2379 /* HACK: we read the known data from hex into 32-bit integers, and
2380 * now we convert it to the known tile data of each player. */
2381 whole_map_iterate(&(wld.map), ptile) {
2382 players_iterate(pplayer) {
2383 p = player_index(pplayer);
2384 l = player_index(pplayer) / 32;
2385
2386 if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
2387 map_set_known(ptile, pplayer);
2388 }
2391
2392 FC_FREE(known);
2393 }
2394}
2395
2396/* =======================================================================
2397 * Load player data.
2398 *
2399 * This is split into two parts as some data can only be loaded if the
2400 * number of players is known and the corresponding player slots are
2401 * defined.
2402 * ======================================================================= */
2403
2404/************************************************************************/
2407static void sg_load_players_basic(struct loaddata *loading)
2408{
2409 int i, k, nplayers;
2410 const char *str;
2411 bool shuffle_loaded = TRUE;
2412
2413 /* Check status and return if not OK (sg_success FALSE). */
2414 sg_check_ret();
2415
2416 if (S_S_INITIAL == loading->server_state
2417 || game.info.is_new_game) {
2418 /* Nothing more to do. */
2419 return;
2420 }
2421
2422 /* Load destroyed wonders: */
2423 str = secfile_lookup_str(loading->file,
2424 "players.destroyed_wonders");
2425 sg_failure_ret(str != NULL, "%s", secfile_error());
2426 sg_failure_ret(strlen(str) == loading->improvement.size,
2427 "Invalid length for 'players.destroyed_wonders' ("
2428 SIZE_T_PRINTF" ~= " SIZE_T_PRINTF ")",
2429 strlen(str), loading->improvement.size);
2430 for (k = 0; k < loading->improvement.size; k++) {
2431 sg_failure_ret(str[k] == '1' || str[k] == '0',
2432 "Undefined value '%c' within "
2433 "'players.destroyed_wonders'.", str[k]);
2434
2435 if (str[k] == '1') {
2436 struct impr_type *pimprove =
2438
2439 if (pimprove) {
2442 }
2443 }
2444 }
2445
2446 server.identity_number
2447 = secfile_lookup_int_default(loading->file, server.identity_number,
2448 "players.identity_number_used");
2449
2450 /* First remove all defined players. */
2451 players_iterate(pplayer) {
2452 server_remove_player(pplayer);
2454
2455 /* Now, load the players from the savefile. */
2456 player_slots_iterate(pslot) {
2457 struct player *pplayer;
2458 struct rgbcolor *prgbcolor = NULL;
2459 int pslot_id = player_slot_index(pslot);
2460
2461 if (NULL == secfile_section_lookup(loading->file, "player%d",
2462 pslot_id)) {
2463 continue;
2464 }
2465
2466 /* Get player AI type. */
2467 str = secfile_lookup_str(loading->file, "player%d.ai_type",
2468 player_slot_index(pslot));
2469 sg_failure_ret(str != NULL, "%s", secfile_error());
2470
2471 /* Get player color */
2472 if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
2473 pslot_id)) {
2474 if (loading->version >= 10 && game_was_started()) {
2475 /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
2476 * as they predate the introduction of configurable player colors. */
2477 log_sg("Game has started, yet player %d has no color defined.",
2478 pslot_id);
2479 /* This will be fixed up later */
2480 } else {
2481 log_verbose("No color defined for player %d.", pslot_id);
2482 /* Colors will be assigned on game start, or at end of savefile
2483 * loading if game has already started */
2484 }
2485 }
2486
2487 /* Create player. */
2488 pplayer = server_create_player(player_slot_index(pslot), str,
2489 prgbcolor,
2492 sg_failure_ret(pplayer != NULL, "Invalid AI type: '%s'!", str);
2493
2494 server_player_init(pplayer, FALSE, FALSE);
2495
2496 /* Free the color definition. */
2497 rgbcolor_destroy(prgbcolor);
2498
2499 /* Multipliers (policies) */
2500
2501 /* First initialise player values with ruleset defaults; this will
2502 * cover any in the ruleset not known when the savefile was created. */
2503 multipliers_iterate(pmul) {
2504 pplayer->multipliers[multiplier_index(pmul)].value
2505 = pplayer->multipliers[multiplier_index(pmul)].target = pmul->def;
2507
2508 /* Now override with any values from the savefile. */
2509 for (k = 0; k < loading->multiplier.size; k++) {
2510 const struct multiplier *pmul = loading->multiplier.order[k];
2511
2512 if (pmul) {
2514 int val =
2515 secfile_lookup_int_default(loading->file, pmul->def,
2516 "player%d.multiplier%d.val",
2517 player_slot_index(pslot), k);
2518 int rval = (((CLIP(pmul->start, val, pmul->stop)
2519 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2520
2521 if (rval != val) {
2522 log_verbose("Player %d had illegal value for multiplier \"%s\": "
2523 "was %d, clamped to %d", pslot_id,
2524 multiplier_rule_name(pmul), val, rval);
2525 }
2526 pplayer->multipliers[idx].value = rval;
2527
2528 val =
2530 pplayer->multipliers[idx].value,
2531 "player%d.multiplier%d.target",
2532 player_slot_index(pslot), k);
2533 rval = (((CLIP(pmul->start, val, pmul->stop)
2534 - pmul->start) / pmul->step) * pmul->step) + pmul->start;
2535
2536 if (rval != val) {
2537 log_verbose("Player %d had illegal value for multiplier_target "
2538 "\"%s\": was %d, clamped to %d", pslot_id,
2539 multiplier_rule_name(pmul), val, rval);
2540 }
2541 pplayer->multipliers[idx].target = rval;
2542
2543 /* Never present in savegame2 format */
2544 pplayer->multipliers[idx].changed = 0;
2545 } /* else silently discard multiplier not in current ruleset */
2546 }
2547
2548 /* Just in case savecompat starts adding it in the future. */
2549 pplayer->server.border_vision =
2551 "player%d.border_vision",
2552 player_slot_index(pslot));
2554
2555 /* check number of players */
2556 nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
2557 sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
2558 "(%d) from the loaded game does not match the number of "
2559 "players present (%d).", nplayers, player_count());
2560
2561 /* Load team information. */
2562 players_iterate(pplayer) {
2563 int team;
2564 struct team_slot *tslot = NULL;
2565
2567 "player%d.team_no",
2568 player_number(pplayer))
2569 && (tslot = team_slot_by_number(team)),
2570 "Invalid team definition for player %s (nb %d).",
2571 player_name(pplayer), player_number(pplayer));
2572 /* Should never fail when slot given is not NULL */
2573 team_add_player(pplayer, team_new(tslot));
2575
2576 /* Loading the shuffle list is quite complex. At the time of saving the
2577 * shuffle data is saved as
2578 * shuffled_player_<number> = player_slot_id
2579 * where number is an increasing number and player_slot_id is a number
2580 * between 0 and the maximum number of player slots. Now we have to create
2581 * a list
2582 * shuffler_players[number] = player_slot_id
2583 * where all player slot IDs are used exactly one time. The code below
2584 * handles this ... */
2585 if (secfile_lookup_int_default(loading->file, -1,
2586 "players.shuffled_player_%d", 0) >= 0) {
2587 int slots = player_slot_count();
2588 int plrcount = player_count();
2589 int shuffled_players[slots];
2590 bool shuffled_player_set[slots];
2591
2592 for (i = 0; i < slots; i++) {
2593 /* Array to save used numbers. */
2594 shuffled_player_set[i] = FALSE;
2595 /* List of all player IDs (needed for set_shuffled_players()). It is
2596 * initialised with the value -1 to indicate that no value is set. */
2597 shuffled_players[i] = -1;
2598 }
2599
2600 /* Load shuffled player list. */
2601 for (i = 0; i < plrcount; i++) {
2602 int shuffle
2603 = secfile_lookup_int_default(loading->file, -1,
2604 "players.shuffled_player_%d", i);
2605
2606 if (shuffle == -1) {
2607 log_sg("Missing player shuffle information (index %d) "
2608 "- reshuffle player list!", i);
2609 shuffle_loaded = FALSE;
2610 break;
2611 } else if (shuffled_player_set[shuffle]) {
2612 log_sg("Player shuffle %d used two times "
2613 "- reshuffle player list!", shuffle);
2614 shuffle_loaded = FALSE;
2615 break;
2616 }
2617 /* Set this ID as used. */
2618 shuffled_player_set[shuffle] = TRUE;
2619
2620 /* Save the player ID in the shuffle list. */
2621 shuffled_players[i] = shuffle;
2622 }
2623
2624 if (shuffle_loaded) {
2625 /* Insert missing numbers. */
2626 int shuffle_index = plrcount;
2627
2628 for (i = 0; i < slots; i++) {
2629 if (!shuffled_player_set[i]) {
2630 shuffled_players[shuffle_index++] = i;
2631 }
2632
2633 /* shuffle_index must not grow higher than size of shuffled_players. */
2634 sg_failure_ret(shuffle_index <= slots,
2635 "Invalid player shuffle data!");
2636 }
2637
2638#ifdef FREECIV_DEBUG
2639 log_debug("[load shuffle] player_count() = %d", player_count());
2640 player_slots_iterate(pslot) {
2641 int plrid = player_slot_index(pslot);
2642
2643 log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
2644 plrid, shuffled_players[plrid], plrid,
2645 shuffled_player_set[plrid] ? "is used" : "-");
2647#endif /* FREECIV_DEBUG */
2648
2649 /* Set shuffle list from savegame. */
2650 set_shuffled_players(shuffled_players);
2651 }
2652 }
2653
2654 if (!shuffle_loaded) {
2655 /* No shuffled players included or error loading them, so shuffle them
2656 * (this may include scenarios). */
2658 }
2659}
2660
2661/************************************************************************/
2664static void sg_load_players(struct loaddata *loading)
2665{
2666 /* Check status and return if not OK (sg_success FALSE). */
2667 sg_check_ret();
2668
2669 if (game.info.is_new_game) {
2670 /* Nothing to do. */
2671 return;
2672 }
2673
2674 players_iterate(pplayer) {
2675 sg_load_player_main(loading, pplayer);
2676 sg_load_player_cities(loading, pplayer);
2677 sg_load_player_units(loading, pplayer);
2678 sg_load_player_attributes(loading, pplayer);
2679
2680 /* Check the success of the functions above. */
2681 sg_check_ret();
2682
2683 /* Print out some information */
2684 if (is_ai(pplayer)) {
2685 log_normal(_("%s has been added as %s level AI-controlled player "
2686 "(%s)."), player_name(pplayer),
2687 ai_level_translated_name(pplayer->ai_common.skill_level),
2688 ai_name(pplayer->ai));
2689 } else {
2690 log_normal(_("%s has been added as human player."),
2691 player_name(pplayer));
2692 }
2694
2695 /* Also load the transport status of the units here. It must be a special
2696 * case as all units must be known (unit on an allied transporter). */
2697 players_iterate(pplayer) {
2698 /* Load unit transport status. */
2699 sg_load_player_units_transport(loading, pplayer);
2701
2702 /* Savegame may contain nation assignments that are incompatible with the
2703 * current nationset -- for instance, if it predates the introduction of
2704 * nationsets. Ensure they are compatible, one way or another. */
2706
2707 /* Some players may have invalid nations in the ruleset. Once all players
2708 * are loaded, pick one of the remaining nations for them. */
2709 players_iterate(pplayer) {
2710 if (pplayer->nation == NO_NATION_SELECTED) {
2711 player_set_nation(pplayer, pick_a_nation(NULL, FALSE, TRUE,
2712 NOT_A_BARBARIAN));
2713 /* TRANS: Minor error message: <Leader> ... <Poles>. */
2714 log_sg(_("%s had invalid nation; changing to %s."),
2715 player_name(pplayer), nation_plural_for_player(pplayer));
2716
2717 ai_traits_init(pplayer);
2718 }
2720
2721 /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
2723 players_iterate_alive(aplayer) {
2724 if (pplayers_allied(plr, aplayer)) {
2725 enum dipl_reason can_ally = pplayer_can_make_treaty(plr, aplayer,
2726 DS_ALLIANCE);
2727
2728 if (can_ally == DIPL_ALLIANCE_PROBLEM_US
2729 || can_ally == DIPL_ALLIANCE_PROBLEM_THEM) {
2730 log_sg("Illegal alliance structure detected: "
2731 "%s alliance to %s reduced to peace treaty.",
2734 player_diplstate_get(plr, aplayer)->type = DS_PEACE;
2735 player_diplstate_get(aplayer, plr)->type = DS_PEACE;
2736 }
2737 }
2740
2741 /* Update cached city illness. This can depend on trade routes,
2742 * so can't be calculated until all players have been loaded. */
2743 if (game.info.illness_on) {
2744 cities_iterate(pcity) {
2745 pcity->server.illness
2746 = city_illness_calc(pcity, NULL, NULL,
2747 &(pcity->illness_trade), NULL);
2749 }
2750
2751 /* Update all city information. This must come after all cities are
2752 * loaded (in player_load) but before player (dumb) cities are loaded
2753 * in player_load_vision(). */
2754 players_iterate(plr) {
2755 city_list_iterate(plr->cities, pcity) {
2756 city_refresh(pcity);
2757 sanity_check_city(pcity);
2758 CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
2761
2762 /* Since the cities must be placed on the map to put them on the
2763 player map we do this afterwards */
2764 players_iterate(pplayer) {
2765 sg_load_player_vision(loading, pplayer);
2766 /* Check the success of the function above. */
2767 sg_check_ret();
2769
2770 /* Check shared vision. */
2771 players_iterate(pplayer) {
2772 BV_CLR_ALL(pplayer->gives_shared_vision);
2773 BV_CLR_ALL(pplayer->server.really_gives_vision);
2775
2776 /* Set up shared vision... */
2777 players_iterate(pplayer) {
2778 int plr1 = player_index(pplayer);
2779
2780 players_iterate(pplayer2) {
2781 int plr2 = player_index(pplayer2);
2782
2784 "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
2785 give_shared_vision(pplayer, pplayer2);
2786 }
2789
2790 /* ...and check it */
2791 players_iterate(pplayer1) {
2792 players_iterate(pplayer2) {
2793 /* TODO: Is there a good reason player is not marked as
2794 * giving shared vision to themselves -> really_gives_vision()
2795 * returning FALSE when pplayer1 == pplayer2 */
2796 if (pplayer1 != pplayer2
2797 && players_on_same_team(pplayer1, pplayer2)) {
2798 if (!really_gives_vision(pplayer1, pplayer2)) {
2799 sg_regr(3000900,
2800 _("%s did not give shared vision to team member %s."),
2801 player_name(pplayer1), player_name(pplayer2));
2802 give_shared_vision(pplayer1, pplayer2);
2803 }
2804 if (!really_gives_vision(pplayer2, pplayer1)) {
2805 sg_regr(3000900,
2806 _("%s did not give shared vision to team member %s."),
2807 player_name(pplayer2), player_name(pplayer1));
2808 give_shared_vision(pplayer2, pplayer1);
2809 }
2810 }
2813
2816
2817 /* All vision is ready; this calls city_thaw_workers_queue(). */
2819
2820 /* Make sure everything is consistent. */
2821 players_iterate(pplayer) {
2822 unit_list_iterate(pplayer->units, punit) {
2824 struct tile *ptile = unit_tile(punit);
2825
2826 log_sg("%s doing illegal activity in savegame!",
2828 log_sg("Activity: %s, Target: %s, Tile: (%d, %d), Terrain: %s",
2829 unit_activity_name(punit->activity),
2832 : "missing",
2833 TILE_XY(ptile), terrain_rule_name(tile_terrain(ptile)));
2834 punit->activity = ACTIVITY_IDLE;
2835 }
2838
2839 cities_iterate(pcity) {
2840 city_refresh(pcity);
2841 city_thaw_workers(pcity); /* may auto_arrange_workers() */
2843
2844 /* Player colors are always needed once game has started. Pre-2.4 savegames
2845 * lack them. This cannot be in compatibility conversion layer as we need
2846 * all the player data available to be able to assign best colors. */
2847 if (game_was_started()) {
2849 }
2850}
2851
2852/************************************************************************/
2855static void sg_load_player_main(struct loaddata *loading,
2856 struct player *plr)
2857{
2858 const char **slist;
2859 int i, plrno = player_number(plr);
2860 const char *str;
2861 struct government *gov;
2862 const char *level;
2863 const char *barb_str;
2864 size_t nval;
2865
2866 /* Check status and return if not OK (sg_success FALSE). */
2867 sg_check_ret();
2868
2869 /* Basic player data. */
2870 str = secfile_lookup_str(loading->file, "player%d.name", plrno);
2871 sg_failure_ret(str != NULL, "%s", secfile_error());
2873 sz_strlcpy(plr->username,
2874 secfile_lookup_str_default(loading->file, "",
2875 "player%d.username", plrno));
2877 "player%d.unassigned_user", plrno),
2878 "%s", secfile_error());
2880 secfile_lookup_str_default(loading->file, "",
2881 "player%d.orig_username",
2882 plrno));
2884 secfile_lookup_str_default(loading->file, "",
2885 "player%d.ranked_username",
2886 plrno));
2888 "player%d.unassigned_ranked", plrno),
2889 "%s", secfile_error());
2890 str = secfile_lookup_str_default(loading->file, "",
2891 "player%d.delegation_username",
2892 plrno);
2893 /* Defaults to no delegation. */
2894 if (strlen(str)) {
2896 }
2897
2898 /* Player flags */
2899 BV_CLR_ALL(plr->flags);
2900 slist = secfile_lookup_str_vec(loading->file, &nval, "player%d.flags", plrno);
2901 for (i = 0; i < nval; i++) {
2902 const char *sval = slist[i];
2903 enum plr_flag_id fid = plr_flag_id_by_name(sval, fc_strcasecmp);
2904
2905 sg_failure_ret(plr_flag_id_is_valid(fid), "Invalid player flag \"%s\".", sval);
2906
2907 BV_SET(plr->flags, fid);
2908 }
2909 free(slist);
2910
2911 /* Nation */
2912 str = secfile_lookup_str(loading->file, "player%d.nation", plrno);
2914 if (plr->nation != NULL) {
2915 ai_traits_init(plr);
2916 }
2917
2918 /* Government */
2919 str = secfile_lookup_str(loading->file, "player%d.government_name",
2920 plrno);
2922 sg_failure_ret(gov != NULL, "Player%d: unsupported government \"%s\".",
2923 plrno, str);
2924 plr->government = gov;
2925
2926 /* Target government */
2927 str = secfile_lookup_str(loading->file,
2928 "player%d.target_government_name", plrno);
2929 if (str != NULL) {
2931 } else {
2932 plr->target_government = NULL;
2933 }
2935 = secfile_lookup_int_default(loading->file, -1,
2936 "player%d.revolution_finishes", plrno);
2937
2939 &plr->server.got_first_city,
2940 "player%d.got_first_city", plrno),
2941 "%s", secfile_error());
2942
2943 /* Load diplomatic data (diplstate + embassy + vision).
2944 * Shared vision is loaded in sg_load_players(). */
2946 players_iterate(pplayer) {
2947 char buf[32];
2948 int unconverted;
2949 struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
2950 i = player_index(pplayer);
2951
2952 /* load diplomatic status */
2953 fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
2954
2955 unconverted =
2956 secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
2957 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
2958 /* Look up what state the unconverted number represents. */
2959 ds->type = loading->ds_t.order[unconverted];
2960 } else {
2961 log_sg("No valid diplomatic state type between players %d and %d",
2962 plrno, i);
2963
2964 ds->type = DS_WAR;
2965 }
2966
2967 unconverted =
2968 secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
2969 if (unconverted >= 0 && unconverted < loading->ds_t.size) {
2970 /* Look up what state the unconverted number represents. */
2971 ds->max_state = loading->ds_t.order[unconverted];
2972 } else {
2973 log_sg("No valid diplomatic max_state between players %d and %d",
2974 plrno, i);
2975
2976 ds->max_state = DS_WAR;
2977 }
2978
2979 ds->first_contact_turn =
2980 secfile_lookup_int_default(loading->file, 0,
2981 "%s.first_contact_turn", buf);
2982 ds->turns_left =
2983 secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
2985 secfile_lookup_int_default(loading->file, 0,
2986 "%s.has_reason_to_cancel", buf);
2987 ds->contact_turns_left =
2988 secfile_lookup_int_default(loading->file, 0,
2989 "%s.contact_turns_left", buf);
2990
2991 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
2992 buf)) {
2993 BV_SET(plr->real_embassy, i);
2994 }
2995 /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
2996 * must be known. */
2998
2999 /* load ai data */
3000 players_iterate(aplayer) {
3001 char buf[32];
3002
3003 fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
3004 player_index(aplayer));
3005
3006 plr->ai_common.love[player_index(aplayer)] =
3007 secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
3008 CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
3010
3011 CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
3012
3013 /* Some sane defaults */
3014 plr->ai_common.fuzzy = 0;
3015 plr->ai_common.expand = 100;
3016 plr->ai_common.science_cost = 100;
3017
3018
3019 level = secfile_lookup_str_default(loading->file, NULL,
3020 "player%d.ai.level", plrno);
3021 if (level != NULL) {
3022 if (!fc_strcasecmp("Handicapped", level)) {
3023 /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
3024 plr->ai_common.skill_level = AI_LEVEL_RESTRICTED;
3025 } else {
3026 plr->ai_common.skill_level = ai_level_by_name(level, fc_strcasecmp);
3027 }
3028 } else {
3029 plr->ai_common.skill_level = ai_level_invalid();
3030 }
3031
3032 if (!ai_level_is_valid(plr->ai_common.skill_level)) {
3036 "player%d.ai.skill_level",
3037 plrno));
3038 }
3039
3040 barb_str = secfile_lookup_str_default(loading->file, "None",
3041 "player%d.ai.barb_type", plrno);
3042 plr->ai_common.barbarian_type = barbarian_type_by_name(barb_str, fc_strcasecmp);
3043
3044 if (!barbarian_type_is_valid(plr->ai_common.barbarian_type)) {
3045 log_sg("Player%d: Invalid barbarian type \"%s\". "
3046 "Changed to \"None\".", plrno, barb_str);
3047 plr->ai_common.barbarian_type = NOT_A_BARBARIAN;
3048 }
3049
3050 if (is_barbarian(plr)) {
3051 server.nbarbarians++;
3052 }
3053
3054 if (is_ai(plr)) {
3056 CALL_PLR_AI_FUNC(gained_control, plr, plr);
3057 }
3058
3059 /* Load nation style. */
3060 {
3061 struct nation_style *style;
3062
3063 str = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
3064
3065 /* Handle pre-2.6 savegames */
3066 if (str == NULL) {
3067 str = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
3068 plrno);
3069 }
3070
3071 sg_failure_ret(str != NULL, "%s", secfile_error());
3072 style = style_by_rule_name(str);
3073 if (style == NULL) {
3074 style = style_by_number(0);
3075 log_sg("Player%d: unsupported city_style_name \"%s\". "
3076 "Changed to \"%s\".", plrno, str, style_rule_name(style));
3077 }
3078 plr->style = style;
3079 }
3080
3082 "player%d.idle_turns", plrno),
3083 "%s", secfile_error());
3085 "player%d.is_male", plrno);
3087 "player%d.is_alive", plrno),
3088 "%s", secfile_error());
3090 "player%d.turns_alive", plrno),
3091 "%s", secfile_error());
3093 "player%d.last_war", plrno),
3094 "%s", secfile_error());
3096 "player%d.phase_done", plrno);
3098 "player%d.gold", plrno),
3099 "%s", secfile_error());
3101 "player%d.rates.tax", plrno),
3102 "%s", secfile_error());
3104 "player%d.rates.science", plrno),
3105 "%s", secfile_error());
3107 "player%d.rates.luxury", plrno),
3108 "%s", secfile_error());
3109 plr->server.bulbs_last_turn =
3110 secfile_lookup_int_default(loading->file, 0,
3111 "player%d.research.bulbs_last_turn", plrno);
3112
3113 /* Traits */
3114 if (plr->nation) {
3115 for (i = 0; i < loading->trait.size; i++) {
3116 enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
3117
3118 if (trait_is_valid(tr)) {
3119 int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
3120 plrno, i);
3121
3122 if (val != -1) {
3123 plr->ai_common.traits[tr].val = val;
3124 }
3125
3126 sg_failure_ret(secfile_lookup_int(loading->file, &val,
3127 "player%d.trait%d.mod", plrno, i),
3128 "%s", secfile_error());
3129 plr->ai_common.traits[tr].mod = val;
3130 }
3131 }
3132 }
3133
3134 /* Achievements */
3135 {
3136 int count;
3137
3138 count = secfile_lookup_int_default(loading->file, -1,
3139 "player%d.achievement_count", plrno);
3140
3141 if (count > 0) {
3142 for (i = 0; i < count; i++) {
3143 const char *name;
3144 struct achievement *pach;
3145 bool first;
3146
3147 name = secfile_lookup_str(loading->file,
3148 "player%d.achievement%d.name", plrno, i);
3150
3151 sg_failure_ret(pach != NULL,
3152 "Unknown achievement \"%s\".", name);
3153
3155 "player%d.achievement%d.first",
3156 plrno, i),
3157 "achievement error: %s", secfile_error());
3158
3159 sg_failure_ret(pach->first == NULL || !first,
3160 "Multiple players listed as first to get achievement \"%s\".",
3161 name);
3162
3163 BV_SET(pach->achievers, player_index(plr));
3164
3165 if (first) {
3166 pach->first = plr;
3167 }
3168 }
3169 }
3170 }
3171
3172 /* Player score. */
3173 plr->score.happy =
3174 secfile_lookup_int_default(loading->file, 0,
3175 "score%d.happy", plrno);
3176 plr->score.content =
3177 secfile_lookup_int_default(loading->file, 0,
3178 "score%d.content", plrno);
3179 plr->score.unhappy =
3180 secfile_lookup_int_default(loading->file, 0,
3181 "score%d.unhappy", plrno);
3182 plr->score.angry =
3183 secfile_lookup_int_default(loading->file, 0,
3184 "score%d.angry", plrno);
3185
3186 /* Make sure that the score about specialists in current ruleset that
3187 * were not present at saving time are set to zero. */
3189 plr->score.specialists[sp] = 0;
3191
3192 for (i = 0; i < loading->specialist.size; i++) {
3194 = secfile_lookup_int_default(loading->file, 0,
3195 "score%d.specialists%d", plrno, i);
3196 }
3197
3198 plr->score.wonders =
3199 secfile_lookup_int_default(loading->file, 0,
3200 "score%d.wonders", plrno);
3201 plr->score.techs =
3202 secfile_lookup_int_default(loading->file, 0,
3203 "score%d.techs", plrno);
3204 plr->score.techout =
3205 secfile_lookup_int_default(loading->file, 0,
3206 "score%d.techout", plrno);
3207 plr->score.landarea =
3208 secfile_lookup_int_default(loading->file, 0,
3209 "score%d.landarea", plrno);
3210 plr->score.settledarea =
3211 secfile_lookup_int_default(loading->file, 0,
3212 "score%d.settledarea", plrno);
3213 plr->score.population =
3214 secfile_lookup_int_default(loading->file, 0,
3215 "score%d.population", plrno);
3216 plr->score.cities =
3217 secfile_lookup_int_default(loading->file, 0,
3218 "score%d.cities", plrno);
3219 plr->score.units =
3220 secfile_lookup_int_default(loading->file, 0,
3221 "score%d.units", plrno);
3222 plr->score.pollution =
3223 secfile_lookup_int_default(loading->file, 0,
3224 "score%d.pollution", plrno);
3225 plr->score.literacy =
3226 secfile_lookup_int_default(loading->file, 0,
3227 "score%d.literacy", plrno);
3228 plr->score.bnp =
3229 secfile_lookup_int_default(loading->file, 0,
3230 "score%d.bnp", plrno);
3231 plr->score.mfg =
3232 secfile_lookup_int_default(loading->file, 0,
3233 "score%d.mfg", plrno);
3234 plr->score.spaceship =
3235 secfile_lookup_int_default(loading->file, 0,
3236 "score%d.spaceship", plrno);
3237 plr->score.units_built =
3238 secfile_lookup_int_default(loading->file, 0,
3239 "score%d.units_built", plrno);
3240 plr->score.units_killed =
3241 secfile_lookup_int_default(loading->file, 0,
3242 "score%d.units_killed", plrno);
3243 plr->score.units_lost =
3244 secfile_lookup_int_default(loading->file, 0,
3245 "score%d.units_lost", plrno);
3246 plr->score.culture =
3247 secfile_lookup_int_default(loading->file, 0,
3248 "score%d.culture", plrno);
3249 plr->score.game =
3250 secfile_lookup_int_default(loading->file, 0,
3251 "score%d.total", plrno);
3252
3253 /* Load space ship data. */
3254 {
3255 struct player_spaceship *ship = &plr->spaceship;
3256 char prefix[32];
3257 const char *st;
3258 int ei;
3259
3260 fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
3261 spaceship_init(ship);
3263 &ei,
3264 "%s.state", prefix),
3265 "%s", secfile_error());
3266 ship->state = ei;
3267
3268 if (ship->state != SSHIP_NONE) {
3270 "%s.structurals", prefix),
3271 "%s", secfile_error());
3273 "%s.components", prefix),
3274 "%s", secfile_error());
3276 "%s.modules", prefix),
3277 "%s", secfile_error());
3278 sg_failure_ret(secfile_lookup_int(loading->file, &ship->fuel,
3279 "%s.fuel", prefix),
3280 "%s", secfile_error());
3282 "%s.propulsion", prefix),
3283 "%s", secfile_error());
3285 "%s.habitation", prefix),
3286 "%s", secfile_error());
3288 "%s.life_support", prefix),
3289 "%s", secfile_error());
3291 "%s.solar_panels", prefix),
3292 "%s", secfile_error());
3293
3294 st = secfile_lookup_str(loading->file, "%s.structure", prefix);
3295 sg_failure_ret(st != NULL, "%s", secfile_error())
3296 for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
3297 sg_failure_ret(st[i] == '1' || st[i] == '0',
3298 "Undefined value '%c' within '%s.structure'.", st[i],
3299 prefix)
3300
3301 if (!(st[i] == '0')) {
3302 BV_SET(ship->structure, i);
3303 }
3304 }
3305 if (ship->state >= SSHIP_LAUNCHED) {
3307 "%s.launch_year", prefix),
3308 "%s", secfile_error());
3309 }
3311 }
3312 }
3313
3314 /* Load lost wonder data. */
3315 str = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
3316 /* If not present, probably an old savegame; nothing to be done */
3317 if (str != NULL) {
3318 int k;
3319
3320 sg_failure_ret(strlen(str) == loading->improvement.size,
3321 "Invalid length for 'player%d.lost_wonders' ("
3322 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ")",
3323 plrno, strlen(str), loading->improvement.size);
3324 for (k = 0; k < loading->improvement.size; k++) {
3325 sg_failure_ret(str[k] == '1' || str[k] == '0',
3326 "Undefined value '%c' within "
3327 "'player%d.lost_wonders'.", plrno, str[k]);
3328
3329 if (str[k] == '1') {
3330 struct impr_type *pimprove =
3332
3333 if (pimprove) {
3334 plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
3335 }
3336 }
3337 }
3338 }
3339
3340 plr->history =
3341 secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
3342 plr->server.huts =
3343 secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
3344}
3345
3346/************************************************************************/
3349static void sg_load_player_cities(struct loaddata *loading,
3350 struct player *plr)
3351{
3352 int ncities, i, plrno = player_number(plr);
3353 bool tasks_handled;
3354 int wlist_max_length = 0;
3355
3356 /* Check status and return if not OK (sg_success FALSE). */
3357 sg_check_ret();
3358
3359 sg_failure_ret(secfile_lookup_int(loading->file, &ncities,
3360 "player%d.ncities", plrno),
3361 "%s", secfile_error());
3362
3363 if (!plr->is_alive && ncities > 0) {
3364 log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
3365 ncities = 0;
3366 }
3367
3368 if (!plr->server.got_first_city && ncities > 0) {
3369 /* Probably barbarians in an old savegame; fix up */
3370 plr->server.got_first_city = TRUE;
3371 }
3372
3373 /* Find longest worklist */
3374 for (i = 0; i < ncities; i++) {
3375 int wl_length = secfile_lookup_int_default(loading->file, 0,
3376 "player%d.c%d.wl_length",
3377 plrno, i);
3378
3379 wlist_max_length = MAX(wlist_max_length, wl_length);
3380 }
3381
3382 /* Load all cities of the player. */
3383 for (i = 0; i < ncities; i++) {
3384 char buf[32];
3385 struct city *pcity;
3386
3387 fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
3388
3389 /* Create a dummy city. */
3390 pcity = create_city_virtual(plr, NULL, buf);
3391 adv_city_alloc(pcity);
3392 if (!sg_load_player_city(loading, plr, pcity, buf, wlist_max_length)) {
3393 adv_city_free(pcity);
3394 destroy_city_virtual(pcity);
3395 sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
3396 }
3397
3399 idex_register_city(&wld, pcity);
3400
3401 /* Load the information about the nationality of citizens. This is done
3402 * here because the city sanity check called by citizens_update() requires
3403 * that the city is registered. */
3404 sg_load_player_city_citizens(loading, plr, pcity, buf);
3405
3406 /* After everything is loaded, but before vision. */
3407 map_claim_ownership(city_tile(pcity), plr, city_tile(pcity), TRUE);
3408
3409 /* adding the city contribution to fog-of-war */
3410 pcity->server.vision = vision_new(plr, city_tile(pcity));
3412 city_refresh_vision(pcity);
3413
3414 city_list_append(plr->cities, pcity);
3415 }
3416
3417 tasks_handled = FALSE;
3418 for (i = 0; !tasks_handled; i++) {
3419 int city_id;
3420 struct city *pcity = NULL;
3421
3422 city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
3423 plrno, i);
3424
3425 if (city_id != -1) {
3426 pcity = player_city_by_number(plr, city_id);
3427 }
3428
3429 if (pcity != NULL) {
3430 const char *str;
3431 int nat_x, nat_y;
3432 struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
3433
3434 nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
3435 nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
3436
3437 ptask->ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3438
3439 str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
3440 ptask->act = unit_activity_by_name(str, fc_strcasecmp);
3441
3442 sg_failure_ret(unit_activity_is_valid(ptask->act),
3443 "Unknown workertask activity %s", str);
3444
3445 str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
3446
3447 if (strcmp("-", str)) {
3449
3450 sg_failure_ret(ptask->tgt != NULL,
3451 "Unknown workertask target %s", str);
3452 } else {
3453 ptask->tgt = NULL;
3454 }
3455
3456 ptask->want = secfile_lookup_int_default(loading->file, 1,
3457 "player%d.task%d.want", plrno, i);
3458
3459 worker_task_list_append(pcity->task_reqs, ptask);
3460 } else {
3461 tasks_handled = TRUE;
3462 }
3463 }
3464}
3465
3466/************************************************************************/
3469static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
3470 struct city *pcity, const char *citystr,
3471 int wlist_max_length)
3472{
3473 struct player *past;
3474 const char *kind, *name, *str;
3475 int id, i, repair, sp_count = 0, workers = 0, value;
3476 int nat_x, nat_y;
3477 citizens size;
3478 const char *stylename;
3479 const struct civ_map *nmap = &(wld.map);
3480
3481 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", citystr),
3482 FALSE, "%s", secfile_error());
3483 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", citystr),
3484 FALSE, "%s", secfile_error());
3485 pcity->tile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3486 sg_warn_ret_val(NULL != pcity->tile, FALSE,
3487 "%s has invalid center tile (%d, %d)",
3488 citystr, nat_x, nat_y);
3489 sg_warn_ret_val(NULL == tile_city(pcity->tile), FALSE,
3490 "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
3491
3492 /* Instead of dying, use 'citystr' string for damaged name. */
3493 city_name_set(pcity, secfile_lookup_str_default(loading->file, citystr,
3494 "%s.name", citystr));
3495
3496 sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->id, "%s.id",
3497 citystr), FALSE, "%s", secfile_error());
3498
3499 id = secfile_lookup_int_default(loading->file, player_number(plr),
3500 "%s.original", citystr);
3501 past = player_by_number(id);
3502 if (NULL != past) {
3503 pcity->original = past;
3504 }
3505
3506 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
3507 citystr), FALSE, "%s", secfile_error());
3508 size = (citizens)value; /* set the correct type */
3509 sg_warn_ret_val(value == (int)size, FALSE,
3510 "Invalid city size: %d, set to %d", value, size);
3511 city_size_set(pcity, size);
3512
3513 for (i = 0; i < loading->specialist.size; i++) {
3514 sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
3515 citystr, i),
3516 FALSE, "%s", secfile_error());
3517 pcity->specialists[specialist_index(loading->specialist.order[i])]
3518 = (citizens)value;
3519 sp_count += value;
3520 }
3521
3522 for (i = 0; i < MAX_TRADE_ROUTES; i++) {
3523 int partner = secfile_lookup_int_default(loading->file, 0,
3524 "%s.traderoute%d", citystr, i);
3525
3526 if (partner != 0) {
3527 struct trade_route *proute = fc_malloc(sizeof(struct trade_route));
3528
3529 proute->partner = partner;
3530 proute->dir = RDIR_BIDIRECTIONAL;
3531 proute->goods = goods_by_number(0); /* First good */
3532
3533 trade_route_list_append(pcity->routes, proute);
3534 }
3535 }
3536
3538 "%s.food_stock", citystr),
3539 FALSE, "%s", secfile_error());
3541 "%s.shield_stock", citystr),
3542 FALSE, "%s", secfile_error());
3543 pcity->history =
3544 secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
3545
3546 pcity->airlift =
3547 secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
3548 pcity->was_happy =
3549 secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
3550 citystr);
3551
3552 pcity->turn_plague =
3553 secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
3554
3556 "%s.anarchy", citystr),
3557 FALSE, "%s", secfile_error());
3558 pcity->rapture =
3559 secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
3560 pcity->steal =
3561 secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
3562
3563 /* before did_buy for undocumented hack */
3564 pcity->turn_founded =
3565 secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
3566 citystr);
3567 sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
3568 citystr), FALSE, "%s", secfile_error());
3569 pcity->did_buy = (i != 0);
3570 if (i == -1 && pcity->turn_founded == -2) {
3571 /* undocumented hack */
3572 pcity->turn_founded = game.info.turn;
3573 }
3574
3575 pcity->did_sell =
3576 secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
3577
3579 "%s.turn_last_built", citystr),
3580 FALSE, "%s", secfile_error());
3581
3582 kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
3583 citystr);
3584 name = secfile_lookup_str(loading->file, "%s.currently_building_name",
3585 citystr);
3586 pcity->production = universal_by_rule_name(kind, name);
3587 sg_warn_ret_val(pcity->production.kind != universals_n_invalid(), FALSE,
3588 "%s.currently_building: unknown \"%s\" \"%s\".",
3589 citystr, kind, name);
3590
3591 kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
3592 citystr);
3593 name = secfile_lookup_str(loading->file, "%s.changed_from_name",
3594 citystr);
3596 sg_warn_ret_val(pcity->changed_from.kind != universals_n_invalid(), FALSE,
3597 "%s.changed_from: unknown \"%s\" \"%s\".",
3598 citystr, kind, name);
3599
3600 pcity->before_change_shields =
3602 "%s.before_change_shields", citystr);
3603 pcity->caravan_shields =
3604 secfile_lookup_int_default(loading->file, 0,
3605 "%s.caravan_shields", citystr);
3606 pcity->disbanded_shields =
3607 secfile_lookup_int_default(loading->file, 0,
3608 "%s.disbanded_shields", citystr);
3610 secfile_lookup_int_default(loading->file, 0,
3611 "%s.last_turns_shield_surplus",
3612 citystr);
3613
3614 stylename = secfile_lookup_str_default(loading->file, NULL,
3615 "%s.style", citystr);
3616 if (stylename != NULL) {
3617 pcity->style = city_style_by_rule_name(stylename);
3618 } else {
3619 pcity->style = 0;
3620 }
3621 if (pcity->style < 0) {
3622 pcity->style = city_style(pcity);
3623 }
3624
3625 pcity->server.synced = FALSE; /* Must re-sync with clients */
3626
3627 /* Initialise list of city improvements. */
3628 for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
3629 pcity->built[i].turn = I_NEVER;
3630 }
3631
3632 /* Load city improvements. */
3633 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
3634 sg_warn_ret_val(str != NULL, FALSE, "%s", secfile_error());
3635 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
3636 "Invalid length of '%s.improvements' ("
3637 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
3638 citystr, strlen(str), loading->improvement.size);
3639 for (i = 0; i < loading->improvement.size; i++) {
3640 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
3641 "Undefined value '%c' within '%s.improvements'.",
3642 str[i], citystr)
3643
3644 if (str[i] == '1') {
3645 struct impr_type *pimprove =
3647
3648 if (pimprove) {
3649 city_add_improvement(pcity, pimprove);
3650 }
3651 }
3652 }
3653
3654 sg_failure_ret_val(loading->worked_tiles != NULL, FALSE,
3655 "No worked tiles map defined.");
3656
3657 city_freeze_workers(pcity);
3658
3659 /* Load new savegame with variable (squared) city radius and worked
3660 * tiles map */
3661
3662 int radius_sq
3663 = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
3664 citystr);
3665 city_map_radius_sq_set(pcity, radius_sq);
3666
3667 city_tile_iterate(nmap, CITY_MAP_MAX_RADIUS_SQ, city_tile(pcity), ptile) {
3668 if (loading->worked_tiles[ptile->index] == pcity->id) {
3669 if (sq_map_distance(ptile, pcity->tile) > radius_sq) {
3670 log_sg("[%s] '%s' (%d, %d) has worker outside current radius "
3671 "at (%d, %d); repairing", citystr, city_name_get(pcity),
3672 TILE_XY(pcity->tile), TILE_XY(ptile));
3674 sp_count++;
3675 } else {
3676 tile_set_worked(ptile, pcity);
3677 workers++;
3678 }
3679
3680#ifdef FREECIV_DEBUG
3681 /* Set this tile to unused; a check for not reset tiles is
3682 * included in game_load_internal() */
3683 loading->worked_tiles[ptile->index] = -1;
3684#endif /* FREECIV_DEBUG */
3685 }
3687
3688 if (tile_worked(city_tile(pcity)) != pcity) {
3689 struct city *pwork = tile_worked(city_tile(pcity));
3690
3691 if (NULL != pwork) {
3692 log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
3693 "(%d,%d) [%d]; repairing", citystr, city_name_get(pcity),
3694 TILE_XY(city_tile(pcity)), city_size_get(pcity), city_name_get(pwork),
3695 TILE_XY(city_tile(pwork)), city_size_get(pwork));
3696
3697 tile_set_worked(city_tile(pcity), NULL); /* remove tile from pwork */
3699 auto_arrange_workers(pwork);
3700 } else {
3701 log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing",
3702 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)),
3703 city_size_get(pcity));
3704 }
3705
3706 /* repair pcity */
3707 tile_set_worked(city_tile(pcity), pcity);
3708 city_repair_size(pcity, -1);
3709 }
3710
3711 repair = city_size_get(pcity) - sp_count - (workers - FREE_WORKED_TILES);
3712 if (0 != repair) {
3713 log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
3714 "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
3715 citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)), city_size_get(pcity),
3716 workers, FREE_WORKED_TILES, sp_count);
3717
3718 /* repair pcity */
3719 city_repair_size(pcity, repair);
3720 }
3721
3722 /* worklist_init() done in create_city_virtual() */
3723 worklist_load(loading->file, wlist_max_length, &pcity->worklist, "%s", citystr);
3724
3725 /* Load city options. */
3726 BV_CLR_ALL(pcity->city_options);
3727 for (i = 0; i < CITYO_LAST; i++) {
3728 if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
3729 citystr, i)) {
3730 BV_SET(pcity->city_options, i);
3731 }
3732 }
3733
3734 CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
3735
3736 return TRUE;
3737}
3738
3739/************************************************************************/
3742static void sg_load_player_city_citizens(struct loaddata *loading,
3743 struct player *plr,
3744 struct city *pcity,
3745 const char *citystr)
3746{
3748 citizens size;
3749
3750 citizens_init(pcity);
3751 player_slots_iterate(pslot) {
3752 int nationality;
3753
3755 "%s.citizen%d", citystr,
3756 player_slot_index(pslot));
3757 if (nationality > 0 && !player_slot_is_used(pslot)) {
3758 log_sg("Citizens of an invalid nation for %s (player slot %d)!",
3759 city_name_get(pcity), player_slot_index(pslot));
3760 continue;
3761 }
3762
3763 if (nationality != -1 && player_slot_is_used(pslot)) {
3765 "Invalid value for citizens of player %d in %s: %d.",
3767 citizens_nation_set(pcity, pslot, nationality);
3768 }
3770 /* Sanity check. */
3771 size = citizens_count(pcity);
3772 if (size != city_size_get(pcity)) {
3773 if (size != 0) {
3774 /* size == 0 can be result from the fact that ruleset had no
3775 * nationality enabled at saving time, so no citizens at all
3776 * were saved. But something more serious must be going on if
3777 * citizens have been saved partially - if some of them are there. */
3778 log_sg("City size and number of citizens does not match in %s "
3779 "(%d != %d)! Repairing ...", city_name_get(pcity),
3780 city_size_get(pcity), size);
3781 }
3782 citizens_update(pcity, NULL);
3783 }
3784 }
3785}
3786
3787/************************************************************************/
3790static void sg_load_player_units(struct loaddata *loading,
3791 struct player *plr)
3792{
3793 int nunits, i, plrno = player_number(plr);
3794
3795 /* Check status and return if not OK (sg_success FALSE). */
3796 sg_check_ret();
3797
3798 sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
3799 "player%d.nunits", plrno),
3800 "%s", secfile_error());
3801 if (!plr->is_alive && nunits > 0) {
3802 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
3803 nunits = 0; /* Some old savegames may be buggy. */
3804 }
3805
3806 for (i = 0; i < nunits; i++) {
3807 struct unit *punit;
3808 struct city *pcity;
3809 const char *name;
3810 char buf[32];
3811 struct unit_type *type;
3812 struct tile *ptile;
3813
3814 fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
3815
3816 name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
3818 sg_failure_ret(type != NULL, "%s: unknown unit type \"%s\".", buf, name);
3819
3820 /* Create a dummy unit. */
3821 punit = unit_virtual_create(plr, NULL, type, 0);
3822 if (!sg_load_player_unit(loading, plr, punit, buf)) {
3824 sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
3825 }
3826
3829
3830 if ((pcity = game_city_by_number(punit->homecity))) {
3831 unit_list_prepend(pcity->units_supported, punit);
3832 } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
3833 log_sg("%s: bad home city %d.", buf, punit->homecity);
3835 }
3836
3837 ptile = unit_tile(punit);
3838
3839 /* allocate the unit's contribution to fog of war */
3842 /* NOTE: There used to be some map_set_known calls here. These were
3843 * unneeded since unfogging the tile when the unit sees it will
3844 * automatically reveal that tile. */
3845
3846 unit_list_append(plr->units, punit);
3847 unit_list_prepend(unit_tile(punit)->units, punit);
3848
3849 /* Claim ownership of fortress? */
3850 if ((extra_owner(ptile) == NULL
3851 || pplayers_at_war(extra_owner(ptile), plr))
3853 tile_claim_bases(ptile, plr);
3854 }
3855 }
3856}
3857
3858/************************************************************************/
3868static int sg_order_to_action(int order, struct unit *act_unit,
3869 struct tile *tgt_tile)
3870{
3871 switch (order) {
3873 if (tile_city(tgt_tile)
3874 && city_owner(tile_city(tgt_tile)) == unit_owner(act_unit)) {
3875 /* The player's cities are loaded right before their units. It wasn't
3876 * possible for rulesets to allow joining foreign cities before 3.0.
3877 * This means that a converted build city order only can be a Join
3878 * City order if it targets a domestic city. */
3879 return ACTION_JOIN_CITY;
3880 } else {
3881 /* Assume that the intention was to found a new city. */
3882 return ACTION_FOUND_CITY;
3883 }
3885 /* Maps one to one with each other. */
3886 return ACTION_HELP_WONDER;
3888 /* Maps one to one with each other. */
3889 return ACTION_TRADE_ROUTE;
3890 case ORDER_OLD_DISBAND:
3891 /* Added to the order system in the same commit as Help Wonder. Assume
3892 * that anyone that intended to order Help Wonder used Help Wonder. */
3893 /* Could in theory be intended as an order to disband in the field. Why
3894 * would the player give a unit an order to go to a non city location
3895 * and disband there? Assume the intention was to recover production
3896 * until a non recovering disband order is found. */
3897 return ACTION_DISBAND_UNIT_RECOVER;
3898 case ORDER_OLD_HOMECITY:
3899 return ACTION_HOME_CITY;
3900 }
3901
3902 /* The order hasn't been replaced by an action. */
3903 return ACTION_NONE;
3904}
3905
3906/************************************************************************/
3909static bool sg_load_player_unit(struct loaddata *loading,
3910 struct player *plr, struct unit *punit,
3911 const char *unitstr)
3912{
3913 enum unit_activity activity;
3914 int nat_x, nat_y;
3915 enum tile_special_type target;
3916 struct extra_type *pextra = NULL;
3917 struct base_type *pbase = NULL;
3918 struct road_type *proad = NULL;
3919 struct tile *ptile;
3920 int extra_id;
3921 int base_id;
3922 int road_id;
3923 int ei;
3924 const char *facing_str;
3925 enum tile_special_type cfspe;
3926 int natnbr;
3927 bool ai_controlled;
3928
3929 sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->id, "%s.id",
3930 unitstr), FALSE, "%s", secfile_error());
3931 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", unitstr),
3932 FALSE, "%s", secfile_error());
3933 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", unitstr),
3934 FALSE, "%s", secfile_error());
3935
3936 ptile = native_pos_to_tile(&(wld.map), nat_x, nat_y);
3937 sg_warn_ret_val(NULL != ptile, FALSE, "%s invalid tile (%d, %d)",
3938 unitstr, nat_x, nat_y);
3939 unit_tile_set(punit, ptile);
3940
3941 facing_str
3942 = secfile_lookup_str_default(loading->file, "x",
3943 "%s.facing", unitstr);
3944 if (facing_str[0] != 'x') {
3945 /* We don't touch punit->facing if savegame does not contain that
3946 * information. Initial orientation set by unit_virtual_create()
3947 * is as good as any. */
3948 enum direction8 facing = char2dir(facing_str[0]);
3949
3950 if (direction8_is_valid(facing)) {
3951 punit->facing = facing;
3952 } else {
3953 log_error("Illegal unit orientation '%s'", facing_str);
3954 }
3955 }
3956
3957 /* If savegame has unit nationality, it doesn't hurt to
3958 * internally set it even if nationality rules are disabled. */
3959 natnbr = secfile_lookup_int_default(loading->file,
3960 player_number(plr),
3961 "%s.nationality", unitstr);
3962
3964 if (punit->nationality == NULL) {
3965 punit->nationality = plr;
3966 }
3967
3969 "%s.homecity", unitstr), FALSE,
3970 "%s", secfile_error());
3972 "%s.moves", unitstr), FALSE,
3973 "%s", secfile_error());
3975 "%s.fuel", unitstr), FALSE,
3976 "%s", secfile_error());
3978 "%s.activity", unitstr), FALSE,
3979 "%s", secfile_error());
3980 activity = unit_activity_by_name(loading->activities.order[ei],
3982
3985 "%s.born", unitstr);
3986
3987 extra_id = secfile_lookup_int_default(loading->file, -2,
3988 "%s.activity_tgt", unitstr);
3989
3990 if (extra_id != -2) {
3991 if (extra_id >= 0 && extra_id < loading->extra.size) {
3992 pextra = loading->extra.order[extra_id];
3993 set_unit_activity_targeted(punit, activity, pextra);
3994 } else if (activity == ACTIVITY_IRRIGATE) {
3996 EC_IRRIGATION,
3998 punit);
3999 if (tgt != NULL) {
4000 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
4001 } else {
4002 set_unit_activity(punit, ACTIVITY_CULTIVATE);
4003 }
4004 } else if (activity == ACTIVITY_MINE) {
4006 EC_MINE,
4008 punit);
4009 if (tgt != NULL) {
4010 set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
4011 } else {
4012 set_unit_activity(punit, ACTIVITY_PLANT);
4013 }
4014 } else {
4015 set_unit_activity(punit, activity);
4016 }
4017 } else {
4018 /* extra_id == -2 -> activity_tgt not set */
4019 base_id = secfile_lookup_int_default(loading->file, -1,
4020 "%s.activity_base", unitstr);
4021 if (base_id >= 0 && base_id < loading->base.size) {
4022 pbase = loading->base.order[base_id];
4023 }
4024 road_id = secfile_lookup_int_default(loading->file, -1,
4025 "%s.activity_road", unitstr);
4026 if (road_id >= 0 && road_id < loading->road.size) {
4027 proad = loading->road.order[road_id];
4028 }
4029
4030 {
4031 int tgt_no = secfile_lookup_int_default(loading->file,
4032 loading->special.size /* S_LAST */,
4033 "%s.activity_target", unitstr);
4034 if (tgt_no >= 0 && tgt_no < loading->special.size) {
4035 target = loading->special.order[tgt_no];
4036 } else {
4037 target = S_LAST;
4038 }
4039 }
4040
4041 if (target == S_OLD_ROAD) {
4042 target = S_LAST;
4044 } else if (target == S_OLD_RAILROAD) {
4045 target = S_LAST;
4047 }
4048
4049 if (activity == ACTIVITY_OLD_ROAD) {
4050 activity = ACTIVITY_GEN_ROAD;
4052 } else if (activity == ACTIVITY_OLD_RAILROAD) {
4053 activity = ACTIVITY_GEN_ROAD;
4055 }
4056
4057 /* We need changed_from == ACTIVITY_IDLE by now so that
4058 * set_unit_activity() and friends don't spuriously restore activity
4059 * points -- unit should have been created this way */
4060 fc_assert(punit->changed_from == ACTIVITY_IDLE);
4061
4062 if (activity == ACTIVITY_BASE) {
4063 if (pbase) {
4065 } else {
4066 log_sg("Cannot find base %d for %s to build",
4067 base_id, unit_rule_name(punit));
4068 set_unit_activity(punit, ACTIVITY_IDLE);
4069 }
4070 } else if (activity == ACTIVITY_GEN_ROAD) {
4071 if (proad) {
4073 } else {
4074 log_sg("Cannot find road %d for %s to build",
4075 road_id, unit_rule_name(punit));
4076 set_unit_activity(punit, ACTIVITY_IDLE);
4077 }
4078 } else if (activity == ACTIVITY_PILLAGE) {
4079 struct extra_type *a_target;
4080
4081 if (target != S_LAST) {
4082 a_target = special_extra_get(target);
4083 } else if (pbase != NULL) {
4084 a_target = base_extra_get(pbase);
4085 } else if (proad != NULL) {
4086 a_target = road_extra_get(proad);
4087 } else {
4088 a_target = NULL;
4089 }
4090 /* An out-of-range base number is seen with old savegames. We take
4091 * it as indicating undirected pillaging. We will assign pillage
4092 * targets before play starts. */
4093 set_unit_activity_targeted(punit, activity, a_target);
4094 } else if (activity == ACTIVITY_IRRIGATE) {
4096 EC_IRRIGATION,
4098 punit);
4099 if (tgt != NULL) {
4100 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
4101 } else {
4102 set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, NULL);
4103 }
4104 } else if (activity == ACTIVITY_MINE) {
4106 EC_MINE,
4108 punit);
4109 if (tgt != NULL) {
4110 set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
4111 } else {
4112 set_unit_activity_targeted(punit, ACTIVITY_MINE, NULL);
4113 }
4114 } else if (activity == ACTIVITY_POLLUTION) {
4116 ERM_CLEANPOLLUTION,
4118 punit);
4119 if (tgt != NULL) {
4120 set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, tgt);
4121 } else {
4122 set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, NULL);
4123 }
4124 } else if (activity == ACTIVITY_FALLOUT) {
4126 ERM_CLEANFALLOUT,
4128 punit);
4129 if (tgt != NULL) {
4130 set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, tgt);
4131 } else {
4132 set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, NULL);
4133 }
4134 } else {
4135 set_unit_activity_targeted(punit, activity, NULL);
4136 }
4137 } /* activity_tgt == NULL */
4138
4140 "%s.activity_count", unitstr), FALSE,
4141 "%s", secfile_error());
4142
4144 secfile_lookup_int_default(loading->file, ACTIVITY_IDLE,
4145 "%s.changed_from", unitstr);
4146
4147 extra_id = secfile_lookup_int_default(loading->file, -2,
4148 "%s.changed_from_tgt", unitstr);
4149
4150 if (extra_id != -2) {
4151 if (extra_id >= 0 && extra_id < loading->extra.size) {
4152 punit->changed_from_target = loading->extra.order[extra_id];
4153 } else {
4154 punit->changed_from_target = NULL;
4155 }
4156 } else {
4157 /* extra_id == -2 -> changed_from_tgt not set */
4158
4159 cfspe =
4161 "%s.changed_from_target", unitstr);
4162 base_id =
4163 secfile_lookup_int_default(loading->file, -1,
4164 "%s.changed_from_base", unitstr);
4165 road_id =
4166 secfile_lookup_int_default(loading->file, -1,
4167 "%s.changed_from_road", unitstr);
4168
4169 if (road_id == -1) {
4170 if (cfspe == S_OLD_ROAD) {
4172 if (proad) {
4173 road_id = road_number(proad);
4174 }
4175 } else if (cfspe == S_OLD_RAILROAD) {
4177 if (proad) {
4178 road_id = road_number(proad);
4179 }
4180 }
4181 }
4182
4183 if (base_id >= 0 && base_id < loading->base.size) {
4184 punit->changed_from_target = base_extra_get(loading->base.order[base_id]);
4185 } else if (road_id >= 0 && road_id < loading->road.size) {
4186 punit->changed_from_target = road_extra_get(loading->road.order[road_id]);
4187 } else if (cfspe != S_LAST) {
4189 } else {
4190 punit->changed_from_target = NULL;
4191 }
4192
4193 if (punit->changed_from == ACTIVITY_IRRIGATE) {
4195 EC_IRRIGATION,
4197 punit);
4198 if (tgt != NULL) {
4200 } else {
4201 punit->changed_from_target = NULL;
4202 }
4203 } else if (punit->changed_from == ACTIVITY_MINE) {
4205 EC_MINE,
4207 punit);
4208 if (tgt != NULL) {
4210 } else {
4211 punit->changed_from_target = NULL;
4212 }
4213 } else if (punit->changed_from == ACTIVITY_POLLUTION) {
4215 ERM_CLEANPOLLUTION,
4217 punit);
4218 if (tgt != NULL) {
4220 } else {
4221 punit->changed_from_target = NULL;
4222 }
4223 } else if (punit->changed_from == ACTIVITY_FALLOUT) {
4225 ERM_CLEANFALLOUT,
4227 punit);
4228 if (tgt != NULL) {
4230 } else {
4231 punit->changed_from_target = NULL;
4232 }
4233 }
4234 }
4235
4237 secfile_lookup_int_default(loading->file, 0,
4238 "%s.changed_from_count", unitstr);
4239
4240 /* Special case: for a long time, we accidentally incremented
4241 * activity_count while a unit was sentried, so it could increase
4242 * without bound (bug #20641) and be saved in old savefiles.
4243 * We zero it to prevent potential trouble overflowing the range
4244 * in network packets, etc. */
4245 if (activity == ACTIVITY_SENTRY) {
4246 punit->activity_count = 0;
4247 }
4248 if (punit->changed_from == ACTIVITY_SENTRY) {
4250 }
4251
4252 punit->veteran
4253 = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
4254 {
4255 /* Protect against change in veteran system in ruleset */
4256 const int levels = utype_veteran_levels(unit_type_get(punit));
4257 if (punit->veteran >= levels) {
4258 fc_assert(levels >= 1);
4259 punit->veteran = levels - 1;
4260 }
4261 }
4264 "%s.done_moving", unitstr);
4267 "%s.battlegroup", unitstr);
4268
4270 "%s.go", unitstr)) {
4271 int gnat_x, gnat_y;
4272
4273 sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_x,
4274 "%s.goto_x", unitstr), FALSE,
4275 "%s", secfile_error());
4276 sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_y,
4277 "%s.goto_y", unitstr), FALSE,
4278 "%s", secfile_error());
4279
4280 punit->goto_tile = native_pos_to_tile(&(wld.map), gnat_x, gnat_y);
4281 } else {
4282 punit->goto_tile = NULL;
4283
4284 /* These variables are not used but needed for saving the unit table.
4285 * Load them to prevent unused variables errors. */
4286 (void) secfile_entry_lookup(loading->file, "%s.goto_x", unitstr);
4287 (void) secfile_entry_lookup(loading->file, "%s.goto_y", unitstr);
4288 }
4289
4290 /* Load AI data of the unit. */
4291 CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
4292
4294 &ai_controlled,
4295 "%s.ai", unitstr), FALSE,
4296 "%s", secfile_error());
4297 if (ai_controlled) {
4298 /* Autosettler and Autoexplore are separated by
4299 * compat_post_load_030100() when set to SSA_AUTOSETTLER */
4300 punit->ssa_controller = SSA_AUTOSETTLER;
4301 } else {
4302 punit->ssa_controller = SSA_NONE;
4303 }
4305 "%s.hp", unitstr), FALSE,
4306 "%s", secfile_error());
4307
4309 = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
4311 = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
4312 punit->moved
4313 = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
4316 "%s.paradropped", unitstr);
4317
4318 /* The transport status (punit->transported_by) is loaded in
4319 * sg_player_units_transport(). */
4320
4321 /* Initialize upkeep values: these are hopefully initialized
4322 * elsewhere before use (specifically, in city_support(); but
4323 * fixme: check whether always correctly initialized?).
4324 * Below is mainly for units which don't have homecity --
4325 * otherwise these don't get initialized (and AI calculations
4326 * etc may use junk values). */
4330
4333 ACT_DEC_NOTHING, action_decision,
4334 "%s.action_decision_want", unitstr);
4335
4336 if (punit->action_decision_want != ACT_DEC_NOTHING) {
4337 /* Load the tile to act against. */
4338 int adwt_x, adwt_y;
4339
4340 if (secfile_lookup_int(loading->file, &adwt_x,
4341 "%s.action_decision_tile_x", unitstr)
4342 && secfile_lookup_int(loading->file, &adwt_y,
4343 "%s.action_decision_tile_y", unitstr)) {
4345 adwt_x, adwt_y);
4346 } else {
4347 punit->action_decision_want = ACT_DEC_NOTHING;
4349 log_sg("Bad action_decision_tile for unit %d", punit->id);
4350 }
4351 } else {
4352 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_x", unitstr);
4353 (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_y", unitstr);
4355 }
4356
4357 /* Load the unit orders */
4358 {
4359 int len = secfile_lookup_int_default(loading->file, 0,
4360 "%s.orders_length", unitstr);
4361
4362 if (len > 0) {
4363 const char *orders_unitstr, *dir_unitstr, *act_unitstr;
4364 const char *tgt_unitstr;
4365 const char *base_unitstr = NULL;
4366 const char *road_unitstr = NULL;
4369 int j;
4370
4371 punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
4374 = secfile_lookup_int_default(loading->file, 0,
4375 "%s.orders_index", unitstr);
4378 "%s.orders_repeat", unitstr);
4381 "%s.orders_vigilant", unitstr);
4382
4383 orders_unitstr
4384 = secfile_lookup_str_default(loading->file, "",
4385 "%s.orders_list", unitstr);
4386 dir_unitstr
4387 = secfile_lookup_str_default(loading->file, "",
4388 "%s.dir_list", unitstr);
4389 act_unitstr
4390 = secfile_lookup_str_default(loading->file, "",
4391 "%s.activity_list", unitstr);
4392 tgt_unitstr
4393 = secfile_lookup_str_default(loading->file, NULL, "%s.tgt_list", unitstr);
4394
4395 if (tgt_unitstr == NULL) {
4396 base_unitstr
4397 = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
4398 road_unitstr
4399 = secfile_lookup_str_default(loading->file, NULL, "%s.road_list", unitstr);
4400 }
4401
4403
4404 for (j = 0; j < len; j++) {
4405 struct unit_order *order = &punit->orders.list[j];
4406
4407 if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
4408 || act_unitstr[j] == '\0') {
4409 log_sg("Invalid unit orders.");
4411 break;
4412 }
4413 order->order = char2order(orders_unitstr[j]);
4414 order->dir = char2dir(dir_unitstr[j]);
4415 order->activity = char2activity(act_unitstr[j]);
4416 /* Target, if needed, is set in compat_post_load_030100() */
4417 order->target = NO_TARGET;
4418 order->sub_target = NO_TARGET;
4419
4420 if (order->order == ORDER_LAST
4421 || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
4422 || (order->order == ORDER_ACTION_MOVE
4423 && !direction8_is_valid(order->dir))
4424 || (order->order == ORDER_ACTIVITY
4425 && order->activity == ACTIVITY_LAST)) {
4426 /* An invalid order. Just drop the orders for this unit. */
4427 free(punit->orders.list);
4428 punit->orders.list = NULL;
4430 break;
4431 }
4432
4433 /* The order may have been replaced by the perform action order */
4434 order->action = sg_order_to_action(order->order, punit,
4435 punit->goto_tile);
4436 if (order->action != ACTION_NONE) {
4437 /* The order was converted by order_to_action */
4438 order->order = ORDER_PERFORM_ACTION;
4439 }
4440
4441 if (tgt_unitstr) {
4442 if (tgt_unitstr[j] != '?') {
4443 extra_id = char2num(tgt_unitstr[j]);
4444
4445 if (extra_id < 0 || extra_id >= loading->extra.size) {
4446 log_sg("Cannot find extra %d for %s to build",
4447 extra_id, unit_rule_name(punit));
4448 order->sub_target = EXTRA_NONE;
4449 } else {
4450 order->sub_target = extra_id;
4451 }
4452 } else {
4453 order->sub_target = EXTRA_NONE;
4454 }
4455 } else {
4456 /* In pre-2.6 savegames, base_list and road_list were only saved
4457 * for those activities (and not e.g. pillaging) */
4458 if (base_unitstr && base_unitstr[j] != '?'
4459 && order->activity == ACTIVITY_BASE) {
4460 base_id = char2num(base_unitstr[j]);
4461
4462 if (base_id < 0 || base_id >= loading->base.size) {
4463 log_sg("Cannot find base %d for %s to build",
4464 base_id, unit_rule_name(punit));
4465 base_id = base_number(get_base_by_gui_type(BASE_GUI_FORTRESS,
4466 NULL, NULL));
4467 }
4468
4469 order->sub_target
4471 } else if (road_unitstr && road_unitstr[j] != '?'
4472 && order->activity == ACTIVITY_GEN_ROAD) {
4473 road_id = char2num(road_unitstr[j]);
4474
4475 if (road_id < 0 || road_id >= loading->road.size) {
4476 log_sg("Cannot find road %d for %s to build",
4477 road_id, unit_rule_name(punit));
4478 road_id = 0;
4479 }
4480
4481 order->sub_target
4483 } else {
4484 order->sub_target = EXTRA_NONE;
4485 }
4486
4487 if (order->activity == ACTIVITY_OLD_ROAD) {
4488 order->activity = ACTIVITY_GEN_ROAD;
4489 order->sub_target
4491 } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
4492 order->activity = ACTIVITY_GEN_ROAD;
4493 order->sub_target
4495 }
4496 }
4497 }
4498 } else {
4500 punit->orders.list = NULL;
4501
4502 (void) secfile_entry_lookup(loading->file, "%s.orders_index", unitstr);
4503 (void) secfile_entry_lookup(loading->file, "%s.orders_repeat", unitstr);
4504 (void) secfile_entry_lookup(loading->file, "%s.orders_vigilant", unitstr);
4505 (void) secfile_entry_lookup(loading->file, "%s.orders_list", unitstr);
4506 (void) secfile_entry_lookup(loading->file, "%s.dir_list", unitstr);
4507 (void) secfile_entry_lookup(loading->file, "%s.activity_list", unitstr);
4508 (void) secfile_entry_lookup(loading->file, "%s.tgt_list", unitstr);
4509 }
4510 }
4511
4512 return TRUE;
4513}
4514
4515/************************************************************************/
4519static void sg_load_player_units_transport(struct loaddata *loading,
4520 struct player *plr)
4521{
4522 int nunits, i, plrno = player_number(plr);
4523
4524 /* Check status and return if not OK (sg_success FALSE). */
4525 sg_check_ret();
4526
4527 /* Recheck the number of units for the player. This is a copied from
4528 * sg_load_player_units(). */
4529 sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
4530 "player%d.nunits", plrno),
4531 "%s", secfile_error());
4532 if (!plr->is_alive && nunits > 0) {
4533 log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
4534 nunits = 0; /* Some old savegames may be buggy. */
4535 }
4536
4537 for (i = 0; i < nunits; i++) {
4538 int id_unit, id_trans;
4539 struct unit *punit, *ptrans;
4540
4541 id_unit = secfile_lookup_int_default(loading->file, -1,
4542 "player%d.u%d.id",
4543 plrno, i);
4544 punit = player_unit_by_number(plr, id_unit);
4545 fc_assert_action(punit != NULL, continue);
4546
4547 id_trans = secfile_lookup_int_default(loading->file, -1,
4548 "player%d.u%d.transported_by",
4549 plrno, i);
4550 if (id_trans == -1) {
4551 /* Not transported. */
4552 continue;
4553 }
4554
4555 ptrans = game_unit_by_number(id_trans);
4556 fc_assert_action(id_trans == -1 || ptrans != NULL, continue);
4557
4558 if (ptrans) {
4559#ifndef FREECIV_NDEBUG
4560 bool load_success =
4561#endif
4562 unit_transport_load(punit, ptrans, TRUE);
4563
4564 fc_assert_action(load_success, continue);
4565 }
4566 }
4567}
4568
4569/************************************************************************/
4572static void sg_load_player_attributes(struct loaddata *loading,
4573 struct player *plr)
4574{
4575 int plrno = player_number(plr);
4576
4577 /* Check status and return if not OK (sg_success FALSE). */
4578 sg_check_ret();
4579
4580 /* Toss any existing attribute_block (should not exist) */
4581 if (plr->attribute_block.data) {
4582 free(plr->attribute_block.data);
4583 plr->attribute_block.data = NULL;
4584 }
4585
4586 /* This is a big heap of opaque data for the client, check everything! */
4588 loading->file, 0, "player%d.attribute_v2_block_length", plrno);
4589
4590 if (0 > plr->attribute_block.length) {
4591 log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
4592 plr->attribute_block.length);
4593 plr->attribute_block.length = 0;
4594 } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
4595 log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
4597 plr->attribute_block.length = 0;
4598 } else if (0 < plr->attribute_block.length) {
4599 int part_nr, parts;
4600 int quoted_length;
4601 char *quoted;
4602#ifndef FREECIV_NDEBUG
4603 size_t actual_length;
4604#endif
4605
4607 secfile_lookup_int(loading->file, &quoted_length,
4608 "player%d.attribute_v2_block_length_quoted",
4609 plrno), "%s", secfile_error());
4611 secfile_lookup_int(loading->file, &parts,
4612 "player%d.attribute_v2_block_parts", plrno),
4613 "%s", secfile_error());
4614
4615 quoted = fc_malloc(quoted_length + 1);
4616 quoted[0] = '\0';
4618 for (part_nr = 0; part_nr < parts; part_nr++) {
4619 const char *current =
4620 secfile_lookup_str(loading->file,
4621 "player%d.attribute_v2_block_data.part%d",
4622 plrno, part_nr);
4623 if (!current) {
4624 log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
4625 break;
4626 }
4627 log_debug("attribute_v2_block_length_quoted=%d"
4628 " have=" SIZE_T_PRINTF " part=" SIZE_T_PRINTF,
4629 quoted_length, strlen(quoted), strlen(current));
4630 fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
4631 strcat(quoted, current);
4632 }
4633 fc_assert_msg(quoted_length == strlen(quoted),
4634 "attribute_v2_block_length_quoted=%d"
4635 " actual=" SIZE_T_PRINTF,
4636 quoted_length, strlen(quoted));
4637
4638#ifndef FREECIV_NDEBUG
4639 actual_length =
4640#endif
4641 unquote_block(quoted,
4642 plr->attribute_block.data,
4643 plr->attribute_block.length);
4644 fc_assert(actual_length == plr->attribute_block.length);
4645 free(quoted);
4646 }
4647}
4648
4649/************************************************************************/
4652static void sg_load_player_vision(struct loaddata *loading,
4653 struct player *plr)
4654{
4655 int plrno = player_number(plr);
4656 int total_ncities =
4657 secfile_lookup_int_default(loading->file, -1,
4658 "player%d.dc_total", plrno);
4659 int i;
4660 bool someone_alive = FALSE;
4661
4662 /* Check status and return if not OK (sg_success FALSE). */
4663 sg_check_ret();
4664
4665 if (game.server.revealmap & REVEAL_MAP_DEAD) {
4666 player_list_iterate(team_members(plr->team), pteam_member) {
4667 if (pteam_member->is_alive) {
4668 someone_alive = TRUE;
4669 break;
4670 }
4672
4673 if (!someone_alive) {
4674 /* Reveal all for completely dead teams. */
4676 }
4677 }
4678
4679 if (!plr->is_alive
4680 || -1 == total_ncities
4681 || !game.info.fogofwar
4683 "game.save_private_map")) {
4684 /* We have:
4685 * - a dead player;
4686 * - fogged cities are not saved for any reason;
4687 * - a savegame with fog of war turned off;
4688 * - or game.save_private_map is not set to FALSE in the scenario /
4689 * savegame. The players private knowledge is set to be what they could
4690 * see without fog of war. */
4691 whole_map_iterate(&(wld.map), ptile) {
4692 if (map_is_known(ptile, plr)) {
4693 struct city *pcity = tile_city(ptile);
4694
4695 update_player_tile_last_seen(plr, ptile);
4696 update_player_tile_knowledge(plr, ptile);
4697
4698 if (NULL != pcity) {
4699 update_dumb_city(plr, pcity);
4700 }
4701 }
4703
4704 /* Nothing more to do; */
4705 return;
4706 }
4707
4708 /* Load player map (terrain). */
4709 LOAD_MAP_CHAR(ch, ptile,
4710 map_get_player_tile(ptile, plr)->terrain
4711 = char2terrain(ch), loading->file,
4712 "player%d.map_t%04d", plrno);
4713
4714 /* Load player map (resources). */
4715 LOAD_MAP_CHAR(ch, ptile,
4716 map_get_player_tile(ptile, plr)->resource
4717 = char2resource(ch), loading->file,
4718 "player%d.map_res%04d", plrno);
4719
4720 if (loading->version >= 30) {
4721 /* 2.6.0 or newer */
4722
4723 /* Load player map (extras). */
4724 halfbyte_iterate_extras(j, loading->extra.size) {
4725 LOAD_MAP_CHAR(ch, ptile,
4727 ch, loading->extra.order + 4 * j),
4728 loading->file, "player%d.map_e%02d_%04d", plrno, j);
4730 } else {
4731 /* Load player map (specials). */
4733 LOAD_MAP_CHAR(ch, ptile,
4734 sg_special_set(ptile, &map_get_player_tile(ptile, plr)->extras,
4735 ch, loading->special.order + 4 * j, FALSE),
4736 loading->file, "player%d.map_spe%02d_%04d", plrno, j);
4738
4739 /* Load player map (bases). */
4740 halfbyte_iterate_bases(j, loading->base.size) {
4741 LOAD_MAP_CHAR(ch, ptile,
4743 ch, loading->base.order + 4 * j),
4744 loading->file, "player%d.map_b%02d_%04d", plrno, j);
4746
4747 /* Load player map (roads). */
4748 if (loading->version >= 20) {
4749 /* 2.5.0 or newer */
4750 halfbyte_iterate_roads(j, loading->road.size) {
4751 LOAD_MAP_CHAR(ch, ptile,
4753 ch, loading->road.order + 4 * j),
4754 loading->file, "player%d.map_r%02d_%04d", plrno, j);
4756 }
4757 }
4758
4760 /* Load player map (border). */
4761 int x, y;
4762
4763 for (y = 0; y < wld.map.ysize; y++) {
4764 const char *buffer
4765 = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
4766 plrno, y);
4767 const char *buffer2
4768 = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
4769 plrno, y);
4770 const char *ptr = buffer;
4771 const char *ptr2 = buffer2;
4772
4773 sg_failure_ret(NULL != buffer,
4774 "Savegame corrupt - map line %d not found.", y);
4775 for (x = 0; x < wld.map.xsize; x++) {
4776 char token[TOKEN_SIZE];
4777 char token2[TOKEN_SIZE];
4778 int number;
4779 struct tile *ptile = native_pos_to_tile(&(wld.map), x, y);
4780
4781 scanin(&ptr, ",", token, sizeof(token));
4782 sg_failure_ret('\0' != token[0],
4783 "Savegame corrupt - map size not correct.");
4784 if (strcmp(token, "-") == 0) {
4785 map_get_player_tile(ptile, plr)->owner = NULL;
4786 } else {
4787 sg_failure_ret(str_to_int(token, &number),
4788 "Savegame corrupt - got tile owner=%s in (%d, %d).",
4789 token, x, y);
4790 map_get_player_tile(ptile, plr)->owner = player_by_number(number);
4791 }
4792
4793 if (loading->version >= 30) {
4794 scanin(&ptr2, ",", token2, sizeof(token2));
4795 sg_failure_ret('\0' != token2[0],
4796 "Savegame corrupt - map size not correct.");
4797 if (strcmp(token2, "-") == 0) {
4798 map_get_player_tile(ptile, plr)->extras_owner = NULL;
4799 } else {
4800 sg_failure_ret(str_to_int(token2, &number),
4801 "Savegame corrupt - got extras owner=%s in (%d, %d).",
4802 token, x, y);
4803 map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
4804 }
4805 } else {
4807 = map_get_player_tile(ptile, plr)->owner;
4808 }
4809 }
4810 }
4811 }
4812
4813 /* Load player map (update time). */
4814 for (i = 0; i < 4; i++) {
4815 /* put 4-bit segments of 16-bit "updated" field */
4816 if (i == 0) {
4817 LOAD_MAP_CHAR(ch, ptile,
4818 map_get_player_tile(ptile, plr)->last_updated
4819 = ascii_hex2bin(ch, i),
4820 loading->file, "player%d.map_u%02d_%04d", plrno, i);
4821 } else {
4822 LOAD_MAP_CHAR(ch, ptile,
4823 map_get_player_tile(ptile, plr)->last_updated
4824 |= ascii_hex2bin(ch, i),
4825 loading->file, "player%d.map_u%02d_%04d", plrno, i);
4826 }
4827 }
4828
4829 /* Load player map known cities. */
4830 for (i = 0; i < total_ncities; i++) {
4831 struct vision_site *pdcity;
4832 char buf[32];
4833 fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
4834
4835 pdcity = vision_site_new(0, NULL, NULL);
4836 if (sg_load_player_vision_city(loading, plr, pdcity, buf)) {
4838 pdcity);
4840 } else {
4841 /* Error loading the data. */
4842 log_sg("Skipping seen city %d for player %d.", i, plrno);
4843 if (pdcity != NULL) {
4844 vision_site_destroy(pdcity);
4845 }
4846 }
4847 }
4848
4849 /* Repair inconsistent player maps. */
4850 whole_map_iterate(&(wld.map), ptile) {
4851 if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
4852 struct city *pcity = tile_city(ptile);
4853
4854 update_player_tile_knowledge(plr, ptile);
4855 reality_check_city(plr, ptile);
4856
4857 if (NULL != pcity) {
4858 update_dumb_city(plr, pcity);
4859 }
4860 } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
4861 /* Non fogged borders aren't loaded. See hrm Bug #879084 */
4862 struct player_tile *plrtile = map_get_player_tile(ptile, plr);
4863
4864 plrtile->owner = tile_owner(ptile);
4865 }
4867}
4868
4869/************************************************************************/
4872static bool sg_load_player_vision_city(struct loaddata *loading,
4873 struct player *plr,
4874 struct vision_site *pdcity,
4875 const char *citystr)
4876{
4877 const char *str;
4878 int i, id, size;
4879 citizens city_size;
4880 int nat_x, nat_y;
4881 const char *stylename;
4882 const char *vname;
4883
4884 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x",
4885 citystr),
4886 FALSE, "%s", secfile_error());
4887 sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y",
4888 citystr),
4889 FALSE, "%s", secfile_error());
4890 pdcity->location = native_pos_to_tile(&(wld.map), nat_x, nat_y);
4891 sg_warn_ret_val(NULL != pdcity->location, FALSE,
4892 "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
4893
4894 sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
4895 citystr),
4896 FALSE, "%s", secfile_error());
4897 pdcity->owner = player_by_number(id);
4898 sg_warn_ret_val(NULL != pdcity->owner, FALSE,
4899 "%s has invalid owner (%d); skipping.", citystr, id);
4900
4902 "%s.id", citystr),
4903 FALSE, "%s", secfile_error());
4904 sg_warn_ret_val(IDENTITY_NUMBER_ZERO < pdcity->identity, FALSE,
4905 "%s has invalid id (%d); skipping.", citystr, id);
4906
4908 "%s.size", citystr),
4909 FALSE, "%s", secfile_error());
4910 city_size = (citizens)size; /* set the correct type */
4911 sg_warn_ret_val(size == (int)city_size, FALSE,
4912 "Invalid city size: %d; set to %d.", size, city_size);
4913 vision_site_size_set(pdcity, city_size);
4914
4915 /* Initialise list of improvements */
4916 BV_CLR_ALL(pdcity->improvements);
4917 str = secfile_lookup_str(loading->file, "%s.improvements", citystr);
4918 sg_warn_ret_val(str != NULL, FALSE, "%s", secfile_error());
4919 sg_warn_ret_val(strlen(str) == loading->improvement.size, FALSE,
4920 "Invalid length of '%s.improvements' ("
4921 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
4922 citystr, strlen(str), loading->improvement.size);
4923 for (i = 0; i < loading->improvement.size; i++) {
4924 sg_warn_ret_val(str[i] == '1' || str[i] == '0', FALSE,
4925 "Undefined value '%c' within '%s.improvements'.",
4926 str[i], citystr)
4927
4928 if (str[i] == '1') {
4929 struct impr_type *pimprove =
4931
4932 if (pimprove) {
4933 BV_SET(pdcity->improvements, improvement_index(pimprove));
4934 }
4935 }
4936 }
4937
4938 vname = secfile_lookup_str_default(loading->file, NULL,
4939 "%s.name", citystr);
4940
4941 if (vname != NULL) {
4942 pdcity->name = fc_strdup(vname);
4943 }
4944
4945 pdcity->occupied = secfile_lookup_bool_default(loading->file, FALSE,
4946 "%s.occupied", citystr);
4947 pdcity->walls = secfile_lookup_bool_default(loading->file, FALSE,
4948 "%s.walls", citystr);
4949 pdcity->happy = secfile_lookup_bool_default(loading->file, FALSE,
4950 "%s.happy", citystr);
4951 pdcity->unhappy = secfile_lookup_bool_default(loading->file, FALSE,
4952 "%s.unhappy", citystr);
4953 stylename = secfile_lookup_str_default(loading->file, NULL,
4954 "%s.style", citystr);
4955 if (stylename != NULL) {
4956 pdcity->style = city_style_by_rule_name(stylename);
4957 } else {
4958 pdcity->style = 0;
4959 }
4960 if (pdcity->style < 0) {
4961 pdcity->style = 0;
4962 }
4963
4964 pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
4965 "%s.city_image", citystr);
4966
4967 pdcity->capital = CAPITAL_NOT;
4968
4969 return TRUE;
4970}
4971
4972/* =======================================================================
4973 * Load the researches.
4974 * ======================================================================= */
4975
4976/************************************************************************/
4979static void sg_load_researches(struct loaddata *loading)
4980{
4981 struct research *presearch;
4982 int count;
4983 int number;
4984 const char *str;
4985 int i, j;
4986
4987 /* Check status and return if not OK (sg_success FALSE). */
4988 sg_check_ret();
4989
4990 /* Initialize all researches. */
4991 researches_iterate(pinitres) {
4992 init_tech(pinitres, FALSE);
4994
4995 /* May be unsaved (e.g. scenario case). */
4996 count = secfile_lookup_int_default(loading->file, 0, "research.count");
4997 for (i = 0; i < count; i++) {
4998 sg_failure_ret(secfile_lookup_int(loading->file, &number,
4999 "research.r%d.number", i),
5000 "%s", secfile_error());
5001 presearch = research_by_number(number);
5002 sg_failure_ret(presearch != NULL,
5003 "Invalid research number %d in 'research.r%d.number'",
5004 number, i);
5005
5006 presearch->tech_goal = technology_load(loading->file,
5007 "research.r%d.goal", i);
5009 &presearch->techs_researched,
5010 "research.r%d.techs", i),
5011 "%s", secfile_error());
5013 &presearch->future_tech,
5014 "research.r%d.futuretech", i),
5015 "%s", secfile_error());
5017 &presearch->bulbs_researched,
5018 "research.r%d.bulbs", i),
5019 "%s", secfile_error());
5021 &presearch->bulbs_researching_saved,
5022 "research.r%d.bulbs_before", i),
5023 "%s", secfile_error());
5024 presearch->researching_saved = technology_load(loading->file,
5025 "research.r%d.saved", i);
5026 presearch->researching = technology_load(loading->file,
5027 "research.r%d.now", i);
5029 &presearch->got_tech,
5030 "research.r%d.got_tech", i),
5031 "%s", secfile_error());
5032
5033 str = secfile_lookup_str(loading->file, "research.r%d.done", i);
5034 sg_failure_ret(str != NULL, "%s", secfile_error());
5035 sg_failure_ret(strlen(str) == loading->technology.size,
5036 "Invalid length of 'research.r%d.done' ("
5037 SIZE_T_PRINTF " ~= " SIZE_T_PRINTF ").",
5038 i, strlen(str), loading->technology.size);
5039 for (j = 0; j < loading->technology.size; j++) {
5040 sg_failure_ret(str[j] == '1' || str[j] == '0',
5041 "Undefined value '%c' within 'research.r%d.done'.",
5042 str[j], i);
5043
5044 if (str[j] == '1') {
5045 struct advance *padvance =
5047
5048 if (padvance) {
5049 research_invention_set(presearch, advance_number(padvance),
5050 TECH_KNOWN);
5051 }
5052 }
5053 }
5054 }
5055
5056 /* In case of tech_leakage, we can update research only after all the
5057 * researches have been loaded */
5058 researches_iterate(pupres) {
5059 research_update(pupres);
5061}
5062
5063/* =======================================================================
5064 * Load the event cache. Should be the last thing to do.
5065 * ======================================================================= */
5066
5067/************************************************************************/
5070static void sg_load_event_cache(struct loaddata *loading)
5071{
5072 /* Check status and return if not OK (sg_success FALSE). */
5073 sg_check_ret();
5074
5075 event_cache_load(loading->file, "event_cache");
5076}
5077
5078/* =======================================================================
5079 * Load the open treaties
5080 * ======================================================================= */
5081
5082/************************************************************************/
5085static void sg_load_treaties(struct loaddata *loading)
5086{
5087 int tidx;
5088 const char *plr0;
5089 struct treaty_list *treaties = get_all_treaties();
5090
5091 /* Check status and return if not OK (sg_success FALSE). */
5092 sg_check_ret();
5093
5094 for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, NULL,
5095 "treaty%d.plr0", tidx)) != NULL ;
5096 tidx++) {
5097 const char *plr1;
5098 const char *ct;
5099 int cidx;
5100 struct player *p0, *p1;
5101
5102 plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
5103
5104 p0 = player_by_name(plr0);
5105 p1 = player_by_name(plr1);
5106
5107 if (p0 == NULL || p1 == NULL) {
5108 log_error("Treaty between unknown players %s and %s", plr0, plr1);
5109 } else {
5110 struct Treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
5111
5112 init_treaty(ptreaty, p0, p1);
5113 treaty_list_prepend(treaties, ptreaty);
5114
5115 for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, NULL,
5116 "treaty%d.clause%d.type",
5117 tidx, cidx)) != NULL ;
5118 cidx++ ) {
5119 enum clause_type type = clause_type_by_name(ct, fc_strcasecmp);
5120 const char *plrx;
5121
5122 if (!clause_type_is_valid(type)) {
5123 log_error("Invalid clause type \"%s\"", ct);
5124 } else {
5125 struct player *pgiver = NULL;
5126
5127 plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
5128 tidx, cidx);
5129
5130 if (!fc_strcasecmp(plrx, plr0)) {
5131 pgiver = p0;
5132 } else if (!fc_strcasecmp(plrx, plr1)) {
5133 pgiver = p1;
5134 } else {
5135 log_error("Clause giver %s is not participant of the treaty"
5136 "between %s and %s", plrx, plr0, plr1);
5137 }
5138
5139 if (pgiver != NULL) {
5140 int value;
5141
5142 value = secfile_lookup_int_default(loading->file, 0,
5143 "treaty%d.clause%d.value",
5144 tidx, cidx);
5145
5146 add_clause(ptreaty, pgiver, type, value, NULL);
5147 }
5148 }
5149 }
5150
5151 /* These must be after clauses have been added so that acceptance
5152 * does not get cleared by what seems like changes to the treaty. */
5153 ptreaty->accept0 = secfile_lookup_bool_default(loading->file, FALSE,
5154 "treaty%d.accept0", tidx);
5155 ptreaty->accept1 = secfile_lookup_bool_default(loading->file, FALSE,
5156 "treaty%d.accept1", tidx);
5157 }
5158 }
5159}
5160
5161/* =======================================================================
5162 * Load the history report
5163 * ======================================================================= */
5164
5165/************************************************************************/
5168static void sg_load_history(struct loaddata *loading)
5169{
5170 struct history_report *hist = history_report_get();
5171 int turn;
5172
5173 /* Check status and return if not OK (sg_success FALSE). */
5174 sg_check_ret();
5175
5176 turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
5177
5178 if (turn != -2) {
5179 hist->turn = turn;
5180 }
5181
5182 if (turn + 1 >= game.info.turn) {
5183 const char *str;
5184
5185 str = secfile_lookup_str(loading->file, "history.title");
5186 sg_failure_ret(str != NULL, "%s", secfile_error());
5187 sz_strlcpy(hist->title, str);
5188 str = secfile_lookup_str(loading->file, "history.body");
5189 sg_failure_ret(str != NULL, "%s", secfile_error());
5190 sz_strlcpy(hist->body, str);
5191 }
5192}
5193
5194/* =======================================================================
5195 * Load the mapimg definitions.
5196 * ======================================================================= */
5197
5198/************************************************************************/
5201static void sg_load_mapimg(struct loaddata *loading)
5202{
5203 int mapdef_count, i;
5204
5205 /* Check status and return if not OK (sg_success FALSE). */
5206 sg_check_ret();
5207
5208 /* Clear all defined map images. */
5209 while (mapimg_count() > 0) {
5210 mapimg_delete(0);
5211 }
5212
5213 mapdef_count = secfile_lookup_int_default(loading->file, 0,
5214 "mapimg.count");
5215 log_verbose("Saved map image definitions: %d.", mapdef_count);
5216
5217 if (0 >= mapdef_count) {
5218 return;
5219 }
5220
5221 for (i = 0; i < mapdef_count; i++) {
5222 const char *p;
5223
5224 p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
5225 if (NULL == p) {
5226 log_verbose("[Mapimg %4d] Missing definition.", i);
5227 continue;
5228 }
5229
5230 if (!mapimg_define(p, FALSE)) {
5231 log_error("Invalid map image definition %4d: %s.", i, p);
5232 }
5233
5234 log_verbose("Mapimg %4d loaded.", i);
5235 }
5236}
5237
5238/* =======================================================================
5239 * Sanity checks for loading a game.
5240 * ======================================================================= */
5241
5242/************************************************************************/
5245static void sg_load_sanitycheck(struct loaddata *loading)
5246{
5247 int players;
5248
5249 /* Check status and return if not OK (sg_success FALSE). */
5250 sg_check_ret();
5251
5252 if (game.info.is_new_game) {
5253 /* Nothing to do for new games (or not started scenarios). */
5254 return;
5255 }
5256
5257 /* Old savegames may have maxplayers lower than current player count,
5258 * fix. */
5259 players = normal_player_count();
5260 if (game.server.max_players < players) {
5261 log_verbose("Max players lower than current players, fixing");
5262 game.server.max_players = players;
5263 }
5264
5265 /* Fix ferrying sanity */
5266 players_iterate(pplayer) {
5267 unit_list_iterate_safe(pplayer->units, punit) {
5270 log_sg("Removing %s unferried %s in %s at (%d, %d)",
5276 }
5279
5280 /* Fix stacking issues. We don't rely on the savegame preserving
5281 * alliance invariants (old savegames often did not) so if there are any
5282 * unallied units on the same tile we just bounce them. */
5283 players_iterate(pplayer) {
5284 players_iterate(aplayer) {
5285 resolve_unit_stacks(pplayer, aplayer, TRUE);
5288
5289 /* Recalculate the potential buildings for each city. Has caused some
5290 * problems with game random state.
5291 * This also changes the game state if you save the game directly after
5292 * loading it and compare the results. */
5293 players_iterate(pplayer) {
5294 /* Building advisor needs data phase open in order to work */
5295 adv_data_phase_init(pplayer, FALSE);
5296 building_advisor(pplayer);
5297 /* Close data phase again so it can be opened again when game starts. */
5298 adv_data_phase_done(pplayer);
5300
5301 /* Prevent a buggy or intentionally crafted save game from crashing
5302 * Freeciv. See hrm Bug #887748 */
5303 players_iterate(pplayer) {
5304 city_list_iterate(pplayer->cities, pcity) {
5305 worker_task_list_iterate(pcity->task_reqs, ptask) {
5306 if (!worker_task_is_sane(ptask)) {
5307 log_error("[city id: %d] Bad worker task %d.",
5308 pcity->id, ptask->act);
5309 worker_task_list_remove(pcity->task_reqs, ptask);
5310 free(ptask);
5311 ptask = NULL;
5312 }
5316
5317 /* Check worked tiles map */
5318#ifdef FREECIV_DEBUG
5319 if (loading->worked_tiles != NULL) {
5320 /* check the entire map for unused worked tiles */
5321 whole_map_iterate(&(wld.map), ptile) {
5322 if (loading->worked_tiles[ptile->index] != -1) {
5323 log_error("[city id: %d] Unused worked tile at (%d, %d).",
5324 loading->worked_tiles[ptile->index], TILE_XY(ptile));
5325 }
5327 }
5328#endif /* FREECIV_DEBUG */
5329
5330 /* Check researching technologies and goals. */
5331 researches_iterate(presearch) {
5332 int techs;
5333
5334 if (presearch->researching != A_UNSET
5335 && !is_future_tech(presearch->researching)
5336 && (valid_advance_by_number(presearch->researching) == NULL
5337 || (research_invention_state(presearch, presearch->researching)
5338 != TECH_PREREQS_KNOWN))) {
5339 log_sg(_("%s had invalid researching technology."),
5340 research_name_translation(presearch));
5341 presearch->researching = A_UNSET;
5342 }
5343 if (presearch->tech_goal != A_UNSET
5344 && !is_future_tech(presearch->tech_goal)
5345 && (valid_advance_by_number(presearch->tech_goal) == NULL
5346 || !research_invention_reachable(presearch, presearch->tech_goal)
5347 || (research_invention_state(presearch, presearch->tech_goal)
5348 == TECH_KNOWN))) {
5349 log_sg(_("%s had invalid technology goal."),
5350 research_name_translation(presearch));
5351 presearch->tech_goal = A_UNSET;
5352 }
5353
5355
5356 if (presearch->techs_researched != techs) {
5357 sg_regr(3000300,
5358 _("%s had finished researches count wrong."),
5359 research_name_translation(presearch));
5360 presearch->techs_researched = techs;
5361 }
5363
5364 players_iterate(pplayer) {
5365 unit_list_iterate_safe(pplayer->units, punit) {
5367 punit->orders.list)) {
5368 log_sg("Invalid unit orders for unit %d.", punit->id);
5370 }
5373
5374 /* Check max rates (rules may have changed since saving) */
5375 players_iterate(pplayer) {
5378
5379 if (0 == strlen(server.game_identifier)
5380 || !is_base64url(server.game_identifier)) {
5381 /* This uses fc_rand(), so random state has to be initialized before. */
5382 randomize_base64url_string(server.game_identifier,
5383 sizeof(server.game_identifier));
5384 }
5385
5386 /* Check if some player has more than one of some UTYF_UNIQUE unit type */
5387 players_iterate(pplayer) {
5388 int unique_count[U_LAST];
5389
5390 memset(unique_count, 0, sizeof(unique_count));
5391
5392 unit_list_iterate(pplayer->units, punit) {
5393 unique_count[utype_index(unit_type_get(punit))]++;
5395
5396 unit_type_iterate(ut) {
5397 if (unique_count[utype_index(ut)] > 1 && utype_has_flag(ut, UTYF_UNIQUE)) {
5398 log_sg(_("%s has multiple units of type %s though it should be possible "
5399 "to have only one."),
5400 player_name(pplayer), utype_name_translation(ut));
5401 }
5404
5405 /* Restore game random state, just in case various initialization code
5406 * inexplicably altered the previously existing state. */
5407 if (!game.info.is_new_game) {
5408 fc_rand_set_state(loading->rstate);
5409
5410 if (loading->version < 30) {
5411 /* For older savegames we have to recalculate the score with current data,
5412 * instead of using beginning-of-turn saved scores. */
5413 players_iterate(pplayer) {
5414 calc_civ_score(pplayer);
5416 }
5417 }
5418
5419 /* At the end do the default sanity checks. */
5420 sanity_check();
5421}
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:1123
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3343
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2772
void city_size_set(struct city *pcity, citizens size)
Definition city.c:1158
void city_add_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3270
void destroy_city_virtual(struct city *pcity)
Definition city.c:3419
int city_style_by_rule_name(const char *s)
Definition city.c:1711
#define cities_iterate_end
Definition city.h:497
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
#define cities_iterate(pcity)
Definition city.h:492
#define CITY_MAP_MAX_RADIUS_SQ
Definition city.h:78
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
#define output_type_iterate(output)
Definition city.h:821
#define city_owner(_pcity_)
Definition city.h:543
#define FREE_WORKED_TILES
Definition city.h:858
#define MAX_CITY_SIZE
Definition city.h:98
#define city_list_iterate_end
Definition city.h:490
#define I_NEVER
Definition city.h:239
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:222
#define city_tile_iterate_end
Definition city.h:230
#define output_type_iterate_end
Definition city.h:827
bool update_dumb_city(struct player *pplayer, struct city *pcity)
Definition citytools.c:2683
bool send_city_suppression(bool now)
Definition citytools.c:2143
static void void city_freeze_workers(struct city *pcity)
Definition citytools.c:135
void city_thaw_workers(struct city *pcity)
Definition citytools.c:145
void reality_check_city(struct player *pplayer, struct tile *ptile)
Definition citytools.c:2751
void city_refresh_vision(struct city *pcity)
Definition citytools.c:3338
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:369
void city_repair_size(struct city *pcity, int change)
Definition cityturn.c:897
bool city_refresh(struct city *pcity)
Definition cityturn.c:161
static char * ruleset
Definition civmanual.c:206
char * techs
Definition comments.c:30
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:2819
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2840
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
void set_ai_level_directer(struct player *pplayer, enum ai_level level)
Definition difficulty.c:39
static struct treaty_list * treaties
Definition diplhand.c:58
struct treaty_list * get_all_treaties(void)
Definition diplhand.c:986
void init_treaty(struct Treaty *ptreaty, struct player *plr0, struct player *plr1)
Definition diptreaty.c:96
bool add_clause(struct Treaty *ptreaty, struct player *pfrom, enum clause_type type, int val, struct player *client_player)
Definition diptreaty.c:142
int int id
Definition editgui_g.h:28
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:740
struct extra_type * extra_type_by_rule_name(const char *name)
Definition extras.c:204
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1068
int extra_number(const struct extra_type *pextra)
Definition extras.c:153
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:765
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:195
#define is_extra_caused_by(e, c)
Definition extras.h:196
#define extra_index(_e_)
Definition extras.h:177
#define EXTRA_NONE
Definition extras.h:82
#define extra_base_get(_e_)
Definition extras.h:184
#define extra_road_get(_e_)
Definition extras.h:185
#define extra_type_by_cause_iterate_end
Definition extras.h:315
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:309
#define NO_TARGET
Definition fc_types.h:324
#define MAX_TRADE_ROUTES
Definition fc_types.h:1111
@ ROCO_RAILROAD
Definition fc_types.h:1105
@ ROCO_RIVER
Definition fc_types.h:1105
@ ROCO_ROAD
Definition fc_types.h:1105
int Tech_type_id
Definition fc_types.h:347
unsigned char citizens
Definition fc_types.h:358
@ RPT_POSSIBLE
Definition fc_types.h:585
int Multiplier_type_id
Definition fc_types.h:356
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:82
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
void initialize_globals(void)
Definition game.c:663
struct city * game_city_by_number(int id)
Definition game.c:102
#define GAME_DEFAULT_TIMEOUTINTINC
Definition game.h:576
#define GAME_DEFAULT_SCORETURN
Definition game.h:560
#define GAME_DEFAULT_TIMEOUTINT
Definition game.h:575
#define GAME_DEFAULT_TIMEOUTINCMULT
Definition game.h:578
#define GAME_DEFAULT_TIMEOUTINC
Definition game.h:577
#define GAME_DEFAULT_RULESETDIR
Definition game.h:654
#define GAME_DEFAULT_TIMEOUTCOUNTER
Definition game.h:580
#define GAME_DEFAULT_PHASE_MODE
Definition game.h:595
#define GAME_HARDCODED_DEFAULT_SKILL_LEVEL
Definition game.h:676
struct government * government_by_rule_name(const char *name)
Definition government.c:54
struct city * owner
Definition citydlg.c:219
GType type
Definition repodlgs.c:1312
void idex_register_unit(struct world *iworld, struct unit *punit)
Definition idex.c:81
void idex_register_city(struct world *iworld, struct city *pcity)
Definition idex.c:66
Impr_type_id improvement_index(const struct impr_type *pimprove)
struct impr_type * improvement_by_rule_name(const char *name)
#define WONDER_DESTROYED
#define WONDER_LOST
void adv_city_free(struct city *pcity)
Definition infracache.c:501
void adv_city_alloc(struct city *pcity)
Definition infracache.c:488
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define log_fatal(message,...)
Definition log.h:100
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1463
#define nat_x
#define nat_y
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:639
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1669
void map_init_topology(struct civ_map *nmap)
Definition map.c:301
void main_map_allocate(void)
Definition map.c:517
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
int map_startpos_count(void)
Definition map.c:1656
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:441
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1446
#define MAP_INDEX_SIZE
Definition map.h:131
#define whole_map_iterate(_map, _tile)
Definition map.h:539
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:151
#define whole_map_iterate_end
Definition map.h:548
@ MAPGEN_SCENARIO
Definition map_types.h:47
void assign_continent_numbers(void)
void player_map_init(struct player *pplayer)
Definition maphand.c:1202
void update_player_tile_last_seen(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1455
void map_claim_ownership(struct tile *ptile, struct player *powner, struct tile *psource, bool claim_bases)
Definition maphand.c:2191
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:886
bool send_tile_suppression(bool now)
Definition maphand.c:472
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:342
void map_know_and_see_all(struct player *pplayer)
Definition maphand.c:1177
bool update_player_tile_knowledge(struct player *pplayer, struct tile *ptile)
Definition maphand.c:1386
void tile_claim_bases(struct tile *ptile, struct player *powner)
Definition maphand.c:2204
void map_set_known(struct tile *ptile, struct player *pplayer)
Definition maphand.c:1159
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:900
void change_playertile_site(struct player_tile *ptile, struct vision_site *new_site)
Definition maphand.c:1140
void map_calculate_borders(void)
Definition maphand.c:2357
void give_shared_vision(struct player *pfrom, struct player *pto)
Definition maphand.c:1620
struct player_tile * map_get_player_tile(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:1370
bool mapimg_define(const char *maparg, bool check)
Definition mapimg.c:768
bool mapimg_delete(int id)
Definition mapimg.c:1203
int mapimg_count(void)
Definition mapimg.c:572
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
void set_meta_patches_string(const char *string)
Definition meta.c:171
const char * default_meta_patches_string(void)
Definition meta.c:82
#define DEFAULT_META_SERVER_ADDR
Definition meta.h:21
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c: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:783
int parts
Definition packhand.c:130
char * lines
Definition packhand.c:129
int len
Definition packhand.c:125
bool player_slot_is_used(const struct player_slot *pslot)
Definition player.c:441
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
struct player * player_by_number(const int player_id)
Definition player.c:840
bool players_on_same_team(const struct player *pplayer1, const struct player *pplayer2)
Definition player.c:1452
int player_count(void)
Definition player.c:808
int player_slot_count(void)
Definition player.c:411
struct player_slot * player_slot_by_number(int player_id)
Definition player.c:456
int player_number(const struct player *pplayer)
Definition player.c:828
enum dipl_reason pplayer_can_make_treaty(const struct player *p1, const struct player *p2, enum diplstate_type treaty)
Definition player.c:153
const char * player_name(const struct player *pplayer)
Definition player.c:886
int player_slot_max_used_number(void)
Definition player.c:469
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
int player_slot_index(const struct player_slot *pslot)
Definition player.c:419
struct player * player_by_name(const char *name)
Definition player.c:872
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1179
int player_index(const struct player *pplayer)
Definition player.c:820
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Definition player.c:852
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:317
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
struct player_slot * slots
Definition player.c:50
#define players_iterate_end
Definition player.h:535
dipl_reason
Definition player.h:194
@ DIPL_ALLIANCE_PROBLEM_THEM
Definition player.h:196
@ DIPL_ALLIANCE_PROBLEM_US
Definition player.h:196
#define players_iterate(_pplayer)
Definition player.h:530
#define MAX_ATTRIBUTE_BLOCK
Definition player.h:225
#define player_list_iterate(playerlist, pplayer)
Definition player.h:553
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define player_slots_iterate(_pslot)
Definition player.h:521
#define is_ai(plr)
Definition player.h:234
#define player_list_iterate_end
Definition player.h:555
#define players_iterate_alive_end
Definition player.h:545
#define player_slots_iterate_end
Definition player.h:525
#define players_iterate_alive(_pplayer)
Definition player.h:540
void server_player_set_name(struct player *pplayer, const char *name)
Definition plrhand.c: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,...)
#define secfile_entry_ignore(_sfile_, _fmt_,...)
struct history_report * history_report_get(void)
Definition report.c:1689
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
struct universal universal_by_rule_name(const char *kind, const char *value)
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c:665
const char * research_name_translation(const struct research *presearch)
Definition research.c:154
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:634
struct research * research_by_number(int number)
Definition research.c:116
int recalculate_techs_researched(const struct research *presearch)
Definition research.c:1318
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
void research_update(struct research *presearch)
Definition research.c:499
#define researches_iterate(_presearch)
Definition research.h:157
#define researches_iterate_end
Definition research.h:160
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Definition rgbcolor.c:74
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, char *path,...)
Definition rgbcolor.c:90
struct extra_type * road_extra_get(const struct road_type *proad)
Definition road.c:42
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
struct road_type * road_by_number(Road_type_id id)
Definition road.c:58
struct road_type * road_by_compat_special(enum road_compat compat)
Definition road.c:160
bool load_rulesets(const char *restore, const char *alt, bool compat_mode, rs_conversion_logger logger, bool act, bool buffer_script, bool load_luadata)
Definition ruleset.c:9227
#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:2407
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:2342
#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:2211
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:2050
#define halfbyte_iterate_extras(e, num_extras_types)
Definition savegame2.c:239
static void sg_load_map(struct loaddata *loading)
Definition savegame2.c:1894
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:3742
static void sg_load_player_cities(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3349
static void sg_load_map_tiles(struct loaddata *loading)
Definition savegame2.c:1979
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:3909
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:3469
static void sg_load_settings(struct loaddata *loading)
Definition savegame2.c:1874
static void sg_load_player_units(struct loaddata *loading, struct player *plr)
Definition savegame2.c:3790
#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:4979
#define halfbyte_iterate_bases_end
Definition savegame2.c:264
static void sg_load_map_worked(struct loaddata *loading)
Definition savegame2.c:2298
static void sg_load_random(struct loaddata *loading)
Definition savegame2.c:1705
#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:4519
static void sg_load_history(struct loaddata *loading)
Definition savegame2.c:5168
#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:2066
#define TOKEN_SIZE
Definition savegame2.c:278
static void sg_load_script(struct loaddata *loading)
Definition savegame2.c:1764
static void sg_load_scenario(struct loaddata *loading)
Definition savegame2.c:1779
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:2855
static void sg_load_treaties(struct loaddata *loading)
Definition savegame2.c:5085
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:2097
#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:5201
#define ORDER_OLD_HOMECITY
Definition savegame2.c:284
static void sg_load_player_attributes(struct loaddata *loading, struct player *plr)
Definition savegame2.c:4572
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:4652
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:4872
static void sg_load_map_startpos(struct loaddata *loading)
Definition savegame2.c:2124
static void loaddata_destroy(struct loaddata *loading)
Definition savegame2.c:495
static void sg_load_players(struct loaddata *loading)
Definition savegame2.c:2664
#define ORDER_OLD_TRADE_ROUTE
Definition savegame2.c:283
static void sg_load_map_tiles_extras(struct loaddata *loading)
Definition savegame2.c:2019
static void sg_load_sanitycheck(struct loaddata *loading)
Definition savegame2.c:5245
static void sg_load_event_cache(struct loaddata *loading)
Definition savegame2.c:5070
static void sg_load_map_tiles_bases(struct loaddata *loading)
Definition savegame2.c:2034
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:3868
#define halfbyte_iterate_roads(r, num_roads_types)
Definition savegame2.c:269
void calc_civ_score(struct player *pplayer)
Definition score.c:251
void script_server_state_load(struct section_file *file)
void settings_game_load(struct section_file *file, const char *section)
Definition settings.c:4648
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
bool str_to_int(const char *str, int *pint)
Definition shared.c:512
bool is_base64url(const char *s)
Definition shared.c:317
char scanin(const char **buf, char *delimiters, char *dest, int size)
Definition shared.c:1912
void randomize_base64url_string(char *s, size_t n)
Definition shared.c:338
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MAX(x, y)
Definition shared.h:54
void spaceship_calc_derived(struct player_spaceship *ship)
Definition spacerace.c:45
void spaceship_init(struct player_spaceship *ship)
Definition spaceship.c:96
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
@ SSHIP_LAUNCHED
Definition spaceship.h:85
@ SSHIP_NONE
Definition spaceship.h:84
struct specialist * specialist_by_rule_name(const char *name)
Definition specialist.c:112
Specialist_type_id specialist_index(const struct specialist *sp)
Definition specialist.c:82
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#define DEFAULT_SPECIALIST
Definition specialist.h:43
size_t size
Definition specvec.h:72
void server_game_init(bool keep_ruleset_value)
Definition srv_main.c:3382
const char * aifill(int amount)
Definition srv_main.c:2395
bool game_was_started(void)
Definition srv_main.c:339
void identity_number_reserve(int id)
Definition srv_main.c:1926
struct server_arguments srvarg
Definition srv_main.c:173
void init_game_seed(void)
Definition srv_main.c:200
void update_nations_with_startpos(void)
Definition srv_main.c:2200
void server_game_free(void)
Definition srv_main.c:3406
int x
Definition rand.h:30
RANDOM_TYPE v[56]
Definition rand.h:29
int k
Definition rand.h:30
bool is_init
Definition rand.h:31
int j
Definition rand.h:30
bool accept0
Definition diptreaty.h:78
bool accept1
Definition diptreaty.h:78
struct player * first
bv_player achievers
int val
Definition traits.h:38
int mod
Definition traits.h:39
int turn
Definition city.h:238
Definition city.h:309
struct worker_task_list * task_reqs
Definition city.h:395
int turn_last_built
Definition city.h:373
int food_stock
Definition city.h:354
struct built_status built[B_LAST]
Definition city.h:380
struct player * original
Definition city.h:313
int history
Definition city.h:393
bool did_sell
Definition city.h:367
int id
Definition city.h:315
int last_turns_shield_surplus
Definition city.h:378
int disbanded_shields
Definition city.h:377
int turn_plague
Definition city.h:361
bv_city_options city_options
Definition city.h:389
bool was_happy
Definition city.h:368
int turn_founded
Definition city.h:372
int airlift
Definition city.h:365
int caravan_shields
Definition city.h:376
bool did_buy
Definition city.h:366
struct trade_route_list * routes
Definition city.h:332
int anarchy
Definition city.h:370
struct worklist worklist
Definition city.h:387
struct universal production
Definition city.h:382
citizens * nationality
Definition city.h:329
int steal
Definition city.h:397
int before_change_shields
Definition city.h:375
int style
Definition city.h:316
bool synced
Definition city.h:431
citizens specialists[SP_MAX]
Definition city.h:324
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
struct vision * vision
Definition city.h:438
struct city::@17::@19 server
struct universal changed_from
Definition city.h:385
struct unit_list * units_supported
Definition city.h:391
int rapture
Definition city.h:371
bool last_updated_year
Definition game.h:234
struct civ_game::@30::@34 server
float turn_change_time
Definition game.h:217
bool vision_reveal_tiles
Definition game.h:199
struct packet_scenario_description scenario_desc
Definition game.h:88
struct packet_ruleset_control control
Definition game.h:83
bool fogofwar_old
Definition game.h:232
struct packet_game_info info
Definition game.h:89
int timeoutcounter
Definition game.h:206
char rulesetdir[MAX_LEN_NAME]
Definition game.h:236
int scoreturn
Definition game.h:223
randseed seed
Definition game.h:225
struct packet_scenario_info scenario
Definition game.h:87
int timeoutint
Definition game.h:202
unsigned revealmap
Definition game.h:176
bool foggedborders
Definition game.h:146
int timeoutincmult
Definition game.h:204
int timeoutinc
Definition game.h:203
int phase_mode_stored
Definition game.h:215
int max_players
Definition game.h:155
int timeoutintinc
Definition game.h:205
int xsize
Definition map_types.h:77
randseed seed
Definition map_types.h:89
int ysize
Definition map_types.h:77
bool have_resources
Definition map_types.h:107
struct civ_map::@41::@43 server
bool have_huts
Definition map_types.h:106
enum map_generator generator
Definition map_types.h:95
int changed_to_times
Definition government.h:61
char title[REPORT_TITLESIZE]
Definition report.h:27
char body[REPORT_BODYSIZE]
Definition report.h:28
const char * secfile_options
Definition savecompat.h:49
int version
Definition savecompat.h:50
RANDOM_STATE rstate
Definition savecompat.h:131
struct loaddata::@107 road
struct loaddata::@106 base
struct loaddata::@104 multiplier
int full_version
Definition savecompat.h:51
size_t size
Definition savecompat.h:56
struct loaddata::@109 ds_t
struct loaddata::@105 special
enum server_states server_state
Definition savecompat.h:128
struct loaddata::@100 technology
struct loaddata::@108 specialist
const char ** order
Definition savecompat.h:55
struct loaddata::@101 activities
struct loaddata::@102 trait
struct loaddata::@99 improvement
int * worked_tiles
Definition savecompat.h:134
struct loaddata::@103 extra
struct section_file * file
Definition savecompat.h:48
int great_wonder_owners[B_LAST]
bool global_advances[A_LAST]
enum ai_level skill_level
enum phase_mode_type phase_mode
char description[MAX_LEN_CONTENT]
char authors[MAX_LEN_PACKET/3]
enum ai_level skill_level
Definition player.h:122
struct ai_trait * traits
Definition player.h:132
enum barbarian_type barbarian_type
Definition player.h:128
int science_cost
Definition player.h:125
int love[MAX_NUM_PLAYER_SLOTS]
Definition player.h:130
int expand
Definition player.h:124
int fuzzy
Definition player.h:123
char contact_turns_left
Definition player.h:206
int first_contact_turn
Definition player.h:203
enum diplstate_type max_state
Definition player.h:202
enum diplstate_type type
Definition player.h:201
char has_reason_to_cancel
Definition player.h:205
int units_killed
Definition player.h:112
int landarea
Definition player.h:101
int population
Definition player.h:103
int pollution
Definition player.h:106
int wonders
Definition player.h:98
int settledarea
Definition player.h:102
int specialists[SP_MAX]
Definition player.h:97
int units_lost
Definition player.h:113
int angry
Definition player.h:96
int techout
Definition player.h:100
int units_built
Definition player.h:111
int content
Definition player.h:94
int happy
Definition player.h:93
int spaceship
Definition player.h:110
int culture
Definition player.h:115
int unhappy
Definition player.h:95
int literacy
Definition player.h:107
int techs
Definition player.h:99
bv_spaceship_structure structure
Definition spaceship.h:100
enum spaceship_state state
Definition spaceship.h:108
struct player * extras_owner
Definition maphand.h:35
struct player * owner
Definition maphand.h:34
struct city_list * cities
Definition player.h:281
int bulbs_last_turn
Definition player.h:351
struct player_ai ai_common
Definition player.h:288
bv_plr_flags flags
Definition player.h:292
bool is_male
Definition player.h:257
bool got_first_city
Definition player.h:320
int wonders[B_LAST]
Definition player.h:301
bool unassigned_ranked
Definition player.h:255
struct government * target_government
Definition player.h:259
char username[MAX_LEN_NAME]
Definition player.h:252
int revolution_finishes
Definition player.h:273
int nturns_idle
Definition player.h:265
struct government * government
Definition player.h:258
struct team * team
Definition player.h:261
int turns_alive
Definition player.h:266
struct unit_list * units
Definition player.h:282
char ranked_username[MAX_LEN_NAME]
Definition player.h:254
int huts
Definition player.h:349
bool is_alive
Definition player.h:268
bv_player real_embassy
Definition player.h:277
struct player_economic economic
Definition player.h:284
struct player_spaceship spaceship
Definition player.h:286
struct attribute_block_s attribute_block
Definition player.h:303
struct player_score score
Definition player.h:283
struct multiplier_value multipliers[MAX_NUM_MULTIPLIERS]
Definition player.h:310
struct nation_type * nation
Definition player.h:260
struct nation_style * style
Definition player.h:279
bool border_vision
Definition player.h:327
bool phase_done
Definition player.h:263
struct player::@69::@71 server
int history
Definition player.h:312
char orig_username[MAX_LEN_NAME]
Definition player.h:347
int last_war_action
Definition player.h:270
bool unassigned_user
Definition player.h:253
const struct tile * tile
Tech_type_id researching
Definition research.h:52
int future_tech
Definition research.h:42
Tech_type_id tech_goal
Definition research.h:85
int bulbs_researching_saved
Definition research.h:63
Tech_type_id researching_saved
Definition research.h:62
bool got_tech
Definition research.h:67
int techs_researched
Definition research.h:42
int bulbs_researched
Definition research.h:53
char metaserver_addr[256]
Definition srv_main.h:29
char serverid[256]
Definition srv_main.h:49
Definition map.c:41
Definition team.c:40
int road_time
Definition terrain.h:201
int mining_time
Definition terrain.h:213
char identifier_load
Definition terrain.h:185
int irrigation_time
Definition terrain.h:210
int base_time
Definition terrain.h:200
Definition tile.h:49
int index
Definition tile.h:50
bv_extras extras
Definition tile.h:54
struct unit_list * units
Definition tile.h:57
struct tile * claimer
Definition tile.h:63
enum route_direction dir
Definition traderoutes.h:86
struct goods_type * goods
Definition traderoutes.h:87
enum unit_orders order
Definition unit.h:93
Definition unit.h:138
int length
Definition unit.h:195
int upkeep[O_LAST]
Definition unit.h:148
bool has_orders
Definition unit.h:193
enum action_decision action_decision_want
Definition unit.h:202
int battlegroup
Definition unit.h:191
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
int ord_city
Definition unit.h:240
bool moved
Definition unit.h:173
int ord_map
Definition unit.h:239
int index
Definition unit.h:195
struct vision * vision
Definition unit.h:242
bool vigilant
Definition unit.h:197
int hp
Definition unit.h:151
struct unit::@79 orders
int fuel
Definition unit.h:153
struct extra_type * changed_from_target
Definition unit.h:170
enum direction8 facing
Definition unit.h:142
struct extra_type * activity_target
Definition unit.h:164
int activity_count
Definition unit.h:162
struct unit_order * list
Definition unit.h:198
enum unit_activity changed_from
Definition unit.h:168
struct player * nationality
Definition unit.h:144
bool repeat
Definition unit.h:196
struct unit::@80::@83 server
int homecity
Definition unit.h:146
bool paradropped
Definition unit.h:174
bool done_moving
Definition unit.h:181
int birth_turn
Definition unit.h:235
struct tile * goto_tile
Definition unit.h:155
struct tile * action_decision_tile
Definition unit.h:203
int veteran
Definition unit.h:152
int changed_from_count
Definition unit.h:169
enum server_side_agent ssa_controller
Definition unit.h:172
enum universals_n kind
Definition fc_types.h:758
char * name
Definition vision.h: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:167
#define RETURN_VALUE_AFTER_EXIT(_val_)
Definition support.h:121
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:175
bool team_add_player(struct player *pplayer, struct team *pteam)
Definition team.c:467
struct team * team_new(struct team_slot *tslot)
Definition team.c:317
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
struct advance * advance_by_rule_name(const char *name)
Definition tech.c:200
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define A_FUTURE
Definition tech.h:46
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
#define A_UNKNOWN
Definition tech.h:49
void init_tech(struct research *research, bool update)
Definition techtools.c:1070
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:174
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:235
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Definition terrain.c:243
#define terrain_type_iterate(_p)
Definition terrain.h:358
#define T_UNKNOWN
Definition terrain.h:57
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:188
#define terrain_type_iterate_end
Definition terrain.h:364
#define RESOURCE_NONE_IDENTIFIER
Definition terrain.h:47
#define RESOURCE_NULL_IDENTIFIER
Definition terrain.h:46
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:209
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1018
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:966
bool tile_set_label(struct tile *ptile, const char *label)
Definition tile.c:1080
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Definition tile.c:343
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
void tile_set_worked(struct tile *ptile, struct city *pcity)
Definition tile.c:106
#define tile_index(_pt_)
Definition tile.h:87
#define tile_worked(_tile)
Definition tile.h: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:1753
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2354
void set_unit_activity(struct unit *punit, enum unit_activity new_activity)
Definition unit.c:1107
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2425
bool can_unit_continue_current_activity(const struct civ_map *nmap, struct unit *punit)
Definition unit.c:845
void set_unit_activity_targeted(struct unit *punit, enum unit_activity new_activity, struct extra_type *new_target)
Definition unit.c:1124
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1617
bool unit_order_list_is_sane(const struct civ_map *nmap, int length, const struct unit_order *orders)
Definition unit.c:2632
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1713
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1281
#define unit_tile(_pu)
Definition unit.h:395
#define BATTLEGROUP_NONE
Definition unit.h:190
unit_orders
Definition unit.h:37
@ ORDER_ACTION_MOVE
Definition unit.h:45
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_FULL_MP
Definition unit.h:43
@ ORDER_MOVE
Definition unit.h:39
@ ORDER_LAST
Definition unit.h:49
@ ORDER_PERFORM_ACTION
Definition unit.h:47
#define unit_owner(_pu)
Definition unit.h:394
void unit_list_sort_ord_map(struct unit_list *punitlist)
Definition unitlist.c:73
void unit_list_sort_ord_city(struct unit_list *punitlist)
Definition unitlist.c:85
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void resolve_unit_stacks(struct player *pplayer, struct player *aplayer, bool verbose)
Definition unittools.c:1414
void unit_refresh_vision(struct unit *punit)
Definition unittools.c:4852
void bounce_unit(struct unit *punit, bool verbose)
Definition unittools.c:1241
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
struct unit_type * unit_type_by_rule_name(const char *name)
Definition unittype.c:1819
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2673
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define unit_type_iterate(_p)
Definition unittype.h:841
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:848
void vision_site_size_set(struct vision_site *psite, citizens size)
Definition vision.c:165
struct vision * vision_new(struct player *pplayer, struct tile *ptile)
Definition vision.c:33
bool vision_reveal_tiles(struct vision *vision, bool reveal_tiles)
Definition vision.c:62
struct vision_site * vision_site_new(int identity, struct tile *location, struct player *owner)
Definition vision.c:86
void vision_site_destroy(struct vision_site *psite)
Definition vision.c:74
bool worker_task_is_sane(struct worker_task *ptask)
Definition workertask.c:40
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35
void worklist_init(struct worklist *pwl)
Definition worklist.c:38