LCOV - code coverage report
Current view: top level - omega-rpg-0.90-pa9 - save.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 483 682 70.8 %
Date: 2017-08-31 19:31:11 Functions: 15 18 83.3 %
Branches: 176 297 59.3 %

           Branch data     Line data    Source code
       1                 :            : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
       2                 :            : /* save.c */
       3                 :            : 
       4                 :            : #ifndef MSDOS_SUPPORTED_ANTIQUE
       5                 :            : #include <unistd.h>
       6                 :            : #include <stdlib.h>
       7                 :            : #endif
       8                 :            : 
       9                 :            : #include "glob.h"
      10                 :            : 
      11                 :            : #ifdef ALLOWING_OLD_SAVEFILES
      12                 :            : /* holds the OLD_ definitions */
      13                 :            : # include "oldsave.h"
      14                 :            : #endif
      15                 :            : 
      16                 :            : /*Various functions for doing game saves and restores */
      17                 :            : /*The game remembers various player information, the city level,
      18                 :            : the country level, and the last or current dungeon level */
      19                 :            : 
      20                 :            : #if defined(MSDOS_SUPPORTED_ANTIQUE) || defined(AMIGA)
      21                 :            : void do_compression(int, char *);
      22                 :            : #endif
      23                 :            : 
      24                 :            : /**************** SAVE FUNCTIONS */
      25                 :            : 
      26                 :            : /* Checks to see if save file already exists.
      27                 :            :    Checks to see if save file can be opened for write.
      28                 :            :    The player, the city level, and the current dungeon level are saved.
      29                 :            : */
      30                 :            : 
      31                 :          5 : int save_game(int compress, char *savestr)
      32                 :            : {
      33                 :            :   FILE *fd;
      34                 :            :   int slashpos;
      35                 :            : #ifdef SAVE_LEVELS
      36                 :            :   int tmpdepth;
      37                 :            : #endif
      38                 :          5 :   int i,writeok=TRUE;
      39                 :            :   plv current, save;
      40                 :            : #ifdef COMPRESS_SAVE_FILES
      41                 :            :   char temp[200];
      42                 :            : #endif
      43                 :            : 
      44                 :            : #ifndef MSDOS_SUPPORTED_ANTIQUE
      45         [ -  + ]:          5 :   if (access(savestr, R_OK) == 0)
      46         [ #  # ]:          0 :     if (access(savestr, W_OK) == 0)
      47                 :            :     {
      48                 :          0 :         mprint(" Overwrite old file?");
      49                 :          0 :         writeok = (ynq() == 'y');
      50                 :            :     }
      51                 :            :     else
      52                 :            :     {
      53                 :          0 :         mprint(" File already exists.");
      54                 :          0 :         writeok = FALSE;
      55                 :            :     }
      56                 :            :   else
      57                 :            :   {
      58 [ +  + ][ +  - ]:         35 :     for (slashpos = strlen(savestr); slashpos > 0 && savestr[slashpos] != '/';
      59                 :         30 :         slashpos--)
      60                 :            :         ;
      61         [ -  + ]:          5 :     if (slashpos > 0)
      62                 :            :     {
      63                 :          0 :         savestr[slashpos] = '\0';
      64         [ #  # ]:          0 :         if (access(savestr, W_OK) == -1)
      65                 :            :         {
      66                 :          0 :             mprint(" Unable to save to that directory.");
      67                 :          0 :             writeok = FALSE;
      68                 :            :         }
      69                 :          0 :         savestr[slashpos] = '/';
      70                 :            :     }
      71                 :            :   }
      72                 :            : #endif
      73                 :          5 :   change_to_user_perms();
      74         [ +  - ]:          5 :   if (writeok) {
      75                 :          5 :     fd = fopen(savestr,"wb");
      76         [ -  + ]:          5 :     if (fd == NULL) {
      77                 :          0 :       writeok = FALSE;
      78                 :          0 :       mprint(" Error opening file.");
      79                 :            :     }
      80                 :            :   }
      81         [ -  + ]:          5 :   if (! writeok)
      82                 :            :   {
      83                 :          0 :     morewait();
      84                 :          0 :     print2("Save aborted.");
      85                 :            :   }
      86                 :            :   else {
      87                 :            : 
      88                 :          5 :     print1("Saving Game....");
      89                 :            : 
      90                 :            :     /* write the version number */
      91                 :          5 :     i = VERSION;
      92                 :          5 :     fwrite((char *)&i,sizeof(int),1,fd);
      93                 :            :     /* write game id to save file */
      94                 :            : 
      95                 :          5 :     writeok &= save_player(fd);
      96                 :          5 :     writeok &= save_country(fd);
      97                 :            : #ifdef SAVE_LEVELS
      98                 :            :     tmpdepth = Level->depth;
      99                 :            :     City = msdos_changelevel(Level,E_CITY,0);
     100                 :            : #endif
     101                 :          5 :     writeok &= save_level(fd,City);
     102                 :            :     
     103 [ +  - ][ +  + ]:          5 :     if (Current_Environment == E_CITY || Current_Environment == E_COUNTRYSIDE)
     104                 :          3 :       save = Dungeon;
     105         [ -  + ]:          2 :     else if (Current_Environment == Current_Dungeon)
     106                 :          0 :       save = Dungeon;
     107                 :            :     else
     108                 :          2 :       save = Level;
     109         [ +  + ]:          7 :     for (i = 0, current = save; current; current = current->next, i++)
     110                 :            :       ;
     111         [ -  + ]:          5 :     if (!fwrite((char *)&i,sizeof(int),1,fd))
     112                 :          0 :       writeok = FALSE;
     113                 :            : #ifdef SAVE_LEVELS
     114                 :            :     Level = msdos_changelevel(NULL,Current_Environment,tmpdepth);
     115                 :            : #endif
     116         [ +  + ]:          7 :     for (current = save; current; current = current->next)
     117         [ -  + ]:          2 :       if (current != Level)
     118                 :          0 :         writeok &= save_level(fd,current);
     119         [ +  + ]:          5 :     if (save)
     120                 :          2 :       writeok &= save_level(fd,Level);      /* put current level last */
     121                 :          5 :     fclose(fd);
     122         [ +  - ]:          5 :     if (writeok)
     123                 :          5 :         print1("Game Saved.");
     124                 :            :     else
     125                 :          0 :         print1("Something didn't work... save aborted.");
     126                 :            : #ifdef COMPRESS_SAVE_FILES
     127                 :            :     if (writeok && compress) {
     128                 :            :       print2("Compressing Save File....");
     129                 :            : # if defined(MSDOS) || defined(AMIGA)
     130                 :            :       do_compression(0, savestr);
     131                 :            :       strcpy(temp, savestr);
     132                 :            :       strcat(temp, "Z");
     133                 :            :       rename(temp, savestr);
     134                 :            : # else
     135                 :            :       strcpy(temp,COMPRESSOR);
     136                 :            :       strcat(temp," ");
     137                 :            :       strcat(temp,savestr);
     138                 :            :       system(temp);
     139                 :            :       sprintf(temp, "%s.%s", savestr, COMPRESS_EXT);
     140                 :            :       unlink(savestr);
     141                 :            :       link(temp, savestr);
     142                 :            :       unlink(temp);     /* renames, but sys-V doesn't have rename()... */
     143                 :            : # endif
     144                 :            :     }
     145                 :            : #endif
     146                 :          5 :     morewait();
     147                 :          5 :     clearmsg();
     148                 :            :   }
     149                 :          5 :   change_to_game_perms();
     150                 :          5 :   return(writeok);
     151                 :            : }
     152                 :            : 
     153                 :            : 
     154                 :            : 
     155                 :            : 
     156                 :            : /* saves game on SIGHUP */
     157                 :            : /* no longer tries to compress, which hangs */
     158                 :          0 : void signalsave(int ignore)
     159                 :            : {
     160                 :          0 :   change_to_user_perms();
     161                 :          0 :   save_game(FALSE, "Omega.Sav");
     162                 :            : #ifdef COMPRESS_SAVE_FILES
     163                 :            :   print1("Signal - Saving uncompressed file 'Omega.Sav'.");
     164                 :            :   print2("You can compress it yourself, if you like.");
     165                 :            : #else
     166                 :          0 :   print1("Signal - Saving file 'Omega.Sav'.");
     167                 :            : #endif
     168                 :          0 :   morewait();
     169                 :          0 :   endgraf();
     170                 :          0 :   exit(0);
     171                 :            : }
     172                 :            : 
     173                 :            : 
     174                 :            : /* also saves some globals like Level->depth... */
     175                 :            : 
     176                 :          5 : int save_player(FILE *fd)
     177                 :            : {
     178                 :            :   int i;
     179                 :          5 :   int ok = 1;
     180                 :            : #ifdef NEW_BANK
     181                 :            :   bank_account *account;
     182                 :            : #endif
     183                 :            : 
     184                 :            :   /* Save random global state information */
     185                 :            : 
     186                 :          5 :   Player.click = (Tick + 1)%60;
     187                 :          5 :   ok &= (fwrite((char *)&Player,sizeof(Player),1,fd) > 0);
     188                 :            : #ifndef NEW_BANK
     189                 :            :   ok &= (fprintf(fd,"%s\n",Password) >= 0);
     190                 :            : #endif
     191                 :          5 :   ok &= (fprintf(fd,"%s\n",Player.name) >= 0);  
     192                 :          5 :   ok &= (fwrite((char *)CitySiteList,sizeof(CitySiteList),1,fd) > 0);
     193                 :          5 :   ok &= (fwrite((char *)&GameStatus,sizeof(long),1,fd) > 0);
     194                 :          5 :   ok &= (fwrite((char *)&Current_Environment,sizeof(int),1,fd) > 0);
     195                 :          5 :   ok &= (fwrite((char *)&Last_Environment,sizeof(int),1,fd) > 0);
     196                 :          5 :   ok &= (fwrite((char *)&Current_Dungeon,sizeof(int),1,fd) > 0);
     197                 :          5 :   ok &= (fwrite((char *)&Villagenum,sizeof(int),1,fd) > 0);
     198                 :          5 :   ok &= (fwrite((char *)&Verbosity,sizeof(char),1,fd) > 0);
     199                 :          5 :   ok &= (fwrite((char *)&Time,sizeof(long),1,fd) > 0);
     200                 :          5 :   ok &= (fwrite((char *)&Tick,sizeof(int),1,fd) > 0);
     201                 :          5 :   ok &= (fwrite((char *)&Searchnum,sizeof(int),1,fd) > 0);
     202                 :          5 :   ok &= (fwrite((char *)&Behavior,sizeof(int),1,fd) > 0);
     203                 :          5 :   ok &= (fwrite((char *)&Phase,sizeof(int),1,fd) > 0);
     204                 :          5 :   ok &= (fwrite((char *)&Date,sizeof(int),1,fd) > 0);
     205                 :          5 :   ok &= (fwrite((char *)&Spellsleft,sizeof(int),1,fd) > 0);
     206                 :          5 :   ok &= (fwrite((char *)&SalaryAmount,sizeof(int),1,fd) > 0);
     207                 :          5 :   ok &= (fwrite((char *)&SalaryAccount,sizeof(int),1,fd) > 0);
     208                 :          5 :   ok &= (fwrite((char *)&Studiesleft,sizeof(int),1,fd) > 0);
     209                 :          5 :   ok &= (fwrite((char *)&SymbolUseHour,sizeof(int),1,fd) > 0);
     210                 :          5 :   ok &= (fwrite((char *)&SymbolUseDay,sizeof(int),1,fd) > 0);
     211                 :          5 :   ok &= (fwrite((char *)&ViewHour,sizeof(int),1,fd) > 0);
     212                 :          5 :   ok &= (fwrite((char *)&ViewDay,sizeof(int),1,fd) > 0);
     213                 :          5 :   ok &= (fwrite((char *)&HelmHour,sizeof(int),1,fd) > 0);
     214                 :          5 :   ok &= (fwrite((char *)&HelmDay,sizeof(int),1,fd) > 0);
     215                 :          5 :   ok &= (fwrite((char *)&Constriction,sizeof(int),1,fd) > 0);
     216                 :          5 :   ok &= (fwrite((char *)&Blessing,sizeof(int),1,fd) > 0);
     217                 :          5 :   ok &= (fwrite((char *)&LastDay,sizeof(int),1,fd) > 0);
     218                 :          5 :   ok &= (fwrite((char *)&RitualHour,sizeof(int),1,fd) > 0);
     219                 :          5 :   ok &= (fwrite((char *)&Lawstone,sizeof(int),1,fd) > 0);
     220                 :          5 :   ok &= (fwrite((char *)&Chaostone,sizeof(int),1,fd) > 0);
     221                 :          5 :   ok &= (fwrite((char *)&Mindstone,sizeof(int),1,fd) > 0);
     222                 :          5 :   ok &= (fwrite((char *)&Arena_Opponent,sizeof(int),1,fd) > 0);
     223                 :          5 :   ok &= (fwrite((char *)&Imprisonment,sizeof(int),1,fd) > 0);
     224                 :          5 :   ok &= (fwrite((char *)&Gymcredit,sizeof(long),1,fd) > 0);
     225                 :            : 
     226                 :            : #ifdef NEW_BANK
     227                 :          5 :   i = 0;
     228         [ +  + ]:         45 :   for( account = bank; account; account = account->next_account ) i++;
     229                 :          5 :   ok &= ( fwrite( (char *)&i, sizeof( int ), 1, fd ) > 0 );
     230         [ +  + ]:         45 :   for( account = bank; account; account = account->next_account )
     231                 :            :     {
     232                 :         40 :       ok &= ( fwrite( (char *)(&(account->player)), sizeof(short), 1, fd ) > 0 );
     233                 :         40 :       ok &= ( fwrite( (char *)(&(account->balance)), sizeof(long), 1, fd ) > 0 );
     234                 :         40 :       ok &= ( fwrite( (char *)(&(account->number)), sizeof(long), 1, fd ) > 0 );
     235                 :         40 :       ok &= ( fprintf( fd, "%s\n", account->password ) >= 0 );
     236                 :            :     }
     237                 :            : #else
     238                 :            :   ok &= (fwrite((char *)&Balance,sizeof(long),1,fd) > 0);
     239                 :            : #endif
     240                 :            : 
     241                 :          5 :   ok &= (fwrite((char *)&StarGemUse,sizeof(int),1,fd) > 0);
     242                 :          5 :   ok &= (fwrite((char *)&HiMagicUse,sizeof(int),1,fd) > 0);
     243                 :          5 :   ok &= (fwrite((char *)&HiMagic,sizeof(int),1,fd) > 0);
     244                 :          5 :   ok &= (fwrite((char *)&FixedPoints,sizeof(long),1,fd) > 0);
     245                 :          5 :   ok &= (fwrite((char *)&LastCountryLocX,sizeof(int),1,fd) > 0);
     246                 :          5 :   ok &= (fwrite((char *)&LastCountryLocY,sizeof(int),1,fd) > 0);
     247                 :          5 :   ok &= (fwrite((char *)&LastTownLocX,sizeof(int),1,fd) > 0);
     248                 :          5 :   ok &= (fwrite((char *)&LastTownLocY,sizeof(int),1,fd) > 0);
     249                 :          5 :   ok &= (fwrite((char *)&Pawndate,sizeof(int),1,fd) > 0);
     250                 :            : 
     251                 :          5 :   ok &= (fwrite((char *)Spells,sizeof(Spells),1,fd) > 0);
     252                 :            : 
     253                 :          5 :   ok &= (fwrite((char *)&Command_Duration,sizeof(Command_Duration),1,fd) > 0);
     254                 :          5 :   ok &= (fwrite((char *)&Precipitation,sizeof(Precipitation),1,fd) > 0);
     255                 :          5 :   ok &= (fwrite((char *)&Lunarity,sizeof(Lunarity),1,fd) > 0);
     256                 :          5 :   ok &= (fwrite((char *)&ZapHour,sizeof(ZapHour),1,fd) > 0);
     257                 :          5 :   ok &= (fwrite((char *)&RitualRoom,sizeof(RitualRoom),1,fd) > 0);
     258                 :            : 
     259                 :            :   /* stuff which used to be statics */
     260                 :          5 :   ok &= (fwrite((char *)&twiddle,sizeof(twiddle),1,fd) > 0);
     261                 :          5 :   ok &= (fwrite((char *)&saved,sizeof(saved),1,fd) > 0);
     262                 :          5 :   ok &= (fwrite((char *)&onewithchaos,sizeof(onewithchaos),1,fd) > 0);
     263                 :          5 :   ok &= (fwrite((char *)&club_hinthour,sizeof(club_hinthour),1,fd) > 0);
     264                 :          5 :   ok &= (fwrite((char *)&winnings,sizeof(winnings),1,fd) > 0);
     265                 :          5 :   ok &= (fwrite((char *)&tavern_hinthour,sizeof(tavern_hinthour),1,fd) > 0);
     266                 :          5 :   ok &= (fwrite((char *)scroll_ids,sizeof(scroll_ids),1,fd) > 0);
     267                 :          5 :   ok &= (fwrite((char *)potion_ids,sizeof(potion_ids),1,fd) > 0);
     268                 :          5 :   ok &= (fwrite((char *)stick_ids,sizeof(stick_ids),1,fd) > 0);
     269                 :          5 :   ok &= (fwrite((char *)ring_ids,sizeof(ring_ids),1,fd) > 0);
     270                 :          5 :   ok &= (fwrite((char *)cloak_ids,sizeof(cloak_ids),1,fd) > 0);
     271                 :          5 :   ok &= (fwrite((char *)boot_ids,sizeof(boot_ids),1,fd) > 0);
     272                 :          5 :   ok &= (fwrite((char *)deepest,sizeof(int),E_MAX + 1,fd) > 0);
     273                 :          5 :   ok &= (fwrite((char *)level_seed,sizeof(int),E_MAX + 1,fd) > 0);
     274                 :            : 
     275                 :            :   /* Save player possessions */
     276                 :            : 
     277         [ -  + ]:          5 :   if (Player.possessions[O_READY_HAND] == Player.possessions[O_WEAPON_HAND])
     278                 :          0 :     Player.possessions[O_READY_HAND] = NULL;
     279         [ +  + ]:         85 :   for(i=0;i<MAXITEMS;i++) ok &= save_item(fd,Player.possessions[i]);
     280         [ +  + ]:        135 :   for(i=0;i<MAXPACK;i++) ok &= save_item(fd,Player.pack[i]);
     281         [ +  + ]:        105 :   for(i=0;i<PAWNITEMS;i++) ok &= save_item(fd,Pawnitems[i]);
     282                 :            : 
     283                 :            :   /* Save items in condo vault */
     284                 :          5 :   ok &= save_itemlist(fd,Condoitems);
     285                 :            :   /* Save items in bag of holding */
     286                 :          5 :   ok &= save_itemlist(fd,Bagitems);
     287                 :            : 
     288                 :            :   /* Save player item knowledge */
     289         [ +  + ]:       1120 :   for (i=0;i<TOTALITEMS;i++)
     290                 :            :   {
     291                 :       1115 :     ok &= (fwrite((char *)&(Objects[i].known),sizeof(Objects[i].known),1,fd) > 0);
     292                 :       1115 :     ok &= (fwrite((char *)&(Objects[i].uniqueness),sizeof(Objects[i].uniqueness),1,fd) > 0);
     293                 :            :   }
     294                 :          5 :   return ok;
     295                 :            : }
     296                 :            : 
     297                 :            : 
     298                 :            : /* Save whatever is pointed to by level */
     299                 :          7 : int save_level(FILE *fd, plv level)
     300                 :            : {
     301                 :            :   int i, j, run;
     302                 :            :   unsigned long int mask;
     303                 :          7 :   int ok = 1;
     304                 :          7 :   int width = level->level_width;
     305                 :          7 :   int length = level->level_length;
     306                 :            : 
     307                 :          7 :   ok &= (fwrite((char *)&level->depth,sizeof(char),1,fd) > 0);
     308                 :          7 :   ok &= (fwrite((char *)&level->numrooms,sizeof(char),1,fd) > 0);
     309                 :          7 :   ok &= (fwrite((char *)&level->tunnelled,sizeof(char),1,fd) > 0);
     310                 :          7 :   ok &= (fwrite((char *)&level->environment,sizeof(int),1,fd) > 0);
     311                 :          7 :   ok &= (fwrite((char *)&level->level_width,sizeof(int),1,fd) > 0);
     312                 :          7 :   ok &= (fwrite((char *)&level->level_length,sizeof(int),1,fd) > 0);
     313         [ +  + ]:        359 :   for (j = 0; j < length; j++)
     314         [ +  + ]:      22880 :     for (i = 0; i < width; i++)
     315         [ -  + ]:      22528 :       if (level->site[i][j].lstatus&CHANGED) {   /* this loc has been changed */
     316 [ #  # ][ #  # ]:          0 :         for (run = i + 1; run < width &&     /* find how many in a row */
     317                 :          0 :           level->site[run][j].lstatus&CHANGED; run++)
     318                 :            :           ;
     319                 :          0 :         ok &= (fwrite((char *)&i,sizeof(int),1,fd) > 0);
     320                 :          0 :         ok &= (fwrite((char *)&j,sizeof(int),1,fd) > 0);
     321                 :          0 :         ok &= (fwrite((char *)&run,sizeof(int),1,fd) > 0);
     322         [ #  # ]:          0 :         for (; i < run; i++)
     323                 :          0 :           ok &= (fwrite((char *)&level->site[i][j],sizeof(struct location),1,fd) > 0);
     324                 :            :       }
     325                 :          7 :   ok &= (fwrite((char *)&i,sizeof(int),1,fd) > 0);
     326                 :          7 :   ok &= (fwrite((char *)&j,sizeof(int),1,fd) > 0);   /* signify end */
     327                 :            :   /* since we don't mark the 'seen' bits as CHANGED, need to save a bitmask */
     328                 :          7 :   run = 8*sizeof(long int);
     329                 :          7 :   mask = 0;
     330         [ +  + ]:        359 :   for (j = 0; j < length; j++)
     331         [ +  + ]:      22880 :     for (i = 0; i < width; i++) {
     332         [ +  + ]:      22528 :       if (run == 0) {
     333                 :        345 :         run = 8*sizeof(long int);
     334                 :        345 :         ok &= (fwrite((char *)&mask,sizeof(long int),1,fd) > 0);
     335                 :        345 :         mask = 0;
     336                 :            :       }
     337                 :      22528 :       mask >>= 1;
     338         [ +  + ]:      22528 :       if (level->site[i][j].lstatus&SEEN)
     339                 :      21098 :         mask |= (1UL<<(sizeof(long int)*8 - 1));
     340                 :      22528 :       run--;
     341                 :            :     }
     342         [ +  - ]:          7 :   if (run < 8*sizeof(long int))
     343                 :          7 :     ok &= (fwrite((char *)&mask,sizeof(long int),1,fd) > 0);
     344                 :          7 :   ok &= save_monsters(fd,level->mlist);
     345         [ +  + ]:        455 :   for(i=0;i<width;i++)
     346         [ +  + ]:      22976 :     for(j=0;j<length;j++)
     347         [ +  + ]:      22528 :       if (level->site[i][j].things) {
     348                 :        183 :         ok &= (fwrite((char *)&i,sizeof(int),1,fd) > 0);
     349                 :        183 :         ok &= (fwrite((char *)&j,sizeof(int),1,fd) > 0);
     350                 :        183 :         ok &= save_itemlist(fd,level->site[i][j].things);
     351                 :            :       }
     352                 :          7 :   ok &= (fwrite((char *)&i,sizeof(int),1,fd) > 0);
     353                 :          7 :   ok &= (fwrite((char *)&j,sizeof(int),1,fd) > 0);   /* signify end */
     354                 :          7 :   return ok;
     355                 :            : }
     356                 :            : 
     357                 :            : 
     358                 :          7 : int save_monsters(FILE *fd, pml ml)
     359                 :            : {
     360                 :            :   pml tml;
     361                 :          7 :   int nummonsters=0;
     362                 :          7 :   int ok = 1;
     363                 :            :   unsigned char type;
     364                 :            : 
     365                 :            :   /* First count monsters */
     366         [ +  + ]:        144 :   for(tml=ml;tml!=NULL;tml=tml->next) 
     367         [ +  - ]:        137 :     if (tml->m->hp > 0) nummonsters++;
     368                 :            : 
     369                 :          7 :   ok &= (fwrite((char *)&nummonsters,sizeof(int),1,fd) > 0);
     370                 :            : 
     371                 :            :   /* Now save monsters */
     372         [ +  + ]:        144 :   for(tml=ml;tml!=NULL;tml=tml->next) {
     373         [ +  - ]:        137 :     if (tml->m->hp > 0) {
     374                 :        137 :       ok &= (fwrite((char *)tml->m,sizeof(montype),1,fd) > 0);
     375         [ +  + ]:        137 :       if (tml->m->id != HISCORE_NPC) {
     376                 :        132 :         type = 0x0;
     377                 :            :         /* DAG use pointer compare rather than strcmp; a bit more effecient */
     378         [ -  + ]:        132 :         if (tml->m->monstring != Monsters[tml->m->id].monstring)
     379                 :          0 :           type |= 0x1;
     380         [ -  + ]:        132 :         if (tml->m->corpsestr != Monsters[tml->m->id].corpsestr)
     381                 :          0 :           type |= 0x2;
     382                 :            :         /* DAG expect from now (version 9000) on that type will always be  */
     383                 :            :         /*     0x3 (both) saved, but leave this way as it may not, and this  */
     384                 :            :         /*     preserves save-file compatibility without requiring code changes */
     385                 :        132 :         ok &= (fwrite((char *)&type,sizeof(unsigned char),1,fd) > 0);
     386         [ -  + ]:        132 :         if (type&1)
     387                 :          0 :           ok &= (fprintf(fd,"%s\n",tml->m->monstring) >= 0);
     388         [ -  + ]:        132 :         if (type&2)
     389                 :          0 :           ok &= (fprintf(fd,"%s\n",tml->m->corpsestr) >= 0);
     390                 :            :         /* WDT: line moved from here... */
     391                 :            :       } /* else it'll be reloaded from the hiscore file on restore */
     392                 :            :       /* WDT: to here.  This bug fix is Sheldon Simm's suggestion
     393                 :            :        * to fix the well-known 'Star Gem' bug; it should allow the
     394                 :            :        * possessions of hiscore NPCs to be restored from the savefile.
     395                 :            :        * See also the complementary change in restore_monsters. */
     396                 :        137 :       ok &= save_itemlist(fd,tml->m->possessions);
     397                 :            :     }
     398                 :            :   }
     399                 :          7 :   return ok;
     400                 :            : }
     401                 :            : 
     402                 :            : 
     403                 :            : /* Save o unless it's null, then save a special flag byte instead */
     404                 :            : /* Use other values of flag byte to indicate what strings are saved */
     405                 :        674 : int save_item(FILE *fd, pob o)
     406                 :            : {
     407                 :        674 :   int ok = 1;
     408                 :            :   unsigned char type;
     409                 :            : 
     410         [ +  + ]:        674 :   if (o == NULL) {
     411                 :        182 :     type = 0xff;
     412                 :        182 :     ok &= (fwrite((char *)&type,sizeof(type),1,fd) > 0);
     413                 :            :   }
     414                 :            :   else {
     415                 :        492 :     type = 0;
     416                 :            :     /* DAG these strcmp could be just pointer comparisons, more efficient. */
     417         [ +  + ]:        492 :     if (strcmp(o->objstr, Objects[o->id].objstr))
     418                 :          7 :       type |= 1;
     419         [ +  + ]:        492 :     if (strcmp(o->truename, Objects[o->id].truename))
     420                 :          7 :       type |= 2;
     421         [ +  + ]:        492 :     if (strcmp(o->cursestr, Objects[o->id].cursestr))
     422                 :          7 :       type |= 4;
     423                 :            :     /* DAG following is true for corpses */
     424 [ +  + ][ +  - ]:        492 :     if ( (type && o->cursestr == o->objstr) && (o->cursestr == o->truename) )
                 [ +  - ]
     425                 :          7 :       type |=8;
     426                 :        492 :     ok &= (fwrite((char *)&type,sizeof(type),1,fd) > 0);
     427                 :        492 :     ok &= (fwrite((char *)o,sizeof(objtype),1,fd) > 0);
     428         [ +  + ]:        492 :     if (type&1)
     429                 :          7 :       ok &= (fprintf(fd,"%s\n",o->objstr) >= 0);
     430         [ +  + ]:        492 :     if (type&2)
     431                 :          7 :       ok &= (fprintf(fd,"%s\n",o->truename) >= 0);
     432         [ +  + ]:        492 :     if (type&4)
     433                 :          7 :       ok &= (fprintf(fd,"%s\n",o->cursestr) >= 0);
     434                 :            :   }
     435                 :        674 :   return ok;
     436                 :            : }
     437                 :            : 
     438                 :        330 : int save_itemlist(FILE *fd, pol ol)
     439                 :            : {
     440                 :        330 :   int numitems = 0;
     441                 :            :   pol tol;
     442                 :        330 :   int ok = 1;
     443                 :            : 
     444         [ +  + ]:        694 :   for(tol=ol;tol!=NULL;tol=tol->next) numitems++;
     445                 :        330 :   ok &= (fwrite((char *)&numitems,sizeof(int),1,fd) > 0);
     446         [ +  + ]:        694 :   for(tol=ol;tol!=NULL;tol=tol->next)
     447                 :        364 :     ok &= save_item(fd,tol->thing);
     448                 :        330 :   return ok;
     449                 :            : }
     450                 :            : 
     451                 :            : 
     452                 :          5 : int save_country(FILE *fd)
     453                 :            : {
     454                 :            :   int i, j;
     455                 :          5 :   int ok = 1;
     456                 :            :   int run;
     457                 :            :   unsigned long int mask;
     458                 :            : 
     459         [ +  + ]:        325 :   for (i = 0; i < COUNTRY_WIDTH; i++)
     460         [ +  + ]:      20800 :     for (j = 0; j < COUNTRY_LENGTH; j++)
     461         [ -  + ]:      20480 :       if (c_statusp(i, j, CHANGED)) {
     462                 :          0 :         ok &= (fwrite((char *)&i,sizeof(int),1,fd) > 0);
     463                 :          0 :         ok &= (fwrite((char *)&j,sizeof(int),1,fd) > 0);
     464                 :          0 :         ok &= (fwrite((char *)&Country[i][j],sizeof(struct terrain),1,fd) > 0);
     465                 :            :       }
     466                 :          5 :   ok &= (fwrite((char *)&i,sizeof(int),1,fd) > 0);
     467                 :          5 :   ok &= (fwrite((char *)&j,sizeof(int),1,fd) > 0);
     468                 :            :   /* since we don't mark the 'seen' bits as CHANGED, need to save a bitmask */
     469                 :          5 :   run = 8*sizeof(long int);
     470                 :          5 :   mask = 0;
     471         [ +  + ]:        325 :   for (i = 0; i < COUNTRY_WIDTH; i++)
     472         [ +  + ]:      20800 :     for (j = 0; j < COUNTRY_LENGTH; j++) {
     473         [ +  + ]:      20480 :       if (run == 0) {
     474                 :        315 :         run = 8*sizeof(long int);
     475                 :        315 :         ok &= (fwrite((char *)&mask,sizeof(long int),1,fd) > 0);
     476                 :        315 :         mask = 0;
     477                 :            :       }
     478                 :      20480 :       mask >>= 1;
     479         [ +  + ]:      20480 :       if (c_statusp(i, j, SEEN))
     480                 :        420 :         mask |= (1UL<<(sizeof(long int)*8 - 1));
     481                 :      20480 :       run--;
     482                 :            :     }
     483         [ +  - ]:          5 :   if (run < 8*sizeof(long int))
     484                 :          5 :     ok &= (fwrite((char *)&mask,sizeof(long int),1,fd) > 0);
     485                 :          5 :   return ok;
     486                 :            : }
     487                 :            : 
     488                 :            : 
     489                 :            : /* returns TRUE if the given version can be restored by this version */
     490                 :          0 : int ok_outdated(int version)
     491                 :            : {
     492                 :            : /* currently all backwards compatibility is broken, so fail ok_outdated()
     493                 :            :    until we actually re-install some type of backwards compatibility. DAG */
     494                 :            : 
     495                 :          0 :   return FALSE;
     496                 :            : 
     497                 :            : #if 0
     498                 :            :   switch (version) {
     499                 :            :     case 80:
     500                 :            :       print1("Converting version 0.80 savefile to current.");
     501                 :            :       morewait();
     502                 :            :       return TRUE;
     503                 :            :       break;
     504                 :            :     case 81:
     505                 :            :       print1("Converting version 0.81 savefile to current.");
     506                 :            :       morewait();
     507                 :            :       return TRUE;
     508                 :            :       break;
     509                 :            :     case 90:
     510                 :            :       print1("Converting version 0.90 savefile to current.");
     511                 :            :       morewait();
     512                 :            :       return TRUE;
     513                 :            :       break;
     514                 :            :     case 91:
     515                 :            :       /* version 91 is same as version 9000 right now */
     516                 :            :       return TRUE;
     517                 :            :       break;
     518                 :            :     case 9000:
     519                 :            :       /* DAG - 9000 is the re-numbered 90, for the new version numbering system. */
     520                 :            :       print1("Converting version 0.90 savefile to current.");
     521                 :            :       morewait();
     522                 :            :       return TRUE;
     523                 :            :       break;
     524                 :            :     default:
     525                 :            :       return FALSE;
     526                 :            :       break;
     527                 :            :   }
     528                 :            : #endif /* #if 0 */
     529                 :            : }
     530                 :            : 
     531                 :            : 
     532                 :            : /* read player data, city level, dungeon level,
     533                 :            :    check on validity of save file, etc.
     534                 :            :    return TRUE if game restored, FALSE otherwise */
     535                 :            : 
     536                 :         10 : int restore_game(char *savestr)
     537                 :            : {
     538                 :            :   int i,version; 
     539                 :            : #ifdef COMPRESS_SAVE_FILES
     540                 :            :   char temp[200];
     541                 :            : #endif
     542                 :            :   FILE *fd;
     543                 :            : 
     544                 :            : #ifndef MSDOS_SUPPORTED_ANTIQUE
     545         [ +  + ]:         10 :   if (access(savestr, F_OK|R_OK|W_OK) == -1) /* access uses real uid */
     546                 :            :   {
     547                 :          2 :     print1("Unable to access save file: ");
     548                 :          2 :     nprint1(savestr);
     549                 :          2 :     morewait();
     550                 :          2 :     return FALSE;
     551                 :            :   }
     552                 :            : #endif
     553                 :          8 :   change_to_user_perms();
     554                 :            : #ifdef COMPRESS_SAVE_FILES
     555                 :            :   fd = fopen(savestr,"rb");
     556                 :            :   if (fd == NULL) {
     557                 :            :     print1("Error restoring game -- aborted.");
     558                 :            :     print2("File name was: ");
     559                 :            :     nprint2(savestr);
     560                 :            :     morewait();
     561                 :            :     change_to_game_perms();
     562                 :            :     return(FALSE);
     563                 :            :   }
     564                 :            :   fread((char *)&version,sizeof(int),1,fd);
     565                 :            :   fclose(fd);
     566                 :            :   if (VERSION != version && !ok_outdated(version)) {
     567                 :            :     print1("Uncompressing Save File....");
     568                 :            : #if defined(MSDOS) || defined(AMIGA)
     569                 :            :     strcpy(temp, savestr);
     570                 :            :     strcat(temp, "Z");
     571                 :            :     rename(savestr, temp);
     572                 :            :     do_compression(1, savestr);
     573                 :            : #else
     574                 :            :     sprintf(temp, "%s.%s", savestr, COMPRESS_EXT);
     575                 :            :     unlink(temp);
     576                 :            :     link(savestr, temp);
     577                 :            :     unlink(savestr);    /* renames, but sys-V doesn't have rename()... */
     578                 :            :     strcpy(temp,UNCOMPRESSOR);
     579                 :            :     strcat(temp," ");
     580                 :            :     strcat(temp,savestr);
     581                 :            :     system(temp);
     582                 :            : #endif
     583                 :            :     print2("Save file uncompressed.");
     584                 :            :     morewait();
     585                 :            :   }
     586                 :            : #endif
     587                 :            :   
     588                 :          8 :   fd = fopen(savestr,"rb");
     589                 :            : 
     590         [ -  + ]:          8 :   if (fd == NULL) {
     591                 :          0 :     print1("Error restoring game -- aborted.");
     592                 :          0 :     print2("File name was: ");
     593                 :          0 :     nprint2(savestr);
     594                 :          0 :     morewait();
     595                 :          0 :     change_to_game_perms();
     596                 :          0 :     return(FALSE);
     597                 :            :   }
     598                 :            :   else {
     599                 :          8 :     print1("Restoring...");
     600                 :            : 
     601                 :          8 :     fread((char *)&version,sizeof(int),1,fd);
     602                 :            : 
     603 [ -  + ][ #  # ]:          8 :     if (VERSION != version && !ok_outdated(version)) {
     604                 :          0 :       change_to_game_perms();
     605                 :          0 :       fclose(fd);
     606                 :          0 :       clearmsg();
     607                 :          0 :       mprint(" Sorry, I can't restore an outdated save file!");
     608                 :          0 :       mprint(" savefile is version ");
     609                 :          0 :       mnumprint(version/10000);
     610                 :          0 :       nprint2(".");
     611                 :          0 :       mnumprint( (version/100)%100);
     612                 :          0 :       morewait();
     613                 :          0 :       return(FALSE);
     614                 :            :     }
     615                 :          8 :     restore_player(fd, version);
     616                 :          8 :     restore_country(fd, version);
     617                 :          8 :     restore_level(fd, version); /* the city level */
     618                 :          8 :     fread((char *)&i,sizeof(int),1,fd);
     619         [ +  + ]:         14 :     for (; i > 0; i--) {
     620                 :            : #ifdef SAVE_LEVELS
     621                 :            :       msdos_changelevel(Level,0,-1);
     622                 :            : #endif
     623                 :          6 :       restore_level(fd, version);
     624         [ -  + ]:          6 :       if (Level->environment == Current_Dungeon) {
     625                 :          0 :         Level->next = Dungeon;
     626                 :          0 :         Dungeon = Level;
     627                 :            :       }
     628         [ -  + ]:          6 :       if (Current_Environment == E_CITY)
     629                 :          0 :         Level = City;
     630                 :            :     }
     631                 :            : 
     632                 :          8 :     fclose(fd);
     633                 :          8 :     print3("Restoration complete.");
     634                 :          8 :     ScreenOffset = -1000;       /* to force a redraw */
     635                 :          8 :     setgamestatus(SKIP_MONSTERS);
     636                 :          8 :     change_to_game_perms();
     637                 :         10 :     return(TRUE);
     638                 :            :   }
     639                 :            : }
     640                 :            : 
     641                 :          8 : void restore_player(FILE *fd, int version)
     642                 :            : {
     643                 :            :   int i;
     644                 :            : #ifdef NEW_BANK
     645                 :            :   int num_accounts;
     646                 :            :   bank_account *account;
     647                 :            :   char pw_buf[ 64 ];
     648                 :            : #endif
     649                 :            : 
     650                 :          8 :   fread((char *)&Player,sizeof(Player),1,fd);
     651                 :            : #ifndef NEW_BANK
     652                 :            :   filescanstring(fd,Password);
     653                 :            : #endif
     654                 :          8 :   filescanstring(fd,Player.name);
     655                 :            : #ifdef ALLOWING_OLD_SAVEFILES
     656                 :            :   if( version < 91 ) /* DAG */
     657                 :            :     fread((char *)CitySiteList,(3*OLD_NUMCITYSITES*sizeof(int)),1,fd);
     658                 :            :   else 
     659                 :            : #endif
     660                 :          8 :     fread((char *)CitySiteList,sizeof(CitySiteList),1,fd);
     661                 :          8 :   fread((char *)&GameStatus,sizeof(long),1,fd);
     662                 :          8 :   fread((char *)&Current_Environment,sizeof(int),1,fd);
     663                 :          8 :   fread((char *)&Last_Environment,sizeof(int),1,fd);
     664                 :          8 :   fread((char *)&Current_Dungeon,sizeof(int),1,fd);
     665                 :          8 :   fread((char *)&Villagenum,sizeof(int),1,fd);
     666   [ -  -  -  -  :          8 :   switch(Current_Dungeon) {
                -  -  + ]
     667                 :          0 :     case E_ASTRAL: MaxDungeonLevels = ASTRALLEVELS; break;
     668                 :          0 :     case E_SEWERS: MaxDungeonLevels = SEWERLEVELS; break;
     669                 :          0 :     case E_CASTLE: MaxDungeonLevels = CASTLELEVELS; break;
     670                 :          0 :     case E_CAVES: MaxDungeonLevels = CAVELEVELS; break;
     671                 :          0 :     case E_VOLCANO: MaxDungeonLevels = VOLCANOLEVELS; break;
     672                 :          0 :     case E_PALACE: MaxDungeonLevels = PALACELEVELS; break;
     673                 :            :   }
     674                 :          8 :   fread((char *)&Verbosity,sizeof(char),1,fd);
     675                 :          8 :   fread((char *)&Time,sizeof(long),1,fd);
     676                 :          8 :   fread((char *)&Tick,sizeof(int),1,fd);
     677                 :          8 :   fread((char *)&Searchnum,sizeof(int),1,fd);
     678                 :          8 :   fread((char *)&Behavior,sizeof(int),1,fd);
     679                 :          8 :   fread((char *)&Phase,sizeof(int),1,fd);
     680                 :          8 :   fread((char *)&Date,sizeof(int),1,fd);
     681                 :          8 :   fread((char *)&Spellsleft,sizeof(int),1,fd);
     682                 :          8 :   fread((char *)&SalaryAmount,sizeof(int),1,fd);
     683                 :          8 :   fread((char *)&SalaryAccount,sizeof(int),1,fd);
     684                 :          8 :   fread((char *)&Studiesleft,sizeof(int),1,fd);
     685                 :          8 :   fread((char *)&SymbolUseHour,sizeof(int),1,fd);
     686                 :          8 :   fread((char *)&SymbolUseDay,sizeof(int),1,fd);
     687                 :          8 :   fread((char *)&ViewHour,sizeof(int),1,fd);
     688                 :          8 :   fread((char *)&ViewDay,sizeof(int),1,fd);
     689                 :          8 :   fread((char *)&HelmHour,sizeof(int),1,fd);
     690                 :          8 :   fread((char *)&HelmDay,sizeof(int),1,fd);
     691                 :          8 :   fread((char *)&Constriction,sizeof(int),1,fd);
     692                 :          8 :   fread((char *)&Blessing,sizeof(int),1,fd);
     693                 :          8 :   fread((char *)&LastDay,sizeof(int),1,fd);
     694                 :          8 :   fread((char *)&RitualHour,sizeof(int),1,fd);
     695                 :          8 :   fread((char *)&Lawstone,sizeof(int),1,fd);
     696                 :          8 :   fread((char *)&Chaostone,sizeof(int),1,fd);
     697                 :          8 :   fread((char *)&Mindstone,sizeof(int),1,fd);
     698                 :          8 :   fread((char *)&Arena_Opponent,sizeof(int),1,fd);
     699                 :          8 :   fread((char *)&Imprisonment,sizeof(int),1,fd);
     700                 :          8 :   fread((char *)&Gymcredit,sizeof(long),1,fd);
     701                 :            : 
     702                 :            : #ifdef NEW_BANK
     703                 :          8 :   fread( (char *)&num_accounts, sizeof( int ), 1, fd );
     704         [ +  + ]:         72 :   for( i = 0; i < num_accounts; i++ )
     705                 :            :     {
     706                 :         64 :       account = (bank_account *)checkmalloc( sizeof( bank_account ));
     707                 :         64 :       fread( (char *)(&(account->player)), sizeof(short), 1, fd );
     708                 :         64 :       fread( (char *)(&(account->balance)), sizeof(long), 1, fd );
     709                 :         64 :       fread( (char *)(&(account->number)), sizeof(long), 1, fd );
     710                 :         64 :       filescanstring( fd, pw_buf );
     711                 :         64 :       account->password = salloc( pw_buf );
     712                 :         64 :       account->next_account = bank;
     713                 :         64 :       bank = account;
     714                 :            :     }
     715                 :            : #else
     716                 :            :   fread((char *)&Balance,sizeof(long),1,fd);
     717                 :            : #endif
     718                 :            : 
     719                 :          8 :   fread((char *)&StarGemUse,sizeof(int),1,fd);
     720                 :          8 :   fread((char *)&HiMagicUse,sizeof(int),1,fd);
     721                 :          8 :   fread((char *)&HiMagic,sizeof(int),1,fd);
     722                 :          8 :   fread((char *)&FixedPoints,sizeof(long),1,fd);
     723                 :          8 :   fread((char *)&LastCountryLocX,sizeof(int),1,fd);
     724                 :          8 :   fread((char *)&LastCountryLocY,sizeof(int),1,fd);
     725                 :          8 :   fread((char *)&LastTownLocX,sizeof(int),1,fd);
     726                 :          8 :   fread((char *)&LastTownLocY,sizeof(int),1,fd);
     727                 :          8 :   fread((char *)&Pawndate,sizeof(int),1,fd);
     728                 :            : 
     729                 :          8 :   fread((char *)Spells,sizeof(Spells),1,fd);
     730                 :            : 
     731                 :          8 :   fread((char *)&Command_Duration,sizeof(Command_Duration),1,fd);
     732                 :          8 :   fread((char *)&Precipitation,sizeof(Precipitation),1,fd);
     733                 :          8 :   fread((char *)&Lunarity,sizeof(Lunarity),1,fd);
     734                 :          8 :   fread((char *)&ZapHour,sizeof(ZapHour),1,fd);
     735                 :          8 :   fread((char *)&RitualRoom,sizeof(RitualRoom),1,fd);
     736                 :            : 
     737                 :            :   /* stuff which used to be statics */
     738                 :          8 :   fread((char *)&twiddle,sizeof(twiddle),1,fd);
     739                 :          8 :   fread((char *)&saved,sizeof(saved),1,fd);
     740                 :          8 :   fread((char *)&onewithchaos,sizeof(onewithchaos),1,fd);
     741                 :          8 :   fread((char *)&club_hinthour,sizeof(club_hinthour),1,fd);
     742                 :          8 :   fread((char *)&winnings,sizeof(winnings),1,fd);
     743                 :          8 :   fread((char *)&tavern_hinthour,sizeof(tavern_hinthour),1,fd);
     744                 :          8 :   fread((char *)scroll_ids,sizeof(scroll_ids),1,fd);
     745                 :          8 :   fread((char *)potion_ids,sizeof(potion_ids),1,fd);
     746                 :          8 :   fread((char *)stick_ids,sizeof(stick_ids),1,fd);
     747                 :          8 :   fread((char *)ring_ids,sizeof(ring_ids),1,fd);
     748                 :          8 :   fread((char *)cloak_ids,sizeof(cloak_ids),1,fd);
     749                 :          8 :   fread((char *)boot_ids,sizeof(boot_ids),1,fd);
     750                 :          8 :   fread((char *)deepest,sizeof(int),E_MAX + 1,fd);
     751                 :          8 :   fread((char *)level_seed,sizeof(int),E_MAX + 1,fd);
     752                 :            : 
     753                 :            :   /* Set up the strings for the id's */
     754                 :          8 :   inititem(FALSE);
     755                 :            : 
     756         [ +  + ]:        136 :   for(i=0;i<MAXITEMS;i++) 
     757                 :        128 :     Player.possessions[i] = restore_item(fd, version);
     758                 :            : 
     759         [ +  - ]:         16 :   if (!Player.possessions[O_READY_HAND] && Player.possessions[O_WEAPON_HAND] &&
           [ +  -  -  + ]
     760                 :          8 :     twohandedp(Player.possessions[O_WEAPON_HAND]->id))
     761                 :          0 :     Player.possessions[O_READY_HAND] = Player.possessions[O_WEAPON_HAND];
     762                 :            : 
     763         [ +  + ]:        216 :   for(i=0;i<MAXPACK;i++) 
     764                 :        208 :     Player.pack[i] = restore_item(fd, version);
     765         [ +  + ]:        168 :   for(i=0;i<PAWNITEMS;i++) 
     766                 :        160 :     Pawnitems[i] = restore_item(fd, version);
     767                 :          8 :   Condoitems = restore_itemlist(fd, version);
     768                 :            :   /* Added bag of holding in 9001, so need to restore list. */
     769         [ -  + ]:          8 :   if (version < 9001)
     770                 :          0 :     Bagitems = NULL;
     771                 :            :   else
     772                 :          8 :     Bagitems = restore_itemlist(fd, version);
     773                 :            : 
     774         [ +  + ]:       1792 :   for (i=0;i<TOTALITEMS;i++) 
     775                 :            :   {
     776                 :            :     /* Add bag of holding, skip its position in the 2 arrays */
     777 [ -  + ][ #  # ]:       1784 :     if ( (version < 9001) && (i == 215) )
     778                 :          0 :       i = 216;
     779                 :       1784 :     fread((char *)&(Objects[i].known),sizeof(Objects[i].known),1,fd);
     780         [ +  - ]:       1784 :     if (version != 80)
     781                 :       1784 :       fread((char *)&(Objects[i].uniqueness),sizeof(Objects[i].uniqueness),1,fd);
     782                 :            :   }
     783                 :          8 : }
     784                 :            : 
     785                 :            : 
     786                 :            : 
     787                 :            : /* Restore an item, the first byte tells us if it's NULL, and what strings */
     788                 :            : /* have been saved as different from the typical */
     789                 :       1210 : pob restore_item(FILE *fd, int version)
     790                 :            : {
     791                 :            :   char tempstr[80];
     792                 :            :   unsigned char type;
     793                 :       1210 :   pob obj = NULL;
     794                 :            : 
     795                 :       1210 :   fread((char *)&type,sizeof(type),1,fd);
     796         [ +  + ]:       1210 :   if (type != 0xff) {
     797                 :        913 :     obj = ((pob) checkmalloc(sizeof(objtype)));
     798                 :        913 :     fread((char *)obj,sizeof(objtype),1,fd);
     799                 :            : 
     800                 :            :     /* DAG -- added object 215 (bag of holding) in 9001;  have to renumber */
     801         [ -  + ]:        913 :     if (version < 9001 )
     802         [ #  # ]:          0 :       if (obj->id >= 215)
     803                 :          0 :         obj->id++;
     804                 :            : 
     805         [ +  + ]:        913 :     if (type&8)
     806                 :            :     {
     807                 :            :       /* DAG case to handle corpses */
     808         [ +  - ]:          9 :       if (type&1)
     809                 :          9 :         filescanstring(fd,tempstr);
     810         [ +  - ]:          9 :       if (type&2)
     811                 :          9 :         filescanstring(fd,tempstr);
     812         [ +  - ]:          9 :       if (type&4)
     813                 :          9 :         filescanstring(fd,tempstr);
     814                 :          9 :       obj->objstr = obj->truename = obj->cursestr = salloc(tempstr);
     815                 :            :     } 
     816                 :            :     else 
     817                 :            :     {
     818         [ -  + ]:        904 :       if (type&1) {
     819                 :          0 :         filescanstring(fd,tempstr);
     820                 :          0 :         obj->objstr = salloc(tempstr);
     821                 :            :       }
     822                 :            :       else
     823                 :        904 :         obj->objstr = Objects[obj->id].objstr;
     824         [ -  + ]:        904 :       if (type&2) {
     825                 :          0 :         filescanstring(fd,tempstr);
     826                 :          0 :         obj->truename = salloc(tempstr);
     827                 :            :       }
     828                 :            :       else
     829                 :        904 :         obj->truename = Objects[obj->id].truename;
     830         [ -  + ]:        904 :       if (type&4) {
     831                 :          0 :         filescanstring(fd,tempstr);
     832                 :          0 :         obj->cursestr = salloc(tempstr);
     833                 :            :       }
     834                 :            :       else
     835                 :        904 :         obj->cursestr = Objects[obj->id].cursestr;
     836                 :            :     }
     837                 :            :   }
     838                 :       1210 :   return obj;
     839                 :            : }
     840                 :            : 
     841                 :        584 : pol restore_itemlist(FILE *fd, int version)
     842                 :            : {
     843                 :        584 :   pol ol=NULL,cur=NULL,new=NULL;
     844                 :        584 :   int i,numitems,firsttime=TRUE;
     845                 :        584 :   fread((char *)&numitems,sizeof(int),1,fd);
     846         [ +  + ]:       1298 :   for(i=0;i<numitems;i++) {
     847                 :        714 :     new = ((pol) checkmalloc(sizeof(oltype)));
     848                 :        714 :     new->thing = restore_item(fd, version);
     849                 :        714 :     new->next = NULL;
     850         [ +  + ]:        714 :     if (firsttime==TRUE) {
     851                 :        466 :       ol = cur = new;
     852                 :        466 :       firsttime = FALSE;
     853                 :            :     }
     854                 :            :     else {
     855                 :        248 :       cur->next = new;
     856                 :        248 :       cur = new;
     857                 :            :     }
     858                 :            :   }
     859                 :        584 :   return(ol);
     860                 :            : }
     861                 :            : 
     862                 :            : /* converts old location function ids to current ones.  DAG */
     863                 :          0 : void fix_p_locf( unsigned char *p_locf, int version )
     864                 :            : /* char *p_locf is pointer to single char, not a string */
     865                 :            : {
     866                 :            : #ifdef ALLOWING_OLD_SAVEFILES
     867                 :            :    if( version < 91 )
     868                 :            :    {
     869                 :            :       switch( *p_locf )
     870                 :            :       {
     871                 :            :       case OLD_L_NO_OP                 : *p_locf =  L_NO_OP; break;
     872                 :            :       case OLD_L_LIFT                  : *p_locf =  L_LIFT; break;
     873                 :            :       case OLD_L_BALANCESTONE          : *p_locf =  L_BALANCESTONE; break;
     874                 :            :       case OLD_L_FIRE                  : *p_locf =  L_FIRE; break;
     875                 :            :       case OLD_L_WHIRLWIND             : *p_locf =  L_WHIRLWIND; break;
     876                 :            :       case OLD_L_VOIDSTONE             : *p_locf =  L_VOIDSTONE; break;
     877                 :            :       case OLD_L_WARNING               : *p_locf =  L_WARNING; break;
     878                 :            :       case OLD_L_ARENA_EXIT            : *p_locf =  L_ARENA_EXIT; break;
     879                 :            :       case OLD_L_HOUSE_EXIT            : *p_locf =  L_HOUSE_EXIT; break;
     880                 :            :       case OLD_L_SAFE                  : *p_locf =  L_SAFE; break;
     881                 :            :       case OLD_L_CHARITY               : *p_locf =  L_CHARITY; break;
     882                 :            :       case OLD_L_ARMORER               : *p_locf =  L_ARMORER; break;
     883                 :            :       case OLD_L_CLUB                  : *p_locf =  L_CLUB; break;
     884                 :            :       case OLD_L_GYM                   : *p_locf =  L_GYM; break;
     885                 :            :       case OLD_L_THIEVES_GUILD         : *p_locf =  L_THIEVES_GUILD; break;
     886                 :            :       case OLD_L_COLLEGE               : *p_locf =  L_COLLEGE; break;
     887                 :            :       case OLD_L_HEALER                : *p_locf =  L_HEALER; break;
     888                 :            :       case OLD_L_CASINO                : *p_locf =  L_CASINO; break;
     889                 :            :       case OLD_L_TAVERN                : *p_locf =  L_TAVERN; break;
     890                 :            :       case OLD_L_MERC_GUILD            : *p_locf =  L_MERC_GUILD; break;
     891                 :            :       case OLD_L_ALCHEMIST             : *p_locf =  L_ALCHEMIST; break;
     892                 :            :       case OLD_L_SORCERORS             : *p_locf =  L_SORCERORS; break;
     893                 :            :       case OLD_L_CASTLE                : *p_locf =  L_CASTLE; break;
     894                 :            :       case OLD_L_ARENA                 : *p_locf =  L_ARENA; break;
     895                 :            :       case OLD_L_DPW                   : *p_locf =  L_DPW; break;
     896                 :            :       case OLD_L_LIBRARY               : *p_locf =  L_LIBRARY; break;
     897                 :            :       case OLD_L_PAWN_SHOP             : *p_locf =  L_PAWN_SHOP; break;
     898                 :            :       case OLD_L_BANK                  : *p_locf =  L_BANK; break;
     899                 :            :       case OLD_L_CONDO                 : *p_locf =  L_CONDO; break;
     900                 :            :       case OLD_L_ORACLE                : *p_locf =  L_ORACLE; break;
     901                 :            :       case OLD_L_ORDER                 : *p_locf =  L_ORDER; break;
     902                 :            :       case OLD_L_DINER                 : *p_locf =  L_DINER; break;
     903                 :            :       case OLD_L_COMMANDANT            : *p_locf =  L_COMMANDANT; break;
     904                 :            :       case OLD_L_CRAP                  : *p_locf =  L_CRAP; break;
     905                 :            :       case OLD_L_TEMPLE                : *p_locf =  L_TEMPLE; break;
     906                 :            :       case OLD_L_COUNTRYSIDE           : *p_locf =  L_COUNTRYSIDE; break;
     907                 :            :       case OLD_L_BROTHEL               : *p_locf =  L_BROTHEL; break;
     908                 :            :       case OLD_L_JAIL                  : *p_locf =  L_JAIL; break;
     909                 :            :       case OLD_L_TEMPLE_WARNING        : *p_locf =  L_TEMPLE_WARNING; break;
     910                 :            :       case OLD_L_LAWSTONE              : *p_locf =  L_LAWSTONE; break;
     911                 :            :       case OLD_L_CHAOSTONE             : *p_locf =  L_CHAOSTONE; break;
     912                 :            :       case OLD_L_EARTH_STATION         : *p_locf =  L_EARTH_STATION; break;
     913                 :            :       case OLD_L_FIRE_STATION          : *p_locf =  L_FIRE_STATION; break;
     914                 :            :       case OLD_L_WATER_STATION         : *p_locf =  L_WATER_STATION; break;
     915                 :            :       case OLD_L_AIR_STATION           : *p_locf =  L_AIR_STATION; break;
     916                 :            :       case OLD_L_VOID_STATION          : *p_locf =  L_VOID_STATION; break;
     917                 :            :       case OLD_L_VOID                  : *p_locf =  L_VOID; break;
     918                 :            :       case OLD_L_VOICE1                : *p_locf =  L_VOICE1; break;
     919                 :            :       case OLD_L_VOICE2                : *p_locf =  L_VOICE2; break;
     920                 :            :       case OLD_L_VOICE3                : *p_locf =  L_VOICE3; break;
     921                 :            :       case OLD_L_SACRIFICESTONE        : *p_locf =  L_SACRIFICESTONE; break;
     922                 :            :       case OLD_L_TOME1                 : *p_locf =  L_TOME1; break;
     923                 :            :       case OLD_L_TOME2                 : *p_locf =  L_TOME2; break;
     924                 :            :       case OLD_L_ENTER_CIRCLE          : *p_locf =  L_ENTER_CIRCLE; break;
     925                 :            :       case OLD_L_CIRCLE_LIBRARY        : *p_locf =  L_CIRCLE_LIBRARY; break;
     926                 :            :       case OLD_L_DRUID                 : *p_locf =  L_DRUID; break;
     927                 :            :       case OLD_L_ALTAR                 : *p_locf =  L_ALTAR; break;
     928                 :            :       case OLD_L_GARDEN                : *p_locf =  L_GARDEN; break;
     929                 :            :       case OLD_L_ADEPT                 : *p_locf =  L_ADEPT; break;
     930                 :            :       case OLD_L_SEWER                 : *p_locf =  L_SEWER; break;
     931                 :            :       case OLD_L_OMEGA                 : *p_locf =  L_OMEGA; break;
     932                 :            :       case OLD_L_CARTOGRAPHER          : *p_locf =  L_CARTOGRAPHER; break;
     933                 :            :       case OLD_L_STABLES               : *p_locf =  L_STABLES; break;
     934                 :            :       case OLD_L_COMMONS               : *p_locf =  L_COMMONS; break;
     935                 :            :       case OLD_L_GRANARY               : *p_locf =  L_GRANARY; break;
     936                 :            :       case OLD_L_MAZE                  : *p_locf =  L_MAZE; break;
     937                 :            :       case OLD_L_HOVEL                 : *p_locf =  L_HOVEL; break;
     938                 :            :       case OLD_L_HOUSE                 : *p_locf =  L_HOUSE; break;
     939                 :            :       case OLD_L_MANSION               : *p_locf =  L_MANSION; break;
     940                 :            :       case OLD_L_OCCUPIED_HOUSE        : *p_locf =  L_OCCUPIED_HOUSE; break;
     941                 :            :       case OLD_L_TACTICAL_EXIT         : *p_locf =  L_TACTICAL_EXIT; break;
     942                 :            :       case OLD_L_VAULT                 : *p_locf =  L_VAULT; break;
     943                 :            :       case OLD_L_CEMETARY              : *p_locf =  L_CEMETARY; break;
     944                 :            :       case OLD_L_THRONE                : *p_locf =  L_THRONE; break;
     945                 :            :       case OLD_L_ESCALATOR             : *p_locf =  L_ESCALATOR; break;
     946                 :            :       case OLD_L_ENTER_COURT           : *p_locf =  L_ENTER_COURT; break;
     947                 :            :       case OLD_L_TRIFID                : *p_locf =  L_TRIFID; break;
     948                 :            :       case OLD_L_FINAL_ABYSS           : *p_locf =  L_FINAL_ABYSS; break;
     949                 :            :       case OLD_L_RAISE_PORTCULLIS      : *p_locf =  L_RAISE_PORTCULLIS; break;
     950                 :            :       case OLD_L_MINDSTONE             : *p_locf =  L_MINDSTONE; break;
     951                 :            :       case OLD_L_CHAOS                 : *p_locf =  L_CHAOS; break;
     952                 :            :       case OLD_L_WATER                 : *p_locf =  L_WATER; break;
     953                 :            :       case OLD_L_LAVA                  : *p_locf =  L_LAVA; break;
     954                 :            :       case OLD_L_MAGIC_POOL            : *p_locf =  L_MAGIC_POOL; break;
     955                 :            :       case OLD_L_PORTCULLIS_TRAP       : *p_locf =  L_PORTCULLIS_TRAP; break;
     956                 :            :       case OLD_L_DROP_EVERY_PORTCULLIS : *p_locf =  L_DROP_EVERY_PORTCULLIS; break;
     957                 :            :       case OLD_L_PORTCULLIS            : *p_locf =  L_PORTCULLIS; break;
     958                 :            :       case OLD_L_TRAP_DART             : *p_locf =  L_TRAP_DART; break;
     959                 :            :       case OLD_L_TRAP_PIT              : *p_locf =  L_TRAP_PIT; break;
     960                 :            :       case OLD_L_TRAP_DOOR             : *p_locf =  L_TRAP_DOOR; break;
     961                 :            :       case OLD_L_TRAP_SNARE            : *p_locf =  L_TRAP_SNARE; break;
     962                 :            :       case OLD_L_TRAP_BLADE            : *p_locf =  L_TRAP_BLADE; break;
     963                 :            :       case OLD_L_TRAP_FIRE             : *p_locf =  L_TRAP_FIRE; break;
     964                 :            :       case OLD_L_TRAP_TELEPORT         : *p_locf =  L_TRAP_TELEPORT; break;
     965                 :            :       case OLD_L_TRAP_DISINTEGRATE     : *p_locf =  L_TRAP_DISINTEGRATE; break;
     966                 :            :       case OLD_L_TRAP_SLEEP_GAS        : *p_locf =  L_TRAP_SLEEP_GAS; break;
     967                 :            :       case OLD_L_TRAP_ACID             : *p_locf =  L_TRAP_ACID; break;
     968                 :            :       case OLD_L_TRAP_MANADRAIN        : *p_locf =  L_TRAP_MANADRAIN; break;
     969                 :            :       case OLD_L_TRAP_ABYSS            : *p_locf =  L_TRAP_ABYSS; break;
     970                 :            :       case OLD_L_TRAP_SIREN            : *p_locf =  L_TRAP_SIREN; break;
     971                 :            :       case OLD_L_STATUE_WAKE           : *p_locf =  L_STATUE_WAKE; break;
     972                 :            :       case OLD_L_STATUE_RANDOM         : *p_locf =  L_STATUE_RANDOM; break;
     973                 :            :       case OLD_L_HEDGE                 : *p_locf =  L_HEDGE; break;
     974                 :            :       case OLD_L_RUBBLE                : *p_locf =  L_RUBBLE; break;
     975                 :            :       case OLD_L_ABYSS                 : *p_locf =  L_ABYSS; break;
     976                 :            :       default: *p_locf = L_NO_OP; break; /* shouldn't happen */
     977                 :            :       }
     978                 :            :    } 
     979                 :            : #endif
     980                 :          0 : }
     981                 :            : 
     982                 :         14 : void restore_level(FILE *fd, int version)
     983                 :            : {
     984                 :            :   int i, j, run;
     985                 :            :   unsigned long int mask;
     986                 :            :   int temp_env;
     987                 :            :   int length, width;
     988                 :            : 
     989                 :         14 :   Level = (plv) checkmalloc(sizeof(levtype));
     990                 :         14 :   clear_level(Level);
     991                 :         14 :   fread((char *)&Level->depth,sizeof(char),1,fd);
     992                 :         14 :   fread((char *)&Level->numrooms,sizeof(char),1,fd);
     993                 :         14 :   fread((char *)&Level->tunnelled,sizeof(char),1,fd);
     994                 :         14 :   fread((char *)&Level->environment,sizeof(int),1,fd);
     995                 :         14 :   fread((char *)&Level->level_width,sizeof(int),1,fd);
     996                 :         14 :   fread((char *)&Level->level_length,sizeof(int),1,fd);
     997                 :            : 
     998                 :         14 :   width = Level->level_width;
     999                 :         14 :   length = Level->level_length;
    1000                 :         14 :   Level->generated = TRUE;
    1001                 :         14 :   temp_env = Current_Environment;
    1002                 :         14 :   Current_Environment = Level->environment;
    1003   [ -  +  +  -  :         14 :   switch(Level->environment) {
          -  -  -  -  -  
          -  -  -  -  -  
                -  -  - ]
    1004                 :            :     case E_COUNTRYSIDE:
    1005                 :          0 :       load_country();
    1006                 :          0 :       break;
    1007                 :            :     case E_CITY:
    1008                 :          8 :       load_city(FALSE);
    1009                 :          8 :       break;
    1010                 :            :     case E_VILLAGE:
    1011                 :          6 :       load_village(Country[LastCountryLocX][LastCountryLocY].aux, FALSE);
    1012                 :          6 :       break;
    1013                 :            :     case E_CAVES: 
    1014                 :          0 :       initrand(Current_Environment, Level->depth);
    1015 [ #  # ][ #  # ]:          0 :       if ((random_range(4)==0) && (Level->depth < MaxDungeonLevels))
    1016                 :          0 :         room_level();
    1017                 :          0 :       else cavern_level();
    1018                 :          0 :       break;
    1019                 :            :     case E_SEWERS: 
    1020                 :          0 :       initrand(Current_Environment, Level->depth);
    1021 [ #  # ][ #  # ]:          0 :       if ((random_range(4)==0) && (Level->depth < MaxDungeonLevels))
    1022                 :          0 :         room_level();
    1023                 :          0 :       else sewer_level(); 
    1024                 :          0 :       break;
    1025                 :            :     case E_CASTLE:
    1026                 :          0 :       initrand(Current_Environment, Level->depth);
    1027                 :          0 :       room_level();
    1028                 :          0 :       break;
    1029                 :            :     case E_PALACE:
    1030                 :          0 :       initrand(Current_Environment, Level->depth);
    1031                 :          0 :       room_level(); /* TODO PGM */
    1032                 :          0 :       break;
    1033                 :            :     case E_ASTRAL:
    1034                 :          0 :       initrand(Current_Environment, Level->depth);
    1035                 :          0 :       maze_level();
    1036                 :          0 :       break;
    1037                 :            :     case E_VOLCANO:
    1038                 :          0 :       initrand(Current_Environment, Level->depth);
    1039   [ #  #  #  # ]:          0 :       switch(random_range(3)) {
    1040                 :          0 :       case 0: cavern_level(); break;
    1041                 :          0 :       case 1: room_level(); break;
    1042                 :          0 :       case 2: maze_level(); break;
    1043                 :            :       }
    1044                 :          0 :       break;
    1045                 :            :     case E_HOVEL:
    1046                 :            :     case E_MANSION:
    1047                 :            :     case E_HOUSE:
    1048                 :          0 :       load_house(Level->environment, FALSE);
    1049                 :          0 :       break;
    1050                 :            :     case E_DLAIR:
    1051                 :          0 :       load_dlair(gamestatusp(KILLED_DRAGONLORD), FALSE);
    1052                 :          0 :       break;
    1053                 :            :     case E_STARPEAK:
    1054                 :          0 :       load_speak(gamestatusp(KILLED_LAWBRINGER), FALSE);
    1055                 :          0 :       break;
    1056                 :            :     case E_MAGIC_ISLE:
    1057                 :          0 :       load_misle(gamestatusp(KILLED_EATER), FALSE);
    1058                 :          0 :       break;
    1059                 :            :     case E_TEMPLE:
    1060                 :          0 :       load_temple(Country[LastCountryLocX][LastCountryLocY].aux, FALSE);
    1061                 :          0 :       break;
    1062                 :            :     case E_CIRCLE:
    1063                 :          0 :       load_circle(FALSE);
    1064                 :          0 :       break;
    1065                 :            :     case E_COURT:
    1066                 :          0 :       load_court(FALSE);
    1067                 :          0 :       break;
    1068                 :          0 :     default: print3("This dungeon not implemented!"); break;
    1069                 :            :   }
    1070         [ -  + ]:         14 :   if (Level->depth > 0) { /* dungeon... */
    1071                 :          0 :     install_traps();
    1072                 :          0 :     install_specials();
    1073                 :          0 :     make_stairs(-1);
    1074                 :          0 :     make_stairs(-1);
    1075                 :          0 :     initrand(E_RESTORE, 0);
    1076                 :            :   }
    1077                 :         14 :   Current_Environment = temp_env;
    1078                 :         14 :   fread((char *)&i,sizeof(int),1,fd);
    1079                 :         14 :   fread((char *)&j,sizeof(int),1,fd);
    1080 [ -  + ][ #  # ]:         14 :   while ((j < length) && (i < width)) {
    1081                 :          0 :     fread((char *)&run,sizeof(int),1,fd);
    1082         [ #  # ]:          0 :     for (; i < run; i++) {
    1083                 :          0 :       fread((char *)&Level->site[i][j],sizeof(struct location),1,fd);
    1084                 :          0 :       fix_p_locf( &(Level->site[i][j].p_locf), version ); /* DAG */
    1085                 :          0 :       Level->site[i][j].creature = NULL;
    1086                 :          0 :       Level->site[i][j].things = NULL;
    1087                 :            :     }
    1088                 :          0 :     fread((char *)&i,sizeof(int),1,fd);
    1089                 :          0 :     fread((char *)&j,sizeof(int),1,fd);
    1090                 :            :   }
    1091                 :         14 :   run = 0;
    1092         [ +  + ]:        622 :   for (j = 0; j < length; j++)
    1093         [ +  + ]:      39520 :     for (i = 0; i < width; i++) {
    1094         [ +  + ]:      38912 :       if (run == 0) {
    1095                 :        608 :         run = 8*sizeof(long int);
    1096                 :        608 :         fread((char *)&mask,sizeof(long int),1,fd);
    1097                 :            :       }
    1098         [ +  + ]:      38912 :       if (mask&1)
    1099                 :      36624 :         lset(i, j, SEEN);
    1100                 :      38912 :       mask >>= 1;
    1101                 :      38912 :       run--;
    1102                 :            :     }
    1103                 :         14 :   restore_monsters(fd,Level, version);
    1104                 :         14 :   fread((char *)&i,sizeof(int),1,fd);
    1105                 :         14 :   fread((char *)&j,sizeof(int),1,fd);
    1106 [ +  + ][ +  - ]:        318 :   while (j < length && i < width) {
    1107                 :        304 :     Level->site[i][j].things = restore_itemlist(fd, version);
    1108                 :        304 :     fread((char *)&i,sizeof(int),1,fd);
    1109                 :        304 :     fread((char *)&j,sizeof(int),1,fd);
    1110                 :            :   }
    1111                 :         14 : }
    1112                 :            : 
    1113                 :            : 
    1114                 :          8 : void restore_hiscore_npc(pmt npc, int npcid)
    1115                 :            : {
    1116                 :            :   int level, behavior;
    1117                 :            :   long status;
    1118                 :            : 
    1119   [ -  -  -  -  :          8 :   switch(npcid) {
          -  -  -  -  -  
             -  +  -  - ]
    1120                 :            :   case 0:
    1121                 :          0 :     strcpy(Str2,Hiscorer);
    1122                 :          0 :     level = Hilevel;
    1123                 :          0 :     behavior = Hibehavior;
    1124                 :          0 :     break;
    1125                 :            :   case 1: case 2: case 3: case 4: case 5: case 6:
    1126                 :          0 :     strcpy(Str2,Priest[npcid]);
    1127                 :          0 :     level = Priestlevel[npcid];
    1128                 :          0 :     behavior = Priestbehavior[npcid];
    1129                 :          0 :     break;
    1130                 :            :   case 7:
    1131                 :          0 :     strcpy(Str2,Shadowlord);
    1132                 :          0 :     level = Shadowlordlevel;
    1133                 :          0 :     behavior = Shadowlordbehavior;
    1134                 :          0 :     break;
    1135                 :            :   case 8:
    1136                 :          0 :     strcpy(Str2,Commandant);
    1137                 :          0 :     level = Commandantlevel;
    1138                 :          0 :     behavior = Commandantbehavior;
    1139                 :          0 :     break;
    1140                 :            :   case 9:
    1141                 :          0 :     strcpy(Str2,Archmage);
    1142                 :          0 :     level = Archmagelevel;
    1143                 :          0 :     behavior = Archmagebehavior;
    1144                 :          0 :     break;
    1145                 :            :   case 10:
    1146                 :          0 :     strcpy(Str2,Prime);
    1147                 :          0 :     level = Primelevel;
    1148                 :          0 :     behavior = Primebehavior;
    1149                 :          0 :     break;
    1150                 :            :   case 11:
    1151                 :          0 :     strcpy(Str2,Champion);
    1152                 :          0 :     level = Championlevel;
    1153                 :          0 :     behavior = Championbehavior;
    1154                 :          0 :     break;
    1155                 :            :   case 12:
    1156                 :          0 :     strcpy(Str2,Duke);
    1157                 :          0 :     level = Dukelevel;
    1158                 :          0 :     behavior = Dukebehavior;
    1159                 :          0 :     break;
    1160                 :            :   case 13:
    1161                 :          0 :     strcpy(Str2,Chaoslord);
    1162                 :          0 :     level = Chaoslordlevel;
    1163                 :          0 :     behavior = Chaoslordbehavior;
    1164                 :          0 :     break;
    1165                 :            :   case 14:
    1166                 :          0 :     strcpy(Str2,Lawlord);
    1167                 :          0 :     level = Lawlordlevel;
    1168                 :          0 :     behavior = Lawlordbehavior;
    1169                 :          0 :     break;
    1170                 :            :   case 15:
    1171                 :          8 :     strcpy(Str2,Justiciar);
    1172                 :          8 :     level = Justiciarlevel;
    1173                 :          8 :     behavior = Justiciarbehavior;
    1174                 :          8 :     break;
    1175                 :            :   case 16:
    1176                 :          0 :     strcpy(Str2,Grandmaster);
    1177                 :          0 :     level = Grandmasterlevel;
    1178                 :          0 :     behavior = Grandmasterbehavior;
    1179                 :          0 :     break;
    1180                 :            :   default:
    1181                 :            :     /* bomb on error */
    1182                 :          0 :     level = behavior = 0;
    1183                 :          0 :     assert(FALSE);
    1184                 :            :   }
    1185                 :          8 :   npc->monstring = salloc(Str2);
    1186                 :          8 :   strcpy(Str1,"The body of ");
    1187                 :          8 :   strcat(Str1,Str2);
    1188                 :          8 :   npc->corpsestr = salloc(Str1);
    1189                 :          8 :   m_status_set( npc, ALLOC );
    1190         [ +  - ]:          8 :   if (!m_statusp(npc, HOSTILE)) {
    1191                 :          8 :     status = npc->status;
    1192                 :          8 :     determine_npc_behavior(npc,level,behavior);
    1193                 :          8 :     npc->status = status;
    1194                 :            :   }
    1195                 :          8 : }
    1196                 :            : 
    1197                 :            : 
    1198                 :         14 : void restore_monsters(FILE *fd, plv level, int version)
    1199                 :            : {
    1200                 :         14 :   pml ml=NULL;
    1201                 :            :   int i,nummonsters;
    1202                 :            :   char tempstr[80];
    1203                 :            :   int temp_x, temp_y;
    1204                 :            :   unsigned char type;
    1205                 :            : 
    1206                 :         14 :   level->mlist = NULL;
    1207                 :            : 
    1208                 :         14 :   fread((char *)&nummonsters,sizeof(int),1,fd);
    1209                 :            :   
    1210         [ +  + ]:        278 :   for(i=0;i<nummonsters;i++) {
    1211                 :        264 :     ml = ((pml) checkmalloc(sizeof(mltype)));
    1212                 :        264 :     ml->m = ((pmt) checkmalloc(sizeof(montype)));
    1213                 :        264 :     ml->next = NULL;
    1214                 :        264 :     fread((char *)ml->m,sizeof(montype),1,fd);
    1215         [ +  + ]:        264 :     if (ml->m->id == HISCORE_NPC)
    1216         [ -  + ]:          8 :       if (version == 80) {
    1217                 :          0 :         temp_x = ml->m->x;
    1218                 :          0 :         temp_y = ml->m->y;
    1219                 :          0 :         make_hiscore_npc(ml->m, ml->m->aux2);
    1220                 :          0 :         ml->m->x = temp_x;
    1221                 :          0 :         ml->m->y = temp_y;
    1222                 :            :       }
    1223                 :            :       else
    1224                 :          8 :         restore_hiscore_npc(ml->m, ml->m->aux2);
    1225                 :            :     else {
    1226                 :        256 :       fread((char *)&type,sizeof(unsigned char),1,fd);
    1227         [ -  + ]:        256 :       if ( type )
    1228                 :            :       {
    1229                 :            :         /* DAG  enforce that if either one of monstring or corpsestr are */
    1230                 :            :         /*      alloced, both are */
    1231                 :          0 :         m_status_set( ml->m, ALLOC );
    1232         [ #  # ]:          0 :         if (type&1) {
    1233                 :          0 :           filescanstring(fd,tempstr);
    1234                 :          0 :           ml->m->monstring = salloc(tempstr);
    1235                 :            :         }
    1236                 :            :         else
    1237                 :          0 :           ml->m->monstring = salloc( Monsters[ml->m->id].monstring );
    1238                 :            : 
    1239         [ #  # ]:          0 :         if (type&2) {
    1240                 :          0 :           filescanstring(fd,tempstr);
    1241                 :          0 :           ml->m->corpsestr = salloc(tempstr);
    1242                 :            :         }
    1243                 :            :         else
    1244                 :          0 :           ml->m->corpsestr = salloc( Monsters[ml->m->id].corpsestr );
    1245                 :            :       } 
    1246                 :            :       else
    1247                 :            :       {
    1248                 :        256 :         ml->m->corpsestr = Monsters[ml->m->id].corpsestr;
    1249                 :        256 :         ml->m->monstring = Monsters[ml->m->id].monstring;
    1250                 :            :       }
    1251                 :            :       /* WDT: As suggested by Sheldon Simms, I'm moving this line... */
    1252         [ -  + ]:        256 :       if ( version <= 80 )
    1253                 :          0 :         ml->m->possessions = restore_itemlist(fd,version);
    1254                 :        256 :       ml->m->meleestr = Monsters[ml->m->id].meleestr;
    1255                 :            :     }
    1256                 :            :     /* WDT: ...to here, so that all creatures will have their stuff
    1257                 :            :      * restored to them.  Savefile versioning added by David Given. */
    1258         [ +  - ]:        264 :     if ( version > 80 )
    1259                 :        264 :       ml->m->possessions = restore_itemlist(fd,version);
    1260                 :        264 :     level->site[ml->m->x][ml->m->y].creature = ml->m;
    1261                 :        264 :     ml->next = level->mlist;
    1262                 :        264 :     level->mlist = ml;
    1263                 :            :   }
    1264                 :         14 : }
    1265                 :            : 
    1266                 :            : 
    1267                 :          8 : void restore_country(FILE *fd, int version)
    1268                 :            : {
    1269                 :            :   int i, j;
    1270                 :            :   int run;
    1271                 :            :   unsigned long int mask;
    1272                 :            : 
    1273                 :          8 :   load_country();
    1274                 :          8 :   fread((char *)&i,sizeof(int),1,fd);
    1275                 :          8 :   fread((char *)&j,sizeof(int),1,fd);
    1276 [ -  + ][ #  # ]:          8 :   while (i < COUNTRY_WIDTH && j < COUNTRY_LENGTH) {
    1277                 :          0 :     fread((char *)&Country[i][j],sizeof(struct terrain),1,fd);
    1278                 :          0 :     fread((char *)&i,sizeof(int),1,fd);
    1279                 :          0 :     fread((char *)&j,sizeof(int),1,fd);
    1280                 :            :   }
    1281                 :          8 :   run = 0;
    1282         [ +  + ]:        520 :   for (i = 0; i < COUNTRY_WIDTH; i++)
    1283         [ +  + ]:      33280 :     for (j = 0; j < COUNTRY_LENGTH; j++) {
    1284         [ +  + ]:      32768 :       if (run == 0) {
    1285                 :        512 :         run = 8*sizeof(long int);
    1286                 :        512 :         fread((char *)&mask,sizeof(long int),1,fd);
    1287                 :            :       }
    1288         [ +  + ]:      32768 :       if (mask&1)
    1289                 :        433 :         c_set(i, j, SEEN);
    1290                 :      32768 :       mask >>= 1;
    1291                 :      32768 :       run--;
    1292                 :            :     }
    1293                 :          8 : }

Generated by: LCOV version 1.11