Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/savegame/savegame2.c Source File

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