~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to server/savegame.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100223220902-kiyrmr9i4152cka5
Tags: 2.2.0-1
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include "idex.h"
37
37
#include "map.h"
38
38
#include "movement.h"
 
39
#include "packets.h"
 
40
#include "specialist.h"
39
41
#include "unit.h"
40
42
#include "unitlist.h"
41
43
#include "version.h"
53
55
#include "mapgen.h"
54
56
#include "maphand.h"
55
57
#include "meta.h"
 
58
#include "notify.h"
56
59
#include "plrhand.h"
57
60
#include "ruleset.h"
58
61
#include "savegame.h"
63
66
#include "techtools.h"
64
67
#include "unittools.h"
65
68
 
 
69
/* generator */
 
70
#include "utilities.h"
 
71
 
66
72
#define TOKEN_SIZE 10
67
73
 
 
74
#define LOG_WORKER              LOG_VERBOSE
 
75
 
 
76
/* enum city_tile_type string constants for savegame */
 
77
#define S_TILE_EMPTY            '0'
 
78
#define S_TILE_WORKER           '1'
 
79
#define S_TILE_UNAVAILABLE      '2'
 
80
#define S_TILE_UNKNOWN          '?'
 
81
 
 
82
 
68
83
/* 
69
84
 * This loops over the entire map to save data. It collects all the data of
70
85
 * a line using GET_XY_CHAR and then executes the macro SECFILE_INSERT_LINE.
89
104
                                                                            \
90
105
  for (_nat_y = 0; _nat_y < map.ysize; _nat_y++) {                          \
91
106
    for (_nat_x = 0; _nat_x < map.xsize; _nat_x++) {                        \
92
 
      struct tile *ptile = native_pos_to_tile(_nat_x, _nat_y);                    \
 
107
      struct tile *ptile = native_pos_to_tile(_nat_x, _nat_y);              \
93
108
      assert(ptile != NULL);                                                \
94
109
      line[_nat_x] = (GET_XY_CHAR);                                         \
95
110
      if (!my_isprint(line[_nat_x] & 0x7f)) {                               \
163
178
    for (_nat_x = 0; _nat_x < map.xsize; _nat_x++) {                    \
164
179
      const char ch = _line[_nat_x];                                    \
165
180
      struct tile *ptile = native_pos_to_tile(_nat_x, _nat_y);          \
166
 
                                                                        \
167
181
      (SET_XY_CHAR);                                                    \
168
182
    }                                                                   \
169
183
  }                                                                     \
187
201
  }                                                                         \
188
202
}
189
203
 
 
204
/* Iterate on the bases half-bytes */
 
205
#define bases_halfbyte_iterate(b, num_bases_types)                          \
 
206
{                                                                           \
 
207
  int b;                                                                    \
 
208
                                                                            \
 
209
  for(b = 0; 4 * b < (num_bases_types); b++) {
 
210
 
 
211
#define bases_halfbyte_iterate_end                                          \
 
212
  }                                                                         \
 
213
}
 
214
 
190
215
/* The following should be removed when compatibility with
191
216
   pre-1.13.0 savegames is broken: startoptions, spacerace2
192
217
   and rulesets */
193
 
#define SAVEFILE_OPTIONS "startoptions spacerace2 rulesets" \
194
 
" diplchance_percent map_editor known32fix turn " \
195
 
"attributes watchtower rulesetdir client_worklists orders " \
196
 
"startunits turn_last_built improvement_order technology_order embassies " \
197
 
"new_owner_map resources"
 
218
static const char savefile_options_default[] =
 
219
        " attributes"           /* unused */
 
220
        " client_worklists"     /* unused */
 
221
        " diplchance_percent"
 
222
        " embassies"
 
223
        " improvement_order"
 
224
        " known32fix"
 
225
        " map_editor"           /* unused */
 
226
        " new_owner_map"
 
227
        " orders"
 
228
        " resources"
 
229
        " rulesetdir"
 
230
        " rulesets"             /* unused */
 
231
        " spacerace2"           /* unused */
 
232
        " startoptions"
 
233
        " startunits"
 
234
        " technology_order"
 
235
        " turn"
 
236
        " turn_last_built"
 
237
        " watchtower"           /* unused */
 
238
        " bases"                /* Since 2.2 */
 
239
        ;/* savefile_options_default */
198
240
 
199
241
static const char hex_chars[] = "0123456789abcdef";
 
242
static const char num_chars[] =
 
243
  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+";
200
244
 
201
 
static void set_savegame_special(bv_special *specials,
 
245
static void set_savegame_special(bv_special *specials, bv_bases *bases,
202
246
                    char ch, const enum tile_special_type *index);
203
247
 
 
248
static void game_load_internal(struct section_file *file);
 
249
 
 
250
static char player_to_identier(const struct player *pplayer);
 
251
static struct player *identifier_to_player(char c);
 
252
 
 
253
 
 
254
static void worklist_load(struct section_file *file, struct worklist *pwl,
 
255
                          const char *path, ...)
 
256
                          fc__attribute((__format__ (__printf__, 3, 4)));
 
257
static void worklist_save(struct section_file *file,
 
258
                          const struct worklist *pwl,
 
259
                          int max_length, const char *path, ...)
 
260
                          fc__attribute((__format__ (__printf__, 4, 5)));
 
261
 
204
262
/***************************************************************
205
263
This returns an ascii hex value of the given half-byte of the binary
206
264
integer. See ascii_hex2bin().
238
296
}
239
297
 
240
298
/****************************************************************************
 
299
  Converts number in to single character. This works to values up to ~70.
 
300
****************************************************************************/
 
301
static char num2char(unsigned int num)
 
302
{
 
303
  if (num >= strlen(num_chars)) {
 
304
    return '?';
 
305
  }
 
306
 
 
307
  return num_chars[num];
 
308
}
 
309
 
 
310
/****************************************************************************
 
311
  Converts single character into numerical value. This is not hex conversion.
 
312
****************************************************************************/
 
313
static int char2num(char ch)
 
314
{
 
315
  char *pch;
 
316
 
 
317
  pch = strchr(num_chars, ch);
 
318
 
 
319
  if (!pch) {
 
320
    die("Unknown ascii value for num: '%c' %d", ch, ch);
 
321
  }
 
322
 
 
323
  return pch - num_chars;
 
324
}
 
325
 
 
326
/****************************************************************************
241
327
  Dereferences the terrain character.  See terrains[].identifier
242
328
    example: char2terrain('a') => T_ARCTIC
243
329
****************************************************************************/
244
330
static struct terrain *char2terrain(char ch)
245
331
{
246
 
  /* terrain_by_identifier plus fatal error */
247
 
  if (ch == UNKNOWN_TERRAIN_IDENTIFIER) {
 
332
  /* find_terrain_by_identifier plus fatal error */
 
333
  if (ch == TERRAIN_UNKNOWN_IDENTIFIER) {
248
334
    return T_UNKNOWN;
249
335
  }
250
336
  terrain_type_iterate(pterrain) {
264
350
static char terrain2char(const struct terrain *pterrain)
265
351
{
266
352
  if (pterrain == T_UNKNOWN) {
267
 
    return UNKNOWN_TERRAIN_IDENTIFIER;
 
353
    return TERRAIN_UNKNOWN_IDENTIFIER;
268
354
  } else {
269
355
    return pterrain->identifier;
270
356
  }
296
382
    return ORDER_BUILD_WONDER;
297
383
  case 't':
298
384
  case 'T':
299
 
    return ORDER_TRADEROUTE;
 
385
    return ORDER_TRADE_ROUTE;
300
386
  case 'h':
301
387
  case 'H':
302
388
    return ORDER_HOMECITY;
324
410
    return 'd';
325
411
  case ORDER_BUILD_WONDER:
326
412
    return 'u';
327
 
  case ORDER_TRADEROUTE:
 
413
  case ORDER_TRADE_ROUTE:
328
414
    return 't';
329
415
  case ORDER_HOMECITY:
330
416
    return 'h';
432
518
    return 'y';
433
519
  case ACTIVITY_FALLOUT:
434
520
    return 'u';
 
521
  case ACTIVITY_BASE:
 
522
    return 'b';
435
523
  case ACTIVITY_UNKNOWN:
436
524
  case ACTIVITY_PATROL_UNUSED:
437
525
    return '?';
514
602
  return length;
515
603
}
516
604
 
 
605
 
 
606
/****************************************************************************
 
607
  Load the worklist elements specified by path to the worklist pointed to
 
608
  by pwl.
 
609
 
 
610
  pwl should be a pointer to an existing worklist.
 
611
 
 
612
  path and ... give the prefix to load from, printf-style.
 
613
****************************************************************************/
 
614
static void worklist_load(struct section_file *file, struct worklist *pwl,
 
615
                          const char *path, ...)
 
616
{
 
617
  int i;
 
618
  const char *kind;
 
619
  const char *name;
 
620
  char path_str[1024];
 
621
  va_list ap;
 
622
 
 
623
  /* The first part of the registry path is taken from the varargs to the
 
624
   * function. */
 
625
  va_start(ap, path);
 
626
  my_vsnprintf(path_str, sizeof(path_str), path, ap);
 
627
  va_end(ap);
 
628
 
 
629
  worklist_init(pwl);
 
630
  pwl->length = secfile_lookup_int_default(file, 0,
 
631
                                           "%s.wl_length", path_str);
 
632
 
 
633
  for (i = 0; i < pwl->length; i++) {
 
634
    kind = secfile_lookup_str_default(file, NULL,
 
635
                                      "%s.wl_kind%d",
 
636
                                      path_str, i);
 
637
    if (!kind) {
 
638
      /* before 2.2.0 unit production was indicated by flag. */
 
639
      bool is_unit = secfile_lookup_bool_default(file, FALSE,
 
640
                                                 "%s.wl_is_unit%d",
 
641
                                                 path_str, i);
 
642
      kind = universal_kind_name(is_unit ? VUT_UTYPE : VUT_IMPROVEMENT);
 
643
    }
 
644
 
 
645
    /* We lookup the production value by name.  An invalid entry isn't a
 
646
     * fatal error; we just truncate the worklist. */
 
647
    name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
 
648
                                      path_str, i);
 
649
    pwl->entries[i] = universal_by_rule_name(kind, name);
 
650
    if (VUT_LAST == pwl->entries[i].kind) {
 
651
      freelog(LOG_ERROR, "%s.wl_value%d: unknown \"%s\" \"%s\".",
 
652
              path_str, i, kind, name);
 
653
      pwl->length = i;
 
654
      break;
 
655
    }
 
656
  }
 
657
}
 
658
 
 
659
/****************************************************************************
 
660
  Save the worklist elements specified by path from the worklist pointed to
 
661
  by pwl.
 
662
 
 
663
  pwl should be a pointer to an existing worklist.
 
664
 
 
665
  path and ... give the prefix to load from, printf-style.
 
666
****************************************************************************/
 
667
static void worklist_save(struct section_file *file,
 
668
                          const struct worklist *pwl,
 
669
                          int max_length, const char *path, ...)
 
670
{
 
671
  char path_str[1024];
 
672
  int i;
 
673
  va_list ap;
 
674
 
 
675
  /* The first part of the registry path is taken from the varargs to the
 
676
   * function. */
 
677
  va_start(ap, path);
 
678
  my_vsnprintf(path_str, sizeof(path_str), path, ap);
 
679
  va_end(ap);
 
680
 
 
681
  secfile_insert_int(file, pwl->length, "%s.wl_length", path_str);
 
682
 
 
683
  for (i = 0; i < pwl->length; i++) {
 
684
    const struct universal *entry = pwl->entries + i;
 
685
 
 
686
    /* before 2.2.0 unit production was indicated by flag. */
 
687
    secfile_insert_bool(file, (VUT_UTYPE == entry->kind),
 
688
                        "%s.wl_is_unit%d", path_str, i);
 
689
 
 
690
    secfile_insert_str(file, universal_type_rule_name(entry),
 
691
                       "%s.wl_kind%d", path_str, i);
 
692
    secfile_insert_str(file, universal_rule_name(entry),
 
693
                       "%s.wl_value%d", path_str, i);
 
694
  }
 
695
 
 
696
  assert(max_length <= MAX_LEN_WORKLIST);
 
697
 
 
698
  /* We want to keep savegame in tabular format, so each line has to be
 
699
   * of equal length. Fill table up to maximum worklist size. */
 
700
  for (i = pwl->length ; i < max_length; i++) {
 
701
    /* before 2.2.0 unit production was indicated by flag. */
 
702
    secfile_insert_bool(file, false, "%s.wl_is_unit%d", path_str, i);
 
703
    secfile_insert_str(file, "", "%s.wl_kind%d", path_str, i);
 
704
    secfile_insert_str(file, "", "%s.wl_value%d", path_str, i);
 
705
  }
 
706
}
 
707
 
 
708
 
517
709
/***************************************************************
518
710
load starting positions for the players from a savegame file
519
711
Now we don't know how many start positions there are nor how many
521
713
many as they are; there should be at least enough for every
522
714
player.  This could be changed/improved in future.
523
715
***************************************************************/
524
 
static void map_startpos_load(struct section_file *file)
 
716
static void map_load_startpos(struct section_file *file)
525
717
{
526
718
  int savegame_start_positions;
527
719
  int i, j;
541
733
    for (i = j = 0; i < savegame_start_positions; i++) {
542
734
      char *nation_name = secfile_lookup_str_default(file, NULL,
543
735
                                                     "map.r%dsnation", i);
544
 
      struct nation_type *pnation;
545
 
 
546
 
      if (!nation_name) {
547
 
        /* Starting positions in normal games are saved without nation.
548
 
           Just ignore it */
549
 
        continue;
550
 
      }
551
 
 
552
 
      pnation = find_nation_by_rule_name(nation_name);
553
 
      if (pnation == NO_NATION_SELECTED) {
554
 
        freelog(LOG_ERROR,
555
 
                "Warning: Unknown nation %s for starting position %d",
556
 
                nation_name, i);
557
 
        continue;
558
 
      }
559
 
      
 
736
      struct nation_type *pnation = NO_NATION_SELECTED;
 
737
 
 
738
      if (nation_name != NULL) {
 
739
        pnation = find_nation_by_rule_name(nation_name);
 
740
        if (pnation == NO_NATION_SELECTED) {
 
741
          freelog(LOG_ERROR,
 
742
                  "Warning: Unknown nation %s for starting position %d",
 
743
                  nation_name, i);
 
744
        }
 
745
      }
 
746
 
560
747
      nat_x = secfile_lookup_int(file, "map.r%dsx", i);
561
748
      nat_y = secfile_lookup_int(file, "map.r%dsy", i);
562
749
 
563
 
      start_positions[j].tile = native_pos_to_tile(nat_x, nat_y);
564
 
      start_positions[j].nation = pnation;
565
 
      j++;
 
750
      map_set_startpos(native_pos_to_tile(nat_x, nat_y), pnation);
 
751
 
 
752
      if (pnation != NO_NATION_SELECTED) {
 
753
        start_positions[j].tile = native_pos_to_tile(nat_x, nat_y);
 
754
        start_positions[j].nation = pnation;
 
755
        j++;
 
756
      }
566
757
    }
567
 
    map.num_start_positions = j;
568
 
    if (map.num_start_positions > 0) {
569
 
      map.start_positions = fc_realloc(map.start_positions,
570
 
                                       map.num_start_positions
571
 
                                       * sizeof(*map.start_positions));
 
758
    map.server.num_start_positions = j;
 
759
    if (map.server.num_start_positions > 0) {
 
760
      map.server.start_positions =
 
761
        fc_realloc(map.server.start_positions,
 
762
                   map.server.num_start_positions
 
763
                   * sizeof(*map.server.start_positions));
572
764
      for (i = 0; i < j; i++) {
573
 
        map.start_positions[i] = start_positions[i];
 
765
        map.server.start_positions[i] = start_positions[i];
574
766
      }
575
767
    }
576
768
  }
577
769
  
578
770
 
579
 
  if (map.num_start_positions
580
 
      && map.num_start_positions < game.info.max_players) {
 
771
  if (map.server.num_start_positions
 
772
      && map.server.num_start_positions < game.info.max_players) {
581
773
    freelog(LOG_VERBOSE,
582
774
            "Number of starts (%d) are lower than rules.max_players (%d),"
583
775
              " lowering rules.max_players.",
584
 
            map.num_start_positions, game.info.max_players);
585
 
    game.info.max_players = map.num_start_positions;
 
776
            map.server.num_start_positions, game.info.max_players);
 
777
    game.info.max_players = map.server.num_start_positions;
586
778
  }
587
779
}
588
780
 
589
781
/***************************************************************
590
782
load the tile map from a savegame file
591
783
***************************************************************/
592
 
static void map_tiles_load(struct section_file *file)
 
784
static void map_load_tiles(struct section_file *file)
593
785
{
594
786
  map.topology_id = secfile_lookup_int_default(file, MAP_ORIGINAL_TOPO,
595
787
                                               "map.topology_id");
597
789
  /* In some cases we read these before, but not always, and
598
790
   * its safe to read them again:
599
791
   */
600
 
  map.xsize=secfile_lookup_int(file, "map.width");
601
 
  map.ysize=secfile_lookup_int(file, "map.height");
 
792
  map.xsize = secfile_lookup_int(file, "map.width");
 
793
  map.ysize = secfile_lookup_int(file, "map.height");
602
794
 
603
795
  /* With a FALSE parameter [xy]size are not changed by this call. */
604
796
  map_init_topology(FALSE);
605
797
 
606
798
  map_allocate();
 
799
  player_slots_iterate(pplayer) {
 
800
    player_map_allocate(pplayer);
 
801
  } player_slots_iterate_end;
607
802
 
608
803
  /* get the terrain type */
609
804
  LOAD_MAP_DATA(ch, line, ptile,
610
805
                secfile_lookup_str(file, "map.t%03d", line),
611
806
                ptile->terrain = char2terrain(ch));
612
807
 
613
 
  assign_continent_numbers(FALSE);
 
808
  assign_continent_numbers();
614
809
 
615
810
  whole_map_iterate(ptile) {
616
811
    ptile->spec_sprite = secfile_lookup_str_default(file, NULL,
628
823
 * recovery). */
629
824
static const enum tile_special_type default_specials[] = {
630
825
  S_LAST, S_ROAD, S_IRRIGATION, S_RAILROAD,
631
 
  S_MINE, S_POLLUTION, S_HUT, S_FORTRESS,
632
 
  S_LAST, S_RIVER, S_FARMLAND, S_AIRBASE,
 
826
  S_MINE, S_POLLUTION, S_HUT, S_OLD_FORTRESS,
 
827
  S_LAST, S_RIVER, S_FARMLAND, S_OLD_AIRBASE,
633
828
  S_FALLOUT, S_LAST, S_LAST, S_LAST
634
829
};
635
830
 
644
839
 
645
840
  This does not need to be called from map_load(), because map_load() loads
646
841
  the rivers overlay along with the rest of the specials.  Call this only
647
 
  if you've already called map_tiles_load(), and want to load only the
 
842
  if you've already called map_load_tiles(), and want to load only the
648
843
  rivers overlay but no other specials.  Scenarios that encode things this
649
844
  way should have the "riversoverlay" capability.
650
845
****************************************************************************/
651
 
static void map_rivers_overlay_load(struct section_file *file,
 
846
static void map_load_rivers_overlay(struct section_file *file,
652
847
                              const enum tile_special_type *special_order)
653
848
{
654
849
  /* used by set_savegame_special */
655
 
  map.have_rivers_overlay = TRUE;
 
850
  map.server.have_rivers_overlay = TRUE;
656
851
 
657
852
  if (special_order) {
658
853
    special_halfbyte_iterate(j) {
661
856
 
662
857
      LOAD_MAP_DATA(ch, nat_y, ptile,
663
858
        secfile_lookup_str(file, buf, nat_y),
664
 
        set_savegame_special(&ptile->special, ch, special_order + 4 * j));
 
859
        set_savegame_special(&ptile->special, NULL, ch, special_order + 4 * j));
665
860
    } special_halfbyte_iterate_end;
666
861
  } else {
667
862
    /* Get the bits of the special flags which contain the river special
669
864
    assert(S_LAST <= 32);
670
865
    LOAD_MAP_DATA(ch, line, ptile,
671
866
      secfile_lookup_str_default(file, NULL, "map.n%03d", line),
672
 
      set_savegame_special(&ptile->special, ch, default_specials + 8));
 
867
      set_savegame_special(&ptile->special, NULL, ch, default_specials + 8));
673
868
  }
674
869
}
675
870
 
681
876
  savegame bit -> special bit. S_LAST is used to mark unused savegame bits.
682
877
****************************************************************************/
683
878
static void set_savegame_special(bv_special *specials,
 
879
                                 bv_bases *bases,
684
880
                                 char ch,
685
881
                                 const enum tile_special_type *index)
686
882
{
696
892
 
697
893
  for (i = 0; i < 4; i++) {
698
894
    enum tile_special_type sp = index[i];
 
895
    struct base_type *pbase;
699
896
 
700
897
    if (sp >= S_LAST) {
701
898
      continue;
702
899
    }
703
 
    if (map.have_rivers_overlay && sp != S_RIVER) {
 
900
    if (map.server.have_rivers_overlay && sp != S_RIVER) {
704
901
      continue;
705
902
    }
 
903
 
706
904
    if (bin & (1 << i)) {
707
 
      set_special(specials, sp);
 
905
      /* Pre 2.2 savegames have fortresses and airbases as part of specials */
 
906
      if (sp == S_OLD_FORTRESS) {
 
907
        if (bases) {
 
908
          pbase = get_base_by_gui_type(BASE_GUI_FORTRESS, NULL, NULL);
 
909
          if (pbase) {
 
910
            BV_SET(*bases, base_index(pbase));
 
911
          }
 
912
        }
 
913
      } else if (sp == S_OLD_AIRBASE) {
 
914
        if (bases) {
 
915
          pbase = get_base_by_gui_type(BASE_GUI_AIRBASE, NULL, NULL);
 
916
          if (pbase) {
 
917
            BV_SET(*bases, base_index(pbase));
 
918
          }
 
919
        }
 
920
      } else {
 
921
        set_special(specials, sp);
 
922
      }
708
923
    }
709
924
  }
710
925
}
733
948
 
734
949
  return hex_chars[bin];
735
950
}
 
951
 
 
952
/****************************************************************************
 
953
  Helper function for loading bases from a savegame.
 
954
 
 
955
  'ch' gives the character loaded from the savegame. Bases are packed
 
956
  in four to a character in hex notation.  'index' is a mapping of
 
957
  savegame bit -> base bit.
 
958
****************************************************************************/
 
959
static void set_savegame_bases(bv_bases *bases,
 
960
                               char ch,
 
961
                               struct base_type **index)
 
962
{
 
963
  int i, bin;
 
964
  char *pch = strchr(hex_chars, ch);
 
965
 
 
966
  if (!pch || ch == '\0') {
 
967
    freelog(LOG_ERROR, "Unknown hex value: '%c' (%d)", ch, ch);
 
968
    bin = 0;
 
969
  } else {
 
970
    bin = pch - hex_chars;
 
971
  }
 
972
 
 
973
  for (i = 0; i < 4; i++) {
 
974
    struct base_type *pbase = index[i];
 
975
 
 
976
    if (pbase == NULL) {
 
977
      continue;
 
978
    }
 
979
    if (bin & (1 << i)) {
 
980
      BV_SET(*bases, base_index(pbase));
 
981
    }
 
982
  }
 
983
}
 
984
 
 
985
/****************************************************************************
 
986
  Helper function for saving bases into a savegame.
 
987
 
 
988
  Specials are packed in four to a character in hex notation.  'index'
 
989
  specifies which set of bases are included in this character.
 
990
****************************************************************************/
 
991
static char get_savegame_bases(bv_bases bases,
 
992
                               const int *index)
 
993
{
 
994
  int i, bin = 0;
 
995
 
 
996
  for (i = 0; i < 4; i++) {
 
997
    int base = index[i];
 
998
 
 
999
    if (base < 0) {
 
1000
      break;
 
1001
    }
 
1002
    if (BV_ISSET(bases, base)) {
 
1003
      bin |= (1 << i);
 
1004
    }
 
1005
  }
 
1006
 
 
1007
  return hex_chars[bin];
 
1008
}
 
1009
 
736
1010
/****************************************************************************
737
1011
  Complicated helper function for reading resources from a savegame.
738
1012
  This reads resources saved in the specials bitvector.
764
1038
****************************************************************************/
765
1039
static struct resource *identifier_to_resource(char c)
766
1040
{
767
 
  if (c == RESOURCE_NULL_IDENTIFIER) {
 
1041
  /* speed common values */
 
1042
  if (c == RESOURCE_NULL_IDENTIFIER
 
1043
   || c == RESOURCE_NONE_IDENTIFIER) {
768
1044
    return NULL;
769
1045
  }
770
 
  resource_type_iterate (r) {
771
 
    if (r->identifier == c) {
772
 
      return r;
773
 
    }
774
 
  } resource_type_iterate_end;
775
 
  return NULL;
 
1046
  return find_resource_by_identifier(c);
776
1047
}
777
1048
 
778
1049
/****************************************************************************
780
1051
****************************************************************************/
781
1052
static char resource_to_identifier(const struct resource *presource)
782
1053
{
783
 
  return presource ? presource->identifier : RESOURCE_NULL_IDENTIFIER;
 
1054
  return presource ? presource->identifier : RESOURCE_NONE_IDENTIFIER;
 
1055
}
 
1056
 
 
1057
/****************************************************************************
 
1058
  Return the identifier for the given player.
 
1059
****************************************************************************/
 
1060
static char player_to_identier(const struct player *pplayer)
 
1061
{
 
1062
  if (!pplayer) {
 
1063
    return ' ';
 
1064
  }
 
1065
  if (player_number(pplayer) < 10) {
 
1066
    return '0' + player_number(pplayer);
 
1067
  }
 
1068
  return 'A' + player_number(pplayer) - 10;
 
1069
}
 
1070
 
 
1071
/****************************************************************************
 
1072
  Return the player for the given identifier.
 
1073
****************************************************************************/
 
1074
static struct player *identifier_to_player(char c)
 
1075
{
 
1076
  if (c == ' ') {
 
1077
    return NULL;
 
1078
  }
 
1079
  if ('0' <= c && c <= '9') {
 
1080
    return player_by_number(c - '0');
 
1081
  }
 
1082
  return player_by_number(10 + c - 'A');
784
1083
}
785
1084
 
786
1085
/***************************************************************
787
1086
load a complete map from a savegame file
788
1087
***************************************************************/
789
1088
static void map_load(struct section_file *file,
790
 
                     const enum tile_special_type *special_order)
 
1089
                     char *savefile_options,
 
1090
                     const enum tile_special_type *special_order,
 
1091
                     struct base_type **base_order,
 
1092
                     int num_bases_types)
791
1093
{
792
 
  char *savefile_options = secfile_lookup_str(file, "savefile.options");
793
 
 
794
1094
  /* map_init();
795
1095
   * This is already called in game_init(), and calling it
796
1096
   * here stomps on map.huts etc.  --dwp
797
1097
   */
798
1098
 
799
 
  map_tiles_load(file);
 
1099
  map_load_tiles(file);
800
1100
  if (secfile_lookup_bool_default(file, TRUE, "game.save_starts")) {
801
 
    map_startpos_load(file);
 
1101
    map_load_startpos(file);
802
1102
  } else {
803
 
    map.num_start_positions = 0;
 
1103
    map.server.num_start_positions = 0;
804
1104
  }
805
1105
 
806
1106
  if (special_order) {
815
1115
 
816
1116
      LOAD_MAP_DATA(ch, nat_y, ptile,
817
1117
          secfile_lookup_str(file, buf, nat_y),
818
 
          set_savegame_special(&ptile->special, ch, special_order + 4 * j));
 
1118
          set_savegame_special(&ptile->special, &ptile->bases, ch, special_order + 4 * j));
819
1119
    } special_halfbyte_iterate_end;
820
1120
  } else {
821
1121
    /* get 4-bit segments of 16-bit "special" field. */
822
1122
    LOAD_MAP_DATA(ch, nat_y, ptile,
823
1123
            secfile_lookup_str(file, "map.l%03d", nat_y),
824
 
            set_savegame_special(&ptile->special, ch, default_specials + 0));
 
1124
            set_savegame_special(&ptile->special, &ptile->bases, ch, default_specials + 0));
825
1125
    LOAD_MAP_DATA(ch, nat_y, ptile,
826
1126
            secfile_lookup_str(file, "map.u%03d", nat_y),
827
 
            set_savegame_special(&ptile->special, ch, default_specials + 4));
 
1127
            set_savegame_special(&ptile->special, &ptile->bases, ch, default_specials + 4));
828
1128
    LOAD_MAP_DATA(ch, nat_y, ptile,
829
1129
            secfile_lookup_str_default(file, NULL, "map.n%03d", nat_y),
830
 
            set_savegame_special(&ptile->special, ch, default_specials + 8));
 
1130
            set_savegame_special(&ptile->special, &ptile->bases, ch, default_specials + 8));
831
1131
    LOAD_MAP_DATA(ch, nat_y, ptile,
832
1132
            secfile_lookup_str_default(file, NULL, "map.f%03d", nat_y),
833
 
            set_savegame_special(&ptile->special, ch, default_specials + 12));
 
1133
            set_savegame_special(&ptile->special, &ptile->bases, ch, default_specials + 12));
834
1134
    /* Setup resources (from half-bytes 1 and 3 of old savegames) */
835
1135
    LOAD_MAP_DATA(ch, nat_y, ptile,
836
1136
        secfile_lookup_str(file, "map.l%03d", nat_y),
842
1142
 
843
1143
  /* after the resources are loaded, indicate those currently valid */
844
1144
  whole_map_iterate(ptile) {
845
 
    if (NULL != ptile->terrain
846
 
     && NULL != ptile->resource
847
 
     && terrain_has_resource(ptile->terrain, ptile->resource)) {
 
1145
    if (NULL == ptile->resource
 
1146
     || NULL == ptile->terrain) {
 
1147
      continue;
 
1148
    }
 
1149
    if (terrain_has_resource(ptile->terrain, ptile->resource)) {
848
1150
      /* cannot use set_special() for internal values */
849
1151
      BV_SET(ptile->special, S_RESOURCE_VALID);
850
1152
    }
853
1155
  /* Owner and ownership source are stored as plain numbers */
854
1156
  if (has_capability("new_owner_map", savefile_options)) {
855
1157
    int x, y;
856
 
 
857
 
    for (y = 0; y < map.ysize; y++) {
858
 
      char *buffer = 
859
 
            secfile_lookup_str_default(file, NULL, "map.owner%03d", y);
860
 
      char *ptr = buffer;
861
 
 
862
 
      if (buffer == NULL) {
863
 
        die("Savegame corrupt - map line %d not found.", y);
864
 
      }
865
 
      for (x = 0; x < map.xsize; x++) {
866
 
        char token[TOKEN_SIZE];
867
 
        int number;
868
 
        struct tile *ptile = native_pos_to_tile(x, y);
869
 
 
870
 
        scanin(&ptr, ",", token, sizeof(token));
871
 
        if (token[0] == '\0') {
872
 
          die("Savegame corrupt - map size not correct.");
873
 
        }
874
 
        if (strcmp(token, "-") == 0) {
875
 
          tile_set_owner(ptile, NULL);
876
 
        } else {
877
 
          if (sscanf(token, "%d", &number)) {
878
 
            tile_set_owner(ptile, get_player(number));
879
 
          } else {
880
 
            die("Savegame corrupt - got map owner %s in (%d, %d).", 
881
 
                token, x, y);
882
 
          }
883
 
        }
884
 
      }
885
 
    }
886
 
    for (y = 0; y < map.ysize; y++) {
 
1158
    struct player *owner = NULL;
 
1159
    struct tile *claimer = NULL;
 
1160
 
 
1161
    for (y = 0; y < map.ysize; y++) {
 
1162
      char *buffer1 = 
 
1163
        secfile_lookup_str_default(file, NULL, "map.owner%03d", y);
887
1164
      char *buffer2 = 
888
 
            secfile_lookup_str_default(file, NULL, "map.source%03d", y);
 
1165
        secfile_lookup_str_default(file, NULL, "map.source%03d", y);
 
1166
      char *ptr1 = buffer1;
889
1167
      char *ptr2 = buffer2;
890
1168
 
 
1169
      if (buffer1 == NULL) {
 
1170
        die("Savegame corrupt - map line %d not found.", y);
 
1171
      }
891
1172
      if (buffer2 == NULL) {
892
1173
        die("Savegame corrupt - map line %d not found.", y);
893
1174
      }
894
1175
      for (x = 0; x < map.xsize; x++) {
 
1176
        char token1[TOKEN_SIZE];
895
1177
        char token2[TOKEN_SIZE];
896
1178
        int number;
897
1179
        struct tile *ptile = native_pos_to_tile(x, y);
898
1180
 
 
1181
        scanin(&ptr1, ",", token1, sizeof(token1));
899
1182
        scanin(&ptr2, ",", token2, sizeof(token2));
900
 
        if (token2[0] == '\0') {
 
1183
        if (token1[0] == '\0' || token2[0] == '\0') {
901
1184
          die("Savegame corrupt - map size not correct.");
902
1185
        }
 
1186
        if (strcmp(token1, "-") == 0) {
 
1187
          owner = NULL;
 
1188
        } else {
 
1189
          if (sscanf(token1, "%d", &number)) {
 
1190
            owner = player_by_number(number);
 
1191
          } else {
 
1192
            die("Savegame corrupt - got map owner %s in (%d, %d).", 
 
1193
                token1, x, y);
 
1194
          }
 
1195
        }
903
1196
        if (strcmp(token2, "-") == 0) {
904
 
          ptile->owner_source = NULL;
 
1197
          claimer = NULL;
905
1198
        } else {
906
1199
          if (sscanf(token2, "%d", &number)) {
907
 
            ptile->owner_source = index_to_tile(number);
 
1200
            claimer = index_to_tile(number);
908
1201
          } else {
909
1202
            die("Savegame corrupt - got map source %s in (%d, %d).", 
910
1203
                token2, x, y);
911
1204
          }
912
1205
        }
 
1206
 
 
1207
        map_claim_ownership(ptile, owner, claimer);
913
1208
      }
914
1209
    }
915
1210
  }
916
1211
 
 
1212
  if (has_capability("bases", savefile_options)) {
 
1213
    char zeroline[map.xsize+1];
 
1214
    int i;
 
1215
 
 
1216
    /* This is needed when new bases has been added to ruleset, and                              
 
1217
     * thus game.control.num_base_types is greater than, when game was saved. */
 
1218
    for (i = 0; i < map.xsize; i++) {
 
1219
      zeroline[i] = '0';
 
1220
    }
 
1221
    zeroline[i] = '\0';
 
1222
 
 
1223
    bases_halfbyte_iterate(j, num_bases_types) {
 
1224
      char buf[16]; /* enough for sprintf() below */
 
1225
      sprintf(buf, "map.b%02d_%%03d", j);
 
1226
 
 
1227
      LOAD_MAP_DATA(ch, nat_y, ptile,
 
1228
                    secfile_lookup_str_default(file, zeroline, buf, nat_y),
 
1229
                    set_savegame_bases(&ptile->bases, ch, base_order + 4 * j));
 
1230
    } bases_halfbyte_iterate_end;
 
1231
  }
 
1232
 
917
1233
  if (secfile_lookup_bool_default(file, TRUE, "game.save_known")) {
918
1234
    int known[MAP_INDEX_SIZE];
919
1235
 
920
1236
    /* get 4-bit segments of the first half of the 32-bit "known" field */
921
1237
    LOAD_MAP_DATA(ch, nat_y, ptile,
922
1238
                  secfile_lookup_str(file, "map.a%03d", nat_y),
923
 
                  known[ptile->index] = ascii_hex2bin(ch, 0));
 
1239
                  known[tile_index(ptile)] = ascii_hex2bin(ch, 0));
924
1240
    LOAD_MAP_DATA(ch, nat_y, ptile,
925
1241
                  secfile_lookup_str(file, "map.b%03d", nat_y),
926
 
                  known[ptile->index] |= ascii_hex2bin(ch, 1));
 
1242
                  known[tile_index(ptile)] |= ascii_hex2bin(ch, 1));
927
1243
    LOAD_MAP_DATA(ch, nat_y, ptile,
928
1244
                  secfile_lookup_str(file, "map.c%03d", nat_y),
929
 
                  known[ptile->index] |= ascii_hex2bin(ch, 2));
 
1245
                  known[tile_index(ptile)] |= ascii_hex2bin(ch, 2));
930
1246
    LOAD_MAP_DATA(ch, nat_y, ptile,
931
1247
                  secfile_lookup_str(file, "map.d%03d", nat_y),
932
 
                  known[ptile->index] |= ascii_hex2bin(ch, 3));
 
1248
                  known[tile_index(ptile)] |= ascii_hex2bin(ch, 3));
933
1249
 
934
1250
    if (has_capability("known32fix", savefile_options)) {
935
1251
      /* get 4-bit segments of the second half of the 32-bit "known" field */
936
1252
      LOAD_MAP_DATA(ch, nat_y, ptile,
937
1253
                    secfile_lookup_str(file, "map.e%03d", nat_y),
938
 
                    known[ptile->index] |= ascii_hex2bin(ch, 4));
 
1254
                    known[tile_index(ptile)] |= ascii_hex2bin(ch, 4));
939
1255
      LOAD_MAP_DATA(ch, nat_y, ptile,
940
1256
                    secfile_lookup_str(file, "map.g%03d", nat_y),
941
 
                    known[ptile->index] |= ascii_hex2bin(ch, 5));
 
1257
                    known[tile_index(ptile)] |= ascii_hex2bin(ch, 5));
942
1258
      LOAD_MAP_DATA(ch, nat_y, ptile,
943
1259
                    secfile_lookup_str(file, "map.h%03d", nat_y),
944
 
                    known[ptile->index] |= ascii_hex2bin(ch, 6));
 
1260
                    known[tile_index(ptile)] |= ascii_hex2bin(ch, 6));
945
1261
      LOAD_MAP_DATA(ch, nat_y, ptile,
946
1262
                    secfile_lookup_str(file, "map.i%03d", nat_y),
947
 
                    known[ptile->index] |= ascii_hex2bin(ch, 7));
 
1263
                    known[tile_index(ptile)] |= ascii_hex2bin(ch, 7));
948
1264
    }
949
1265
 
950
1266
    /* HACK: we read the known data from hex into a 32-bit integer, and
951
1267
     * now we convert it to bv_player. */
952
1268
    whole_map_iterate(ptile) {
953
1269
      BV_CLR_ALL(ptile->tile_known);
954
 
      players_iterate(pplayer) {
955
 
        if (known[ptile->index] & (1u << pplayer->player_no)) {
956
 
          BV_SET(ptile->tile_known, pplayer->player_no);
957
 
        }
958
 
      } players_iterate_end;
 
1270
      player_slots_iterate(pslot) {
 
1271
        if (known[tile_index(ptile)] & (1u << player_index(pslot))) {
 
1272
          map_set_known(ptile, pslot);
 
1273
        }
 
1274
      } player_slots_iterate_end;
959
1275
    } whole_map_iterate_end;
960
1276
  }
961
 
 
962
 
 
963
 
  map.have_resources = TRUE;
 
1277
  map.server.have_resources = TRUE;
964
1278
}
965
1279
 
966
1280
/***************************************************************
974
1288
   * are now always saved in game_save()
975
1289
   */
976
1290
 
977
 
  /* Old freecivs expect map.is_earth to be present in the savegame. */
978
 
  secfile_insert_bool(file, FALSE, "map.is_earth");
979
 
 
980
 
  secfile_insert_bool(file, game.save_options.save_starts, "game.save_starts");
981
 
  if (game.save_options.save_starts) {
982
 
    for (i=0; i<map.num_start_positions; i++) {
983
 
      struct tile *ptile = map.start_positions[i].tile;
984
 
 
985
 
      secfile_insert_int(file, ptile->nat_x, "map.r%dsx", i);
986
 
      secfile_insert_int(file, ptile->nat_y, "map.r%dsy", i);
987
 
 
988
 
      if (map.start_positions[i].nation != NO_NATION_SELECTED) {
989
 
        secfile_insert_str(file, nation_rule_name(map.start_positions[i].nation),
990
 
                           "map.r%dsnation", i);
 
1291
  secfile_insert_bool(file, game.server.save_options.save_starts,
 
1292
                      "game.save_starts");
 
1293
  if (game.server.save_options.save_starts) {
 
1294
    if (map_startpositions_set()) {
 
1295
      /* Save starting positions from editor */
 
1296
      int i = 0;
 
1297
 
 
1298
      whole_map_iterate(ptile) {
 
1299
        if (map_has_startpos(ptile)) {
 
1300
          const struct nation_type *pnat = map_get_startpos(ptile);
 
1301
 
 
1302
          secfile_insert_int(file, ptile->nat_x, "map.r%dsx", i);
 
1303
          secfile_insert_int(file, ptile->nat_y, "map.r%dsy", i);
 
1304
          if (pnat != NULL) {
 
1305
            secfile_insert_str(file, nation_rule_name(pnat),
 
1306
                               "map.r%dsnation", i);
 
1307
          }
 
1308
          i++;
 
1309
        }
 
1310
      } whole_map_iterate_end;
 
1311
    } else {
 
1312
      /* Save starting positions generated by mapgenerator */
 
1313
      for (i = 0; i < map.server.num_start_positions; i++) {
 
1314
        struct tile *ptile = map.server.start_positions[i].tile;
 
1315
 
 
1316
        secfile_insert_int(file, ptile->nat_x, "map.r%dsx", i);
 
1317
        secfile_insert_int(file, ptile->nat_y, "map.r%dsy", i);
 
1318
 
 
1319
        if (map.server.start_positions[i].nation != NO_NATION_SELECTED) {
 
1320
          secfile_insert_str(file, nation_rule_name(map.server.start_positions[i].nation),
 
1321
                             "map.r%dsnation", i);
 
1322
        }
991
1323
      }
992
1324
    }
993
1325
  }
995
1327
  whole_map_iterate(ptile) {
996
1328
    if (ptile->spec_sprite) {
997
1329
      secfile_insert_str(file, ptile->spec_sprite, "map.spec_sprite_%d_%d",
998
 
                         ptile->nat_x, ptile->nat_y);
 
1330
                         ptile->nat_x, ptile->nat_y);
999
1331
    }
1000
1332
  } whole_map_iterate_end;
1001
1333
    
1003
1335
  SAVE_NORMAL_MAP_DATA(ptile, file, "map.t%03d",
1004
1336
                       terrain2char(ptile->terrain));
1005
1337
 
1006
 
  if (!map.have_resources) {
1007
 
    if (map.have_rivers_overlay) {
 
1338
  if (!map.server.have_resources) {
 
1339
    if (map.server.have_rivers_overlay) {
1008
1340
      /* 
1009
1341
       * Save the rivers overlay map; this is a special case to allow
1010
1342
       * re-saving scenarios which have rivers overlay data.  This only
1042
1374
                         get_savegame_special(ptile->special, mod));
1043
1375
  } special_halfbyte_iterate_end;
1044
1376
 
 
1377
  bases_halfbyte_iterate(j, game.control.num_base_types) {
 
1378
    char buf[16]; /* enough for sprintf() below */
 
1379
    int mod[4];
 
1380
    int l;
 
1381
 
 
1382
    for (l = 0; l < 4; l++) {
 
1383
      if (4 * j + 1 > game.control.num_base_types) {
 
1384
        mod[l] = -1;
 
1385
      } else {
 
1386
        mod[l] = 4 * j + l;
 
1387
      }
 
1388
    }
 
1389
    sprintf (buf, "map.b%02d_%%03d", j);
 
1390
    SAVE_NORMAL_MAP_DATA(ptile, file, buf,
 
1391
                         get_savegame_bases(ptile->bases, mod));
 
1392
  } bases_halfbyte_iterate_end;
 
1393
 
1045
1394
  /* Store owner and ownership source as plain numbers */
1046
1395
  {
1047
1396
    int x, y;
1057
1406
        if (tile_owner(ptile) == NULL) {
1058
1407
          strcpy(token, "-");
1059
1408
        } else {
1060
 
          my_snprintf(token, sizeof(token), "%d", tile_owner(ptile)->player_no);
 
1409
          my_snprintf(token, sizeof(token), "%d", player_number(tile_owner(ptile)));
1061
1410
        }
1062
1411
        strcat(line, token);
1063
1412
        if (x + 1 < map.xsize) {
1074
1423
        char token[TOKEN_SIZE];
1075
1424
        struct tile *ptile = native_pos_to_tile(x, y);
1076
1425
 
1077
 
        if (ptile->owner_source == NULL) {
 
1426
        if (ptile->claimer == NULL) {
1078
1427
          strcpy(token, "-");
1079
1428
        } else {
1080
 
          my_snprintf(token, sizeof(token), "%d", ptile->owner_source->index);
 
1429
          my_snprintf(token, sizeof(token), "%d", tile_index(ptile->claimer));
1081
1430
        }
1082
1431
        strcat(line, token);
1083
1432
        if (x + 1 < map.xsize) {
1088
1437
    }
1089
1438
  }
1090
1439
 
1091
 
  secfile_insert_bool(file, game.save_options.save_known, "game.save_known");
1092
 
  if (game.save_options.save_known) {
 
1440
  secfile_insert_bool(file, game.server.save_options.save_known,
 
1441
                      "game.save_known");
 
1442
  if (game.server.save_options.save_known) {
1093
1443
    int known[MAP_INDEX_SIZE];
1094
1444
 
1095
1445
    /* HACK: we convert the data into a 32-bit integer, and then save it as
1098
1448
    whole_map_iterate(ptile) {
1099
1449
      players_iterate(pplayer) {
1100
1450
        if (map_is_known(ptile, pplayer)) {
1101
 
          known[ptile->index] |= (1u << pplayer->player_no);
 
1451
          known[tile_index(ptile)] |= (1u << player_index(pplayer));
1102
1452
        }
1103
1453
      } players_iterate_end;
1104
1454
    } whole_map_iterate_end;
1105
1455
 
1106
1456
    /* put 4-bit segments of the 32-bit "known" field */
1107
1457
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.a%03d",
1108
 
                         bin2ascii_hex(known[ptile->index], 0));
 
1458
                         bin2ascii_hex(known[tile_index(ptile)], 0));
1109
1459
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.b%03d",
1110
 
                         bin2ascii_hex(known[ptile->index], 1));
 
1460
                         bin2ascii_hex(known[tile_index(ptile)], 1));
1111
1461
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.c%03d",
1112
 
                         bin2ascii_hex(known[ptile->index], 2));
 
1462
                         bin2ascii_hex(known[tile_index(ptile)], 2));
1113
1463
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.d%03d",
1114
 
                         bin2ascii_hex(known[ptile->index], 3));
 
1464
                         bin2ascii_hex(known[tile_index(ptile)], 3));
1115
1465
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.e%03d",
1116
 
                         bin2ascii_hex(known[ptile->index], 4));
 
1466
                         bin2ascii_hex(known[tile_index(ptile)], 4));
1117
1467
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.g%03d",
1118
 
                         bin2ascii_hex(known[ptile->index], 5));
 
1468
                         bin2ascii_hex(known[tile_index(ptile)], 5));
1119
1469
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.h%03d",
1120
 
                         bin2ascii_hex(known[ptile->index], 6));
 
1470
                         bin2ascii_hex(known[tile_index(ptile)], 6));
1121
1471
    SAVE_NORMAL_MAP_DATA(ptile, file, "map.i%03d",
1122
 
                         bin2ascii_hex(known[ptile->index], 7));
 
1472
                         bin2ascii_hex(known[tile_index(ptile)], 7));
1123
1473
  }
1124
1474
}
1125
1475
 
1131
1481
 * backwards compatibility we have here a list of unit names from before
1132
1482
 * the change was made.  When loading an old savegame (one that doesn't
1133
1483
 * have the type string) we need to lookup the type into this array
1134
 
 * to get the "proper" type string.  And when saving a new savegame we
1135
 
 * insert the "old" type index into the array so that old servers can
1136
 
 * load the savegame.
 
1484
 * to get the "proper" type string.
1137
1485
 *
1138
1486
 * Note that this list includes the AWACS, which was not in 1.14.1.
1139
1487
 */
1258
1606
};
1259
1607
 
1260
1608
/****************************************************************************
1261
 
  Nowadays unit types are saved by name, but old servers need the
1262
 
  unit_type_id.  This function tries to find the correct _old_ id for the
1263
 
  unit's type.  It is used when the unit is saved.
1264
 
****************************************************************************/
1265
 
static Unit_type_id old_unit_type_id(const struct unit_type *type)
1266
 
{
1267
 
  const char** types;
1268
 
  int num_types, i;
1269
 
 
1270
 
  if (strcmp(game.rulesetdir, "civ1") == 0) {
1271
 
    types = old_civ1_unit_types;
1272
 
    num_types = ARRAY_SIZE(old_civ1_unit_types);
1273
 
  } else {
1274
 
    types = old_default_unit_types;
1275
 
    num_types = ARRAY_SIZE(old_default_unit_types);
1276
 
  }
1277
 
 
1278
 
  for (i = 0; i < num_types; i++) {
1279
 
    if (mystrcasecmp(utype_rule_name(type), types[i]) == 0) {
1280
 
      return i;
1281
 
    }
1282
 
  }
1283
 
 
1284
 
  /* It's a new unit. Savegame cannot be forward compatible so we can
1285
 
   * return anything */
1286
 
  return type->index;
1287
 
}
1288
 
 
1289
 
/****************************************************************************
1290
1609
  Convert an old-style unit type id into a unit type name.
1291
1610
****************************************************************************/
1292
1611
static const char* old_unit_type_name(int id)
1293
1612
{
1294
1613
  /* before 1.15.0 unit types used to be saved by id */
1295
1614
  if (id < 0) {
1296
 
    freelog(LOG_FATAL, "Wrong unit type id value (%d)", id);
1297
 
    exit(EXIT_FAILURE);
 
1615
    return NULL;
1298
1616
  }
1299
1617
  /* Different rulesets had different unit names. */
1300
 
  if (strcmp(game.rulesetdir, "civ1") == 0) {
 
1618
  if (strcmp(game.server.rulesetdir, "civ1") == 0) {
1301
1619
    if (id >= ARRAY_SIZE(old_civ1_unit_types)) {
1302
 
      freelog(LOG_FATAL, "Wrong unit type id value (%d)", id);
1303
 
      exit(EXIT_FAILURE);
 
1620
      return NULL;
1304
1621
    }
1305
1622
    return old_civ1_unit_types[id];
1306
1623
  } else {
1307
1624
    if (id >= ARRAY_SIZE(old_default_unit_types)) {
1308
 
      freelog(LOG_FATAL, "Wrong unit type id value (%d)", id);
1309
 
      exit(EXIT_FAILURE);
 
1625
      return NULL;
1310
1626
    }
1311
1627
    return old_default_unit_types[id];
1312
1628
  }
1313
1629
}
1314
1630
 
1315
 
/****************************************************************************
1316
 
  Nowadays improvement types are saved by name, but old servers need the
1317
 
  Impr_type_id.  This function tries to find the correct _old_ id for the
1318
 
  improvements's type.  It is used when the improvement is saved.
1319
 
****************************************************************************/
1320
 
static int old_impr_type_id(Impr_type_id type)
1321
 
{
1322
 
  int i;
1323
 
 
1324
 
  for (i = 0; i < ARRAY_SIZE(old_impr_types); i++) {
1325
 
    if (mystrcasecmp(improvement_rule_name(type),
1326
 
                     old_impr_types[i]) == 0) {
1327
 
      return i;
1328
 
    }
1329
 
  }
1330
 
 
1331
 
  /* It's a new improvement. Savegame cannot be forward compatible so we can
1332
 
   * return anything */
1333
 
  return type;
1334
 
}
1335
 
 
1336
1631
/***************************************************************
1337
1632
  Convert old-style improvement type id into improvement type name
1338
1633
***************************************************************/
1340
1635
{
1341
1636
  /* before 1.15.0 improvement types used to be saved by id */
1342
1637
  if (id < 0 || id >= ARRAY_SIZE(old_impr_types)) {
1343
 
    freelog(LOG_FATAL, "Wrong improvement type id value (%d)", id);
1344
 
    exit(EXIT_FAILURE);
 
1638
    return NULL;
1345
1639
  }
1346
1640
  return old_impr_types[id];
1347
1641
}
1361
1655
}
1362
1656
 
1363
1657
/****************************************************************************
1364
 
  Insert improvement into old-style bitvector
1365
 
 
1366
 
  Improvement lists in cities and destroyed_wonders are saved as a
1367
 
  bitvector in a string array.  New bitvectors do not depend on ruleset
1368
 
  order. However, we want to create savegames which can be read by 
1369
 
  1.14.x and earlier servers.  This function adds an improvement into the
1370
 
  bitvector string according to the 1.14.1 improvement ordering.
1371
 
****************************************************************************/
1372
 
static void add_improvement_into_old_bitvector(char* bitvector,
1373
 
                                               Impr_type_id id)
1374
 
{
1375
 
  int old_id;
1376
 
 
1377
 
  old_id = old_impr_type_id(id);
1378
 
  if (old_id < 0 || old_id >= ARRAY_SIZE(old_impr_types)) {
1379
 
    return;
1380
 
  }
1381
 
  bitvector[old_id] = '1';
1382
 
}
1383
 
 
1384
 
/****************************************************************************
1385
 
  Nowadays techs are saved by name, but old servers need numbers
1386
 
  This function tries to find the correct _old_ id for the
1387
 
  technology. It is used when the technology is saved.
1388
 
****************************************************************************/
1389
 
static int old_tech_id(Tech_type_id tech)
1390
 
{
1391
 
  const char* technology_name;
1392
 
  int i;
1393
 
  
1394
 
  /* old (1.14.1) servers used to save it as 0 and interpret it from context */
1395
 
  if (is_future_tech(tech)) {
1396
 
    return 0;
1397
 
  }
1398
 
 
1399
 
  /* old (1.14.1) servers used to save it as 0 and interpret it from context */  
1400
 
  if (tech == A_UNSET) {
1401
 
    return 0;
1402
 
  }
1403
 
  
1404
 
  technology_name = advance_rule_name(tech);
1405
 
  
1406
 
  /* this is the only place where civ1 was different from 1.14.1 defaults */
1407
 
  if (strcmp(game.rulesetdir, "civ1") == 0
1408
 
      && mystrcasecmp(technology_name, "Religion") == 0) {
1409
 
    return 83;
1410
 
  }
1411
 
  
1412
 
  for (i = 0; i < ARRAY_SIZE(old_default_techs); i++) {
1413
 
    if (mystrcasecmp(technology_name, old_default_techs[i]) == 0) {
1414
 
      return i;
1415
 
    }
1416
 
  }
1417
 
  
1418
 
  /* It's a new technology. Savegame cannot be forward compatible so we can
1419
 
   * return anything */
1420
 
  return tech;
1421
 
}
1422
 
 
1423
 
/****************************************************************************
1424
1658
  Convert an old-style technology id into a tech name.
 
1659
  Caller uses -1 to indicate missing value.
1425
1660
****************************************************************************/
1426
1661
static const char* old_tech_name(int id)
1427
1662
{
 
1663
  /* Longstanding value (through 2.1) for A_LAST at 200,
 
1664
   * and A_UNSET at 199 */
 
1665
  if (id == -1 || id >= 199) {
 
1666
    return "A_UNSET";
 
1667
  }
 
1668
 
1428
1669
  /* This was 1.14.1 value for A_FUTURE */
1429
1670
  if (id == 198) {
1430
1671
    return "A_FUTURE";
1431
1672
  }
1432
1673
  
1433
 
  if (id == -1 || id == 0) {
 
1674
  if (id == 0) {
1434
1675
    return "A_NONE";
1435
1676
  }
1436
1677
  
1437
 
  if (id == A_UNSET) {
1438
 
    return "A_UNSET";
1439
 
  }
1440
 
 
1441
1678
  if (id < 0 || id >= ARRAY_SIZE(old_default_techs)) {
1442
 
    freelog(LOG_FATAL, "Wrong tech type id value (%d)", id);
1443
 
    exit(EXIT_FAILURE);
 
1679
    return NULL;
1444
1680
  }
1445
1681
 
1446
 
  if (strcmp(game.rulesetdir, "civ1") == 0 && id == 83) {
 
1682
  if (strcmp(game.server.rulesetdir, "civ1") == 0 && id == 83) {
1447
1683
    return "Religion";
1448
1684
  }
1449
1685
  
1464
1700
  bitvector[ARRAY_SIZE(old_default_techs)] = '\0';
1465
1701
}
1466
1702
 
1467
 
/****************************************************************************
1468
 
  Insert technology into old-style bitvector
1469
 
 
1470
 
  New bitvectors do not depend on ruleset order. However, we want to create
1471
 
  savegames which can be read by 1.14.x and earlier servers. 
1472
 
  This function adds a technology into the bitvector string according
1473
 
  to the 1.14.1 technology ordering.
1474
 
****************************************************************************/
1475
 
static void add_technology_into_old_bitvector(char* bitvector,
1476
 
                                              Tech_type_id id)
1477
 
{
1478
 
  int old_id;
1479
 
 
1480
 
  old_id = old_tech_id(id);
1481
 
  if (old_id < 0 || old_id >= ARRAY_SIZE(old_default_techs)) {
1482
 
    return;
1483
 
  }
1484
 
  bitvector[old_id] = '1';
1485
 
}
1486
 
 
1487
1703
 
1488
1704
/*****************************************************************************
1489
1705
  Load technology from path_name and if doesn't exist (because savegame
1490
1706
  is too old) load from path.
1491
1707
*****************************************************************************/
1492
 
static Tech_type_id load_technology(struct section_file *file,
 
1708
static Tech_type_id technology_load(struct section_file *file,
1493
1709
                                    const char* path, int plrno)
1494
1710
{
1495
1711
  char path_with_name[128];
1496
1712
  const char* name;
 
1713
  struct advance *padvance;
1497
1714
  int id;
1498
1715
  
1499
1716
  my_snprintf(path_with_name, sizeof(path_with_name), 
1500
1717
              "%s_name", path);
1501
 
              
 
1718
 
1502
1719
  name = secfile_lookup_str_default(file, NULL, path_with_name, plrno);
1503
1720
  if (!name) {
1504
1721
    id = secfile_lookup_int_default(file, -1, path, plrno);
1505
1722
    name = old_tech_name(id);
 
1723
    if (!name) {
 
1724
      freelog(LOG_FATAL, "%s: value (%d) out of range.",
 
1725
              path, id);
 
1726
      exit(EXIT_FAILURE);
 
1727
    }
1506
1728
  }
1507
 
  
 
1729
 
1508
1730
  if (mystrcasecmp(name, "A_FUTURE") == 0) {
1509
1731
    return A_FUTURE;
1510
1732
  }
1515
1737
    return A_UNSET;
1516
1738
  }
1517
1739
  if (name[0] == '\0') {
1518
 
    /* it is used by changed_from */
1519
 
    return -1;
 
1740
    /* used by researching_saved */
 
1741
    return A_UNKNOWN;
1520
1742
  }
1521
 
  
1522
 
  id = find_advance_by_rule_name(name);
1523
 
  if (id == A_LAST) {
1524
 
    freelog(LOG_FATAL, "Unknown technology \"%s\".", name);
 
1743
 
 
1744
  padvance = find_advance_by_rule_name(name);
 
1745
  if (NULL == padvance) {
 
1746
    freelog(LOG_FATAL, "%s: unknown technology \"%s\".",
 
1747
            path_with_name, name);
1525
1748
    exit(EXIT_FAILURE);    
1526
1749
  }
1527
 
  return id;
 
1750
  return advance_number(padvance);
1528
1751
}
1529
1752
 
1530
1753
/*****************************************************************************
1531
 
  Save technology in secfile entry called path_name and for forward
1532
 
  compatibility in path(by number).
 
1754
  Save technology in secfile entry called path_name.
1533
1755
*****************************************************************************/
1534
 
static void save_technology(struct section_file *file,
 
1756
static void technology_save(struct section_file *file,
1535
1757
                            const char* path, int plrno, Tech_type_id tech)
1536
1758
{
1537
1759
  char path_with_name[128];
1541
1763
              "%s_name", path);
1542
1764
  
1543
1765
  switch (tech) {
1544
 
    case -1: /* used in changed_from */
 
1766
    case A_UNKNOWN: /* used by researching_saved */
1545
1767
       name = "";
1546
1768
       break;
1547
1769
    case A_NONE:
1554
1776
      name = "A_FUTURE";
1555
1777
      break;
1556
1778
    default:
1557
 
      name = advance_rule_name(tech);
 
1779
      name = advance_rule_name(advance_by_number(tech));
1558
1780
      break;
1559
1781
  }
1560
1782
  secfile_insert_str(file, name, path_with_name, plrno);
1561
 
  secfile_insert_int(file, old_tech_id(tech), path, plrno);
1562
 
}
1563
 
 
1564
 
/****************************************************************************
1565
 
  Nowadays governments are saved by name, but old servers need the
1566
 
  index.  This function tries to find the correct _old_ id for the
1567
 
  government. It is used when the government is saved.
1568
 
****************************************************************************/
1569
 
static int old_government_id(struct government *gov)
1570
 
{
1571
 
  const char** names;
1572
 
  int num_names, i;
1573
 
 
1574
 
  if (strcmp(game.rulesetdir, "civ2") == 0) {
1575
 
    names = old_civ2_governments;
1576
 
    num_names = ARRAY_SIZE(old_civ2_governments);
1577
 
  } else {
1578
 
    names = old_default_governments;
1579
 
    num_names = ARRAY_SIZE(old_default_governments);
1580
 
  }
1581
 
 
1582
 
  for (i = 0; i < num_names; i++) {
1583
 
    if (mystrcasecmp(government_rule_name(gov), names[i]) == 0) {
1584
 
      return i;
1585
 
    }
1586
 
  }
1587
 
 
1588
 
  /* It's a new government. Savegame cannot be forward compatible so we can
1589
 
   * return anything */
1590
 
  return gov->index;
1591
1783
}
1592
1784
 
1593
1785
/****************************************************************************
1601
1793
    exit(EXIT_FAILURE);
1602
1794
  }
1603
1795
  /* Different rulesets had different governments. */
1604
 
  if (strcmp(game.rulesetdir, "civ2") == 0) {
 
1796
  if (strcmp(game.server.rulesetdir, "civ2") == 0) {
1605
1797
    if (id >= ARRAY_SIZE(old_civ2_governments)) {
1606
1798
      freelog(LOG_FATAL, "Wrong government type id value (%d)", id);
1607
1799
      exit(EXIT_FAILURE);
1619
1811
/****************************************************************************
1620
1812
  Loads the units for the given player.
1621
1813
****************************************************************************/
1622
 
static void load_player_units(struct player *plr, int plrno,
1623
 
                              struct section_file *file)
 
1814
static void player_load_units(struct player *plr, int plrno,
 
1815
                              struct section_file *file,
 
1816
                              char *savefile_options,
 
1817
                              struct base_type **base_order,
 
1818
                              int num_base_types)
1624
1819
{
1625
1820
  int nunits, i, j;
1626
1821
  enum unit_activity activity;
1627
 
  char *savefile_options = secfile_lookup_str(file, "savefile.options");
1628
1822
 
1629
1823
  plr->units = unit_list_new();
1630
1824
  nunits = secfile_lookup_int(file, "player%d.nunits", plrno);
1638
1832
    int nat_x, nat_y;
1639
1833
    const char* type_name;
1640
1834
    struct unit_type *type;
1641
 
    
1642
 
    type_name = secfile_lookup_str_default(file, NULL, 
 
1835
    struct base_type *pbase = NULL;
 
1836
    int base;
 
1837
 
 
1838
    type_name = secfile_lookup_str_default(file, NULL,
1643
1839
                                           "player%d.u%d.type_by_name",
1644
 
                                           plrno, i);
 
1840
                                           plrno, i);
1645
1841
    if (!type_name) {
1646
1842
      /* before 1.15.0 unit types used to be saved by id. */
1647
 
      int t = secfile_lookup_int(file, "player%d.u%d.type",
1648
 
                             plrno, i);
1649
 
      if (t < 0) {
1650
 
        freelog(LOG_FATAL, "Wrong player%d.u%d.type value (%d)",
1651
 
                plrno, i, t);
1652
 
        exit(EXIT_FAILURE);
1653
 
      }
 
1843
      int t = secfile_lookup_int_default(file, -1,
 
1844
                                         "player%d.u%d.type",
 
1845
                                         plrno, i);
1654
1846
      type_name = old_unit_type_name(t);
1655
 
 
 
1847
      if (!type_name) {
 
1848
        freelog(LOG_FATAL, "player%d.u%d.type: unknown (%d)",
 
1849
                plrno, i, t);
 
1850
        exit(EXIT_FAILURE);
 
1851
      }
1656
1852
    }
1657
1853
    
1658
1854
    type = find_unit_type_by_rule_name(type_name);
1659
1855
    if (!type) {
1660
 
      freelog(LOG_FATAL, "Unknown unit type '%s' in player%d section",
1661
 
              type_name, plrno);
 
1856
      freelog(LOG_FATAL, "player%d.u%d: unknown unit type \"%s\".",
 
1857
              plrno, i, type_name);
1662
1858
      exit(EXIT_FAILURE);
1663
1859
    }
1664
1860
    
1665
1861
    punit = create_unit_virtual(plr, NULL, type,
1666
1862
        secfile_lookup_int(file, "player%d.u%d.veteran", plrno, i));
1667
1863
    punit->id = secfile_lookup_int(file, "player%d.u%d.id", plrno, i);
1668
 
    alloc_id(punit->id);
 
1864
    identity_number_reserve(punit->id);
1669
1865
    idex_register_unit(punit);
1670
1866
 
1671
1867
    nat_x = secfile_lookup_int(file, "player%d.u%d.x", plrno, i);
1672
1868
    nat_y = secfile_lookup_int(file, "player%d.u%d.y", plrno, i);
1673
1869
    punit->tile = native_pos_to_tile(nat_x, nat_y);
 
1870
    if (NULL == punit->tile) {
 
1871
      freelog(LOG_FATAL, "player%d.u%d invalid tile (%d,%d)",
 
1872
              plrno, i,
 
1873
              nat_x, nat_y);
 
1874
      exit(EXIT_FAILURE);
 
1875
    }
1674
1876
 
1675
1877
    /* Avoid warning when loading pre-2.1 saves containing foul status */
1676
1878
    secfile_lookup_bool_default(file, FALSE, "player%d.u%d.foul",
1681
1883
 
1682
1884
    if ((pcity = game_find_city_by_number(punit->homecity))) {
1683
1885
      unit_list_prepend(pcity->units_supported, punit);
 
1886
    } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
 
1887
      freelog(LOG_ERROR, "player%d.u%d: bad home city %d.",
 
1888
              plrno, i, punit->homecity);
 
1889
      punit->homecity = IDENTITY_NUMBER_ZERO;
1684
1890
    }
1685
 
    
 
1891
 
1686
1892
    punit->moves_left
1687
1893
      = secfile_lookup_int(file, "player%d.u%d.moves", plrno, i);
1688
1894
    punit->fuel = secfile_lookup_int(file, "player%d.u%d.fuel", plrno, i);
 
1895
    punit->birth_turn = secfile_lookup_int_default(file, game.info.turn,
 
1896
                                                   "player%d.u%d.born", plrno, i);
1689
1897
    activity = secfile_lookup_int(file, "player%d.u%d.activity", plrno, i);
 
1898
    base = secfile_lookup_int_default(file, -1,
 
1899
                                      "player%d.u%d.activity_base", plrno, i);
 
1900
 
1690
1901
    if (activity == ACTIVITY_PATROL_UNUSED) {
1691
1902
      /* Previously ACTIVITY_PATROL and ACTIVITY_GOTO were used for
1692
1903
       * client-side goto.  Now client-side goto is handled by setting
1697
1908
       * into idle mode. */
1698
1909
      activity = ACTIVITY_IDLE;
1699
1910
    }
1700
 
    set_unit_activity(punit, activity);
 
1911
 
 
1912
    if (activity == ACTIVITY_FORTRESS) {
 
1913
      pbase = get_base_by_gui_type(BASE_GUI_FORTRESS, punit, punit->tile);
 
1914
    } else if (activity == ACTIVITY_AIRBASE) {
 
1915
      pbase = get_base_by_gui_type(BASE_GUI_AIRBASE, punit, punit->tile);
 
1916
    } else if (activity == ACTIVITY_BASE) {
 
1917
      if (base >= 0 && base < num_base_types) {
 
1918
        pbase = base_order[base];
 
1919
      } else {
 
1920
        freelog(LOG_ERROR, "Cannot find base %d for %s to build",
 
1921
                base, unit_rule_name(punit));
 
1922
        set_unit_activity(punit, ACTIVITY_IDLE);
 
1923
      }
 
1924
    } else {
 
1925
      set_unit_activity(punit, activity);
 
1926
    }
 
1927
 
 
1928
    if (pbase) {
 
1929
      set_unit_activity_base(punit, base_number(pbase));
 
1930
    }
1701
1931
 
1702
1932
    /* need to do this to assign/deassign settlers correctly -- Syela
1703
1933
     *
1710
1940
      = secfile_lookup_int_default(file, S_LAST,
1711
1941
                                   "player%d.u%d.activity_target", plrno, i);
1712
1942
 
 
1943
    if (activity == ACTIVITY_PILLAGE) {
 
1944
      struct base_type *pbase = NULL;
 
1945
 
 
1946
      if (punit->activity_target == S_OLD_FORTRESS) {
 
1947
        punit->activity_target = S_LAST;
 
1948
        pbase = find_base_type_by_rule_name("Fortress");
 
1949
      } else if (punit->activity_target == S_OLD_AIRBASE) {
 
1950
        punit->activity_target = S_LAST;
 
1951
        pbase = find_base_type_by_rule_name("Airbase");
 
1952
      }
 
1953
 
 
1954
      if (pbase != NULL) {
 
1955
        punit->activity_base = base_index(pbase);
 
1956
      } else {
 
1957
        punit->activity_base = -1;
 
1958
      }
 
1959
    }
 
1960
 
1713
1961
    punit->done_moving = secfile_lookup_bool_default(file,
1714
1962
        (punit->moves_left == 0), "player%d.u%d.done_moving", plrno, i);
1715
1963
 
1763
2011
       otherwise these don't get initialized (and AI calculations
1764
2012
       etc may use junk values).
1765
2013
    */
 
2014
    output_type_iterate(o) {
 
2015
      punit->upkeep[o] = utype_upkeep_cost(type, plr, o);
 
2016
    } output_type_iterate_end;
1766
2017
 
1767
2018
    /* load the unit orders */
1768
2019
    if (has_capability("orders", savefile_options)) {
1769
2020
      int len = secfile_lookup_int_default(file, 0,
1770
2021
                        "player%d.u%d.orders_length", plrno, i);
1771
2022
      if (len > 0) {
1772
 
        char *orders_buf, *dir_buf, *act_buf;
 
2023
        char *orders_buf, *dir_buf, *act_buf, *base_buf;
1773
2024
 
1774
2025
        punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
1775
2026
        punit->orders.length = len;
1786
2037
                        "player%d.u%d.dir_list", plrno, i);
1787
2038
        act_buf = secfile_lookup_str_default(file, "",
1788
2039
                        "player%d.u%d.activity_list", plrno, i);
 
2040
        base_buf = secfile_lookup_str_default(file, NULL,
 
2041
                                             "player%d.u%d.base_list", plrno, i);
1789
2042
        punit->has_orders = TRUE;
1790
2043
        for (j = 0; j < len; j++) {
1791
2044
          struct unit_order *order = &punit->orders.list[j];
 
2045
          struct base_type *pbase = NULL;
1792
2046
 
1793
2047
          if (orders_buf[j] == '\0' || dir_buf[j] == '\0'
1794
2048
              || act_buf[j] == '\0') {
1809
2063
            punit->has_orders = FALSE;
1810
2064
            break;
1811
2065
          }
 
2066
 
 
2067
          /* Pre 2.2 savegames had activities ACTIVITY_FORTRESS and ACTIVITY_AIRBASE */
 
2068
          if (order->activity == ACTIVITY_FORTRESS) {
 
2069
            pbase = get_base_by_gui_type(BASE_GUI_FORTRESS, NULL, NULL);
 
2070
            order->activity = ACTIVITY_IDLE; /* In case no matching gui_type found */
 
2071
          } else if (order->activity == ACTIVITY_AIRBASE) {
 
2072
            pbase = get_base_by_gui_type(BASE_GUI_AIRBASE, NULL, NULL);
 
2073
            order->activity = ACTIVITY_IDLE; /* In case no matching gui_type found */
 
2074
          }
 
2075
          if (pbase) {
 
2076
            /* Either ACTIVITY_FORTRESS or ACTIVITY_AIRBASE */
 
2077
            order->activity = ACTIVITY_BASE;
 
2078
            order->base = base_number(pbase);
 
2079
          } else if (base_buf && base_buf[j] != '?') {
 
2080
            base = char2num(base_buf[j]);
 
2081
 
 
2082
            if (base >= 0 && base < num_base_types) {
 
2083
              pbase = base_order[base];
 
2084
            } else {
 
2085
              freelog(LOG_ERROR, "Cannot find base %d for %s to build",
 
2086
                      base, unit_rule_name(punit));
 
2087
              base = base_number(get_base_by_gui_type(BASE_GUI_FORTRESS, NULL, NULL));
 
2088
            }
 
2089
 
 
2090
            order->base = base;
 
2091
          }
1812
2092
        }
1813
2093
      } else {
1814
2094
        punit->has_orders = FALSE;
1821
2101
    }
1822
2102
 
1823
2103
    /* allocate the unit's contribution to fog of war */
1824
 
    punit->server.vision = vision_new(unit_owner(punit), punit->tile, TRUE);
 
2104
    punit->server.vision = vision_new(unit_owner(punit), punit->tile);
1825
2105
    unit_refresh_vision(punit);
1826
2106
    /* NOTE: There used to be some map_set_known calls here.  These were
1827
2107
     * unneeded since unfogging the tile when the unit sees it will
1830
2110
    unit_list_append(plr->units, punit);
1831
2111
 
1832
2112
    unit_list_prepend(punit->tile->units, punit);
 
2113
 
 
2114
    /* Claim ownership of fortress? */
 
2115
    if (tile_has_claimable_base(punit->tile, unit_type(punit))
 
2116
        && (!tile_owner(punit->tile)
 
2117
            || (tile_owner(punit->tile)
 
2118
                && pplayers_at_war(tile_owner(punit->tile), plr)))) {
 
2119
      map_claim_ownership(punit->tile, plr, punit->tile);
 
2120
      map_claim_border(punit->tile, plr);
 
2121
      /* city_thaw_workers_queue() later */
 
2122
      /* city_refresh() later */
 
2123
    }
1833
2124
  }
1834
2125
}
1835
2126
 
1837
2128
  Load all information about player "plrno" into the structure pointed to
1838
2129
  by "plr".
1839
2130
****************************************************************************/
1840
 
static void player_load(struct player *plr, int plrno,
1841
 
                        struct section_file *file,
1842
 
                        char** improvement_order,
1843
 
                        int improvement_order_size,
1844
 
                        char** technology_order,
1845
 
                        int technology_order_size)
 
2131
static void player_load_main(struct player *plr, int plrno,
 
2132
                             struct section_file *file,
 
2133
                             char *savefile_options,
 
2134
                             char **technology_order,
 
2135
                             int technology_order_size)
1846
2136
{
1847
 
  int i, j, k, x, y, ncities, c_s;
 
2137
  int i, k, c_s;
1848
2138
  const char *p;
1849
2139
  const char *name;
1850
 
  char *savefile_options = secfile_lookup_str(file, "savefile.options");
1851
2140
  struct ai_data *ai;
1852
2141
  struct government *gov;
1853
2142
  int id;
1855
2144
  struct player_research *research;
1856
2145
  struct nation_type *pnation;
1857
2146
 
1858
 
  /* not all players have teams */
 
2147
  /* All players should now have teams. This is not the case with
 
2148
   * old savegames. */
1859
2149
  id = secfile_lookup_int_default(file, -1, "player%d.team_no", plrno);
1860
 
  pteam = team_get_by_id(id);
 
2150
  pteam = team_by_number(id);
1861
2151
  if (pteam == NULL) {
1862
2152
    pteam = find_empty_team();
1863
2153
  }
1864
 
  
 
2154
 
1865
2155
  team_add_player(plr, pteam);
1866
 
  
 
2156
 
1867
2157
  research = get_player_research(plr);
1868
2158
 
1869
 
  server_player_init(plr, TRUE, FALSE);
1870
2159
  ai = ai_data_get(plr);
1871
2160
 
1872
 
  plr->ai.barbarian_type = secfile_lookup_int_default(file, 0, "player%d.ai.is_barbarian",
 
2161
  plr->ai_data.barbarian_type = secfile_lookup_int_default(file, 0,
 
2162
                                                    "player%d.ai.is_barbarian",
1873
2163
                                                    plrno);
1874
 
  if (is_barbarian(plr)) game.info.nbarbarians++;
 
2164
  if (is_barbarian(plr)) {
 
2165
    server.nbarbarians++;
 
2166
  }
1875
2167
 
1876
2168
  sz_strlcpy(plr->name, secfile_lookup_str(file, "player%d.name", plrno));
1877
2169
  sz_strlcpy(plr->username,
1913
2205
  pnation = find_nation_by_rule_name(p);
1914
2206
 
1915
2207
  if (pnation != NO_NATION_SELECTED) {
1916
 
    player_set_nation(plr, pnation);
 
2208
 
 
2209
    /* 2.1 and earlier savegames have same nation for both barbarian players.
 
2210
     * Reassign correct nations for such barbarians. */
 
2211
    enum barbarian_type nat_barb_type = nation_barbarian_type(pnation);
 
2212
 
 
2213
    if ((is_sea_barbarian(plr) && nat_barb_type != SEA_BARBARIAN)
 
2214
        || (is_land_barbarian(plr) && nat_barb_type != LAND_BARBARIAN)) {
 
2215
      freelog(LOG_VERBOSE, "Reassigning barbarian nation for %s",
 
2216
              player_name(plr));
 
2217
      plr->nation = NO_NATION_SELECTED;
 
2218
    } else {
 
2219
      player_set_nation(plr, pnation);
 
2220
    }
1917
2221
  } else {
1918
2222
    plr->nation = NO_NATION_SELECTED;
1919
2223
  }
1926
2230
   * necessary.  The savegame should already mark those techs as known.
1927
2231
   * give_initial_techs will crash if the nation is unset. */
1928
2232
 
 
2233
  /* It is important that barbarian_type is loaded before
 
2234
   * calling is_barbarian() and is_land_barbarian() */
1929
2235
  if (is_barbarian(plr) && plr->nation == NO_NATION_SELECTED) {
1930
 
    pnation = pick_barbarian_nation();
 
2236
    if (is_land_barbarian(plr)) {
 
2237
      pnation = pick_a_nation(NULL, FALSE, TRUE, LAND_BARBARIAN);
 
2238
    } else {
 
2239
      pnation = pick_a_nation(NULL, FALSE, TRUE, SEA_BARBARIAN);
 
2240
    }
1931
2241
    player_set_nation(plr, pnation);
1932
2242
  }
1933
2243
 
1964
2274
    plr->target_government = government_of_player(plr);
1965
2275
  }
1966
2276
 
1967
 
  BV_CLR_ALL(plr->embassy);
 
2277
  BV_CLR_ALL(plr->real_embassy);
1968
2278
  if (has_capability("embassies", savefile_options)) {
1969
 
    players_iterate(pother) {
1970
 
      if (secfile_lookup_bool(file, "player%d.embassy%d",
1971
 
                              plrno, pother->player_no)) {
1972
 
        BV_SET(plr->embassy, pother->player_no);
 
2279
    player_slots_iterate(pother) {
 
2280
      if (secfile_lookup_bool_default(file, FALSE, "player%d.embassy%d",
 
2281
                                      plrno, player_index(pother))) {
 
2282
        BV_SET(plr->real_embassy, player_index(pother));
1973
2283
      }
1974
 
    } players_iterate_end;
 
2284
    } player_slots_iterate_end;
1975
2285
  } else {
1976
2286
    /* Required for 2.0 and earlier savegames.  Remove eventually and make
1977
2287
     * the cap check mandatory. */
1978
2288
    int embassy = secfile_lookup_int(file, "player%d.embassy", plrno);
1979
2289
 
1980
 
    players_iterate(pother) {
1981
 
      if (embassy & (1 << pother->player_no)) {
1982
 
        BV_SET(plr->embassy, pother->player_no);
 
2290
    player_slots_iterate(pother) {
 
2291
      if (embassy & (1 << player_index(pother))) {
 
2292
        BV_SET(plr->real_embassy, player_index(pother));
1983
2293
      }
1984
 
    } players_iterate_end;
1985
 
 
 
2294
    } player_slots_iterate_end;
1986
2295
  }
1987
2296
 
1988
2297
  p = secfile_lookup_str_default(file, NULL, "player%d.city_style_by_name",
2015
2324
  plr->is_male=secfile_lookup_bool_default(file, TRUE, "player%d.is_male", plrno);
2016
2325
  plr->is_alive=secfile_lookup_bool(file, "player%d.is_alive", plrno);
2017
2326
  /* "Old" observer players will still be loaded but are considered dead. */
2018
 
  plr->ai.control = secfile_lookup_bool(file, "player%d.ai.control", plrno);
 
2327
  plr->ai_data.control = secfile_lookup_bool(file, "player%d.ai.control", plrno);
2019
2328
  for (i = 0; i < MAX_NUM_PLAYERS; i++) {
2020
 
    plr->ai.love[i]
 
2329
    plr->ai_data.love[i]
2021
2330
         = secfile_lookup_int_default(file, 1, "player%d.ai%d.love", plrno, i);
2022
2331
    ai->diplomacy.player_intel[i].spam 
2023
2332
         = secfile_lookup_int_default(file, 0, "player%d.ai%d.spam", plrno, i);
2039
2348
 
2040
2349
  /* Backwards-compatibility: the tech goal value is still stored in the
2041
2350
   * "ai" section even though it was moved into the research struct. */
2042
 
  research->tech_goal
2043
 
    = load_technology(file, "player%d.ai.tech_goal", plrno);
 
2351
  research->tech_goal =
 
2352
    technology_load(file, "player%d.ai.tech_goal", plrno);
2044
2353
 
2045
2354
  if (research->tech_goal == A_NONE) {
2046
2355
    /* Old servers (1.14.1) saved both A_UNSET and A_NONE by 0
2049
2358
    research->tech_goal = A_UNSET;
2050
2359
  }
2051
2360
  /* Some sane defaults */
2052
 
  plr->ai.handicap = 0;         /* set later */
2053
 
  plr->ai.fuzzy = 0;            /* set later */
2054
 
  plr->ai.expand = 100;         /* set later */
2055
 
  plr->ai.science_cost = 100;   /* set later */
2056
 
  plr->ai.skill_level =
 
2361
  BV_CLR_ALL(plr->ai_data.handicaps); /* set later */
 
2362
  plr->ai_data.fuzzy = 0;                /* set later */
 
2363
  plr->ai_data.expand = 100;             /* set later */
 
2364
  plr->ai_data.science_cost = 100;       /* set later */
 
2365
  plr->ai_data.skill_level =
2057
2366
    secfile_lookup_int_default(file, game.info.skill_level,
2058
 
                               "player%d.ai.skill_level", plrno);
2059
 
  if (plr->ai.control && plr->ai.skill_level==0) {
2060
 
    plr->ai.skill_level = GAME_OLD_DEFAULT_SKILL_LEVEL;
 
2367
                               "player%d.ai.skill_level", plrno);
 
2368
  if (plr->ai_data.control && plr->ai_data.skill_level==0) {
 
2369
    plr->ai_data.skill_level = GAME_OLD_DEFAULT_SKILL_LEVEL;
2061
2370
  }
2062
 
  if (plr->ai.control) {
 
2371
  if (plr->ai_data.control) {
2063
2372
    /* Set AI parameters */
2064
 
    set_ai_level_directer(plr, plr->ai.skill_level);
 
2373
    set_ai_level_directer(plr, plr->ai_data.skill_level);
2065
2374
  }
2066
2375
 
2067
2376
  plr->economic.gold=secfile_lookup_int(file, "player%d.gold", plrno);
2071
2380
  
2072
2381
  plr->bulbs_last_turn =
2073
2382
    secfile_lookup_int_default(file, 0,
2074
 
                               "player%d.bulbs_last_turn",
2075
 
                               plrno);
2076
 
 
2077
 
  /* how many future techs were researched already by player */
2078
 
  research->future_tech
2079
 
    = secfile_lookup_int(file, "player%d.futuretech", plrno);
2080
 
 
2081
 
  /* We use default values for bulbs_researched_before, changed_from
 
2383
                               "player%d.bulbs_last_turn", plrno);
 
2384
 
 
2385
  /* The number of techs and future techs the player has
 
2386
   * researched/acquired. */
 
2387
  research->techs_researched =
 
2388
    secfile_lookup_int(file, "player%d.researchpoints", plrno);
 
2389
  research->future_tech =
 
2390
    secfile_lookup_int(file, "player%d.futuretech", plrno);
 
2391
 
 
2392
  /* We use default values for bulbs_researching_saved, researching_saved,
2082
2393
   * and got_tech to preserve backwards-compatibility with save files
2083
 
   * that didn't store this information. */
2084
 
  research->bulbs_researched
2085
 
    = secfile_lookup_int(file, "player%d.researched", plrno);
2086
 
  research->bulbs_researched_before =
2087
 
          secfile_lookup_int_default(file, 0,
2088
 
                                     "player%d.researched_before", plrno);
2089
 
  research->changed_from = 
2090
 
          load_technology(file, "player%d.research_changed_from", plrno);
2091
 
  research->got_tech = secfile_lookup_bool_default(file, FALSE,
2092
 
                                              "player%d.research_got_tech",
2093
 
                                              plrno);
2094
 
  research->techs_researched
2095
 
    = secfile_lookup_int(file, "player%d.researchpoints", plrno);
2096
 
  research->researching
2097
 
    = load_technology(file, "player%d.researching", plrno);
 
2394
   * that didn't store this information.  But the local variables have
 
2395
   * changed to reflect such minor differences. */
 
2396
  research->bulbs_researching_saved =
 
2397
    secfile_lookup_int_default(file, 0,
 
2398
                               "player%d.researched_before", plrno);
 
2399
  research->researching_saved =
 
2400
    technology_load(file, "player%d.research_changed_from", plrno);
 
2401
 
 
2402
  research->bulbs_researched =
 
2403
    secfile_lookup_int(file, "player%d.researched", plrno);
 
2404
  research->researching =
 
2405
    technology_load(file, "player%d.researching", plrno);
 
2406
 
2098
2407
  if (research->researching == A_NONE) {
2099
2408
    /* Old servers (1.14.1) used to save A_FUTURE by 0 
2100
2409
     * This has to be interpreted from context because A_NONE was also
2102
2411
     */
2103
2412
    research->researching = A_FUTURE;
2104
2413
  }
2105
 
  
 
2414
 
 
2415
  research->got_tech =
 
2416
    secfile_lookup_bool_default(file, FALSE,
 
2417
                                "player%d.research_got_tech", plrno);
 
2418
 
 
2419
  /* For new savegames using the technology_order[] list, any unknown
 
2420
   * inventions are ignored.  Older games are more strictly enforced,
 
2421
   * as an invalid index is probably indication of corruption.
 
2422
   */
2106
2423
  p = secfile_lookup_str_default(file, NULL, "player%d.invs_new", plrno);
2107
2424
  if (!p) {
2108
2425
    /* old savegames */
2109
2426
    p = secfile_lookup_str(file, "player%d.invs", plrno);
2110
2427
    for (k = 0; p[k];  k++) {
 
2428
      const char *name = old_tech_name(k);
 
2429
      if (!name) {
 
2430
        freelog(LOG_FATAL, "player%d.invs: value (%d) out of range.",
 
2431
                plrno, k);
 
2432
        exit(EXIT_FAILURE);
 
2433
      }
2111
2434
      if (p[k] == '1') {
2112
 
        name = old_tech_name(k);
2113
 
        id = find_advance_by_rule_name(name);
2114
 
        if (id != A_LAST) {
2115
 
          set_invention(plr, id, TECH_KNOWN);
2116
 
        }
 
2435
        struct advance *padvance = find_advance_by_rule_name(name);
 
2436
        if (padvance) {
 
2437
          player_invention_set(plr, advance_number(padvance), TECH_KNOWN);
 
2438
        }
2117
2439
      }
2118
2440
    }
2119
2441
  } else {
2120
2442
    for (k = 0; k < technology_order_size && p[k]; k++) {
2121
2443
      if (p[k] == '1') {
2122
 
        id = find_advance_by_rule_name(technology_order[k]);
2123
 
        if (id != A_LAST) {
2124
 
          set_invention(plr, id, TECH_KNOWN);
2125
 
        }
 
2444
        struct advance *padvance =
 
2445
               find_advance_by_rule_name(technology_order[k]);
 
2446
        if (padvance) {
 
2447
          player_invention_set(plr, advance_number(padvance), TECH_KNOWN);
 
2448
        }
2126
2449
      }
2127
2450
    }
2128
2451
  }
2139
2462
                                                plrno);
2140
2463
 
2141
2464
    if (revolution == 0) {
2142
 
      if (government_of_player(plr) != game.government_when_anarchy) {
 
2465
      if (government_of_player(plr) != game.government_during_revolution) {
2143
2466
        revolution = -1;
2144
2467
      } else {
2145
2468
        /* some old savegames may be buggy */
2153
2476
                                   "player%d.revolution_finishes", plrno);
2154
2477
  }
2155
2478
 
2156
 
  for (i = 0; i < game.info.nplayers; i++) {
 
2479
  for (i = 0; i < player_slot_count(); i++) {
2157
2480
    plr->diplstates[i].type = 
2158
2481
      secfile_lookup_int_default(file, DS_WAR,
2159
2482
                                 "player%d.diplstate%d.type", plrno, i);
2174
2497
      secfile_lookup_int_default(file, 0,
2175
2498
                           "player%d.diplstate%d.contact_turns_left", plrno, i);
2176
2499
  }
2177
 
  /* We don't need this info, but savegames carry it anyway.
2178
 
     To avoid getting "unused" warnings we touch the values like this. */
2179
 
  for (i = game.info.nplayers; i < MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS; i++) {
2180
 
    secfile_lookup_int_default(file, DS_WAR,
2181
 
                               "player%d.diplstate%d.type", plrno, i);
2182
 
    secfile_lookup_int_default(file, 0,
2183
 
                               "player%d.diplstate%d.turns_left", plrno, i);
2184
 
    secfile_lookup_int_default(file, 0,
2185
 
                               "player%d.diplstate%d.has_reason_to_cancel",
2186
 
                               plrno, i);
2187
 
    secfile_lookup_int_default(file, 0,
2188
 
                           "player%d.diplstate%d.contact_turns_left", plrno, i);
2189
 
  }
2190
2500
 
2191
2501
  { /* spacerace */
2192
2502
    struct player_spaceship *ship = &plr->spaceship;
2225
2535
      spaceship_calc_derived(ship);
2226
2536
    }
2227
2537
  }
 
2538
}
 
2539
 
 
2540
/****************************************************************************
 
2541
...
 
2542
****************************************************************************/
 
2543
static void player_load_cities(struct player *plr, int plrno,
 
2544
                               struct section_file *file,
 
2545
                               char *savefile_options,
 
2546
                               char **improvement_order,
 
2547
                               int improvement_order_size)
 
2548
{
 
2549
  char named[MAX_LEN_NAME];
 
2550
  struct player *past;
 
2551
  struct city *pcity;
 
2552
  const char *kind;
 
2553
  const char *name;
 
2554
  const char *p;
 
2555
  int id, i, j, k;
 
2556
  int ncities = secfile_lookup_int(file, "player%d.ncities", plrno);
2228
2557
 
2229
2558
  plr->cities = city_list_new();
2230
 
  ncities=secfile_lookup_int(file, "player%d.ncities", plrno);
 
2559
 
2231
2560
  if (!plr->is_alive && ncities > 0) {
 
2561
    freelog(LOG_ERROR, "player%d.ncities=%d for dead player!",
 
2562
            plrno,
 
2563
            ncities);
2232
2564
    ncities = 0; /* Some old savegames may be buggy. */
2233
2565
  }
2234
2566
 
2235
2567
  for (i = 0; i < ncities; i++) { /* read the cities */
2236
 
    struct city *pcity;
2237
 
    const char *name;
2238
 
    int id, k;
2239
2568
    int citizens = 0;
 
2569
    int nat_y = secfile_lookup_int(file, "player%d.c%d.y", plrno, i);
2240
2570
    int nat_x = secfile_lookup_int(file, "player%d.c%d.x", plrno, i);
2241
 
    int nat_y = secfile_lookup_int(file, "player%d.c%d.y", plrno, i);
2242
 
    struct tile *ptile = native_pos_to_tile(nat_x, nat_y);
2243
 
 
2244
 
    pcity = create_city_virtual(plr, ptile,
2245
 
                      secfile_lookup_str(file, "player%d.c%d.name", plrno, i));
2246
 
    ptile->owner_source = pcity->tile;
2247
 
    tile_set_owner(ptile, plr);
2248
 
 
2249
 
    pcity->id=secfile_lookup_int(file, "player%d.c%d.id", plrno, i);
2250
 
    alloc_id(pcity->id);
 
2571
    struct tile *pcenter = native_pos_to_tile(nat_x, nat_y);
 
2572
    int y;
 
2573
 
 
2574
    if (NULL == pcenter) {
 
2575
      freelog(LOG_FATAL, "player%d.c%d invalid tile (%d,%d)",
 
2576
              plrno, i,
 
2577
              nat_x, nat_y);
 
2578
      exit(EXIT_FAILURE);
 
2579
    }
 
2580
 
 
2581
    if (NULL != tile_city(pcenter)) {
 
2582
      freelog(LOG_FATAL, "player%d.c%d duplicate city (%d,%d)",
 
2583
              plrno, i,
 
2584
              nat_x, nat_y);
 
2585
      exit(EXIT_FAILURE);
 
2586
    }
 
2587
 
 
2588
    /* lookup name out of order */
 
2589
    my_snprintf(named, sizeof(named), "player%d.c%d.name", plrno, i);
 
2590
    /* instead of dying, use name string for damaged name */
 
2591
    name = secfile_lookup_str_default(file, named, "%s", named);
 
2592
    /* copied into city->name */
 
2593
    pcity = create_city_virtual(plr, pcenter, name);
 
2594
 
 
2595
    pcity->id = secfile_lookup_int(file, "player%d.c%d.id", plrno, i);
 
2596
    identity_number_reserve(pcity->id);
2251
2597
    idex_register_city(pcity);
2252
2598
 
2253
 
    id = secfile_lookup_int_default(file, -1,
 
2599
    id = secfile_lookup_int_default(file, plrno,
2254
2600
                                    "player%d.c%d.original", plrno, i);
2255
 
    if (id >= 0 && id < game.info.nplayers) {
2256
 
      pcity->original = get_player(id);
2257
 
    } else {
2258
 
      pcity->original = get_player(plrno);
 
2601
    past = player_by_number(id);
 
2602
    if (NULL != past) {
 
2603
      pcity->original = past;
2259
2604
    }
2260
2605
 
2261
 
    pcity->size=secfile_lookup_int(file, "player%d.c%d.size", plrno, i);
 
2606
    tile_set_owner(pcenter, plr, pcenter); /* for city_owner(), just in case? */
 
2607
    /* no city_choose_build_default(), values loaded below! */
2262
2608
 
2263
 
    pcity->steal=secfile_lookup_int(file, "player%d.c%d.steal", plrno, i);
 
2609
    pcity->size = secfile_lookup_int(file, "player%d.c%d.size", plrno, i);
2264
2610
 
2265
2611
    specialist_type_iterate(sp) {
2266
2612
      citizens +=
2267
 
      pcity->specialists[sp]
2268
 
        = secfile_lookup_int(file, "player%d.c%d.n%s", plrno, i,
2269
 
                             get_specialist(sp)->name);
 
2613
      pcity->specialists[sp] =
 
2614
        secfile_lookup_int(file, "player%d.c%d.n%s", plrno, i,
 
2615
                           specialist_rule_name(specialist_by_number(sp)));
2270
2616
    } specialist_type_iterate_end;
2271
2617
 
2272
 
    for (j = 0; j < NUM_TRADEROUTES; j++)
2273
 
      pcity->trade[j]=secfile_lookup_int(file, "player%d.c%d.traderoute%d",
2274
 
                                         plrno, i, j);
2275
 
    
2276
 
    pcity->food_stock = secfile_lookup_int(file, "player%d.c%d.food_stock", 
2277
 
                                           plrno, i);
2278
 
    pcity->shield_stock = secfile_lookup_int(file,
2279
 
                                             "player%d.c%d.shield_stock", 
2280
 
                                             plrno, i);
2281
 
    pcity->anarchy = secfile_lookup_int(file, "player%d.c%d.anarchy",
2282
 
                                        plrno, i);
2283
 
    pcity->rapture = secfile_lookup_int_default(file, 0,
2284
 
                                                "player%d.c%d.rapture",
2285
 
                                                plrno, i);
2286
 
    pcity->was_happy = secfile_lookup_bool(file,
2287
 
                                           "player%d.c%d.was_happy",
2288
 
                                           plrno, i);
2289
 
    pcity->production.is_unit =
2290
 
      secfile_lookup_bool(file, 
2291
 
                         "player%d.c%d.is_building_unit", plrno, i);
2292
 
    name = secfile_lookup_str_default(file, NULL,
2293
 
                                      "player%d.c%d.currently_building_name",
2294
 
                                      plrno, i);
2295
 
    if (pcity->production.is_unit) {
2296
 
      if (!name) {
2297
 
        id = secfile_lookup_int(file, "player%d.c%d.currently_building", 
2298
 
                                plrno, i);
2299
 
        name = old_unit_type_name(id);
2300
 
      }
2301
 
      pcity->production.value = find_unit_type_by_rule_name(name)->index;
2302
 
    } else {
2303
 
      if (!name) {
2304
 
        id = secfile_lookup_int(file, "player%d.c%d.currently_building",
2305
 
                                plrno, i);
2306
 
        name = old_impr_type_name(id);
2307
 
      }
2308
 
      pcity->production.value = find_improvement_by_rule_name(name);
2309
 
    }
 
2618
    for (j = 0; j < NUM_TRADE_ROUTES; j++) {
 
2619
      pcity->trade[j] =
 
2620
        secfile_lookup_int(file, "player%d.c%d.traderoute%d", plrno, i, j);
 
2621
    }
 
2622
 
 
2623
    pcity->food_stock =
 
2624
      secfile_lookup_int(file, "player%d.c%d.food_stock", plrno, i);
 
2625
    pcity->shield_stock =
 
2626
      secfile_lookup_int(file, "player%d.c%d.shield_stock", plrno, i);
 
2627
 
 
2628
    pcity->airlift =
 
2629
      secfile_lookup_int_default(file, 0, "player%d.c%d.airlift", plrno,i);
 
2630
    pcity->was_happy =
 
2631
      secfile_lookup_bool_default(file, FALSE, "player%d.c%d.was_happy",
 
2632
                                  plrno,i);
 
2633
    pcity->turn_plague =
 
2634
      secfile_lookup_int_default(file, 0, "player%d.c%d.turn_plague",
 
2635
                                 plrno,i);
 
2636
 
 
2637
    pcity->anarchy =
 
2638
      secfile_lookup_int(file, "player%d.c%d.anarchy", plrno, i);
 
2639
    pcity->rapture =
 
2640
      secfile_lookup_int_default(file, 0, "player%d.c%d.rapture",
 
2641
                                 plrno,i);
 
2642
    pcity->steal =
 
2643
      secfile_lookup_int_default(file, 0, "player%d.c%d.steal",
 
2644
                                 plrno,i);
 
2645
 
 
2646
    /* before did_buy for undocumented hack */
 
2647
    pcity->turn_founded =
 
2648
      secfile_lookup_int_default(file, -2, "player%d.c%d.turn_founded",
 
2649
                                 plrno, i);
 
2650
    j = secfile_lookup_int(file, "player%d.c%d.did_buy", plrno, i);
 
2651
    pcity->did_buy = (j != 0);
 
2652
    if (j == -1 && pcity->turn_founded == -2) {
 
2653
      /* undocumented hack */
 
2654
      pcity->turn_founded = game.info.turn;
 
2655
    }
 
2656
    pcity->did_sell =
 
2657
      secfile_lookup_bool_default(file, FALSE, "player%d.c%d.did_sell", plrno,i);
2310
2658
 
2311
2659
    if (has_capability("turn_last_built", savefile_options)) {
2312
 
      pcity->turn_last_built = secfile_lookup_int(file,
2313
 
                                "player%d.c%d.turn_last_built", plrno, i);
 
2660
      pcity->turn_last_built =
 
2661
        secfile_lookup_int(file, "player%d.c%d.turn_last_built", plrno, i);
2314
2662
    } else {
2315
2663
      /* Before, turn_last_built was stored as a year.  There is no easy
2316
2664
       * way to convert this into a turn value. */
2317
2665
      pcity->turn_last_built = 0;
2318
2666
    }
2319
 
    pcity->changed_from.is_unit =
2320
 
      secfile_lookup_bool_default(file, pcity->production.is_unit,
2321
 
                                 "player%d.c%d.changed_from_is_unit",
2322
 
                                  plrno, i);
 
2667
 
 
2668
    kind = secfile_lookup_str_default(file, NULL,
 
2669
                                      "player%d.c%d.currently_building_kind",
 
2670
                                      plrno, i);
 
2671
    if (!kind) {
 
2672
      /* before 2.2.0 unit production was indicated by flag. */
 
2673
      bool is_unit = secfile_lookup_bool_default(file, FALSE,
 
2674
                                                 "player%d.c%d.is_building_unit",
 
2675
                                                 plrno, i);
 
2676
      kind = universal_kind_name(is_unit ? VUT_UTYPE : VUT_IMPROVEMENT);
 
2677
    }
 
2678
 
 
2679
    name = secfile_lookup_str_default(file, NULL,
 
2680
                                      "player%d.c%d.currently_building_name",
 
2681
                                      plrno, i);
 
2682
    if (!name) {
 
2683
      /* before 1.15.0 production was saved by id. */
 
2684
      int id = secfile_lookup_int_default(file, -1,
 
2685
                                          "player%d.c%d.currently_building",
 
2686
                                          plrno, i);
 
2687
      switch (pcity->production.kind) {
 
2688
      case VUT_UTYPE:
 
2689
        name = old_unit_type_name(id);
 
2690
        if (!name) {
 
2691
          freelog(LOG_FATAL,
 
2692
                  "player%d.c%d.currently_building: unknown unit (%d)",
 
2693
                  plrno, i, id);
 
2694
          exit(EXIT_FAILURE);
 
2695
        }
 
2696
        break;
 
2697
      case VUT_IMPROVEMENT:
 
2698
        name = old_impr_type_name(id);
 
2699
        if (!name) {
 
2700
          freelog(LOG_FATAL,
 
2701
                  "player%d.c%d.currently_building: unknown improvement (%d)",
 
2702
                  plrno, i, id);
 
2703
          exit(EXIT_FAILURE);
 
2704
        }
 
2705
        break;
 
2706
      default:
 
2707
        freelog(LOG_FATAL, "player%d.c%d.currently_building: version mismatch.",
 
2708
                plrno, i);
 
2709
        exit(EXIT_FAILURE);
 
2710
      };
 
2711
    }
 
2712
    pcity->production = universal_by_rule_name(kind, name);
 
2713
    if (VUT_LAST == pcity->production.kind) {
 
2714
      freelog(LOG_FATAL, "player%d.c%d.currently_building: unknown \"%s\" \"%s\".",
 
2715
              plrno, i, kind, name);
 
2716
      exit(EXIT_FAILURE);
 
2717
    }
 
2718
 
 
2719
    kind = secfile_lookup_str_default(file, NULL,
 
2720
                                      "player%d.c%d.changed_from_kind",
 
2721
                                      plrno, i);
 
2722
    if (!kind) {
 
2723
      /* before 2.2.0 unit production was indicated by flag. */
 
2724
      bool is_unit = secfile_lookup_bool_default(file, FALSE,
 
2725
                                                 "player%d.c%d.changed_from_is_unit",
 
2726
                                                 plrno, i);
 
2727
      kind = universal_kind_name(is_unit ? VUT_UTYPE : VUT_IMPROVEMENT);
 
2728
    }
 
2729
 
2323
2730
    name = secfile_lookup_str_default(file, NULL,
2324
2731
                                      "player%d.c%d.changed_from_name",
2325
2732
                                      plrno, i);
2326
 
    if (pcity->changed_from.is_unit) {
2327
 
      if (!name) {
2328
 
        id = secfile_lookup_int(file, "player%d.c%d.changed_from_id", 
2329
 
                                plrno, i);
2330
 
        name = old_unit_type_name(id);
2331
 
      }
2332
 
      pcity->changed_from.value = find_unit_type_by_rule_name(name)->index;
2333
 
    } else {
2334
 
      if (!name) {
2335
 
        id = secfile_lookup_int(file, "player%d.c%d.changed_from_id",
2336
 
                                plrno, i);
2337
 
        name = old_impr_type_name(id);
2338
 
      }
2339
 
      pcity->changed_from.value = find_improvement_by_rule_name(name);
2340
 
    }
2341
 
                         
2342
 
    pcity->before_change_shields=
 
2733
    if (!name) {
 
2734
      /* before 1.15.0 production was saved by id. */
 
2735
      int id = secfile_lookup_int_default(file, -1,
 
2736
                                          "player%d.c%d.changed_from_id",
 
2737
                                          plrno, i);
 
2738
      switch (pcity->production.kind) {
 
2739
      case VUT_UTYPE:
 
2740
        name = old_unit_type_name(id);
 
2741
        if (!name) {
 
2742
          freelog(LOG_FATAL,
 
2743
                  "player%d.c%d.changed_from_id: unknown unit (%d)",
 
2744
                  plrno, i, id);
 
2745
          exit(EXIT_FAILURE);
 
2746
        }
 
2747
        break;
 
2748
      case VUT_IMPROVEMENT:
 
2749
        name = old_impr_type_name(id);
 
2750
        if (!name) {
 
2751
          freelog(LOG_FATAL,
 
2752
                  "player%d.c%d.changed_from_id: unknown improvement (%d)",
 
2753
                  plrno, i, id);
 
2754
          exit(EXIT_FAILURE);
 
2755
        }
 
2756
        break;
 
2757
      default:
 
2758
        freelog(LOG_FATAL, "player%d.c%d.changed_from_id: version mismatch.",
 
2759
                plrno, i);
 
2760
        exit(EXIT_FAILURE);
 
2761
      };
 
2762
    }
 
2763
    pcity->changed_from = universal_by_rule_name(kind, name);
 
2764
    if (VUT_LAST == pcity->changed_from.kind) {
 
2765
      freelog(LOG_FATAL, "player%d.c%d.changed_from: unknown \"%s\" \"%s\".",
 
2766
              plrno, i, kind, name);
 
2767
      exit(EXIT_FAILURE);
 
2768
    }
 
2769
 
 
2770
    pcity->before_change_shields =
2343
2771
      secfile_lookup_int_default(file, pcity->shield_stock,
2344
2772
                                 "player%d.c%d.before_change_shields", plrno, i);
2345
 
    pcity->disbanded_shields=
 
2773
    pcity->caravan_shields =
 
2774
      secfile_lookup_int_default(file, 0,
 
2775
                                 "player%d.c%d.caravan_shields", plrno, i);
 
2776
    pcity->disbanded_shields =
2346
2777
      secfile_lookup_int_default(file, 0,
2347
2778
                                 "player%d.c%d.disbanded_shields", plrno, i);
2348
 
    pcity->caravan_shields=
2349
 
      secfile_lookup_int_default(file, 0,
2350
 
                                 "player%d.c%d.caravan_shields", plrno, i);
2351
2779
    pcity->last_turns_shield_surplus =
2352
2780
      secfile_lookup_int_default(file, 0,
2353
2781
                                 "player%d.c%d.last_turns_shield_surplus",
2354
2782
                                 plrno, i);
2355
2783
 
2356
 
    pcity->synced = FALSE; /* must re-sync with clients */
2357
 
 
2358
 
    pcity->turn_founded =
2359
 
        secfile_lookup_int_default(file, -2, "player%d.c%d.turn_founded",
2360
 
                                   plrno, i);
2361
 
 
2362
 
    j = secfile_lookup_int(file, "player%d.c%d.did_buy", plrno, i);
2363
 
    pcity->did_buy = (j != 0);
2364
 
    if (j == -1 && pcity->turn_founded == -2) {
2365
 
      pcity->turn_founded = game.info.turn;
2366
 
    }
2367
 
 
2368
 
    pcity->did_sell =
2369
 
      secfile_lookup_bool_default(file, FALSE, "player%d.c%d.did_sell", plrno,i);
2370
 
    
2371
 
    pcity->airlift = secfile_lookup_bool_default(file, FALSE,
2372
 
                                        "player%d.c%d.airlift", plrno,i);
2373
 
 
2374
 
    /* New city-options form as of freeciv 2.1.  Old (<= 2.0) city options
2375
 
     * are lost on upgrade. */
2376
 
    BV_CLR_ALL(pcity->city_options);
2377
 
    for (j = 0; j < CITYO_LAST; j++) {
2378
 
      if (secfile_lookup_bool_default(file, FALSE,
2379
 
                                      "player%d.c%d.option%d",
2380
 
                                      plrno, i, j)) {
2381
 
        BV_SET(pcity->city_options, j);
2382
 
      }
2383
 
    }
 
2784
    pcity->server.synced = FALSE; /* must re-sync with clients */
2384
2785
 
2385
2786
    /* Fix for old buggy savegames. */
2386
2787
    if (!has_capability("known32fix", savefile_options)
2387
2788
        && plrno >= 16) {
2388
 
      map_city_radius_iterate(pcity->tile, tile1) {
 
2789
      city_tile_iterate(pcenter, tile1) {
2389
2790
        map_set_known(tile1, plr);
2390
 
      } map_city_radius_iterate_end;
 
2791
      } city_tile_iterate_end;
2391
2792
    }
2392
 
    
2393
 
    /* adding the cities contribution to fog-of-war */
2394
 
    pcity->server.vision = vision_new(city_owner(pcity), pcity->tile, FALSE);
2395
 
    city_refresh_vision(pcity);
2396
2793
 
2397
2794
    pcity->units_supported = unit_list_new();
2398
2795
 
2399
 
    /* Initialize pcity->city_map[][], using set_worker_city() so that
2400
 
       ptile->worked gets initialized correctly.  The pre-initialisation
2401
 
       to C_TILE_EMPTY is necessary because set_worker_city() accesses
2402
 
       the existing value to possibly adjust ptile->worked, so need to
2403
 
       initialize a non-worked value so ptile->worked (possibly already
2404
 
       set from neighbouring city) does not get unset for C_TILE_EMPTY
2405
 
       or C_TILE_UNAVAILABLE here.  -- dwp
2406
 
    */
2407
 
    p=secfile_lookup_str(file, "player%d.c%d.workers", plrno, i);
2408
 
    for(y=0; y<CITY_MAP_SIZE; y++) {
2409
 
      for(x=0; x<CITY_MAP_SIZE; x++) {
2410
 
        bool valid = is_valid_city_coords(x, y);
2411
 
        pcity->city_map[x][y] = valid ? C_TILE_EMPTY : C_TILE_UNAVAILABLE;
2412
 
 
2413
 
        if (*p == '0') {
2414
 
          if (!valid) {
2415
 
            /* oops, inconsistent savegame; minimal fix: */
2416
 
            freelog(LOG_VERBOSE, "Invalid workers '%c' for %s (%d,%d), "
2417
 
                    "ignoring", *p, city_name(pcity), x, y);
 
2796
    /* Update pcity->city_map[][] and ptile->worked directly.
 
2797
       Initialized to C_TILE_UNUSABLE (0) by create_city_virtual().
 
2798
       Ensure ptile->worked (possibly already set from neighbouring
 
2799
       city) does not get unset by conflicting values.  Principally for
 
2800
       repair_city_worker() below.
 
2801
     */
 
2802
    city_freeze_workers(pcity);
 
2803
 
 
2804
    p = secfile_lookup_str(file, "player%d.c%d.workers", plrno, i);
 
2805
 
 
2806
    if (strlen(p) != CITY_MAP_SIZE * CITY_MAP_SIZE) {
 
2807
      /* FIXME: somehow need to rearrange */
 
2808
      freelog(LOG_ERROR, "player%d.c%d.workers"
 
2809
              " length %lu not equal city map size %lu, needs rearranging!",
 
2810
              plrno, i,
 
2811
              (unsigned long)strlen(p),
 
2812
              (unsigned long)(CITY_MAP_SIZE * CITY_MAP_SIZE));
 
2813
    }
 
2814
 
 
2815
    for(y = 0; y < CITY_MAP_SIZE; y++) {
 
2816
      struct city *pwork = NULL;
 
2817
      int x;
 
2818
 
 
2819
      for(x = 0; x < CITY_MAP_SIZE; x++) {
 
2820
        struct tile *ptile = is_valid_city_coords(x, y)
 
2821
                             ? city_map_to_tile(pcenter, x, y)
 
2822
                             : NULL;
 
2823
 
 
2824
        switch (*p) {
 
2825
        case '\0':
 
2826
          /* too short, will yield very odd results! */
 
2827
          continue;
 
2828
 
 
2829
        case S_TILE_EMPTY:
 
2830
          if (NULL == ptile) {
 
2831
            freelog(LOG_WORKER, "player%d.c%d.workers"
 
2832
                    " {%d,%d} '%c' not valid for (%d,%d) \"%s\"[%d], ignoring",
 
2833
                    plrno, i,
 
2834
                    x, y, *p,
 
2835
                    TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2836
          } else if (NULL != (pwork = tile_worked(ptile))) {
 
2837
            freelog(LOG_WORKER, "player%d.c%d.workers"
 
2838
                    " {%d,%d} '%c' conflict at (%d,%d)"
 
2839
                    " for (%d,%d) \"%s\"[%d]"
 
2840
                    " with (%d,%d) \"%s\"[%d],"
 
2841
                    " converting to unavailable",
 
2842
                    plrno, i,
 
2843
                    x, y, *p,
 
2844
                    TILE_XY(ptile),
 
2845
                    TILE_XY(pcenter), city_name(pcity), pcity->size,
 
2846
                    TILE_XY(city_tile(pwork)), city_name(pwork), pwork->size);
 
2847
            pcity->city_map[x][y] = C_TILE_UNAVAILABLE;
2418
2848
          } else {
2419
 
            set_worker_city(pcity, x, y,
2420
 
                            NULL != city_map_to_map(pcity, x, y)
2421
 
                            ? C_TILE_EMPTY : C_TILE_UNAVAILABLE);
 
2849
            pcity->city_map[x][y] = C_TILE_EMPTY;
2422
2850
          }
2423
 
        } else if (*p=='1') {
2424
 
          struct tile *ptile;
2425
 
          if (!valid) {
2426
 
            /* oops, inconsistent savegame; minimal fix: */
2427
 
            freelog(LOG_VERBOSE, "Invalid workers '%c' for %s (%d,%d), "
2428
 
                    "ignoring", *p, city_name(pcity), x, y);
2429
 
          } else if (NULL == (ptile = city_map_to_map(pcity, x, y))
2430
 
                  || ptile->worked) {
2431
 
            /* oops, inconsistent savegame; minimal fix: */
2432
 
            freelog(LOG_VERBOSE, "Inconsistent worked for %s (%d,%d), "
2433
 
                    "converting to specialist", city_name(pcity), x, y);
 
2851
          break;
 
2852
 
 
2853
        case S_TILE_WORKER:
 
2854
          if (NULL == ptile) {
 
2855
            freelog(LOG_WORKER, "player%d.c%d.workers"
 
2856
                    " {%d,%d} '%c' not valid for (%d,%d) \"%s\"[%d], ignoring",
 
2857
                    plrno, i,
 
2858
                    x, y, *p,
 
2859
                    TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2860
          } else if (NULL != (pwork = tile_worked(ptile))) {
 
2861
            freelog(LOG_WORKER, "player%d.c%d.workers"
 
2862
                    " {%d,%d} '%c' conflict at (%d,%d)"
 
2863
                    " for (%d,%d) \"%s\"[%d]"
 
2864
                    " with (%d,%d) \"%s\"[%d],"
 
2865
                    " converting to default specialist",
 
2866
                    plrno, i,
 
2867
                    x, y, *p,
 
2868
                    TILE_XY(ptile),
 
2869
                    TILE_XY(pcenter), city_name(pcity), pcity->size,
 
2870
                    TILE_XY(city_tile(pwork)), city_name(pwork), pwork->size);
 
2871
 
 
2872
            pcity->city_map[x][y] = C_TILE_UNAVAILABLE;
2434
2873
            pcity->specialists[DEFAULT_SPECIALIST]++;
2435
 
            set_worker_city(pcity, x, y, C_TILE_UNAVAILABLE);
2436
 
            citizens++;
2437
 
          } else {
2438
 
            set_worker_city(pcity, x, y, C_TILE_WORKER);
2439
 
            citizens++;
2440
 
          }
2441
 
        } else if (*p == '2') {
2442
 
          if (valid) {
2443
 
            set_worker_city(pcity, x, y, C_TILE_UNAVAILABLE);
2444
 
          }
2445
 
          assert(pcity->city_map[x][y] == C_TILE_UNAVAILABLE);
2446
 
        } else {
2447
 
           freelog(LOG_VERBOSE, "Invalid workers '%c' for %s (%d,%d), "
2448
 
                   "ignoring", *p, city_name(pcity), x, y);
2449
 
        }
 
2874
            auto_arrange_workers(pcity);
 
2875
            citizens++;
 
2876
          } else {
 
2877
            pcity->city_map[x][y] = C_TILE_WORKER;
 
2878
            tile_set_worked(ptile, pcity);
 
2879
            citizens++;
 
2880
          }
 
2881
          break;
 
2882
 
 
2883
        case S_TILE_UNAVAILABLE:
 
2884
          if (NULL == ptile) {
 
2885
            /* before 2.2.0 same as C_TILE_UNUSABLE */
 
2886
          } else {
 
2887
            pcity->city_map[x][y] = C_TILE_UNAVAILABLE;
 
2888
          }
 
2889
          break;
 
2890
 
 
2891
        case S_TILE_UNKNOWN:
 
2892
          if (NULL == ptile) {
 
2893
            /* already set C_TILE_UNUSABLE */
 
2894
          } else {
 
2895
            freelog(LOG_WORKER, "player%d.c%d.workers"
 
2896
                    " {%d,%d} '%c' not valid at (%d,%d)"
 
2897
                    " for (%d,%d) \"%s\"[%d],"
 
2898
                    " converting to unavailable",
 
2899
                    plrno, i,
 
2900
                    x, y, *p,
 
2901
                    TILE_XY(ptile),
 
2902
                    TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2903
            pcity->city_map[x][y] = C_TILE_UNAVAILABLE;
 
2904
          }
 
2905
          break;
 
2906
 
 
2907
        default:
 
2908
          freelog(LOG_WORKER, "player%d.c%d.workers"
 
2909
                  " {%d,%d} '%c' not valid for (%d,%d) \"%s\"[%d], ignoring",
 
2910
                  plrno, i,
 
2911
                  x, y, *p,
 
2912
                  TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2913
          break;
 
2914
        };
2450
2915
        p++;
2451
2916
      }
2452
2917
    }
2453
 
    /* center tile worker isn't counted in city size */
2454
 
    if (citizens > 1) {
2455
 
      citizens--;
 
2918
 
 
2919
    if (tile_worked(pcenter) != pcity) {
 
2920
      struct city *pwork = tile_worked(pcenter);
 
2921
 
 
2922
      if (NULL != pwork) {
 
2923
        int city_x, city_y;
 
2924
 
 
2925
        freelog(LOG_ERROR, "player%d.c%d.workers"
 
2926
                " city center is worked by (%d,%d) \"%s\"[%d],"
 
2927
                " repairing (%d,%d) \"%s\"[%d]",
 
2928
                plrno, i,
 
2929
                TILE_XY(city_tile(pwork)), city_name(pwork), pwork->size,
 
2930
                TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2931
 
 
2932
        city_tile_to_city_map(&city_x, &city_y, city_tile(pwork), pcenter);
 
2933
        pwork->city_map[city_x][city_y] = C_TILE_UNAVAILABLE;
 
2934
        pwork->specialists[DEFAULT_SPECIALIST]++;
 
2935
        auto_arrange_workers(pwork);
 
2936
      } else {
 
2937
        freelog(LOG_ERROR, "player%d.c%d.workers"
 
2938
                " city center is empty,"
 
2939
                " repairing (%d,%d) \"%s\"[%d]",
 
2940
                plrno, i,
 
2941
                TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2942
      }
 
2943
 
 
2944
      pcity->city_map[CITY_MAP_SIZE/2][CITY_MAP_SIZE/2] = C_TILE_WORKER;
 
2945
      tile_set_worked(pcenter, pcity); /* repair */
 
2946
 
 
2947
      city_repair_size(pcity, -1);
2456
2948
    }
2457
 
    if (citizens != pcity->size) {
2458
 
      freelog(LOG_ERROR, "player_load()"
2459
 
              " %d citizens not equal %d city size in \"%s\".",
2460
 
              citizens,
2461
 
              pcity->size,
2462
 
              city_name(pcity));
 
2949
 
 
2950
    k = pcity->size + FREE_WORKED_TILES - citizens;
 
2951
    if (0 != k) {
 
2952
      freelog(LOG_ERROR, "player%d.c%d.workers"
 
2953
              " %d citizens not equal %d + [size],"
 
2954
              " repairing (%d,%d) \"%s\"[%d]",
 
2955
              plrno, i,
 
2956
              citizens, FREE_WORKED_TILES,
 
2957
              TILE_XY(pcenter), city_name(pcity), pcity->size);
 
2958
 
 
2959
      city_repair_size(pcity, k);
2463
2960
    }
2464
2961
 
2465
2962
    /* Initialise list of improvements with City- and Building-wide
2466
2963
       equiv_ranges */
2467
 
    for (k = 0; k < ARRAY_SIZE(pcity->improvements); k++) {
2468
 
      pcity->improvements[k] = I_NONE;
 
2964
    for (k = 0; k < ARRAY_SIZE(pcity->built); k++) {
 
2965
      pcity->built[k].turn = I_NEVER;
2469
2966
    }
2470
2967
 
 
2968
    /* For new savegames using the improvement_order[] list, any unknown
 
2969
     * improvements are ignored.  Older games are more strictly enforced,
 
2970
     * as an invalid index is probably indication of corruption.
 
2971
     */
2471
2972
    p = secfile_lookup_str_default(file, NULL,
2472
2973
                                   "player%d.c%d.improvements_new",
2473
2974
                                   plrno, i);
2475
2976
      /* old savegames */
2476
2977
      p = secfile_lookup_str(file, "player%d.c%d.improvements", plrno, i);
2477
2978
      for (k = 0; p[k]; k++) {
 
2979
        const char *name = old_impr_type_name(k);
 
2980
        if (!name) {
 
2981
          freelog(LOG_FATAL,
 
2982
                  "player%d.c%d.improvements: unknown building (%d)",
 
2983
                  plrno, i, k);
 
2984
          exit(EXIT_FAILURE);
 
2985
        }
2478
2986
        if (p[k] == '1') {
2479
 
          name = old_impr_type_name(k);
2480
 
          id = find_improvement_by_rule_name(name);
2481
 
          if (id != -1) {
2482
 
            city_add_improvement(pcity, id);
2483
 
          }
2484
 
        }
 
2987
          struct impr_type *pimprove = find_improvement_by_rule_name(name);
 
2988
          if (pimprove) {
 
2989
            city_add_improvement(pcity, pimprove);
 
2990
          }
 
2991
        }
2485
2992
      }
2486
2993
    } else {
2487
2994
      for (k = 0; k < improvement_order_size && p[k]; k++) {
2488
2995
        if (p[k] == '1') {
2489
 
          id = find_improvement_by_rule_name(improvement_order[k]);
2490
 
          if (id != -1) {
2491
 
            city_add_improvement(pcity, id);
2492
 
          }
2493
 
        }
 
2996
          struct impr_type *pimprove =
 
2997
                 find_improvement_by_rule_name(improvement_order[k]);
 
2998
          if (pimprove) {
 
2999
            city_add_improvement(pcity, pimprove);
 
3000
          }
 
3001
        }
2494
3002
      }
2495
3003
    }
2496
3004
 
 
3005
    /* worklist_init() done in create_city_virtual() */
2497
3006
    worklist_load(file, &pcity->worklist, "player%d.c%d", plrno, i);
2498
3007
 
 
3008
    /* after 2.1.0 new options format.  Old options are lost on upgrade. */
 
3009
    BV_CLR_ALL(pcity->city_options);
 
3010
    for (j = 0; j < CITYO_LAST; j++) {
 
3011
      if (secfile_lookup_bool_default(file, FALSE,
 
3012
                                      "player%d.c%d.option%d",
 
3013
                                      plrno, i, j)) {
 
3014
        BV_SET(pcity->city_options, j);
 
3015
      }
 
3016
    }
 
3017
 
2499
3018
    /* FIXME: remove this when the urgency is properly recalculated. */
2500
 
    pcity->ai.urgency = secfile_lookup_int_default(file, 0, 
2501
 
                                "player%d.c%d.ai.urgency", plrno, i);
 
3019
    pcity->ai->urgency =
 
3020
      secfile_lookup_int_default(file, 0, "player%d.c%d.ai.urgency",
 
3021
                                 plrno, i);
2502
3022
 
2503
3023
    /* avoid myrand recalculations on subsequent reload. */
2504
 
    pcity->ai.next_recalc = secfile_lookup_int_default(file, 0, 
2505
 
                                "player%d.c%d.ai.building_turn", plrno, i);
 
3024
    pcity->ai->building_turn =
 
3025
      secfile_lookup_int_default(file, 0, "player%d.c%d.ai.building_turn",
 
3026
                                 plrno, i);
 
3027
    pcity->ai->building_wait =
 
3028
      secfile_lookup_int_default(file, BUILDING_WAIT_MINIMUM,
 
3029
                                 "player%d.c%d.ai.building_wait",
 
3030
                                 plrno, i);
2506
3031
 
2507
3032
    /* avoid myrand and expensive recalculations on subsequent reload. */
2508
 
    pcity->ai.next_founder_want_recalc = secfile_lookup_int_default(file, 0, 
2509
 
                                "player%d.c%d.ai.founder_turn", plrno, i);
2510
 
    pcity->ai.founder_want = secfile_lookup_int_default(file, 0, 
2511
 
                                "player%d.c%d.ai.founder_want", plrno, i);
2512
 
    pcity->ai.founder_boat = secfile_lookup_bool_default(file,
2513
 
                                (pcity->ai.founder_want < 0), 
2514
 
                                "player%d.c%d.ai.founder_boat", plrno, i);
2515
 
 
2516
 
    /* do after all the set_worker_city() are done. */
2517
 
    tile_set_city(pcity->tile, pcity);
 
3033
    pcity->ai->founder_turn =
 
3034
      secfile_lookup_int_default(file, 0, "player%d.c%d.ai.founder_turn",
 
3035
                                 plrno, i);
 
3036
    pcity->ai->founder_want =
 
3037
      secfile_lookup_int_default(file, 0, "player%d.c%d.ai.founder_want",
 
3038
                                 plrno, i);
 
3039
    pcity->ai->founder_boat =
 
3040
      secfile_lookup_bool_default(file, (pcity->ai->founder_want < 0),
 
3041
                                  "player%d.c%d.ai.founder_boat",
 
3042
                                  plrno, i);
 
3043
 
 
3044
    /* After everything is loaded, but before vision. */
 
3045
    map_claim_ownership(pcenter, plr, pcenter);
 
3046
 
 
3047
    /* adding the city contribution to fog-of-war */
 
3048
    pcity->server.vision = vision_new(plr, pcenter);
 
3049
    vision_reveal_tiles(pcity->server.vision, game.info.vision_reveal_tiles);
 
3050
    city_refresh_vision(pcity);
 
3051
 
2518
3052
    city_list_append(plr->cities, pcity);
2519
3053
  }
2520
 
 
2521
 
  load_player_units(plr, plrno, file);
2522
 
 
 
3054
}
 
3055
 
 
3056
/****************************************************************************
 
3057
...
 
3058
****************************************************************************/
 
3059
static void player_load_attributes(struct player *plr, int plrno,
 
3060
                                   struct section_file *file)
 
3061
{
2523
3062
  /* Toss any existing attribute_block (should not exist) */
2524
3063
  if (plr->attribute_block.data) {
2525
3064
    free(plr->attribute_block.data);
2590
3129
  }
2591
3130
}
2592
3131
 
2593
 
/********************************************************************** 
2594
 
The private map for fog of war
2595
 
***********************************************************************/
2596
 
static void player_map_load(struct player *plr, int plrno,
2597
 
                      struct section_file *file,
2598
 
                      char** improvement_order, int improvement_order_size,
2599
 
                      const enum tile_special_type *special_order)
 
3132
/****************************************************************************
 
3133
  Load the private vision map for fog of war
 
3134
****************************************************************************/
 
3135
static void player_load_vision(struct player *plr, int plrno,
 
3136
                               struct section_file *file,
 
3137
                               char *savefile_options,
 
3138
                               const enum tile_special_type *special_order,
 
3139
                               char **improvement_order,
 
3140
                               int improvement_order_size,
 
3141
                               struct base_type **base_order,
 
3142
                               int num_base_types)
2600
3143
{
2601
 
  int i;
 
3144
  const char *p;
 
3145
  int i, k, id;
 
3146
  int nat_x, nat_y;
 
3147
  int total_ncities =
 
3148
    secfile_lookup_int_default(file, -1, "player%d.total_ncities", plrno);
2602
3149
 
2603
3150
  if (!plr->is_alive)
2604
3151
    map_know_and_see_all(plr);
2610
3157
  */
2611
3158
  if (secfile_lookup_int_default(file, -1, "game.fogofwar") != -1
2612
3159
      && game.info.fogofwar == TRUE
2613
 
      && secfile_lookup_int_default(file, -1,"player%d.total_ncities", plrno) != -1
 
3160
      && -1 != total_ncities
2614
3161
      && secfile_lookup_bool_default(file, TRUE, "game.save_private_map")) {
2615
3162
    LOAD_MAP_DATA(ch, nat_y, ptile,
2616
3163
                  secfile_lookup_str(file, "player%d.map_t%03d",
2630
3177
        LOAD_MAP_DATA(ch, nat_y, ptile,
2631
3178
            secfile_lookup_str(file, buf, nat_y),
2632
3179
            set_savegame_special(&map_get_player_tile(ptile, plr)->special,
 
3180
                                 &map_get_player_tile(ptile, plr)->bases,
2633
3181
                                 ch, special_order + 4 * j));
2634
3182
      } special_halfbyte_iterate_end;
2635
3183
    } else {
2637
3185
      LOAD_MAP_DATA(ch, nat_y, ptile,
2638
3186
          secfile_lookup_str(file, "player%d.map_l%03d", plrno, nat_y),
2639
3187
          set_savegame_special(&map_get_player_tile(ptile, plr)->special,
 
3188
                               &map_get_player_tile(ptile, plr)->bases,
2640
3189
                               ch, default_specials + 0));
2641
3190
      LOAD_MAP_DATA(ch, nat_y, ptile,
2642
3191
          secfile_lookup_str(file, "player%d.map_u%03d", plrno, nat_y),
2643
3192
          set_savegame_special(&map_get_player_tile(ptile, plr)->special,
 
3193
                               &map_get_player_tile(ptile, plr)->bases,
2644
3194
                               ch, default_specials + 4));
2645
3195
      LOAD_MAP_DATA(ch, nat_y, ptile,
2646
3196
          secfile_lookup_str_default (file, NULL, "player%d.map_n%03d",
2647
3197
                                      plrno, nat_y),
2648
3198
          set_savegame_special(&map_get_player_tile(ptile, plr)->special,
 
3199
                               &map_get_player_tile(ptile, plr)->bases,
2649
3200
                               ch, default_specials + 8));
2650
3201
      LOAD_MAP_DATA(ch, nat_y, ptile,
2651
3202
        secfile_lookup_str(file, "map.l%03d", nat_y),
2657
3208
                                  ptile->terrain, ch, 1));
2658
3209
    }
2659
3210
 
 
3211
    if (has_capability("bases", savefile_options)) {
 
3212
      char zeroline[map.xsize+1];
 
3213
      int i;
 
3214
 
 
3215
      /* This is needed when new bases has been added to ruleset, and
 
3216
       * thus game.control.num_base_types is greater than, when game was saved. */
 
3217
      for(i = 0; i < map.xsize; i++) {
 
3218
        zeroline[i] = '0';
 
3219
      }
 
3220
      zeroline[i]= '\0';
 
3221
 
 
3222
      bases_halfbyte_iterate(j, num_base_types) {
 
3223
        char buf[32]; /* should be enough for snprintf() below */
 
3224
 
 
3225
        my_snprintf(buf, sizeof(buf), "player%d.map_b%02d_%%03d", plrno, j);
 
3226
 
 
3227
        LOAD_MAP_DATA(ch, nat_y, ptile,
 
3228
                      secfile_lookup_str_default(file, zeroline, buf, nat_y),
 
3229
                      set_savegame_bases(&map_get_player_tile(ptile, plr)->bases,
 
3230
                                         ch, base_order + 4 * j));
 
3231
      } bases_halfbyte_iterate_end;
 
3232
    } else {
 
3233
      /* Already loaded fortresses and airbases as part of specials */
 
3234
    }
 
3235
 
 
3236
    if (game.server.foggedborders) {
 
3237
      LOAD_MAP_DATA(ch, nat_y, ptile,
 
3238
          secfile_lookup_str(file, "player%d.map_owner%03d", plrno, nat_y),
 
3239
          map_get_player_tile(ptile, plr)->owner = identifier_to_player(ch));
 
3240
    }
 
3241
 
2660
3242
    /* get 4-bit segments of 16-bit "updated" field */
2661
3243
    LOAD_MAP_DATA(ch, nat_y, ptile,
2662
3244
                  secfile_lookup_str
2679
3261
                  map_get_player_tile(ptile, plr)->last_updated |=
2680
3262
                  ascii_hex2bin(ch, 3));
2681
3263
 
2682
 
    {
2683
 
      int j;
2684
 
      i = secfile_lookup_int(file, "player%d.total_ncities", plrno);
2685
 
      for (j = 0; j < i; j++) {
2686
 
        int nat_x, nat_y;
2687
 
        int k, id;
2688
 
        const char *p;
2689
 
        struct tile *ptile;
2690
 
        struct vision_base *pdcity = fc_calloc(1, sizeof(*pdcity));
2691
 
 
2692
 
        pdcity->identity = secfile_lookup_int(file, "player%d.dc%d.id", plrno, j);
2693
 
        if (VISION_BASE_RUIN >= pdcity->identity) {
2694
 
          freelog(LOG_ERROR, "[player%d] dc%d has invalid id (%d); skipping.",
2695
 
                  plrno, j, pdcity->identity);
2696
 
          free(pdcity);
2697
 
          continue;
2698
 
        }
2699
 
 
2700
 
        nat_x = secfile_lookup_int(file, "player%d.dc%d.x", plrno, j);
2701
 
        nat_y = secfile_lookup_int(file, "player%d.dc%d.y", plrno, j);
2702
 
        ptile = native_pos_to_tile(nat_x, nat_y);
2703
 
        pdcity->location = ptile;
2704
 
 
2705
 
        sz_strlcpy(pdcity->name, secfile_lookup_str(file, "player%d.dc%d.name", plrno, j));
2706
 
        pdcity->size = secfile_lookup_int(file, "player%d.dc%d.size", plrno, j);
2707
 
        pdcity->occupied = secfile_lookup_bool_default(file, FALSE,
2708
 
                                        "player%d.dc%d.occupied", plrno, j);
2709
 
        pdcity->walls = secfile_lookup_bool_default(file, FALSE,
2710
 
                                        "player%d.dc%d.walls", plrno, j);
2711
 
        pdcity->happy = secfile_lookup_bool_default(file, FALSE,
2712
 
                                        "player%d.dc%d.happy", plrno, j);
2713
 
        pdcity->unhappy = secfile_lookup_bool_default(file, FALSE,
2714
 
                                        "player%d.dc%d.unhappy", plrno, j);
2715
 
 
2716
 
        id = secfile_lookup_int(file, "player%d.dc%d.owner", plrno, j);
2717
 
        pdcity->owner = get_player(id);
2718
 
        if (NULL == vision_owner(pdcity)) {
2719
 
          freelog(LOG_ERROR, "[player%d] dc%d has invalid owner (%d); skipping.",
2720
 
                  plrno, j, id);
2721
 
          free(pdcity);
2722
 
          continue;
2723
 
        }
2724
 
 
2725
 
        /* Initialise list of improvements */
2726
 
        BV_CLR_ALL(pdcity->improvements);
2727
 
 
2728
 
        p = secfile_lookup_str_default(file, NULL,
2729
 
                                       "player%d.dc%d.improvements", plrno, j);
2730
 
        if (!p) {
2731
 
          /* old savegames */
2732
 
        } else {
2733
 
          for (k = 0; k < improvement_order_size && p[k]; k++) {
2734
 
            if (p[k] == '1') {
2735
 
              id = find_improvement_by_rule_name(improvement_order[k]);
2736
 
              if (id != -1) {
2737
 
                BV_SET(pdcity->improvements, id);
2738
 
              }
2739
 
            }
2740
 
          }
2741
 
        }
2742
 
 
2743
 
        map_get_player_tile(ptile, plr)->vision_source = pdcity;
2744
 
        alloc_id(pdcity->identity);
2745
 
      }
 
3264
    for (i = 0; i < total_ncities; i++) {
 
3265
      /* similar to create_vision_site() */
 
3266
      struct vision_site *pdcity = create_vision_site(0, NULL, NULL);
 
3267
 
 
3268
      nat_y = secfile_lookup_int(file, "player%d.dc%d.y", plrno, i);
 
3269
      nat_x = secfile_lookup_int(file, "player%d.dc%d.x", plrno, i);
 
3270
      pdcity->location = native_pos_to_tile(nat_x, nat_y);
 
3271
      if (NULL == pdcity->location) {
 
3272
        freelog(LOG_ERROR, "player%d.dc%d invalid tile (%d,%d)",
 
3273
                plrno, i,
 
3274
                nat_x, nat_y);
 
3275
        free(pdcity);
 
3276
        continue;
 
3277
      }
 
3278
 
 
3279
      pdcity->identity = secfile_lookup_int(file, "player%d.dc%d.id", plrno, i);
 
3280
      if (IDENTITY_NUMBER_ZERO >= pdcity->identity) {
 
3281
        freelog(LOG_ERROR, "player%d.dc%d has invalid id (%d); skipping.",
 
3282
                plrno, i, pdcity->identity);
 
3283
        free(pdcity);
 
3284
        continue;
 
3285
      }
 
3286
 
 
3287
      id = secfile_lookup_int(file, "player%d.dc%d.owner", plrno, i);
 
3288
      if (id == plrno) {
 
3289
        /* Earlier versions redundantly saved the dummy for their own cities.
 
3290
         * Since 2.2.0, map_claim_ownership() rebuilds them at city load time.
 
3291
         */
 
3292
        freelog(LOG_VERBOSE, "player%d.dc%d has same owner (%d); skipping.",
 
3293
                plrno, i, id);
 
3294
        free(pdcity);
 
3295
        continue;
 
3296
      }
 
3297
 
 
3298
      pdcity->owner = player_by_number(id);
 
3299
      if (NULL == vision_owner(pdcity)) {
 
3300
        freelog(LOG_ERROR, "player%d.dc%d has invalid owner (%d); skipping.",
 
3301
                plrno, i, id);
 
3302
        free(pdcity);
 
3303
        continue;
 
3304
      }
 
3305
 
 
3306
      pdcity->size = secfile_lookup_int(file, "player%d.dc%d.size", plrno, i);
 
3307
      pdcity->occupied = secfile_lookup_bool_default(file, FALSE,
 
3308
                                      "player%d.dc%d.occupied", plrno, i);
 
3309
      pdcity->walls = secfile_lookup_bool_default(file, FALSE,
 
3310
                                      "player%d.dc%d.walls", plrno, i);
 
3311
      pdcity->happy = secfile_lookup_bool_default(file, FALSE,
 
3312
                                      "player%d.dc%d.happy", plrno, i);
 
3313
      pdcity->unhappy = secfile_lookup_bool_default(file, FALSE,
 
3314
                                      "player%d.dc%d.unhappy", plrno, i);
 
3315
 
 
3316
      /* Initialise list of improvements */
 
3317
      BV_CLR_ALL(pdcity->improvements);
 
3318
 
 
3319
      p = secfile_lookup_str_default(file, NULL,
 
3320
                                     "player%d.dc%d.improvements", plrno, i);
 
3321
      if (!p) {
 
3322
        /* old savegames */
 
3323
      } else {
 
3324
        for (k = 0; k < improvement_order_size && p[k]; k++) {
 
3325
          if (p[k] == '1') {
 
3326
            struct impr_type *pimprove =
 
3327
                      find_improvement_by_rule_name(improvement_order[k]);
 
3328
            if (pimprove) {
 
3329
              BV_SET(pdcity->improvements, improvement_index(pimprove));
 
3330
            }
 
3331
          }
 
3332
        }
 
3333
      }
 
3334
      sz_strlcpy(pdcity->name, secfile_lookup_str(file, "player%d.dc%d.name", plrno, i));
 
3335
 
 
3336
      change_playertile_site(map_get_player_tile(pdcity->location, plr),
 
3337
                             pdcity);
 
3338
      identity_number_reserve(pdcity->identity);
2746
3339
    }
2747
3340
 
2748
 
    /* This shouldn't be neccesary if the savegame was consistent, but there
2749
 
       is a bug in some pre-1.11 savegames. Anyway, it can't hurt */
 
3341
    /* Repair inconsistent player maps. There was a bug in some pre-1.11
 
3342
       savegames, and possibly other versions, and border support changed
 
3343
       from time to time. Anyway, it shouldn't hurt. */
2750
3344
    whole_map_iterate(ptile) {
2751
3345
      if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
 
3346
        struct city *pcity = tile_city(ptile);
 
3347
 
2752
3348
        update_player_tile_knowledge(plr, ptile);
2753
3349
        reality_check_city(plr, ptile);
2754
 
        if (tile_get_city(ptile)) {
2755
 
          update_dumb_city(plr, tile_get_city(ptile));
 
3350
 
 
3351
        if (NULL != pcity) {
 
3352
          update_dumb_city(plr, pcity);
2756
3353
        }
2757
3354
      }
2758
3355
    } whole_map_iterate_end;
2759
 
 
2760
3356
  } else {
2761
3357
    /* We have an old savegame or fog of war was turned off; the
2762
3358
       players private knowledge is set to be what he could see
2763
3359
       without fog of war */
2764
3360
    whole_map_iterate(ptile) {
2765
3361
      if (map_is_known(ptile, plr)) {
2766
 
        struct city *pcity = tile_get_city(ptile);
 
3362
        struct city *pcity = tile_city(ptile);
 
3363
 
2767
3364
        update_player_tile_last_seen(plr, ptile);
2768
3365
        update_player_tile_knowledge(plr, ptile);
2769
 
        if (pcity)
 
3366
 
 
3367
        if (NULL != pcity) {
2770
3368
          update_dumb_city(plr, pcity);
 
3369
        }
2771
3370
      }
2772
3371
    } whole_map_iterate_end;
2773
3372
  }
2774
3373
}
2775
3374
 
2776
 
/***************************************************************
 
3375
/****************************************************************************
2777
3376
...
2778
 
***************************************************************/
2779
 
static void player_save(struct player *plr, int plrno,
2780
 
                        struct section_file *file)
 
3377
****************************************************************************/
 
3378
static void player_save_main(struct player *plr, int plrno,
 
3379
                             struct section_file *file)
2781
3380
{
2782
3381
  int i;
2783
3382
  char invs[A_LAST+1];
2784
3383
  struct player_spaceship *ship = &plr->spaceship;
2785
3384
  struct ai_data *ai = ai_data_get(plr);
2786
 
  int wlist_max_length = 0;
2787
3385
 
2788
3386
  secfile_insert_str(file, player_name(plr), "player%d.name", plrno);
2789
3387
  secfile_insert_str(file, plr->username, "player%d.username", plrno);
2791
3389
                     plrno);
2792
3390
  secfile_insert_str(file, nation_rule_name(nation_of_player(plr)),
2793
3391
                     "player%d.nation", plrno);
2794
 
  /* 1.15 and later won't use the race field, they key on the nation string 
2795
 
   * This field is kept only for forward compatibility
2796
 
   * Nations can't be saved correctly because race must be < 62 */
2797
 
  secfile_insert_int(file, plrno, "player%d.race", plrno);
2798
3392
 
2799
 
  secfile_insert_int(file, plr->team ? plr->team->index : -1,
 
3393
  secfile_insert_int(file, plr->team ? team_index(plr->team) : -1,
2800
3394
                     "player%d.team_no", plrno);
2801
3395
 
2802
3396
  secfile_insert_str(file, government_rule_name(government_of_player(plr)),
2803
3397
                     "player%d.government_name", plrno);
2804
 
  /* 1.15 and later won't use "government" field; it's kept for forward 
2805
 
   * compatibility */
2806
 
  secfile_insert_int(file, old_government_id(government_of_player(plr)),
2807
 
                     "player%d.government", plrno);
2808
3398
 
2809
3399
  if (plr->target_government) {
2810
3400
    secfile_insert_str(file, government_rule_name(government_of_player(plr)),
2812
3402
  }
2813
3403
 
2814
3404
  players_iterate(pother) {
2815
 
    secfile_insert_bool(file, BV_ISSET(plr->embassy, pother->player_no),
2816
 
                        "player%d.embassy%d", plrno, pother->player_no);
 
3405
    secfile_insert_bool(file, player_has_real_embassy(plr, pother),
 
3406
                        "player%d.embassy%d", plrno, player_number(pother));
2817
3407
  } players_iterate_end;
2818
3408
 
2819
3409
  /* Required for 2.0 and earlier servers.  Remove eventually. */
2829
3419
 
2830
3420
  secfile_insert_bool(file, plr->is_male, "player%d.is_male", plrno);
2831
3421
  secfile_insert_bool(file, plr->is_alive, "player%d.is_alive", plrno);
2832
 
  secfile_insert_bool(file, plr->ai.control, "player%d.ai.control", plrno);
 
3422
  secfile_insert_bool(file, plr->ai_data.control, "player%d.ai.control", plrno);
 
3423
 
2833
3424
  for (i = 0; i < MAX_NUM_PLAYERS; i++) {
2834
 
    secfile_insert_int(file, plr->ai.love[i],
 
3425
    secfile_insert_int(file, plr->ai_data.love[i],
2835
3426
                       "player%d.ai%d.love", plrno, i);
2836
3427
    secfile_insert_int(file, ai->diplomacy.player_intel[i].spam, 
2837
3428
                       "player%d.ai%d.spam", plrno, i);
2850
3441
    secfile_insert_int(file, ai->diplomacy.player_intel[i].asked_about_ceasefire, 
2851
3442
                       "player%d.ai%d.ask_ceasefire", plrno, i);
2852
3443
  }
2853
 
  save_technology(file, "player%d.ai.tech_goal",
2854
 
                  plrno, get_player_research(plr)->tech_goal);
2855
 
  secfile_insert_int(file, plr->ai.skill_level,
 
3444
 
 
3445
  technology_save(file, "player%d.ai.tech_goal",
 
3446
                  plrno, get_player_research(plr)->tech_goal);
 
3447
 
 
3448
  secfile_insert_int(file, plr->ai_data.skill_level,
2856
3449
                     "player%d.ai.skill_level", plrno);
2857
 
  secfile_insert_int(file, plr->ai.barbarian_type, "player%d.ai.is_barbarian", plrno);
 
3450
  secfile_insert_int(file, plr->ai_data.barbarian_type,
 
3451
                     "player%d.ai.is_barbarian", plrno);
2858
3452
  secfile_insert_int(file, plr->economic.gold, "player%d.gold", plrno);
2859
3453
  secfile_insert_int(file, plr->economic.tax, "player%d.tax", plrno);
2860
3454
  secfile_insert_int(file, plr->economic.science, "player%d.science", plrno);
2863
3457
  secfile_insert_int(file, plr->bulbs_last_turn, "player%d.bulbs_last_turn",
2864
3458
                     plrno);
2865
3459
 
 
3460
  secfile_insert_int(file, get_player_research(plr)->techs_researched,
 
3461
                     "player%d.researchpoints", plrno);
2866
3462
  secfile_insert_int(file, get_player_research(plr)->future_tech,
2867
 
                     "player%d.futuretech", plrno);
 
3463
                     "player%d.futuretech", plrno);
 
3464
 
 
3465
  secfile_insert_int(file, get_player_research(plr)->bulbs_researching_saved,
 
3466
                     "player%d.researched_before", plrno);
 
3467
  technology_save(file, "player%d.research_changed_from", plrno,
 
3468
                  get_player_research(plr)->researching_saved);
2868
3469
 
2869
3470
  secfile_insert_int(file, get_player_research(plr)->bulbs_researched, 
2870
 
                     "player%d.researched", plrno);
2871
 
  secfile_insert_int(file, get_player_research(plr)->bulbs_researched_before,
2872
 
                     "player%d.researched_before", plrno);
 
3471
                     "player%d.researched", plrno);
 
3472
  technology_save(file, "player%d.researching", plrno,
 
3473
                  get_player_research(plr)->researching);
 
3474
 
2873
3475
  secfile_insert_bool(file, get_player_research(plr)->got_tech,
2874
 
                      "player%d.research_got_tech", plrno);
2875
 
  save_technology(file, "player%d.research_changed_from", plrno, 
2876
 
                  get_player_research(plr)->changed_from);
2877
 
  secfile_insert_int(file, get_player_research(plr)->techs_researched,
2878
 
                     "player%d.researchpoints", plrno);
2879
 
  save_technology(file, "player%d.researching", plrno,
2880
 
                  get_player_research(plr)->researching);  
 
3476
                      "player%d.research_got_tech", plrno);
2881
3477
 
2882
3478
  secfile_insert_bool(file, plr->capital, "player%d.capital", plrno);
2883
3479
 
2902
3498
  /* 1.14 servers depend on technology order in ruleset. Here we are trying
2903
3499
   * to simulate 1.14.1 default order */
2904
3500
  init_old_technology_bitvector(invs);
2905
 
  tech_type_iterate(tech_id) {
2906
 
    if (get_invention(plr, tech_id) == TECH_KNOWN) {
2907
 
      add_technology_into_old_bitvector(invs, tech_id);
2908
 
    }
2909
 
  } tech_type_iterate_end;
2910
 
  secfile_insert_str(file, invs, "player%d.invs", plrno);
2911
 
  
2912
 
  /* Save technology lists as bitvector. Note that technology order is 
 
3501
  /* removed after 2.1 */
 
3502
 
 
3503
  /* Save technology lists as bytevector. Note that technology order is 
2913
3504
   * saved in savefile.technology_order */
2914
 
  tech_type_iterate(tech_id) {
2915
 
    invs[tech_id] = (get_invention(plr, tech_id) == TECH_KNOWN) ? '1' : '0';
2916
 
  } tech_type_iterate_end;
 
3505
  advance_index_iterate(A_NONE, tech_id) {
 
3506
    invs[tech_id] = (player_invention_state(plr, tech_id) == TECH_KNOWN) ? '1' : '0';
 
3507
  } advance_index_iterate_end;
2917
3508
  invs[game.control.num_tech_types] = '\0';
2918
3509
  secfile_insert_str(file, invs, "player%d.invs_new", plrno);
2919
3510
 
2936
3527
    char vision[MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS+1];
2937
3528
 
2938
3529
    for (i=0; i < MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++)
2939
 
      vision[i] = gives_shared_vision(plr, get_player(i)) ? '1' : '0';
 
3530
      vision[i] = gives_shared_vision(plr, player_by_number(i)) ? '1' : '0';
2940
3531
    vision[i] = '\0';
2941
3532
    secfile_insert_str(file, vision, "player%d.gives_shared_vision", plrno);
2942
3533
  }
2973
3564
                     plrno);
2974
3565
  secfile_insert_int(file, city_list_size(plr->cities), "player%d.ncities", 
2975
3566
                     plrno);
2976
 
 
2977
 
  i = -1;
 
3567
}
 
3568
 
 
3569
/****************************************************************************
 
3570
  Saves the units for the given player.
 
3571
****************************************************************************/
 
3572
static void player_save_units(struct player *plr, int plrno,
 
3573
                              struct section_file *file)
 
3574
{
 
3575
  int i = -1;
 
3576
 
2978
3577
  unit_list_iterate(plr->units, punit) {
 
3578
    int activity = punit->activity;
 
3579
    char basenum = -1;
 
3580
 
2979
3581
    i++;
 
3582
 
2980
3583
    secfile_insert_int(file, punit->id, "player%d.u%d.id", plrno, i);
2981
3584
    secfile_insert_int(file, punit->tile->nat_x, "player%d.u%d.x", plrno, i);
2982
3585
    secfile_insert_int(file, punit->tile->nat_y, "player%d.u%d.y", plrno, i);
2985
3588
    secfile_insert_int(file, punit->hp, "player%d.u%d.hp", plrno, i);
2986
3589
    secfile_insert_int(file, punit->homecity, "player%d.u%d.homecity",
2987
3590
                                plrno, i);
2988
 
    /* .type is actually kept only for forward compatibility */
2989
 
    secfile_insert_int(file, old_unit_type_id(unit_type(punit)),
2990
 
                       "player%d.u%d.type",
2991
 
                       plrno, i);
2992
3591
    secfile_insert_str(file, unit_rule_name(punit),
2993
3592
                       "player%d.u%d.type_by_name",
2994
3593
                       plrno, i);
2995
 
    secfile_insert_int(file, punit->activity, "player%d.u%d.activity",
2996
 
                                plrno, i);
 
3594
 
 
3595
    if (activity == ACTIVITY_BASE) {
 
3596
      basenum = punit->activity_base;
 
3597
    }
 
3598
    secfile_insert_int(file, activity, "player%d.u%d.activity",
 
3599
                       plrno, i);
2997
3600
    secfile_insert_int(file, punit->activity_count, 
2998
3601
                                "player%d.u%d.activity_count",
2999
3602
                                plrno, i);
3000
3603
    secfile_insert_int(file, punit->activity_target, 
3001
3604
                                "player%d.u%d.activity_target",
3002
3605
                                plrno, i);
 
3606
    secfile_insert_int(file, basenum, "player%d.u%d.activity_base", plrno, i);
3003
3607
    secfile_insert_bool(file, punit->done_moving,
3004
3608
                        "player%d.u%d.done_moving", plrno, i);
3005
3609
    secfile_insert_int(file, punit->moves_left, "player%d.u%d.moves",
3006
3610
                                plrno, i);
3007
3611
    secfile_insert_int(file, punit->fuel, "player%d.u%d.fuel",
3008
3612
                                plrno, i);
 
3613
    secfile_insert_int(file, punit->birth_turn, "player%d.u%d.born",
 
3614
                       plrno, i);
3009
3615
    secfile_insert_int(file, punit->battlegroup,
3010
3616
                       "player%d.u%d.battlegroup", plrno, i);
3011
3617
 
3038
3644
                       "player%d.u%d.transported_by", plrno, i);
3039
3645
    if (punit->has_orders) {
3040
3646
      int len = punit->orders.length, j;
3041
 
      char orders_buf[len + 1], dir_buf[len + 1], act_buf[len + 1];
 
3647
      char orders_buf[len + 1], dir_buf[len + 1], act_buf[len + 1], base_buf[len + 1];
3042
3648
 
3043
3649
      secfile_insert_int(file, len, "player%d.u%d.orders_length", plrno, i);
3044
3650
      secfile_insert_int(file, punit->orders.index,
3052
3658
        orders_buf[j] = order2char(punit->orders.list[j].order);
3053
3659
        dir_buf[j] = '?';
3054
3660
        act_buf[j] = '?';
 
3661
        base_buf[j] = '?';
3055
3662
        switch (punit->orders.list[j].order) {
3056
3663
        case ORDER_MOVE:
3057
3664
          dir_buf[j] = dir2char(punit->orders.list[j].dir);
3058
3665
          break;
3059
3666
        case ORDER_ACTIVITY:
3060
 
          act_buf[j] = activity2char(punit->orders.list[j].activity);
 
3667
          if (punit->orders.list[j].activity == ACTIVITY_BASE) {
 
3668
            base_buf[j] = num2char(punit->orders.list[j].base);
 
3669
          }
 
3670
          act_buf[j] = activity2char(punit->orders.list[j].activity);
3061
3671
          break;
3062
3672
        case ORDER_FULL_MP:
3063
3673
        case ORDER_BUILD_CITY:
3064
3674
        case ORDER_DISBAND:
3065
3675
        case ORDER_BUILD_WONDER:
3066
 
        case ORDER_TRADEROUTE:
 
3676
        case ORDER_TRADE_ROUTE:
3067
3677
        case ORDER_HOMECITY:
3068
3678
        case ORDER_LAST:
3069
3679
          break;
3077
3687
                         "player%d.u%d.dir_list", plrno, i);
3078
3688
      secfile_insert_str(file, act_buf,
3079
3689
                         "player%d.u%d.activity_list", plrno, i);
 
3690
      secfile_insert_str(file, base_buf,
 
3691
                         "player%d.u%d.base_list", plrno, i);
3080
3692
    } else {
3081
3693
      /* Put all the same fields into the savegame - otherwise the
3082
3694
       * registry code can't correctly use a tabular format and the
3093
3705
                         "player%d.u%d.dir_list", plrno, i);
3094
3706
      secfile_insert_str(file, "-",
3095
3707
                         "player%d.u%d.activity_list", plrno, i);
 
3708
      secfile_insert_str(file, "-",
 
3709
                         "player%d.u%d.base_list", plrno, i);
3096
3710
    }
3097
 
  }
3098
 
  unit_list_iterate_end;
 
3711
  } unit_list_iterate_end;
 
3712
}
3099
3713
 
3100
 
  i = -1;
 
3714
/****************************************************************************
 
3715
...
 
3716
****************************************************************************/
 
3717
static void player_save_cities(struct player *plr, int plrno,
 
3718
                               struct section_file *file)
 
3719
{
 
3720
  int wlist_max_length = 0;
 
3721
  int i = -1;
3101
3722
 
3102
3723
  /* First determine lenght of longest worklist */
3103
3724
  city_list_iterate(plr->cities, pcity) {
3110
3731
    int j, x, y;
3111
3732
    char citymap_buf[CITY_MAP_SIZE * CITY_MAP_SIZE + 1];
3112
3733
    char impr_buf[MAX_NUM_ITEMS + 1];
 
3734
    struct tile *pcenter = city_tile(pcity);
3113
3735
 
3114
3736
    i++;
 
3737
    secfile_insert_int(file, pcenter->nat_y, "player%d.c%d.y", plrno, i);
 
3738
    secfile_insert_int(file, pcenter->nat_x, "player%d.c%d.x", plrno, i);
3115
3739
    secfile_insert_int(file, pcity->id, "player%d.c%d.id", plrno, i);
3116
 
    secfile_insert_int(file, pcity->tile->nat_x, "player%d.c%d.x", plrno, i);
3117
 
    secfile_insert_int(file, pcity->tile->nat_y, "player%d.c%d.y", plrno, i);
3118
 
    secfile_insert_str(file, city_name(pcity), "player%d.c%d.name", plrno, i);
3119
 
    secfile_insert_int(file, pcity->original->player_no,
 
3740
 
 
3741
    secfile_insert_int(file, player_number(pcity->original),
3120
3742
                       "player%d.c%d.original", plrno, i);
 
3743
 
3121
3744
    secfile_insert_int(file, pcity->size, "player%d.c%d.size", plrno, i);
3122
 
    secfile_insert_int(file, pcity->steal, "player%d.c%d.steal", plrno, i);
 
3745
 
3123
3746
    specialist_type_iterate(sp) {
3124
3747
      secfile_insert_int(file, pcity->specialists[sp],
3125
3748
                         "player%d.c%d.n%s", plrno, i,
3126
 
                         get_specialist(sp)->name);
 
3749
                         specialist_rule_name(specialist_by_number(sp)));
3127
3750
    } specialist_type_iterate_end;
3128
3751
 
3129
 
    for (j = 0; j < NUM_TRADEROUTES; j++)
 
3752
    for (j = 0; j < NUM_TRADE_ROUTES; j++)
3130
3753
      secfile_insert_int(file, pcity->trade[j], "player%d.c%d.traderoute%d", 
3131
3754
                         plrno, i, j);
3132
3755
    
3134
3757
                       plrno, i);
3135
3758
    secfile_insert_int(file, pcity->shield_stock, "player%d.c%d.shield_stock", 
3136
3759
                       plrno, i);
 
3760
 
 
3761
    secfile_insert_int(file, pcity->airlift, "player%d.c%d.airlift",
 
3762
                       plrno, i);
 
3763
    secfile_insert_bool(file, pcity->was_happy, "player%d.c%d.was_happy",
 
3764
                        plrno, i);
 
3765
    secfile_insert_int(file, pcity->turn_plague, "player%d.c%d.turn_plague",
 
3766
                       plrno, i);
 
3767
 
 
3768
    secfile_insert_int(file, pcity->anarchy, "player%d.c%d.anarchy", plrno,i);
 
3769
    secfile_insert_int(file, pcity->rapture, "player%d.c%d.rapture", plrno,i);
 
3770
    secfile_insert_int(file, pcity->steal, "player%d.c%d.steal", plrno, i);
 
3771
 
 
3772
    secfile_insert_int(file, pcity->turn_founded,
 
3773
                       "player%d.c%d.turn_founded", plrno, i);
 
3774
    if (pcity->turn_founded == game.info.turn) {
 
3775
      j = -1; /* undocumented hack */
 
3776
    } else {
 
3777
      assert(pcity->did_buy == TRUE || pcity->did_buy == FALSE);
 
3778
      j = pcity->did_buy ? 1 : 0;
 
3779
    }
 
3780
    secfile_insert_int(file, j, "player%d.c%d.did_buy", plrno, i);
 
3781
    secfile_insert_bool(file, pcity->did_sell, "player%d.c%d.did_sell", plrno,i);
3137
3782
    secfile_insert_int(file, pcity->turn_last_built,
3138
3783
                       "player%d.c%d.turn_last_built", plrno, i);
3139
 
    secfile_insert_bool(file, pcity->changed_from.is_unit,
3140
 
                       "player%d.c%d.changed_from_is_unit", plrno, i);
3141
 
    if (pcity->changed_from.is_unit) {
3142
 
      struct unit_type *punittype = utype_by_number(pcity->changed_from.value);
3143
 
 
3144
 
      secfile_insert_int(file, old_unit_type_id(punittype),
3145
 
                         "player%d.c%d.changed_from_id", plrno, i);
3146
 
      secfile_insert_str(file, utype_rule_name(punittype),
3147
 
                         "player%d.c%d.changed_from_name", plrno, i);
3148
 
    } else {
3149
 
      secfile_insert_int(file, old_impr_type_id(pcity->changed_from.value),
3150
 
                         "player%d.c%d.changed_from_id", plrno, i);    
3151
 
      secfile_insert_str(file, improvement_rule_name(
3152
 
                                 pcity->changed_from.value),
3153
 
                         "player%d.c%d.changed_from_name", plrno, i);
3154
 
    }
 
3784
 
 
3785
    /* for visual debugging, variable length strings together here */
 
3786
    secfile_insert_str(file, city_name(pcity), "player%d.c%d.name", plrno, i);
 
3787
 
 
3788
    /* before 2.2.0 unit production was indicated by flag. */
 
3789
    secfile_insert_str(file, universal_type_rule_name(&pcity->production),
 
3790
                       "player%d.c%d.currently_building_kind", plrno, i);
 
3791
    secfile_insert_str(file, universal_rule_name(&pcity->production),
 
3792
                       "player%d.c%d.currently_building_name", plrno, i);
 
3793
 
 
3794
    /* before 2.2.0 unit production was indicated by flag. */
 
3795
    secfile_insert_str(file, universal_type_rule_name(&pcity->changed_from),
 
3796
                       "player%d.c%d.changed_from_kind", plrno, i);
 
3797
    secfile_insert_str(file, universal_rule_name(&pcity->changed_from),
 
3798
                       "player%d.c%d.changed_from_name", plrno, i);
3155
3799
 
3156
3800
    secfile_insert_int(file, pcity->before_change_shields,
3157
3801
                       "player%d.c%d.before_change_shields", plrno, i);
 
3802
    secfile_insert_int(file, pcity->caravan_shields,
 
3803
                       "player%d.c%d.caravan_shields", plrno, i);
3158
3804
    secfile_insert_int(file, pcity->disbanded_shields,
3159
3805
                       "player%d.c%d.disbanded_shields", plrno, i);
3160
 
    secfile_insert_int(file, pcity->caravan_shields,
3161
 
                       "player%d.c%d.caravan_shields", plrno, i);
3162
3806
    secfile_insert_int(file, pcity->last_turns_shield_surplus,
3163
3807
                       "player%d.c%d.last_turns_shield_surplus", plrno, i);
3164
3808
 
3165
 
    secfile_insert_int(file, pcity->anarchy, "player%d.c%d.anarchy", plrno,i);
3166
 
    secfile_insert_int(file, pcity->rapture, "player%d.c%d.rapture", plrno,i);
3167
 
    secfile_insert_bool(file, pcity->was_happy, "player%d.c%d.was_happy", plrno,i);
3168
 
    if (pcity->turn_founded == game.info.turn) {
3169
 
      j = -1;
3170
 
    } else {
3171
 
      assert(pcity->did_buy == TRUE || pcity->did_buy == FALSE);
3172
 
      j = pcity->did_buy ? 1 : 0;
3173
 
    }
3174
 
    secfile_insert_int(file, j, "player%d.c%d.did_buy", plrno, i);
3175
 
    secfile_insert_int(file, pcity->turn_founded,
3176
 
                       "player%d.c%d.turn_founded", plrno, i);
3177
 
    secfile_insert_bool(file, pcity->did_sell, "player%d.c%d.did_sell", plrno,i);
3178
 
    secfile_insert_bool(file, pcity->airlift, "player%d.c%d.airlift", plrno,i);
3179
 
 
3180
 
    /* New options format as of Freeciv 2.1. */
3181
 
    for (j = 0; j < CITYO_LAST; j++) {
3182
 
      secfile_insert_bool(file, BV_ISSET(pcity->city_options, j),
3183
 
                          "player%d.c%d.option%d", plrno, i, j);
3184
 
    }
3185
 
 
 
3809
    /* The saved city_map[][] uses a specific ordering.  The defined
 
3810
       iterators index outward from the center, and cannot be used here.
 
3811
       After 2.2.0, use the (more reliable) main map itself for saving.
 
3812
     */
3186
3813
    j=0;
3187
3814
    for(y=0; y<CITY_MAP_SIZE; y++) {
3188
3815
      for(x=0; x<CITY_MAP_SIZE; x++) {
3189
 
        switch (get_worker_city(pcity, x, y)) {
3190
 
        case C_TILE_EMPTY:
3191
 
          citymap_buf[j++] = '0';
3192
 
          break;
3193
 
        case C_TILE_WORKER:
3194
 
          citymap_buf[j++] = '1';
3195
 
          break;
3196
 
        case C_TILE_UNAVAILABLE:
3197
 
          citymap_buf[j++] = '2';
3198
 
          break;
3199
 
        default:
3200
 
          citymap_buf[j++] = '?';
3201
 
          assert(0);
3202
 
          break;
3203
 
        }
 
3816
        struct tile *ptile = is_valid_city_coords(x, y)
 
3817
                             ? city_map_to_tile(pcenter, x, y)
 
3818
                             : NULL;
 
3819
 
 
3820
        if (NULL == ptile) {
 
3821
          citymap_buf[j++] = S_TILE_UNKNOWN;
 
3822
        } else if (tile_worked(ptile) == pcity) {
 
3823
          /* is currently worked, but actually may be unavailable */
 
3824
          citymap_buf[j++] = S_TILE_WORKER;
 
3825
        } else if (city_can_work_tile(pcity, ptile)) {
 
3826
          citymap_buf[j++] = S_TILE_EMPTY;
 
3827
        } else {
 
3828
          citymap_buf[j++] = S_TILE_UNAVAILABLE;
 
3829
        }
3204
3830
      }
3205
3831
    }
3206
3832
    citymap_buf[j]='\0';
3207
3833
    assert(j < ARRAY_SIZE(citymap_buf));
3208
3834
    secfile_insert_str(file, citymap_buf, "player%d.c%d.workers", plrno, i);
3209
3835
 
3210
 
    secfile_insert_bool(file, pcity->production.is_unit, 
3211
 
                       "player%d.c%d.is_building_unit", plrno, i);
3212
 
    if (pcity->production.is_unit) {
3213
 
      struct unit_type *punittype = utype_by_number(pcity->production.value);
3214
 
      secfile_insert_int(file, old_unit_type_id(punittype),
3215
 
                         "player%d.c%d.currently_building", plrno, i);
3216
 
      secfile_insert_str(file, utype_rule_name(punittype),
3217
 
                         "player%d.c%d.currently_building_name", plrno, i);
3218
 
    } else {
3219
 
      secfile_insert_int(file, old_impr_type_id(pcity->production.value),
3220
 
                         "player%d.c%d.currently_building", plrno, i);
3221
 
      secfile_insert_str(file, improvement_rule_name(
3222
 
                                   pcity->production.value),
3223
 
                         "player%d.c%d.currently_building_name", plrno, i);
3224
 
    }
3225
 
 
3226
 
    /* 1.14 servers depend on improvement order in ruleset. Here we
3227
 
     * are trying to simulate 1.14.1 default order
3228
 
     */
3229
 
    init_old_improvement_bitvector(impr_buf);
3230
 
    impr_type_iterate(id) {
3231
 
      if (pcity->improvements[id] != I_NONE) {
3232
 
        add_improvement_into_old_bitvector(impr_buf, id);
3233
 
      }
3234
 
    } impr_type_iterate_end;
3235
 
    assert(strlen(impr_buf) < sizeof(impr_buf));
3236
 
    secfile_insert_str(file, impr_buf, "player%d.c%d.improvements", plrno, i);
3237
 
 
3238
 
    /* Save improvement list as bitvector. Note that improvement order
 
3836
    /* Save improvement list as bytevector. Note that improvement order
3239
3837
     * is saved in savefile.improvement_order.
3240
3838
     */
3241
 
    impr_type_iterate(id) {
3242
 
      impr_buf[id] = (pcity->improvements[id] != I_NONE) ? '1' : '0';
3243
 
    } impr_type_iterate_end;
3244
 
    impr_buf[game.control.num_impr_types] = '\0';
 
3839
    improvement_iterate(pimprove) {
 
3840
      impr_buf[improvement_index(pimprove)] =
 
3841
        (pcity->built[improvement_index(pimprove)].turn <= I_NEVER)
 
3842
        ? '0' : '1';
 
3843
    } improvement_iterate_end;
 
3844
    impr_buf[improvement_count()] = '\0';
3245
3845
    assert(strlen(impr_buf) < sizeof(impr_buf));
3246
3846
    secfile_insert_str(file, impr_buf,
3247
3847
                       "player%d.c%d.improvements_new", plrno, i);    
3249
3849
    worklist_save(file, &pcity->worklist, wlist_max_length,
3250
3850
                  "player%d.c%d", plrno, i);
3251
3851
 
 
3852
    /* after 2.1.0 new options format.  Old options are lost on upgrade. */
 
3853
    for (j = 0; j < CITYO_LAST; j++) {
 
3854
      secfile_insert_bool(file, BV_ISSET(pcity->city_options, j),
 
3855
                          "player%d.c%d.option%d", plrno, i, j);
 
3856
    }
 
3857
 
3252
3858
    /* FIXME: remove this when the urgency is properly recalculated. */
3253
 
    secfile_insert_int(file, pcity->ai.urgency,
 
3859
    secfile_insert_int(file, pcity->ai->urgency,
3254
3860
                       "player%d.c%d.ai.urgency", plrno, i);
3255
3861
 
3256
3862
    /* avoid myrand recalculations on subsequent reload. */
3257
 
    secfile_insert_int(file, pcity->ai.next_recalc,
 
3863
    secfile_insert_int(file, pcity->ai->building_turn,
3258
3864
                       "player%d.c%d.ai.building_turn", plrno, i);
 
3865
    secfile_insert_int(file, pcity->ai->building_wait,
 
3866
                       "player%d.c%d.ai.building_wait", plrno, i);
3259
3867
 
3260
3868
    /* avoid myrand and expensive recalculations on subsequent reload. */
3261
 
    secfile_insert_int(file, pcity->ai.next_founder_want_recalc,
 
3869
    secfile_insert_int(file, pcity->ai->founder_turn,
3262
3870
                       "player%d.c%d.ai.founder_turn", plrno, i);
3263
 
    secfile_insert_int(file, pcity->ai.founder_want,
 
3871
    secfile_insert_int(file, pcity->ai->founder_want,
3264
3872
                       "player%d.c%d.ai.founder_want", plrno, i);
3265
 
    secfile_insert_bool(file, pcity->ai.founder_boat,
 
3873
    secfile_insert_bool(file, pcity->ai->founder_boat,
3266
3874
                       "player%d.c%d.ai.founder_boat", plrno, i);
3267
 
  }
3268
 
  city_list_iterate_end;
3269
 
 
3270
 
  /********** Put the players private map **********/
3271
 
 /* Otherwise the player can see all, and there's no reason to save the private map. */
3272
 
  if (game.info.fogofwar
3273
 
      && game.save_options.save_private_map) {
3274
 
 
3275
 
    /* put the terrain type */
3276
 
    SAVE_PLAYER_MAP_DATA(ptile, file,"player%d.map_t%03d", plrno, 
3277
 
                         terrain2char(map_get_player_tile
3278
 
                                      (ptile, plr)->terrain));
3279
 
    SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_res%03d", plrno,
3280
 
        resource_to_identifier(map_get_player_tile(ptile, plr)->resource));
3281
 
 
3282
 
    special_halfbyte_iterate(j) {
3283
 
      char buf[32]; /* enough for sprintf() below */
3284
 
      enum tile_special_type mod[4];
3285
 
      int l;
3286
 
 
3287
 
      for (l = 0; l < 4; l++) {
3288
 
        mod[l] = MIN(4 * j + l, S_LAST);
 
3875
  } city_list_iterate_end;
 
3876
}
 
3877
 
 
3878
/****************************************************************************
 
3879
  Save the private vision map for fog of war
 
3880
****************************************************************************/
 
3881
static void player_save_vision(struct player *plr, int plrno,
 
3882
                               struct section_file *file)
 
3883
{
 
3884
  char impr_buf[MAX_NUM_ITEMS + 1];
 
3885
  int i = 0;
 
3886
 
 
3887
  if (!game.info.fogofwar || !game.server.save_options.save_private_map) {
 
3888
    /* The player can see all, there's no reason to save the private map. */
 
3889
    return;
 
3890
  }
 
3891
 
 
3892
  /* put the terrain type */
 
3893
  SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_t%03d", plrno,
 
3894
                       terrain2char(map_get_player_tile
 
3895
                                    (ptile, plr)->terrain));
 
3896
  SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_res%03d", plrno,
 
3897
      resource_to_identifier(map_get_player_tile(ptile, plr)->resource));
 
3898
 
 
3899
  if (game.server.foggedborders) {
 
3900
    SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_owner%03d", plrno,
 
3901
      player_to_identier(map_get_player_tile(ptile, plr)->owner));
 
3902
  }
 
3903
 
 
3904
  special_halfbyte_iterate(j) {
 
3905
    char buf[32]; /* enough for sprintf() below */
 
3906
    enum tile_special_type mod[4];
 
3907
    int l;
 
3908
 
 
3909
    for (l = 0; l < 4; l++) {
 
3910
      mod[l] = MIN(4 * j + l, S_LAST);
 
3911
    }
 
3912
    sprintf (buf, "player%%d.map_spe%02d_%%03d", j);
 
3913
    SAVE_PLAYER_MAP_DATA(ptile, file, buf, plrno,
 
3914
      get_savegame_special(map_get_player_tile(ptile, plr)->special, mod));
 
3915
  } special_halfbyte_iterate_end;
 
3916
 
 
3917
  bases_halfbyte_iterate(j, game.control.num_base_types) {
 
3918
    char buf[32]; /* enough for sprintf() below */
 
3919
    int mod[4];
 
3920
    int l;
 
3921
 
 
3922
    for (l = 0; l < 4; l++) {
 
3923
      if (4 * j + 1 > game.control.num_base_types) {
 
3924
        mod[l] = -1;
 
3925
      } else {
 
3926
        mod[l] = 4 * j + l;
3289
3927
      }
3290
 
      sprintf (buf, "player%%d.map_spe%02d_%%03d", j);
3291
 
      SAVE_PLAYER_MAP_DATA(ptile, file, buf, plrno,
3292
 
        get_savegame_special(map_get_player_tile(ptile, plr)->special, mod));
3293
 
    } special_halfbyte_iterate_end;
3294
 
 
3295
 
    /* put 4-bit segments of 16-bit "updated" field */
3296
 
    SAVE_PLAYER_MAP_DATA(ptile, file,"player%d.map_ua%03d", plrno,
3297
 
                         bin2ascii_hex(map_get_player_tile
3298
 
                                       (ptile, plr)->last_updated, 0));
3299
 
    SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_ub%03d", plrno,
3300
 
                         bin2ascii_hex(map_get_player_tile
3301
 
                                       (ptile, plr)->last_updated, 1));
3302
 
    SAVE_PLAYER_MAP_DATA(ptile, file,"player%d.map_uc%03d", plrno,
3303
 
                         bin2ascii_hex(map_get_player_tile
3304
 
                                       (ptile, plr)->last_updated, 2));
3305
 
    SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_ud%03d", plrno,
3306
 
                         bin2ascii_hex(map_get_player_tile
3307
 
                                       (ptile, plr)->last_updated, 3));
3308
 
 
3309
 
    {
3310
 
      struct vision_base *pdcity;
3311
 
      char impr_buf[MAX_NUM_ITEMS + 1];
3312
 
 
3313
 
      i = 0;
3314
 
      
3315
 
      whole_map_iterate(ptile) {
3316
 
        if (NULL != (pdcity = map_get_player_base(ptile, plr))
3317
 
         && VISION_BASE_RUIN < pdcity->identity) {
3318
 
          secfile_insert_int(file, pdcity->identity, "player%d.dc%d.id",
3319
 
                             plrno, i);
3320
 
          secfile_insert_int(file, ptile->nat_x,
3321
 
                             "player%d.dc%d.x", plrno, i);
3322
 
          secfile_insert_int(file, ptile->nat_y,
3323
 
                             "player%d.dc%d.y", plrno, i);
3324
 
          secfile_insert_str(file, pdcity->name, "player%d.dc%d.name",
3325
 
                             plrno, i);
3326
 
          secfile_insert_int(file, pdcity->size, "player%d.dc%d.size",
3327
 
                             plrno, i);
3328
 
          secfile_insert_bool(file, FALSE,
3329
 
                              "player%d.dc%d.has_walls", plrno, i);
3330
 
          secfile_insert_bool(file, pdcity->occupied,
3331
 
                              "player%d.dc%d.occupied", plrno, i);
3332
 
          secfile_insert_bool(file, pdcity->walls,
3333
 
                              "player%d.dc%d.walls", plrno, i);
3334
 
          secfile_insert_bool(file, pdcity->happy,
3335
 
                              "player%d.dc%d.happy", plrno, i);
3336
 
          secfile_insert_bool(file, pdcity->unhappy,
3337
 
                              "player%d.dc%d.unhappy", plrno, i);
3338
 
          secfile_insert_int(file, vision_owner(pdcity)->player_no,
3339
 
                             "player%d.dc%d.owner", plrno, i);
3340
 
 
3341
 
          /* Save improvement list as bitvector. Note that improvement order
3342
 
           * is saved in savefile.improvement_order.
3343
 
           */
3344
 
          impr_type_iterate(id) {
3345
 
            impr_buf[id] = BV_ISSET(pdcity->improvements, id) ? '1' : '0';
3346
 
          } impr_type_iterate_end;
3347
 
          impr_buf[game.control.num_impr_types] = '\0';
3348
 
          assert(strlen(impr_buf) < sizeof(impr_buf));
3349
 
          secfile_insert_str(file, impr_buf,
3350
 
                             "player%d.dc%d.improvements", plrno, i);    
3351
 
 
3352
 
          i++;
3353
 
        }
3354
 
      } whole_map_iterate_end;
3355
 
    }
3356
 
    secfile_insert_int(file, i, "player%d.total_ncities", plrno);
3357
 
  }
3358
 
 
 
3928
    }
 
3929
    sprintf (buf, "player%%d.map_b%02d_%%03d", j);
 
3930
    SAVE_PLAYER_MAP_DATA(ptile, file, buf, plrno,
 
3931
                         get_savegame_bases(map_get_player_tile(ptile, plr)->bases, mod));
 
3932
  } bases_halfbyte_iterate_end;
 
3933
 
 
3934
  /* put 4-bit segments of 16-bit "updated" field */
 
3935
  SAVE_PLAYER_MAP_DATA(ptile, file,"player%d.map_ua%03d", plrno,
 
3936
                       bin2ascii_hex(map_get_player_tile
 
3937
                                     (ptile, plr)->last_updated, 0));
 
3938
  SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_ub%03d", plrno,
 
3939
                       bin2ascii_hex(map_get_player_tile
 
3940
                                     (ptile, plr)->last_updated, 1));
 
3941
  SAVE_PLAYER_MAP_DATA(ptile, file,"player%d.map_uc%03d", plrno,
 
3942
                       bin2ascii_hex(map_get_player_tile
 
3943
                                     (ptile, plr)->last_updated, 2));
 
3944
  SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_ud%03d", plrno,
 
3945
                       bin2ascii_hex(map_get_player_tile
 
3946
                                     (ptile, plr)->last_updated, 3));
 
3947
 
 
3948
  whole_map_iterate(ptile) {
 
3949
    struct vision_site *pdcity = map_get_player_city(ptile, plr);
 
3950
 
 
3951
    if (NULL != pdcity && plr != vision_owner(pdcity)) {
 
3952
      secfile_insert_int(file, ptile->nat_y,
 
3953
                         "player%d.dc%d.y", plrno, i);
 
3954
      secfile_insert_int(file, ptile->nat_x,
 
3955
                         "player%d.dc%d.x", plrno, i);
 
3956
      secfile_insert_int(file, pdcity->identity,
 
3957
                         "player%d.dc%d.id", plrno, i);
 
3958
      secfile_insert_int(file, player_number(vision_owner(pdcity)),
 
3959
                         "player%d.dc%d.owner", plrno, i);
 
3960
 
 
3961
      secfile_insert_int(file, pdcity->size,
 
3962
                         "player%d.dc%d.size", plrno, i);
 
3963
      secfile_insert_bool(file, pdcity->occupied,
 
3964
                          "player%d.dc%d.occupied", plrno, i);
 
3965
      secfile_insert_bool(file, pdcity->walls,
 
3966
                          "player%d.dc%d.walls", plrno, i);
 
3967
      secfile_insert_bool(file, pdcity->happy,
 
3968
                          "player%d.dc%d.happy", plrno, i);
 
3969
      secfile_insert_bool(file, pdcity->unhappy,
 
3970
                          "player%d.dc%d.unhappy", plrno, i);
 
3971
 
 
3972
      /* Save improvement list as bitvector. Note that improvement order
 
3973
       * is saved in savefile.improvement_order.
 
3974
       */
 
3975
      assert(improvement_count() < sizeof(impr_buf));
 
3976
      improvement_iterate(pimprove) {
 
3977
        impr_buf[improvement_index(pimprove)] =
 
3978
          BV_ISSET(pdcity->improvements, improvement_index(pimprove))
 
3979
          ? '1' : '0';
 
3980
      } improvement_iterate_end;
 
3981
      impr_buf[improvement_count()] = '\0';
 
3982
      secfile_insert_str(file, impr_buf,
 
3983
                         "player%d.dc%d.improvements", plrno, i);
 
3984
 
 
3985
      secfile_insert_str(file, pdcity->name,
 
3986
                         "player%d.dc%d.name", plrno, i);
 
3987
 
 
3988
      i++;
 
3989
    }
 
3990
  } whole_map_iterate_end;
 
3991
 
 
3992
  secfile_insert_int(file, i, "player%d.total_ncities", plrno);
 
3993
}
 
3994
 
 
3995
/****************************************************************************
 
3996
...
 
3997
****************************************************************************/
 
3998
static void player_save_attributes(struct player *plr, int plrno,
 
3999
                                   struct section_file *file)
 
4000
{
3359
4001
  /* This is a big heap of opaque data from the client.  Although the binary
3360
4002
   * format is not user editable, keep the lines short enough for debugging,
3361
4003
   * and hope that data compression will keep the file a reasonable size.
3429
4071
#undef PART_SIZE
3430
4072
}
3431
4073
 
3432
 
 
3433
4074
/***************************************************************
3434
4075
 Assign values to ord_city and ord_map for each unit, so the
3435
4076
 values can be saved.
3478
4119
}
3479
4120
 
3480
4121
/***************************************************************
3481
 
Old savegames have defects...
 
4122
  Revised algorithms or savegame defects may cause changes.
 
4123
  Update pcity->city_map[][] and ptile->worked directly.
3482
4124
***************************************************************/
3483
 
static void check_city(struct city *pcity)
 
4125
static void repair_city_worker(struct city *pcity)
3484
4126
{
3485
 
  city_map_iterate(x, y) {
3486
 
    bool res = city_can_work_tile(pcity, x, y);
 
4127
  struct tile *pcenter = city_tile(pcity);
 
4128
 
 
4129
  city_tile_iterate_cxy(pcenter, ptile, x, y) {
 
4130
    bool res = city_can_work_tile(pcity, ptile);
 
4131
 
 
4132
    /* bypass city_map_status() checks is_valid_city_coords() */
3487
4133
    switch (pcity->city_map[x][y]) {
3488
4134
    case C_TILE_EMPTY:
3489
4135
      if (!res) {
3490
 
        set_worker_city(pcity, x, y, C_TILE_UNAVAILABLE);
3491
 
        freelog(LOG_VERBOSE, "Unavailable tile marked as empty"
3492
 
                " for %s (%d,%d)",
3493
 
                city_name(pcity), x, y);
 
4136
        pcity->city_map[x][y] = C_TILE_UNAVAILABLE;
 
4137
 
 
4138
        freelog(LOG_WORKER, "repair_city_worker()"
 
4139
                " {%d,%d} empty tile (%d,%d)"
 
4140
                " should be unavailable"
 
4141
                " for (%d,%d) \"%s\"[%d]",
 
4142
                x, y,
 
4143
                TILE_XY(ptile),
 
4144
                TILE_XY(pcenter), city_name(pcity), pcity->size);
3494
4145
      }
3495
4146
      break;
 
4147
 
3496
4148
    case C_TILE_WORKER:
3497
4149
      if (!res) {
3498
 
        struct tile *ptile= city_map_to_map(pcity, x, y);
3499
 
 
3500
 
        pcity->specialists[DEFAULT_SPECIALIST]++;
3501
 
        set_worker_city(pcity, x, y, C_TILE_UNAVAILABLE);
3502
 
        freelog(LOG_VERBOSE, "Worked tile was unavailable"
3503
 
                " for %s (%d,%d)",
3504
 
                city_name(pcity), x, y);
3505
 
 
3506
 
        map_city_radius_iterate(ptile, tile2) {
3507
 
          struct city *pcity2 = tile_get_city(tile2);
3508
 
          if (pcity2)
3509
 
            check_city(pcity2);
3510
 
        } map_city_radius_iterate_end;
 
4150
        pcity->city_map[x][y] = C_TILE_UNAVAILABLE;
 
4151
        if (tile_worked(ptile) == pcity) {
 
4152
          /* duplicates map_claim_ownership() city_map_update_tile_frozen() */
 
4153
          tile_set_worked(ptile, NULL);
 
4154
          pcity->specialists[DEFAULT_SPECIALIST]++;
 
4155
          auto_arrange_workers(pcity);
 
4156
        }
 
4157
 
 
4158
        freelog(LOG_WORKER, "repair_city_worker()"
 
4159
                " {%d,%d} worked tile (%d,%d)"
 
4160
                " should be unavailable"
 
4161
                " for (%d,%d) \"%s\"[%d]",
 
4162
                x, y,
 
4163
                TILE_XY(ptile),
 
4164
                TILE_XY(pcenter), city_name(pcity), pcity->size);
 
4165
 
 
4166
        city_tile_iterate(ptile, tile2) {
 
4167
          struct city *pcity2 = tile_city(tile2);
 
4168
 
 
4169
          if (pcity2 && pcity2 != pcity) {
 
4170
            freelog(LOG_WORKER, "repair_city_worker()"
 
4171
                    " checking nearby \"%s\"",
 
4172
                    city_name(pcity2));
 
4173
            repair_city_worker(pcity2);
 
4174
            freelog(LOG_WORKER, "repair_city_worker()"
 
4175
                    " continuing with \"%s\"",
 
4176
                    city_name(pcity));
 
4177
          }
 
4178
        } city_tile_iterate_end;
3511
4179
      }
3512
4180
      break;
 
4181
 
3513
4182
    case C_TILE_UNAVAILABLE:
3514
4183
      if (res) {
3515
 
        set_worker_city(pcity, x, y, C_TILE_EMPTY);
3516
 
        freelog(LOG_VERBOSE, "Empty tile marked as unavailable"
3517
 
                " for %s (%d,%d)",
3518
 
                city_name(pcity), x, y);
 
4184
        pcity->city_map[x][y] = C_TILE_EMPTY;
 
4185
 
 
4186
        freelog(LOG_WORKER, "repair_city_worker()"
 
4187
                " {%d,%d} unavailable tile (%d,%d)"
 
4188
                " should be empty"
 
4189
                " for (%d,%d) \"%s\"[%d]",
 
4190
                x, y,
 
4191
                TILE_XY(ptile),
 
4192
                TILE_XY(pcenter), city_name(pcity), pcity->size);
3519
4193
      }
3520
4194
      break;
3521
 
    }
3522
 
  } city_map_iterate_end;
3523
4195
 
3524
 
  city_refresh(pcity);
 
4196
    default:
 
4197
      freelog(LOG_ERROR, "repair_city_worker()"
 
4198
              " {%d,%d} bad city tile (%d,%d)"
 
4199
              " value %d"
 
4200
              " for (%d,%d) \"%s\"[%d]",
 
4201
              x, y,
 
4202
              TILE_XY(ptile),
 
4203
              pcity->city_map[x][y],
 
4204
              TILE_XY(pcenter), city_name(pcity), pcity->size);
 
4205
      break;
 
4206
    };
 
4207
  } city_tile_iterate_cxy_end;
3525
4208
}
3526
4209
 
3527
4210
/***************************************************************
3530
4213
***************************************************************/
3531
4214
void game_load(struct section_file *file)
3532
4215
{
3533
 
  int i, k, id;
 
4216
  bool was_send_city_suppressed = send_city_suppression(TRUE);
 
4217
  bool was_send_tile_suppressed = send_tile_suppression(TRUE);
 
4218
 
 
4219
  game_load_internal(file);
 
4220
 
 
4221
  send_tile_suppression(was_send_tile_suppressed);
 
4222
  send_city_suppression(was_send_city_suppressed);
 
4223
}
 
4224
 
 
4225
/***************************************************************
 
4226
  Real game_load function.
 
4227
***************************************************************/
 
4228
static void game_load_internal(struct section_file *file)
 
4229
{
 
4230
  int i, k;
 
4231
  int game_version;
3534
4232
  enum server_states tmp_server_state;
3535
4233
  RANDOM_STATE rstate;
3536
 
  char *savefile_options;
3537
4234
  const char *string;
3538
 
  char** improvement_order = NULL;
3539
4235
  int improvement_order_size = 0;
3540
 
  char** technology_order = NULL;
3541
 
  enum tile_special_type *special_order = NULL;
3542
4236
  int technology_order_size = 0;
3543
 
  const char* name;
3544
4237
  int civstyle = 0;
 
4238
  char *scen_text;
 
4239
  char **improvement_order = NULL;
 
4240
  char **technology_order = NULL;
 
4241
  enum tile_special_type *special_order = NULL;
 
4242
  struct base_type **base_order = NULL;
 
4243
  int num_base_types = 0;
 
4244
  char *savefile_options = secfile_lookup_str(file, "savefile.options");
3545
4245
 
3546
4246
  /* [savefile] */
3547
 
  savefile_options = secfile_lookup_str(file, "savefile.options");
3548
4247
 
3549
4248
  /* We don't need savefile.reason, but read it anyway to avoid
3550
4249
   * warnings about unread secfile entries. */
3577
4276
    }
3578
4277
  }
3579
4278
 
 
4279
  /* [scenario] */
 
4280
  scen_text = secfile_lookup_str_default(file, "", "scenario.name");
 
4281
  if (scen_text[0] != '\0') {
 
4282
    game.scenario.is_scenario = TRUE;
 
4283
    sz_strlcpy(game.scenario.name, scen_text);
 
4284
    scen_text = secfile_lookup_str_default(file, "",
 
4285
                                           "scenarion.description");
 
4286
    if (scen_text[0] != '\0') {
 
4287
      sz_strlcpy(game.scenario.description, scen_text);
 
4288
    } else {
 
4289
      game.scenario.description[0] = '\0';
 
4290
    }
 
4291
    game.scenario.players
 
4292
      = secfile_lookup_bool_default(file, TRUE, "scenario.save_players");
 
4293
  } else {
 
4294
    game.scenario.is_scenario = FALSE;
 
4295
  }
 
4296
 
3580
4297
  /* [game] */
3581
 
  game.version = secfile_lookup_int_default(file, 0, "game.version");
 
4298
  game_version = secfile_lookup_int_default(file, 0, "game.version");
3582
4299
 
3583
4300
  /* we require at least version 1.9.0 */
3584
 
  if (10900 > game.version) {
3585
 
    /* TRANS: Fatal error message. */
 
4301
  if (10900 > game_version) {
3586
4302
    freelog(LOG_FATAL,
 
4303
            /* TRANS: Fatal error message. */
3587
4304
            _("Saved game is too old, at least version 1.9.0 required."));
3588
4305
    exit(EXIT_FAILURE);
3589
4306
  }
3590
4307
 
3591
 
  tmp_server_state = (enum server_states)
3592
 
    secfile_lookup_int_default(file, S_S_RUNNING, "game.server_state");
 
4308
  tmp_server_state = server_states_invalid();
 
4309
  if (section_file_lookup(file, "game.server_state")) {
 
4310
    string = secfile_lookup_str_int(file, (int *) &tmp_server_state,
 
4311
                                    "game.server_state");
 
4312
    if (NULL != string) {
 
4313
      /* new in 2.2: server_state as string; see srv_main.h */
 
4314
      tmp_server_state = server_states_by_name(string, strcmp);
 
4315
    }
 
4316
  }
 
4317
  if (!server_states_is_valid(tmp_server_state)) {
 
4318
    tmp_server_state = S_S_RUNNING;
 
4319
  }
3593
4320
 
3594
4321
  {
3595
4322
    set_meta_patches_string(secfile_lookup_str_default(file, 
3596
4323
                                                default_meta_patches_string(),
3597
4324
                                                "game.metapatches"));
3598
 
    game.meta_info.user_message_set = secfile_lookup_bool_default(file,
3599
 
                                                                  FALSE,
3600
 
                                                "game.user_metamessage");
3601
 
    if (game.meta_info.user_message_set) {
 
4325
    game.server.meta_info.user_message_set =
 
4326
      secfile_lookup_bool_default(file, FALSE, "game.user_metamessage");
 
4327
    if (game.server.meta_info.user_message_set) {
3602
4328
      set_user_meta_message_string(secfile_lookup_str_default(file, 
3603
4329
                                                default_meta_message_string(),
3604
4330
                                                "game.metamessage"));
3620
4346
      game.info.skill_level = GAME_OLD_DEFAULT_SKILL_LEVEL;
3621
4347
 
3622
4348
    game.info.timeout       = secfile_lookup_int(file, "game.timeout");
3623
 
    game.timeoutint = secfile_lookup_int_default(file,
3624
 
                                                 GAME_DEFAULT_TIMEOUTINT,
3625
 
                                                 "game.timeoutint");
3626
 
    game.timeoutintinc =
 
4349
    game.server.timeoutint =
 
4350
      secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINT,
 
4351
                                 "game.timeoutint");
 
4352
    game.server.timeoutintinc =
3627
4353
        secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINTINC,
3628
4354
                                   "game.timeoutintinc");
3629
 
    game.timeoutinc =
 
4355
    game.server.timeoutinc =
3630
4356
        secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINC,
3631
4357
                                   "game.timeoutinc");
3632
 
    game.timeoutincmult =
 
4358
    game.server.timeoutincmult =
3633
4359
        secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINCMULT,
3634
4360
                                   "game.timeoutincmult");
3635
 
    game.timeoutcounter =
 
4361
    game.server.timeoutcounter =
3636
4362
        secfile_lookup_int_default(file, 1, "game.timeoutcounter");
3637
4363
 
3638
 
    game.timeoutaddenemymove
3639
 
      = secfile_lookup_int_default(file, game.timeoutaddenemymove,
 
4364
    game.server.timeoutaddenemymove
 
4365
      = secfile_lookup_int_default(file, game.server.timeoutaddenemymove,
3640
4366
                                   "game.timeoutaddenemymove");
3641
4367
 
3642
 
    
3643
 
    game.info.end_year      = secfile_lookup_int(file, "game.end_year");
 
4368
    game.info.end_turn      = secfile_lookup_int_default(file, 5000,
 
4369
                                                         "game.end_turn");
3644
4370
    game.info.shieldbox
3645
4371
      = secfile_lookup_int_default(file, GAME_DEFAULT_SHIELDBOX,
3646
4372
                                   "game.box_shield");
3657
4383
    }
3658
4384
 
3659
4385
    game.info.year          = secfile_lookup_int(file, "game.year");
 
4386
    game.info.year_0_hack   = secfile_lookup_bool_default(file, FALSE,
 
4387
                                                          "game.year_0_hack");
3660
4388
 
3661
4389
    if (has_capability("turn", savefile_options)) {
3662
4390
      game.info.turn = secfile_lookup_int(file, "game.turn");
3663
4391
    } else {
3664
4392
      game.info.turn = 0;
3665
4393
    }
3666
 
    game.info.simultaneous_phases
3667
 
      = secfile_lookup_bool_default(file, TRUE,
3668
 
                                    "game.simultaneous_phases_now");
3669
 
    game.simultaneous_phases_stored
3670
 
      = secfile_lookup_bool_default(file, TRUE,
3671
 
                                    "game.simultaneous_phases_stored");
 
4394
 
 
4395
    if (section_file_lookup(file, "game.simultaneous_phases_now")) {
 
4396
      bool sp_now;
 
4397
 
 
4398
      sp_now = secfile_lookup_bool(file, "game.simultaneous_phases_now");
 
4399
      game.info.phase_mode = (sp_now ? PMT_CONCURRENT
 
4400
                              : PMT_PLAYERS_ALTERNATE);
 
4401
 
 
4402
    } else {
 
4403
      game.info.phase_mode = GAME_DEFAULT_PHASE_MODE;
 
4404
    }
 
4405
 
 
4406
    if (section_file_lookup(file, "game.simultaneous_phases_stored")) {
 
4407
      bool sp_stored;
 
4408
 
 
4409
      sp_stored
 
4410
        = secfile_lookup_bool(file, "game.simultaneous_phases_stored");
 
4411
      game.server.phase_mode_stored = (sp_stored ? PMT_CONCURRENT
 
4412
                                       : PMT_PLAYERS_ALTERNATE);
 
4413
    } else {
 
4414
      game.server.phase_mode_stored = game.info.phase_mode;
 
4415
    }
 
4416
 
 
4417
    game.info.phase_mode
 
4418
      = secfile_lookup_int_default(file, game.info.phase_mode,
 
4419
                                   "game.phase_mode");
 
4420
    game.server.phase_mode_stored
 
4421
      = secfile_lookup_int_default(file, game.server.phase_mode_stored,
 
4422
                                   "game.phase_mode_stored");
3672
4423
 
3673
4424
    game.info.min_players   = secfile_lookup_int(file, "game.min_players");
3674
4425
    game.info.max_players   = secfile_lookup_int(file, "game.max_players");
3676
4427
    game.info.heating = secfile_lookup_int_default(file, 0, "game.heating");
3677
4428
    game.info.globalwarming = secfile_lookup_int(file, "game.globalwarming");
3678
4429
    game.info.warminglevel  = secfile_lookup_int(file, "game.warminglevel");
 
4430
    game.info.nuclearwinter = secfile_lookup_int_default(file, 0, "game.nuclearwinter");
3679
4431
    game.info.cooling = secfile_lookup_int_default(file, 0, "game.cooling");
3680
 
    game.info.nuclearwinter = secfile_lookup_int_default(file, 0, "game.nuclearwinter");
3681
4432
    game.info.coolinglevel = secfile_lookup_int_default(file, 8, "game.coolinglevel");
3682
 
    game.info.notradesize = 
 
4433
    game.info.notradesize =
3683
4434
      secfile_lookup_int_default(file, GAME_DEFAULT_NOTRADESIZE, "game.notradesize");
3684
 
    game.info.fulltradesize = 
 
4435
    game.info.fulltradesize =
3685
4436
      secfile_lookup_int_default(file, GAME_DEFAULT_FULLTRADESIZE, "game.fulltradesize");
3686
 
    game.info.unhappysize = 
3687
 
      secfile_lookup_int_default(file, GAME_DEFAULT_UNHAPPYSIZE, "game.unhappysize");
3688
 
    game.info.angrycitizen = 
 
4437
    game.info.trademindist =
 
4438
      secfile_lookup_int_default(file, GAME_DEFAULT_TRADEMINDIST, "game.trademindist");
 
4439
    game.info.angrycitizen =
3689
4440
      secfile_lookup_bool_default(file, GAME_DEFAULT_ANGRYCITIZEN, "game.angrycitizen");
3690
 
    game.info.cityfactor  = 
3691
 
      secfile_lookup_int_default(file, GAME_DEFAULT_CITYFACTOR, "game.cityfactor");
3692
 
    game.info.diplcost    = 
 
4441
    game.info.citymindist =
 
4442
      secfile_lookup_int_default(file, GAME_DEFAULT_CITYMINDIST, "game.citymindist");
 
4443
    game.info.rapturedelay =
 
4444
      secfile_lookup_int_default(file, GAME_DEFAULT_RAPTUREDELAY, "game.rapturedelay");
 
4445
    game.info.diplcost =
3693
4446
      secfile_lookup_int_default(file, GAME_DEFAULT_DIPLCOST, "game.diplcost");
3694
 
    game.info.freecost    = 
 
4447
    game.info.freecost =
3695
4448
      secfile_lookup_int_default(file, GAME_DEFAULT_FREECOST, "game.freecost");
3696
 
    game.info.conquercost = 
 
4449
    game.info.conquercost =
3697
4450
      secfile_lookup_int_default(file, GAME_DEFAULT_CONQUERCOST, "game.conquercost");
3698
 
    game.info.foodbox   = secfile_lookup_int_default(file, 0, "game.box_food");
 
4451
 
 
4452
    game.info.foodbox = secfile_lookup_int_default(file, 0, "game.box_food");
3699
4453
    if (game.info.foodbox == 0) {
3700
4454
      /* foodbox was used for 2.0 and earlier servers. */
3701
4455
      game.info.foodbox = 10 * secfile_lookup_int_default(file, 100, "game.foodbox");
3702
4456
    }
3703
 
    game.info.techpenalty = 
 
4457
    game.info.techpenalty =
3704
4458
      secfile_lookup_int_default(file, GAME_DEFAULT_TECHPENALTY, "game.techpenalty");
3705
 
    game.info.razechance  = 
 
4459
    game.info.razechance =
3706
4460
      secfile_lookup_int_default(file, GAME_DEFAULT_RAZECHANCE, "game.razechance");
3707
 
    game.info.save_nturns = 
 
4461
 
 
4462
    civstyle = secfile_lookup_int_default(file, 2, "game.civstyle");
 
4463
    game.info.save_nturns =
3708
4464
      secfile_lookup_int_default(file, GAME_DEFAULT_SAVETURNS, "game.save_nturns");
3709
4465
 
3710
4466
    /* suppress warnings about unused entries in old savegames: */
3713
4469
    (void) section_file_lookup(file, "game.rail_trade");
3714
4470
    (void) section_file_lookup(file, "game.farmfood");
3715
4471
 
3716
 
    civstyle = secfile_lookup_int_default(file, 2, "game.civstyle");
3717
 
 
3718
 
    game.info.citymindist  = secfile_lookup_int_default(file,
3719
 
      GAME_DEFAULT_CITYMINDIST, "game.citymindist");
3720
 
 
3721
 
    game.info.rapturedelay  = secfile_lookup_int_default(file,
3722
 
      GAME_DEFAULT_RAPTUREDELAY, "game.rapturedelay");
3723
 
 
3724
4472
    /* National borders setting. */
3725
4473
    game.info.borders = secfile_lookup_int_default(file, 0, "game.borders");
 
4474
    if (game.info.borders > GAME_MAX_BORDERS) {
 
4475
      game.info.borders = 1;
 
4476
    }
3726
4477
    game.info.happyborders = secfile_lookup_bool_default(file, FALSE, 
3727
4478
                                                    "game.happyborders");
3728
4479
 
3730
4481
    game.info.diplomacy = secfile_lookup_int_default(file, GAME_DEFAULT_DIPLOMACY, 
3731
4482
                                                "game.diplomacy");
3732
4483
 
3733
 
    sz_strlcpy(game.save_name,
 
4484
    sz_strlcpy(game.server.save_name,
3734
4485
               secfile_lookup_str_default(file, GAME_DEFAULT_SAVE_NAME,
3735
4486
                                          "game.save_name"));
3736
4487
    game.info.save_compress_level
3737
4488
      = secfile_lookup_int_default(file, GAME_DEFAULT_COMPRESS_LEVEL,
3738
4489
                                   "game.save_compress_level");
 
4490
    game.info.save_compress_type
 
4491
      = secfile_lookup_int_default(file, GAME_DEFAULT_COMPRESS_TYPE,
 
4492
                                   "game.save_compress_type");
3739
4493
 
3740
4494
    game.info.aifill = secfile_lookup_int_default(file, 0, "game.aifill");
3741
4495
 
3742
 
    game.scorelog = secfile_lookup_bool_default(file, FALSE, "game.scorelog");
3743
 
    game.scoreturn =
3744
 
      secfile_lookup_int_default(file, game.info.turn + GAME_DEFAULT_SCORETURN,
3745
 
                                       "game.scoreturn");
3746
 
    sz_strlcpy(game.id, secfile_lookup_str_default(file, "", "game.id"));
 
4496
    game.server.scorelog = secfile_lookup_bool_default(file, FALSE,
 
4497
                                                       "game.scorelog");
 
4498
    game.server.scoreturn =
 
4499
      secfile_lookup_int_default(file,
 
4500
                                 game.info.turn + GAME_DEFAULT_SCORETURN,
 
4501
                                 "game.scoreturn");
 
4502
    sz_strlcpy(server.game_identifier,
 
4503
               secfile_lookup_str_default(file, "", "game.id"));
 
4504
    /* We are not checking game_identifier legality just yet.
 
4505
     * That's done when we are sure that rand seed has been initialized,
 
4506
     * so that we can generate new game_identifier, if needed. */
3747
4507
 
3748
4508
    game.info.fogofwar = secfile_lookup_bool_default(file, FALSE, "game.fogofwar");
3749
 
    game.fogofwar_old = game.info.fogofwar;
3750
 
  
 
4509
    game.server.fogofwar_old = game.info.fogofwar;
 
4510
 
 
4511
    game.server.foggedborders
 
4512
      = secfile_lookup_bool_default(file, GAME_DEFAULT_FOGGEDBORDERS,
 
4513
                                    "game.foggedborders");
 
4514
 
3751
4515
    game.info.civilwarsize =
3752
4516
      secfile_lookup_int_default(file, GAME_DEFAULT_CIVILWARSIZE,
3753
4517
                                 "game.civilwarsize");
3770
4534
      }
3771
4535
    }
3772
4536
 
3773
 
    game.info.aqueductloss = secfile_lookup_int_default(file, game.info.aqueductloss,
3774
 
                                                   "game.aqueductloss");
3775
 
    game.info.killcitizen = secfile_lookup_int_default(file, game.info.killcitizen,
3776
 
                                                  "game.killcitizen");
3777
 
    game.info.savepalace = secfile_lookup_bool_default(file, game.info.savepalace,
3778
 
                                                "game.savepalace");
3779
 
    game.info.turnblock = secfile_lookup_bool_default(file, game.info.turnblock,
3780
 
                                                "game.turnblock");
3781
 
    game.info.fixedlength = secfile_lookup_bool_default(file, game.info.fixedlength,
3782
 
                                                  "game.fixedlength");
3783
 
    game.info.barbarianrate = secfile_lookup_int_default(file, game.info.barbarianrate,
3784
 
                                                    "game.barbarians");
3785
 
    game.info.onsetbarbarian = secfile_lookup_int_default(file, game.info.onsetbarbarian,
3786
 
                                                     "game.onsetbarbs");
3787
 
    game.info.revolution_length
3788
 
      = secfile_lookup_int_default(file, game.info.revolution_length,
3789
 
                                   "game.revolen");
3790
 
    game.info.nbarbarians = 0; /* counted in player_load for compatibility with 
3791
 
                             1.10.0 */
3792
 
    game.info.occupychance = secfile_lookup_int_default(file, game.info.occupychance,
3793
 
                                                   "game.occupychance");
3794
 
    game.info.autoattack = secfile_lookup_bool_default(file,
3795
 
                                                  GAME_DEFAULT_AUTOATTACK,
3796
 
                                                  "game.autoattack");
3797
 
    game.seed = secfile_lookup_int_default(file, game.seed,
3798
 
                                           "game.randseed");
 
4537
    game.info.aqueductloss =
 
4538
      secfile_lookup_int_default(file, game.info.aqueductloss,
 
4539
                                 "game.aqueductloss");
 
4540
    game.info.killcitizen =
 
4541
      secfile_lookup_int_default(file, game.info.killcitizen,
 
4542
                                 "game.killcitizen");
 
4543
    game.info.savepalace =
 
4544
      secfile_lookup_bool_default(file, game.info.savepalace,
 
4545
                                  "game.savepalace");
 
4546
    game.info.turnblock =
 
4547
      secfile_lookup_bool_default(file, game.info.turnblock,
 
4548
                                  "game.turnblock");
 
4549
    game.info.fixedlength =
 
4550
      secfile_lookup_bool_default(file, game.info.fixedlength,
 
4551
                                  "game.fixedlength");
 
4552
    game.info.barbarianrate =
 
4553
      secfile_lookup_int_default(file, game.info.barbarianrate,
 
4554
                                 "game.barbarians");
 
4555
    game.info.onsetbarbarian =
 
4556
      secfile_lookup_int_default(file, game.info.onsetbarbarian,
 
4557
                                 "game.onsetbarbs");
 
4558
    game.info.revolution_length =
 
4559
      secfile_lookup_int_default(file, game.info.revolution_length,
 
4560
                                 "game.revolen");
 
4561
    game.info.occupychance =
 
4562
      secfile_lookup_int_default(file, game.info.occupychance,
 
4563
                                 "game.occupychance");
 
4564
    game.info.autoattack =
 
4565
      secfile_lookup_bool_default(file, GAME_DEFAULT_AUTOATTACK,
 
4566
                                  "game.autoattack");
 
4567
    game.server.seed =
 
4568
      secfile_lookup_int_default(file, game.server.seed,
 
4569
                                 "game.randseed");
3799
4570
    game.info.allowed_city_names =
3800
 
        secfile_lookup_int_default(file, game.info.allowed_city_names,
3801
 
                                   "game.allowed_city_names"); 
 
4571
      secfile_lookup_int_default(file, game.info.allowed_city_names,
 
4572
                                 "game.allowed_city_names"); 
 
4573
    game.info.migration =
 
4574
      secfile_lookup_int_default(file, game.info.migration,
 
4575
                                 "game.migration");
 
4576
    game.info.mgr_turninterval =
 
4577
      secfile_lookup_int_default(file, game.info.mgr_turninterval,
 
4578
                                 "game.mgr_turninterval");
 
4579
    game.info.mgr_foodneeded =
 
4580
      secfile_lookup_bool_default(file, game.info.mgr_foodneeded,
 
4581
                                 "game.mgr_foodneeded");
 
4582
    game.info.mgr_distance =
 
4583
      secfile_lookup_int_default(file, game.info.mgr_distance,
 
4584
                                 "game.mgr_distance");
 
4585
    game.info.mgr_nationchance =
 
4586
      secfile_lookup_int_default(file, game.info.mgr_nationchance,
 
4587
                                 "game.mgr_nationchance");
 
4588
    game.info.mgr_worldchance =
 
4589
      secfile_lookup_int_default(file, game.info.mgr_worldchance,
 
4590
                                 "game.mgr_worldchance");
3802
4591
 
3803
4592
    if(civstyle == 1) {
3804
4593
      string = "civ1";
3838
4627
      T("game.info.t.game");
3839
4628
#undef T
3840
4629
 
3841
 
      sz_strlcpy(game.rulesetdir, str);
 
4630
      sz_strlcpy(game.server.rulesetdir, str);
3842
4631
    } else {
3843
 
      sz_strlcpy(game.rulesetdir, 
 
4632
      sz_strlcpy(game.server.rulesetdir, 
3844
4633
               secfile_lookup_str_default(file, string,
3845
4634
                                          "game.rulesetdir"));
3846
4635
    }
3847
4636
 
3848
 
    sz_strlcpy(game.demography,
 
4637
    sz_strlcpy(game.server.demography,
3849
4638
               secfile_lookup_str_default(file, GAME_DEFAULT_DEMOGRAPHY,
3850
4639
                                          "game.demography"));
3851
 
    sz_strlcpy(game.allow_take,
 
4640
    sz_strlcpy(game.server.allow_take,
3852
4641
               secfile_lookup_str_default(file, GAME_DEFAULT_ALLOW_TAKE,
3853
4642
                                          "game.allow_take"));
3854
4643
 
3855
4644
    game.info.spacerace = secfile_lookup_bool_default(file, game.info.spacerace,
3856
4645
                                                "game.spacerace");
 
4646
    game.info.endspaceship =
 
4647
      secfile_lookup_bool_default(file, game.info.endspaceship,
 
4648
                                  "game.endspaceship");
3857
4649
 
3858
4650
    game.info.auto_ai_toggle = 
3859
4651
      secfile_lookup_bool_default(file, game.info.auto_ai_toggle, 
3860
4652
                                  "game.auto_ai_toggle");
3861
4653
 
 
4654
    game.server.event_cache.turns =
 
4655
      secfile_lookup_int_default(file, game.server.event_cache.turns,
 
4656
                                 "game.event_cache.turns");
 
4657
    game.server.event_cache.max_size =
 
4658
      secfile_lookup_int_default(file, game.server.event_cache.max_size,
 
4659
                                 "game.event_cache.max_size");
 
4660
    game.server.event_cache.chat =
 
4661
      secfile_lookup_bool_default(file, game.server.event_cache.chat,
 
4662
                                 "game.event_cache.chat");
 
4663
    game.server.event_cache.info =
 
4664
      secfile_lookup_bool_default(file, game.server.event_cache.info,
 
4665
                                 "game.event_cache.info");
 
4666
 
3862
4667
    load_rulesets();
3863
4668
  }
3864
4669
 
 
4670
  if (has_capability("bases", savefile_options)) {
 
4671
    char **modname = NULL;
 
4672
    int j;
 
4673
 
 
4674
    num_base_types = secfile_lookup_int_default(file, 0,
 
4675
                                                "savefile.num_bases");
 
4676
 
 
4677
    if (num_base_types > 0) {
 
4678
      modname = secfile_lookup_str_vec(file, &num_base_types,
 
4679
                                       "savefile.bases");
 
4680
    }
 
4681
 
 
4682
    /* make sure that the size of the array is divisible by 4 */
 
4683
    base_order = fc_calloc(4 * ((num_base_types + 3) / 4),
 
4684
                           sizeof(*base_order));
 
4685
    for (j = 0; j < num_base_types; j++) {
 
4686
      base_order[j] = find_base_type_by_rule_name(modname[j]);
 
4687
    }
 
4688
    free(modname);
 
4689
  }
 
4690
 
3865
4691
  /* Free all players from teams, and teams from players
3866
4692
   * This must be done while players_iterate() still iterates
3867
4693
   * to the previous number of players. */
3869
4695
    team_remove_player(pplayer);
3870
4696
  } players_iterate_end;
3871
4697
 
3872
 
  game.info.nplayers      = secfile_lookup_int(file, "game.nplayers");
3873
 
 
 
4698
  set_player_count(secfile_lookup_int_default(file, 0, "game.nplayers"));
 
4699
  player_slots_iterate(pplayer) {
 
4700
      server_player_init(pplayer, FALSE, FALSE);
 
4701
  } player_slots_iterate_end;
3874
4702
 
3875
4703
  script_state_load(file);
3876
4704
 
3901
4729
 
3902
4730
      map.topology_id = secfile_lookup_int_default(file, MAP_ORIGINAL_TOPO,
3903
4731
                                                   "map.topology_id");
3904
 
      map.size = secfile_lookup_int_default(file, MAP_DEFAULT_SIZE,
3905
 
                                            "map.size");
3906
 
      map.riches = secfile_lookup_int(file, "map.riches");
3907
 
      map.huts = secfile_lookup_int(file, "map.huts");
3908
 
      map.generator = secfile_lookup_int(file, "map.generator");
3909
 
      map.startpos = secfile_lookup_int_default(file, MAP_DEFAULT_STARTPOS,
3910
 
                                                "map.startpos");
3911
 
      map.seed = secfile_lookup_int(file, "map.seed");
3912
 
      map.landpercent = secfile_lookup_int(file, "map.landpercent");
3913
 
      map.wetness = secfile_lookup_int_default(file, MAP_DEFAULT_WETNESS,
3914
 
                                               "map.wetness");
3915
 
      map.steepness = secfile_lookup_int_default(file, MAP_DEFAULT_STEEPNESS, 
3916
 
                                                 "map.steepness");
3917
 
      map.have_huts = secfile_lookup_bool_default(file, TRUE,
3918
 
                                                  "map.have_huts");
3919
 
      map.temperature =
3920
 
        secfile_lookup_int_default(file,
3921
 
                                   MAP_DEFAULT_TEMPERATURE, "map.temperature");
3922
 
      map.alltemperate
 
4732
      map.server.size = secfile_lookup_int_default(file, MAP_DEFAULT_SIZE,
 
4733
                                                   "map.size");
 
4734
      map.server.riches = secfile_lookup_int(file, "map.riches");
 
4735
      map.server.huts = secfile_lookup_int(file, "map.huts");
 
4736
      map.server.generator = secfile_lookup_int(file, "map.generator");
 
4737
      map.server.startpos = secfile_lookup_int_default(file,
 
4738
                                                       MAP_DEFAULT_STARTPOS,
 
4739
                                                       "map.startpos");
 
4740
      map.server.seed = secfile_lookup_int(file, "map.seed");
 
4741
      map.server.landpercent = secfile_lookup_int(file, "map.landpercent");
 
4742
      map.server.wetness =
 
4743
        secfile_lookup_int_default(file, MAP_DEFAULT_WETNESS, "map.wetness");
 
4744
      map.server.steepness =
 
4745
        secfile_lookup_int_default(file, MAP_DEFAULT_STEEPNESS,
 
4746
                                   "map.steepness");
 
4747
      map.server.have_huts = secfile_lookup_bool_default(file, TRUE,
 
4748
                                                         "map.have_huts");
 
4749
      map.server.temperature =
 
4750
        secfile_lookup_int_default(file, MAP_DEFAULT_TEMPERATURE,
 
4751
                                   "map.temperature");
 
4752
      map.server.alltemperate
3923
4753
        = secfile_lookup_bool_default(file, MAP_DEFAULT_ALLTEMPERATE,
3924
4754
                                      "map.alltemperate");
3925
 
      map.tinyisles
 
4755
      map.server.tinyisles
3926
4756
        = secfile_lookup_bool_default(file, MAP_DEFAULT_TINYISLES,
3927
4757
                                      "map.tinyisles");
3928
 
      map.separatepoles
 
4758
      map.server.separatepoles
3929
4759
        = secfile_lookup_bool_default(file, MAP_DEFAULT_SEPARATE_POLES,
3930
4760
                                      "map.separatepoles");
3931
4761
 
3938
4768
        map.ysize = secfile_lookup_int(file, "map.ysize");
3939
4769
      }
3940
4770
 
3941
 
      if (S_S_INITIAL == tmp_server_state && 0 == map.generator) {
3942
 
        /* generator 0 = map done with map editor */
3943
 
        /* aka a "scenario" */
 
4771
      if (S_S_INITIAL == tmp_server_state && 0 == map.server.generator) {
 
4772
        /* generator 0 = map done with a map editor aka a "scenario" */
3944
4773
        if (has_capability("specials",savefile_options)) {
3945
 
          map_load(file, special_order);
 
4774
          map_load(file, savefile_options, special_order,
 
4775
                   base_order, num_base_types);
3946
4776
          return;
3947
4777
        }
3948
 
        map_tiles_load(file);
 
4778
        map_load_tiles(file);
3949
4779
        if (has_capability("riversoverlay",savefile_options)) {
3950
 
          map_rivers_overlay_load(file, special_order);
 
4780
          map_load_rivers_overlay(file, special_order);
3951
4781
        }
3952
4782
        if (has_capability("startpos",savefile_options)) {
3953
 
          map_startpos_load(file);
 
4783
          map_load_startpos(file);
3954
4784
          return;
3955
4785
        }
3956
4786
        return;
3990
4820
    }
3991
4821
  }
3992
4822
 
 
4823
  if (0 == strlen(server.game_identifier)
 
4824
      || !is_base64url(server.game_identifier)) {
 
4825
    /* This uses myrand(), so random state has to be initialized before this. */
 
4826
    randomize_base64url_string(server.game_identifier,
 
4827
                               sizeof(server.game_identifier));
 
4828
  }
3993
4829
 
3994
4830
  game.info.is_new_game = !secfile_lookup_bool_default(file, TRUE,
3995
 
                                                  "game.save_players");
 
4831
                                                       "game.save_players");
3996
4832
 
3997
 
  map_load(file, special_order);
 
4833
  map_load(file, savefile_options, special_order,
 
4834
           base_order, num_base_types);
3998
4835
 
3999
4836
  if (game.info.is_new_game) {
4000
4837
    /* override previous load */
4001
 
    game.info.nplayers = 0;
 
4838
    set_player_count(0);
4002
4839
  } else {
 
4840
    int loaded_players = 0;
 
4841
 
4003
4842
    /* destroyed wonders: */
4004
4843
    string = secfile_lookup_str_default(file, NULL,
4005
4844
                                        "game.destroyed_wonders_new");
4008
4847
      string = secfile_lookup_str_default(file, "",
4009
4848
                                          "game.destroyed_wonders");
4010
4849
      for (k = 0; string[k]; k++) {
 
4850
        const char *name = old_impr_type_name(k);
 
4851
        if (!name) {
 
4852
          freelog(LOG_FATAL,
 
4853
                  "game.destroyed_wonders: unknown building (%d)",
 
4854
                  k);
 
4855
          exit(EXIT_FAILURE);
 
4856
        }
4011
4857
        if (string[k] == '1') {
4012
 
          name = old_impr_type_name(k);
4013
 
          id = find_improvement_by_rule_name(name);
4014
 
          if (id != -1) {
4015
 
            game.info.great_wonders[id] = -1;
4016
 
          }
4017
 
        }
 
4858
          struct impr_type *pimprove = find_improvement_by_rule_name(name);
 
4859
          if (pimprove) {
 
4860
            game.info.great_wonder_owners[improvement_index(pimprove)] =
 
4861
                WONDER_DESTROYED;
 
4862
          }
 
4863
        }
4018
4864
      }
4019
4865
    } else {
4020
4866
      for (k = 0; k < improvement_order_size && string[k]; k++) {
4021
4867
        if (string[k] == '1') {
4022
 
          id = find_improvement_by_rule_name(improvement_order[k]);
4023
 
          if (id != -1) {
4024
 
            game.info.great_wonders[id] = -1;
4025
 
          }
4026
 
        }
 
4868
          struct impr_type *pimprove = 
 
4869
                        find_improvement_by_rule_name(improvement_order[k]);
 
4870
          if (pimprove) {
 
4871
            game.info.great_wonder_owners[improvement_index(pimprove)] =
 
4872
                WONDER_DESTROYED;
 
4873
          }
 
4874
        }
4027
4875
      }
4028
4876
    }
4029
4877
 
 
4878
    server.identity_number =
 
4879
      secfile_lookup_int_default(file, server.identity_number,
 
4880
                                 "game.identity_number_used");
 
4881
 
4030
4882
    /* Initialize nations we loaded from rulesets. This has to be after
4031
4883
     * map loading and before we seek nations for players */
4032
4884
    init_available_nations();
4033
4885
 
4034
4886
    /* Now, load the players. */
4035
 
    players_iterate(pplayer) {
4036
 
      player_load(pplayer, pplayer->player_no, file, improvement_order,
4037
 
                  improvement_order_size, technology_order,
4038
 
                  technology_order_size);
4039
 
    } players_iterate_end;
 
4887
    player_slots_iterate(pplayer) {
 
4888
      int plrno = player_number(pplayer);
 
4889
      if (!secfile_has_section(file, "player%d", plrno)) {
 
4890
        player_slot_set_used(pplayer, FALSE);
 
4891
        continue;
 
4892
      }
 
4893
      player_slot_set_used(pplayer, TRUE);
 
4894
      player_load_main(pplayer, plrno, file, savefile_options,
 
4895
                       technology_order, technology_order_size);
 
4896
      player_load_cities(pplayer, plrno, file, savefile_options,
 
4897
                         improvement_order, improvement_order_size);
 
4898
      player_load_units(pplayer, plrno, file, savefile_options,
 
4899
                        base_order, num_base_types);
 
4900
      player_load_attributes(pplayer, plrno, file);
 
4901
      loaded_players++;
 
4902
    } player_slots_iterate_end;
 
4903
 
 
4904
    /* Check that the number of players loaded matches the
 
4905
     * number of players set in the save file. */
 
4906
    if (loaded_players != player_count()) {
 
4907
      freelog(LOG_ERROR, "The value of game.nplayers (%d) from the loaded "
 
4908
              "game does not match the number of players present (%d). "
 
4909
              "Setting game.nplayers to %d.",
 
4910
              player_count(), loaded_players, loaded_players);
 
4911
      set_player_count(loaded_players);
 
4912
    }
4040
4913
 
4041
4914
    /* In case of tech_leakage, we can update research only after all
4042
4915
     * the players have been loaded */
4043
4916
    players_iterate(pplayer) {
4044
4917
      /* Mark the reachable techs */
4045
 
      update_research(pplayer);
 
4918
      player_research_update(pplayer);
4046
4919
    } players_iterate_end;
4047
4920
 
4048
4921
    /* Some players may have invalid nations in the ruleset.  Once all 
4050
4923
     */
4051
4924
    players_iterate(pplayer) {
4052
4925
      if (pplayer->nation == NO_NATION_SELECTED) {
4053
 
        player_set_nation(pplayer, pick_a_nation(NULL, FALSE, TRUE));
 
4926
        player_set_nation(pplayer, pick_a_nation(NULL, FALSE, TRUE,
 
4927
                                                 NOT_A_BARBARIAN));
4054
4928
        /* TRANS: Minor error message: <Leader> ... <Poles>. */
4055
4929
        freelog(LOG_ERROR, _("%s had invalid nation; changing to %s."),
4056
4930
                player_name(pplayer),
4057
4931
                nation_plural_for_player(pplayer));
4058
4932
      }
4059
4933
    } players_iterate_end;
4060
 
 
4061
 
    /* Assign players with no team listed onto an empty team. */
4062
 
    players_iterate(pplayer) {
4063
 
      if (!pplayer->team) {
4064
 
        team_add_player(pplayer, find_empty_team());
4065
 
      }
4066
 
    } players_iterate_end;
4067
 
 
 
4934
    
4068
4935
    /* Sanity check alliances, prevent allied-with-ally-of-enemy */
4069
4936
    players_iterate(plr) {
4070
4937
      players_iterate(aplayer) {
4075
4942
               == DIPL_ALLIANCE_PROBLEM) {
4076
4943
          freelog(LOG_ERROR, "Illegal alliance structure detected: "
4077
4944
                  "%s alliance to %s reduced to peace treaty.",
4078
 
                  nation_rule_name(plr->nation),
4079
 
                  nation_rule_name(aplayer->nation));
4080
 
          plr->diplstates[aplayer->player_no].type = DS_PEACE;
4081
 
          aplayer->diplstates[plr->player_no].type = DS_PEACE;
 
4945
                  nation_rule_name(nation_of_player(plr)),
 
4946
                  nation_rule_name(nation_of_player(aplayer)));
 
4947
          plr->diplstates[player_index(aplayer)].type = DS_PEACE;
 
4948
          aplayer->diplstates[player_index(plr)].type = DS_PEACE;
4082
4949
        }
4083
4950
      } players_iterate_end;
4084
4951
    } players_iterate_end;
4085
4952
 
4086
 
 
4087
4953
    /* Update all city information.  This must come after all cities are
4088
4954
     * loaded (in player_load) but before player (dumb) cities are loaded
4089
 
     * (in player_map_load).
4090
 
     *
4091
 
     * This is a bit ugly since generic_city_refresh assumes a city that
4092
 
     * has already been refreshed at some point (even if it's out of date).
4093
 
     * Here we follow the simplest method of just refreshing all cities,
4094
 
     * and updating trade routes at the same time.  This could lead to memory
4095
 
     * issues because the refresh might look at some data of another city
4096
 
     * that hasn't itself been refreshed yet.  However this shouldn't cause
4097
 
     * any problems because in the end all cities are refreshed once (or
4098
 
     * more) and recursive dependencies are all taken care of. */
 
4955
     * in player_load_vision(). */
4099
4956
    cities_iterate(pcity) {
4100
 
      generic_city_refresh(pcity, TRUE, NULL);
 
4957
      city_refresh_from_main_map(pcity, TRUE);
4101
4958
    } cities_iterate_end;
4102
4959
 
4103
4960
    /* Since the cities must be placed on the map to put them on the
4104
4961
       player map we do this afterwards */
4105
 
    for(i = 0; i < game.info.nplayers; i++) {
4106
 
      player_map_load(&game.players[i], i, file, improvement_order,
4107
 
                      improvement_order_size, special_order); 
4108
 
    }
 
4962
    players_iterate(pplayer) {
 
4963
      int n = player_index(pplayer);
 
4964
      player_load_vision(pplayer, n, file, savefile_options, special_order,
 
4965
                         improvement_order, improvement_order_size,
 
4966
                         base_order, num_base_types);
 
4967
    } players_iterate_end;
 
4968
 
 
4969
    whole_map_iterate(ptile) {
 
4970
      struct player *owner = tile_owner(ptile);
 
4971
 
 
4972
      if (owner) {
 
4973
        base_type_iterate(pbase) {
 
4974
          if (tile_has_base(ptile, pbase)) {
 
4975
            if (pbase->vision_main_sq > 0) {
 
4976
              map_refog_circle(owner, ptile, -1, pbase->vision_main_sq,
 
4977
                               game.info.vision_reveal_tiles, V_MAIN);
 
4978
            }
 
4979
            if (pbase->vision_invis_sq > 0) {
 
4980
              map_refog_circle(owner, ptile, -1, pbase->vision_invis_sq,
 
4981
                               game.info.vision_reveal_tiles, V_INVIS);
 
4982
            }
 
4983
          }
 
4984
        } base_type_iterate_end;
 
4985
      }
 
4986
    } whole_map_iterate_end;
4109
4987
 
4110
4988
    /* We do this here since if the did it in player_load, player 1
4111
4989
       would try to unfog (unloaded) player 2's map when player 1's units
4116
4994
    } players_iterate_end;
4117
4995
 
4118
4996
    players_iterate(pplayer) {
4119
 
      char *vision;
4120
 
      int plrno = pplayer->player_no;
4121
 
 
4122
 
      vision = secfile_lookup_str_default(file, NULL,
4123
 
                                          "player%d.gives_shared_vision",
4124
 
                                          plrno);
 
4997
      int n = player_index(pplayer);
 
4998
      char *vision =
 
4999
        secfile_lookup_str_default(file, NULL,
 
5000
                                   "player%d.gives_shared_vision",
 
5001
                                   n);
4125
5002
      if (vision) {
4126
5003
        players_iterate(pplayer2) {
4127
 
          if (vision[pplayer2->player_no] == '1') {
 
5004
          if (vision[player_index(pplayer2)] == '1') {
4128
5005
            give_shared_vision(pplayer, pplayer2);
4129
5006
          }
4130
5007
        } players_iterate_end;
4134
5011
    initialize_globals();
4135
5012
    apply_unit_ordering();
4136
5013
 
 
5014
    /* all vision is ready */
 
5015
    map_calculate_borders(); /* does city_thaw_workers_queue() */
 
5016
    /* city_refresh() below */
 
5017
 
4137
5018
    /* Make sure everything is consistent. */
4138
5019
    players_iterate(pplayer) {
4139
5020
      unit_list_iterate(pplayer->units, punit) {
4144
5025
      } unit_list_iterate_end;
4145
5026
 
4146
5027
      city_list_iterate(pplayer->cities, pcity) {
4147
 
        check_city(pcity);
 
5028
        repair_city_worker(pcity);
4148
5029
      } city_list_iterate_end;
4149
5030
    } players_iterate_end;
 
5031
 
 
5032
    cities_iterate(pcity) {
 
5033
      city_refresh(pcity); /* again */
 
5034
      city_thaw_workers(pcity); /* may auto_arrange_workers() */
 
5035
    } cities_iterate_end;
4150
5036
  }
4151
5037
 
4152
5038
  if (secfile_lookup_int_default(file, -1,
4153
5039
                                 "game.shuffled_player_%d", 0) >= 0) {
4154
 
    int shuffled_players[game.info.nplayers];
 
5040
    int shuffled_players[player_slot_count()];
4155
5041
 
4156
 
    for (i = 0; i < game.info.nplayers; i++) {
4157
 
      shuffled_players[i]
4158
 
        = secfile_lookup_int(file, "game.shuffled_player_%d", i);
 
5042
    /* players_iterate() not used here */
 
5043
    for (i = 0; i < player_slot_count(); i++) {
 
5044
      shuffled_players[i] = secfile_lookup_int_default(file,
 
5045
          i, "game.shuffled_player_%d", i);
4159
5046
    }
4160
5047
    set_shuffled_players(shuffled_players);
4161
5048
  } else {
4164
5051
    shuffle_players();
4165
5052
  }
4166
5053
 
4167
 
  game.info.player_idx = 0;
4168
 
  game.player_ptr=&game.players[0];  
4169
 
 
4170
5054
  /* Fix ferrying sanity */
4171
5055
  players_iterate(pplayer) {
4172
5056
    unit_list_iterate_safe(pplayer->units, punit) {
4199
5083
  /* Recalculate the potential buildings for each city.  
4200
5084
   * Has caused some problems with game random state. */
4201
5085
  players_iterate(pplayer) {
4202
 
    bool saved_ai_control = pplayer->ai.control;
 
5086
    bool saved_ai_control = pplayer->ai_data.control;
4203
5087
 
4204
5088
    /* Recalculate for all players. */
4205
 
    pplayer->ai.control = FALSE;
4206
 
    ai_manage_buildings(pplayer);
4207
 
 
4208
 
    pplayer->ai.control = saved_ai_control;
 
5089
    pplayer->ai_data.control = FALSE;
 
5090
 
 
5091
    if (pplayer->ai->funcs.building_advisor_init) {
 
5092
      pplayer->ai->funcs.building_advisor_init(pplayer);
 
5093
    }
 
5094
 
 
5095
    pplayer->ai_data.control = saved_ai_control;
4209
5096
  } players_iterate_end;
4210
5097
  
4211
5098
  /* Restore game random state, just in case various initialization code
4213
5100
  if (!game.info.is_new_game) {
4214
5101
    set_myrand_state(rstate);
4215
5102
  }
 
5103
 
 
5104
  /* load event cache */
 
5105
  event_cache_load(file, "event_cache");
4216
5106
}
4217
5107
 
4218
5108
/***************************************************************
4219
 
...
 
5109
  Main game saving function
4220
5110
***************************************************************/
4221
 
void game_save(struct section_file *file, const char *save_reason)
 
5111
void game_save(struct section_file *file, const char *save_reason,
 
5112
               bool scenario)
4222
5113
{
4223
5114
  int i;
4224
5115
  int version;
4225
5116
  char options[512];
4226
5117
  char temp[B_LAST+1];
4227
5118
  const char *user_message;
4228
 
 
4229
 
  version = MAJOR_VERSION *10000 + MINOR_VERSION *100 + PATCH_VERSION; 
4230
 
  secfile_insert_int(file, version, "game.version");
4231
 
 
4232
 
  /* Game state: once the game is no longer a new game (ie, has been
4233
 
   * started the first time), it should always be considered a running
4234
 
   * game for savegame purposes:
4235
 
   */
4236
 
  secfile_insert_int(file, (int) (game.info.is_new_game ? server_state() :
4237
 
                                  S_S_RUNNING), "game.server_state");
4238
 
  
4239
 
  secfile_insert_str(file, get_meta_patches_string(), "game.metapatches");
4240
 
  secfile_insert_bool(file, game.meta_info.user_message_set,
4241
 
                      "game.user_metamessage");
4242
 
  user_message = get_user_meta_message_string();
4243
 
  if (user_message != NULL) {
4244
 
    secfile_insert_str(file, user_message, "game.metamessage");
4245
 
  }
4246
 
  secfile_insert_str(file, meta_addr_port(), "game.metaserver");
4247
 
  secfile_insert_str(file, srvarg.serverid, "game.serverid");
4248
 
 
4249
 
  sz_strlcpy(options, SAVEFILE_OPTIONS);
4250
 
  if (game.info.is_new_game) {
4251
 
    if (map.num_start_positions>0) {
 
5119
  bool save_players;
 
5120
  enum server_states srv_state;
 
5121
 
 
5122
  /* [savefile] */
 
5123
  sz_strlcpy(options, savefile_options_default);
 
5124
  if (game.info.is_new_game
 
5125
      || (scenario && !game.scenario.players)) {
 
5126
    if (map.server.num_start_positions > 0
 
5127
        || map_startpositions_set()) {
4252
5128
      sz_strlcat(options, " startpos");
4253
5129
    }
4254
 
    if (map.have_resources) {
4255
 
      sz_strlcat(options, " specials");
4256
 
    }
4257
 
    if (map.have_rivers_overlay && !map.have_resources) {
 
5130
  }
 
5131
  if (map.server.have_resources) {
 
5132
    sz_strlcat(options, " specials");
 
5133
  }
 
5134
 
 
5135
  if (game.info.is_new_game) {
 
5136
    if (map.server.have_rivers_overlay && !map.server.have_resources) {
4258
5137
      sz_strlcat(options, " riversoverlay");
4259
5138
    }
4260
5139
  }
4261
5140
  secfile_insert_str(file, options, "savefile.options");
4262
5141
  secfile_insert_str(file, save_reason, "savefile.reason");
 
5142
 
4263
5143
  /* Save improvement order in savegame, so we are not dependent on
4264
5144
   * ruleset order.
4265
5145
   * If the game isn't started improvements aren't loaded
4266
5146
   * so we can not save the order.
4267
5147
   */
4268
 
  if (game.control.num_impr_types > 0) {
4269
 
    const char* buf[game.control.num_impr_types];
4270
 
    impr_type_iterate(id) {
4271
 
      buf[id] = improvement_rule_name(id);
4272
 
    } impr_type_iterate_end;
4273
 
    secfile_insert_str_vec(file, buf, game.control.num_impr_types,
 
5148
  if (improvement_count() > 0) {
 
5149
    const char* buf[improvement_count()];
 
5150
 
 
5151
    improvement_iterate(pimprove) {
 
5152
      buf[improvement_index(pimprove)] = improvement_rule_name(pimprove);
 
5153
    } improvement_iterate_end;
 
5154
 
 
5155
    secfile_insert_str_vec(file, buf, improvement_count(),
4274
5156
                           "savefile.improvement_order");
4275
5157
  }
4276
5158
  
4279
5161
   * so we can not save the order. */
4280
5162
  if (game.control.num_tech_types > 0) {
4281
5163
    const char* buf[game.control.num_tech_types];
4282
 
    tech_type_iterate(tech) {
4283
 
      if (tech == A_NONE) {
4284
 
        buf[tech] = "A_NONE";
4285
 
      } else {
4286
 
        buf[tech] = advance_rule_name(tech);
4287
 
      }
4288
 
    } tech_type_iterate_end;
 
5164
    buf[A_NONE] = "A_NONE";
 
5165
    advance_iterate(A_FIRST, a) {
 
5166
      buf[advance_index(a)] = advance_rule_name(a);
 
5167
    } advance_iterate_end;
4289
5168
    secfile_insert_str_vec(file, buf, game.control.num_tech_types,
4290
5169
                           "savefile.technology_order");
4291
5170
  }
4294
5173
 
4295
5174
    /* Save specials order */
4296
5175
    modname = fc_calloc(S_LAST, sizeof(*modname));
 
5176
 
4297
5177
    tile_special_type_iterate(j) {
4298
5178
      modname[j] = special_rule_name(j);
4299
5179
    } tile_special_type_iterate_end;
 
5180
 
 
5181
    /* Obsoleted entries */
 
5182
    modname[S_OLD_FORTRESS] = "Obsolete";
 
5183
    modname[S_OLD_AIRBASE] = "Obsolete";
 
5184
 
4300
5185
    secfile_insert_str_vec(file, modname, S_LAST,
4301
5186
                           "savefile.specials");
4302
5187
    free(modname);
4303
5188
  }
4304
 
 
 
5189
  {
 
5190
    secfile_insert_int(file, game.control.num_base_types, "savefile.num_bases");
 
5191
    if (game.control.num_base_types > 0) {
 
5192
      const char **modname;
 
5193
      int i = 0;
 
5194
 
 
5195
      /* Save bases order */
 
5196
      modname = fc_calloc(game.control.num_base_types, sizeof(*modname));
 
5197
 
 
5198
      base_type_iterate(pbase) {
 
5199
        modname[i++] = base_rule_name(pbase);
 
5200
      } base_type_iterate_end;
 
5201
 
 
5202
      secfile_insert_str_vec(file, modname, game.control.num_base_types,
 
5203
                             "savefile.bases");
 
5204
      free(modname);
 
5205
    }
 
5206
  }
 
5207
 
 
5208
  /* [scenario] */
 
5209
  if (scenario) {
 
5210
    secfile_insert_str(file, game.scenario.name, "scenario.name");
 
5211
    secfile_insert_str(file, game.scenario.description,
 
5212
                       "scenario.description");
 
5213
    secfile_insert_bool(file, game.scenario.players, "scenario.save_players");
 
5214
  }
 
5215
 
 
5216
  /* [game] */
 
5217
  version = MAJOR_VERSION *10000 + MINOR_VERSION *100 + PATCH_VERSION; 
 
5218
  secfile_insert_int(file, version, "game.version");
 
5219
 
 
5220
  /* Game state: once the game is no longer a new game (ie, has been
 
5221
   * started the first time), it should always be considered a running
 
5222
   * game for savegame purposes:
 
5223
   */
 
5224
  if (scenario && !game.scenario.players) {
 
5225
    srv_state = S_S_INITIAL;
 
5226
  } else {
 
5227
    srv_state = game.info.is_new_game ? server_state() : S_S_RUNNING;
 
5228
  }
 
5229
 
 
5230
  /* new in 2.2: save server state as string; see srv_main.h */
 
5231
  secfile_insert_str(file, server_states_name(srv_state),
 
5232
                     "game.server_state");
 
5233
 
 
5234
  secfile_insert_str(file, get_meta_patches_string(), "game.metapatches");
 
5235
  secfile_insert_bool(file, game.server.meta_info.user_message_set,
 
5236
                      "game.user_metamessage");
 
5237
  user_message = get_user_meta_message_string();
 
5238
  if (user_message != NULL) {
 
5239
    secfile_insert_str(file, user_message, "game.metamessage");
 
5240
  }
 
5241
  secfile_insert_str(file, meta_addr_port(), "game.metaserver");
 
5242
  secfile_insert_str(file, srvarg.serverid, "game.serverid");
4305
5243
  
4306
5244
  secfile_insert_int(file, game.info.gold, "game.gold");
4307
5245
  secfile_insert_int(file, game.info.tech, "game.tech");
4308
5246
  secfile_insert_int(file, game.info.skill_level, "game.skill_level");
4309
5247
  secfile_insert_int(file, game.info.timeout, "game.timeout");
4310
 
  secfile_insert_int(file, game.timeoutint, "game.timeoutint");
4311
 
  secfile_insert_int(file, game.timeoutintinc, "game.timeoutintinc");
4312
 
  secfile_insert_int(file, game.timeoutinc, "game.timeoutinc");
4313
 
  secfile_insert_int(file, game.timeoutincmult, "game.timeoutincmult"); 
4314
 
  secfile_insert_int(file, game.timeoutcounter, "game.timeoutcounter");
4315
 
  secfile_insert_int(file, game.timeoutaddenemymove,
4316
 
                     "game.info.timeoutaddenemymove");
4317
 
  secfile_insert_int(file, game.info.end_year, "game.end_year");
 
5248
  secfile_insert_int(file, game.server.timeoutint, "game.timeoutint");
 
5249
  secfile_insert_int(file, game.server.timeoutintinc, "game.timeoutintinc");
 
5250
  secfile_insert_int(file, game.server.timeoutinc, "game.timeoutinc");
 
5251
  secfile_insert_int(file, game.server.timeoutincmult, "game.timeoutincmult"); 
 
5252
  secfile_insert_int(file, game.server.timeoutcounter, "game.timeoutcounter");
 
5253
 
 
5254
  secfile_insert_int(file, game.info.end_turn, "game.end_turn");
4318
5255
  secfile_insert_int(file, game.info.year, "game.year");
4319
5256
  secfile_insert_int(file, game.info.turn, "game.turn");
4320
 
  secfile_insert_bool(file, game.info.simultaneous_phases,
4321
 
                      "game.simultaneous_phases_now");
4322
 
  secfile_insert_bool(file, game.simultaneous_phases_stored,
4323
 
                      "game.simultaneous_phases_stored");
 
5257
  secfile_insert_bool(file, game.info.year_0_hack, "game.year_0_hack");
 
5258
  secfile_insert_int(file, game.info.phase_mode,
 
5259
                     "game.phase_mode");
 
5260
  secfile_insert_int(file, game.server.phase_mode_stored,
 
5261
                     "game.phase_mode_stored");
4324
5262
  secfile_insert_int(file, game.info.min_players, "game.min_players");
4325
5263
  secfile_insert_int(file, game.info.max_players, "game.max_players");
4326
 
  secfile_insert_int(file, game.info.nplayers, "game.nplayers");
4327
5264
  secfile_insert_int(file, game.info.heating, "game.heating");
4328
5265
  secfile_insert_int(file, game.info.globalwarming, "game.globalwarming");
4329
5266
  secfile_insert_int(file, game.info.warminglevel, "game.warminglevel");
4332
5269
  secfile_insert_int(file, game.info.coolinglevel, "game.coolinglevel");
4333
5270
  secfile_insert_int(file, game.info.notradesize, "game.notradesize");
4334
5271
  secfile_insert_int(file, game.info.fulltradesize, "game.fulltradesize");
4335
 
  secfile_insert_int(file, game.info.unhappysize, "game.unhappysize");
 
5272
  secfile_insert_int(file, game.info.trademindist, "game.trademindist");
4336
5273
  secfile_insert_bool(file, game.info.angrycitizen, "game.angrycitizen");
4337
 
  secfile_insert_int(file, game.info.cityfactor, "game.cityfactor");
4338
5274
  secfile_insert_int(file, game.info.citymindist, "game.citymindist");
4339
5275
  secfile_insert_int(file, game.info.civilwarsize, "game.civilwarsize");
4340
5276
  secfile_insert_int(file, game.info.contactturns, "game.contactturns");
4345
5281
  secfile_insert_int(file, game.info.foodbox, "game.box_food");
4346
5282
  secfile_insert_int(file, game.info.shieldbox, "game.box_shield");
4347
5283
  secfile_insert_int(file, game.info.sciencebox, "game.box_science");
4348
 
  {
4349
 
    /* These values are for compatibility with 2.0 and previous servers. */
4350
 
    secfile_insert_int(file, game.info.sciencebox / 5, "game.researchcost");
4351
 
  secfile_insert_int(file, game.info.foodbox / 10, "game.foodbox");
4352
 
  }
 
5284
 
4353
5285
  secfile_insert_int(file, game.info.techpenalty, "game.techpenalty");
4354
5286
  secfile_insert_int(file, game.info.razechance, "game.razechance");
4355
5287
 
4356
5288
  /* Write civstyle for compatibility with old servers */
4357
5289
  secfile_insert_int(file, 2, "game.civstyle");
4358
5290
  secfile_insert_int(file, game.info.save_nturns, "game.save_nturns");
4359
 
  secfile_insert_str(file, game.save_name, "game.save_name");
 
5291
  secfile_insert_str(file, game.server.save_name, "game.save_name");
4360
5292
  secfile_insert_int(file, game.info.save_compress_level,
4361
5293
                     "game.save_compress_level");
 
5294
  secfile_insert_int(file, game.info.save_compress_type,
 
5295
                     "game.save_compress_type");
4362
5296
  secfile_insert_int(file, game.info.aifill, "game.aifill");
4363
 
  secfile_insert_bool(file, game.scorelog, "game.scorelog");
4364
 
  secfile_insert_int(file, game.scoreturn, "game.scoreturn");
4365
 
  secfile_insert_str(file, game.id, "game.id");
 
5297
  secfile_insert_bool(file, game.server.scorelog, "game.scorelog");
 
5298
  secfile_insert_int(file, game.server.scoreturn, "game.scoreturn");
 
5299
  secfile_insert_str(file, server.game_identifier, "game.id");
 
5300
 
4366
5301
  secfile_insert_bool(file, game.info.fogofwar, "game.fogofwar");
 
5302
  secfile_insert_bool(file, game.server.foggedborders, "game.foggedborders");
4367
5303
  secfile_insert_bool(file, game.info.spacerace, "game.spacerace");
 
5304
  secfile_insert_bool(file, game.info.endspaceship, "game.endspaceship");
4368
5305
  secfile_insert_bool(file, game.info.auto_ai_toggle, "game.auto_ai_toggle");
4369
5306
  secfile_insert_int(file, game.info.diplchance, "game.diplchance");
4370
5307
  secfile_insert_int(file, game.info.aqueductloss, "game.aqueductloss");
4371
5308
  secfile_insert_int(file, game.info.killcitizen, "game.killcitizen");
 
5309
  secfile_insert_bool(file, game.info.savepalace, "game.savepalace");
4372
5310
  secfile_insert_bool(file, game.info.turnblock, "game.turnblock");
4373
 
  secfile_insert_bool(file, game.info.savepalace, "game.savepalace");
4374
5311
  secfile_insert_bool(file, game.info.fixedlength, "game.fixedlength");
4375
5312
  secfile_insert_int(file, game.info.barbarianrate, "game.barbarians");
4376
5313
  secfile_insert_int(file, game.info.onsetbarbarian, "game.onsetbarbs");
4377
5314
  secfile_insert_int(file, game.info.revolution_length, "game.revolen");
4378
5315
  secfile_insert_int(file, game.info.occupychance, "game.occupychance");
4379
5316
  secfile_insert_bool(file, game.info.autoattack, "game.autoattack");
4380
 
  secfile_insert_str(file, game.demography, "game.demography");
4381
 
  secfile_insert_str(file, game.allow_take, "game.allow_take");
 
5317
  secfile_insert_str(file, game.server.demography, "game.demography");
 
5318
  secfile_insert_str(file, game.server.allow_take, "game.allow_take");
4382
5319
  secfile_insert_int(file, game.info.borders, "game.borders");
4383
5320
  secfile_insert_bool(file, game.info.happyborders, "game.happyborders");
4384
5321
  secfile_insert_int(file, game.info.diplomacy, "game.diplomacy");
4385
5322
  secfile_insert_int(file, game.info.allowed_city_names, "game.allowed_city_names");
4386
 
 
4387
 
  /* old (1.14.1) servers need to have these server variables.  The values
4388
 
   * don't matter, though. */
4389
 
  secfile_insert_int(file, 2, "game.settlers");
4390
 
  secfile_insert_int(file, 1, "game.explorer");
4391
 
  secfile_insert_int(file, 30, "map.mountains");
4392
 
  secfile_insert_int(file, 35, "map.grass");
4393
 
  secfile_insert_int(file, 5, "map.swampsize");
4394
 
  secfile_insert_int(file, 5, "map.deserts");
4395
 
  secfile_insert_int(file, 5, "map.riverlength");
4396
 
  secfile_insert_int(file, 20, "map.forestsize");
4397
 
 
4398
 
  if (TRUE) {
 
5323
  secfile_insert_bool(file, game.info.migration,
 
5324
                      "game.migration");
 
5325
  secfile_insert_int(file, game.info.mgr_turninterval,
 
5326
                     "game.mgr_turninterval");
 
5327
  secfile_insert_bool(file, game.info.mgr_foodneeded,
 
5328
                      "game.mgr_foodneeded");
 
5329
  secfile_insert_int(file, game.info.mgr_distance,
 
5330
                     "game.mgr_distance");
 
5331
  secfile_insert_int(file, game.info.mgr_nationchance,
 
5332
                     "game.mgr_nationchance");
 
5333
  secfile_insert_int(file, game.info.mgr_worldchance,
 
5334
                     "game.mgr_worldchance");
 
5335
  secfile_insert_int(file, game.server.event_cache.turns,
 
5336
                     "game.event_cache.turns");
 
5337
  secfile_insert_int(file, game.server.event_cache.max_size,
 
5338
                     "game.event_cache.max_size");
 
5339
  secfile_insert_bool(file, game.server.event_cache.chat,
 
5340
                      "game.event_cache.chat");
 
5341
  secfile_insert_bool(file, game.server.event_cache.info,
 
5342
                      "game.event_cache.info");
 
5343
 
 
5344
  {
4399
5345
    /* Now always save these, so the server options reflect the
4400
5346
     * actual values used at the start of the game.
4401
5347
     * The first two used to be saved as "map.xsize" and "map.ysize"
4402
5348
     * when S_S_INITIAL, but I'm standardizing on width,height --dwp
4403
5349
     */
4404
5350
    secfile_insert_int(file, map.topology_id, "map.topology_id");
4405
 
    secfile_insert_int(file, map.size, "map.size");
 
5351
    secfile_insert_int(file, map.server.size, "map.size");
4406
5352
    secfile_insert_int(file, map.xsize, "map.width");
4407
5353
    secfile_insert_int(file, map.ysize, "map.height");
4408
5354
    secfile_insert_str(file, game.info.start_units, "game.start_units");
4409
5355
    secfile_insert_int(file, game.info.dispersion, "game.dispersion");
4410
 
    secfile_insert_int(file, map.seed, "map.seed");
4411
 
    secfile_insert_int(file, map.landpercent, "map.landpercent");
4412
 
    secfile_insert_int(file, map.riches, "map.riches");
4413
 
    secfile_insert_int(file, map.wetness, "map.wetness");
4414
 
    secfile_insert_int(file, map.steepness, "map.steepness");
4415
 
    secfile_insert_int(file, map.huts, "map.huts");
4416
 
    secfile_insert_int(file, map.generator, "map.generator");
4417
 
    secfile_insert_int(file, map.startpos, "map.startpos");
4418
 
    secfile_insert_bool(file, map.have_huts, "map.have_huts");
4419
 
    secfile_insert_int(file, map.temperature, "map.temperature");
4420
 
    secfile_insert_bool(file, map.alltemperate, "map.alltemperate");
4421
 
    secfile_insert_bool(file, map.tinyisles, "map.tinyisles");
4422
 
    secfile_insert_bool(file, map.separatepoles, "map.separatepoles");
 
5356
    secfile_insert_int(file, map.server.seed, "map.seed");
 
5357
    secfile_insert_int(file, map.server.landpercent, "map.landpercent");
 
5358
    secfile_insert_int(file, map.server.riches, "map.riches");
 
5359
    secfile_insert_int(file, map.server.wetness, "map.wetness");
 
5360
    secfile_insert_int(file, map.server.steepness, "map.steepness");
 
5361
    secfile_insert_int(file, map.server.huts, "map.huts");
 
5362
    secfile_insert_int(file, scenario ? 0 : map.server.generator,
 
5363
                       "map.generator");
 
5364
    secfile_insert_int(file, map.server.startpos, "map.startpos");
 
5365
    secfile_insert_bool(file, map.server.have_huts, "map.have_huts");
 
5366
    secfile_insert_int(file, map.server.temperature, "map.temperature");
 
5367
    secfile_insert_bool(file, map.server.alltemperate, "map.alltemperate");
 
5368
    secfile_insert_bool(file, map.server.tinyisles, "map.tinyisles");
 
5369
    secfile_insert_bool(file, map.server.separatepoles, "map.separatepoles");
4423
5370
  } 
4424
5371
 
4425
 
  secfile_insert_int(file, game.seed, "game.randseed");
 
5372
  secfile_insert_int(file, game.server.seed, "game.randseed");
4426
5373
  
4427
 
  if (myrand_is_init() && game.save_options.save_random) {
 
5374
  if (myrand_is_init() && game.server.save_options.save_random) {
4428
5375
    RANDOM_STATE rstate = get_myrand_state();
4429
5376
    secfile_insert_int(file, 1, "game.save_random");
4430
5377
    assert(rstate.is_init);
4447
5394
    secfile_insert_int(file, 0, "game.save_random");
4448
5395
  }
4449
5396
 
4450
 
  secfile_insert_str(file, game.rulesetdir, "game.rulesetdir");
 
5397
  secfile_insert_str(file, game.server.rulesetdir, "game.rulesetdir");
4451
5398
 
4452
5399
  if (!map_is_empty()) {
4453
5400
    map_save(file);
4459
5406
    return; /* want to save scenarios as well */
4460
5407
  }
4461
5408
 
4462
 
  secfile_insert_bool(file, game.save_options.save_players,
 
5409
  if (scenario) {
 
5410
    save_players = game.scenario.players;
 
5411
  } else {
 
5412
    save_players = TRUE;
 
5413
  }
 
5414
 
 
5415
  secfile_insert_bool(file, save_players,
4463
5416
                      "game.save_players");
4464
 
  if (game.save_options.save_players) {
 
5417
  if (save_players) {
4465
5418
    /* 1.14 servers depend on improvement order in ruleset. Here we
4466
5419
     * are trying to simulate 1.14.1 default order
4467
5420
     */
4468
5421
    init_old_improvement_bitvector(temp);
4469
 
    impr_type_iterate(id) {
4470
 
      if (is_great_wonder(id) && great_wonder_was_built(id)
4471
 
          && !find_city_from_great_wonder(id)) {
4472
 
        add_improvement_into_old_bitvector(temp, id);
4473
 
      } 
4474
 
    } impr_type_iterate_end;
4475
 
    secfile_insert_str(file, temp, "game.destroyed_wonders");
 
5422
    /* removed after 2.1 */
4476
5423
    
4477
5424
    /* Save destroyed wonders as bitvector. Note that improvement order
4478
5425
     * is saved in savefile.improvement_order
4479
5426
     */
4480
 
    impr_type_iterate(id) {
4481
 
      if (is_great_wonder(id) && great_wonder_was_built(id)
4482
 
          && !find_city_from_great_wonder(id)) {
4483
 
        temp[id] = '1';
 
5427
    improvement_iterate(pimprove) {
 
5428
      if (is_great_wonder(pimprove)
 
5429
          && great_wonder_is_destroyed(pimprove)) {
 
5430
        temp[improvement_index(pimprove)] = '1';
4484
5431
      } else {
4485
 
        temp[id] = '0';
 
5432
        temp[improvement_index(pimprove)] = '0';
4486
5433
      }
4487
 
    } impr_type_iterate_end;
4488
 
    temp[game.control.num_impr_types] = '\0';
 
5434
    } improvement_iterate_end;
 
5435
    temp[improvement_count()] = '\0';
4489
5436
    secfile_insert_str(file, temp, "game.destroyed_wonders_new");
4490
5437
 
 
5438
    secfile_insert_int(file, server.identity_number, "game.identity_number_used");
 
5439
 
4491
5440
    calc_unit_ordering();
4492
5441
 
 
5442
    secfile_insert_int(file, player_count(), "game.nplayers");
4493
5443
    players_iterate(pplayer) {
4494
 
      player_save(pplayer, pplayer->player_no, file);
 
5444
      int n = player_index(pplayer);
 
5445
      player_save_main(pplayer, n, file);
 
5446
      player_save_cities(pplayer, n, file);
 
5447
      player_save_units(pplayer, n, file);
 
5448
      player_save_attributes(pplayer, n, file);
 
5449
      player_save_vision(pplayer, n, file);
4495
5450
    } players_iterate_end;
4496
5451
 
4497
 
    for (i = 0; i < game.info.nplayers; i++) {
4498
 
      secfile_insert_int(file, shuffled_player(i)->player_no,
 
5452
    i = 0;
 
5453
    shuffled_players_iterate(pplayer) {
 
5454
      secfile_insert_int(file, player_number(pplayer),
4499
5455
                         "game.shuffled_player_%d", i);
4500
 
    }
 
5456
      i++;
 
5457
    } shuffled_players_iterate_end;
 
5458
 
 
5459
    /* save event cache */
 
5460
    event_cache_save(file, "event_cache");
4501
5461
  }
4502
5462
}