LCOV - code coverage report
Current view: top level - omega-rpg-0.90-pa9 - util.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 284 603 47.1 %
Date: 2017-09-08 22:00:26 Functions: 38 47 80.9 %
Branches: 216 567 38.1 %

           Branch data     Line data    Source code
       1                 :            : /* copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
       2                 :            : /* utils.c */
       3                 :            : 
       4                 :            : /* Random utility functions called from all over */
       5                 :            : 
       6                 :            : #ifndef MSDOS_SUPPORTED_ANTIQUE
       7                 :            : #include <sys/types.h>
       8                 :            : #include <sys/time.h>
       9                 :            : #include <sys/wait.h>
      10                 :            : #include <unistd.h>
      11                 :            : int setreuid(uid_t ruid, uid_t euid);
      12                 :            : #include <stdlib.h>
      13                 :            : #endif
      14                 :            : 
      15                 :            : #include "glob.h"
      16                 :            : 
      17                 :          6 : void setPlayerXY(int x, int y)
      18                 :            : {
      19                 :          6 :   Player.x = x;
      20                 :          6 :   Player.y = y;
      21                 :          6 : }
      22                 :            : 
      23                 :            : /* x and y on level? */
      24                 :     105803 : int inbounds(int x, int y)
      25                 :            : {
      26         [ +  + ]:     105803 :   if (Current_Environment != E_COUNTRYSIDE)
      27                 :            :     {
      28 [ +  + ][ +  + ]:     105441 :     return((x>=0)&&(y>=0)&&(x<(Level->level_width))&&(y<(Level->level_length)));
         [ +  - ][ +  + ]
      29                 :            :   }
      30                 :            :   else
      31 [ +  - ][ +  - ]:        362 :     return((x>=0)&&(y>=0)&&(x<COUNTRY_WIDTH)&&(y<COUNTRY_LENGTH));
         [ +  - ][ +  - ]
      32                 :            : }
      33                 :            : 
      34                 :            : /* RANDFUNCTION is defined in odefs.h */
      35                 :       6588 : unsigned random_range(unsigned k)
      36                 :            : {
      37         [ +  - ]:       6588 :   return( k==0 ? 0 : (int) (RANDFUNCTION() % k) ) ;
      38                 :            :   /*return( k==0 ? 0 : (int) ((RANDFUNCTION()%10000)*k)/10000); */
      39                 :            : }
      40                 :            : 
      41                 :            : 
      42                 :            : /* modify absolute y coord relative to which part of level we are on */
      43                 :      18332 : int screenmody(int y)
      44                 :            : {
      45                 :      18332 :   return(y-ScreenOffset);
      46                 :            : }
      47                 :            : 
      48                 :            : /* modify absolute x coord relative to which part of level we are on */
      49                 :            : /* PGM - horizontal scrolling */
      50                 :      13090 : int screenmodx(int x)
      51                 :            : {
      52                 :      13090 :   return(x-ScreenXOffset);
      53                 :            : }
      54                 :            : 
      55                 :            : /* this could be optimized; is it neccessary? PGM */
      56                 :      14794 : int offscreen(int x, int y)
      57                 :            : {
      58                 :            : 
      59                 :            :   /* PGM : The Country not acually being a level, it is naturally a 
      60                 :            :    * special case... PGM */
      61                 :            : 
      62                 :      14794 :   int width = COUNTRY_WIDTH;
      63                 :      14794 :   int length = COUNTRY_LENGTH;
      64                 :            : 
      65                 :            :   int xyes, yyes;
      66                 :            : 
      67         [ +  + ]:      14794 :   if (Current_Environment != E_COUNTRYSIDE)
      68                 :            :   {
      69                 :      14431 :     width = Level->level_width;
      70                 :      14431 :     length = Level->level_length;
      71                 :            :   }
      72                 :            :     
      73         [ +  - ]:      14794 :   yyes = ((y<0)||
      74         [ +  - ]:      14794 :          (y<ScreenOffset) ||
      75 [ +  - ][ -  + ]:      29588 :          (y>ScreenOffset+ScreenLength-1) ||
      76                 :            :          (y>length));
      77                 :            : 
      78         [ +  + ]:      14794 :   xyes = ((x<0)||
      79         [ +  - ]:      13315 :          (x<ScreenXOffset) ||
      80 [ +  - ][ -  + ]:      29588 :          (x>ScreenXOffset+ScreenWidth-1) ||
      81                 :            :          (x>width));
      82                 :            : 
      83 [ +  + ][ -  + ]:      14794 :   return ( xyes || yyes );
      84                 :            : }
      85                 :            : 
      86                 :            : 
      87                 :            : /* always hit on a natural 0; never hit on a natural 19 */
      88                 :         37 : int hitp(int hit, int ac)
      89                 :            : {
      90                 :         37 :   int roll = random_range(20);
      91         [ +  + ]:         37 :   if (roll == 0) return(TRUE);
      92         [ +  + ]:         34 :   else if (roll == 19) return(FALSE);
      93                 :         31 :   else return((roll < (hit - ac)) ? TRUE : FALSE );
      94                 :            : }
      95                 :            : 
      96                 :            : 
      97                 :            : /* number of moves from x1,y1 to x2,y2 */
      98                 :       4590 : int distance(int x1, int y1, int x2, int y2)
      99                 :            : {
     100                 :       4590 :   return(max(abs(x2-x1),abs(y2-y1)));
     101                 :            : }
     102                 :            : 
     103                 :            : 
     104                 :            : /* can you shoot, or move monsters through a spot? */
     105                 :        735 : int unblocked(int x, int y)
     106                 :            : {
     107 [ +  - ][ +  + ]:        735 :   if ((! inbounds(x,y)) ||
     108         [ +  - ]:        729 :       (Level->site[x][y].creature != NULL) ||
     109         [ +  - ]:        729 :       (Level->site[x][y].locchar == WALL) ||
     110         [ +  - ]:        729 :       (Level->site[x][y].locchar == PORTCULLIS) ||
     111         [ +  + ]:        729 :       (Level->site[x][y].locchar == STATUE) ||
     112         [ +  - ]:        547 :       (Level->site[x][y].locchar == HEDGE) ||
     113         [ +  - ]:        547 :       (Level->site[x][y].locchar == CLOSED_DOOR) ||
     114         [ +  + ]:        547 :       loc_statusp(x,y,SECRET) ||
     115         [ +  - ]:         34 :       ((x==Player.x) && (y==Player.y)))
     116                 :        222 :     return(FALSE);
     117                 :            :   else 
     118                 :        513 :     return(TRUE);
     119                 :            : }
     120                 :            : 
     121                 :            : 
     122                 :            : /* do monsters want to move through a spot */
     123                 :        913 : int m_unblocked(pmt m, int x, int y)
     124                 :            : {
     125 [ +  + ][ +  + ]:        913 :   if ((! inbounds(x,y)) || ((x==Player.x) && (y==Player.y)))
                 [ -  + ]
     126                 :        124 :     return(FALSE);
     127 [ +  + ][ -  + ]:        789 :   else if ((Level->site[x][y].creature != NULL) ||
     128                 :         83 :            (Level->site[x][y].locchar == SPACE)) return(FALSE);
     129         [ -  + ]:        706 :   else if (m_statusp(m,ONLYSWIM)) 
     130                 :          0 :     return(Level->site[x][y].locchar == WATER);
     131         [ -  + ]:        706 :   else if (loc_statusp(x,y,SECRET)) {
     132         [ #  # ]:          0 :     if (m->movef == M_MOVE_SMART) {
     133         [ #  # ]:          0 :       if (los_p(x, y, Player.x, Player.y)) {
     134                 :          0 :         mprint("You see a secret door swing open!");
     135                 :          0 :         lreset(x, y, SECRET);
     136                 :          0 :         lset(x, y, CHANGED);
     137                 :            :       }
     138                 :            :       else
     139                 :          0 :         mprint("You hear a door creak open, and then close again.");
     140                 :            :         /* smart monsters would close secret doors behind them if the */
     141                 :            :         /* player didn't see them using it */
     142                 :          0 :       return(TRUE);
     143                 :            :     }
     144                 :            :     else
     145                 :          0 :       return(m_statusp(m,INTANGIBLE));
     146                 :            :   }
     147 [ +  + ][ -  + ]:        706 :   else if ((Level->site[x][y].locchar == FLOOR) ||
     148                 :        658 :            (Level->site[x][y].locchar == OPEN_DOOR))
     149                 :         48 :     return(TRUE);
     150 [ +  - ][ +  - ]:        658 :   else if ((Level->site[x][y].locchar == PORTCULLIS) ||
     151         [ -  + ]:        658 :            (Level->site[x][y].locchar == WALL) ||
     152                 :        658 :            (Level->site[x][y].locchar == STATUE))
     153                 :          0 :     return(m_statusp(m,INTANGIBLE));
     154         [ +  + ]:        658 :   else if (Level->site[x][y].locchar==WATER)
     155         [ +  - ]:        517 :     return(m_statusp(m,SWIMMING) || 
     156         [ +  - ]:        258 :            m_statusp(m,ONLYSWIM) ||
     157 [ +  + ][ -  + ]:        517 :            m_statusp(m,INTANGIBLE) ||
     158                 :        258 :            m_statusp(m,FLYING));
     159         [ -  + ]:        399 :   else if (Level->site[x][y].locchar == CLOSED_DOOR) {
     160         [ #  # ]:          0 :     if (m->movef==M_MOVE_SMART) {
     161                 :          0 :       mprint("You hear a door creak open.");
     162                 :          0 :       Level->site[x][y].locchar = OPEN_DOOR;
     163                 :          0 :       lset(x, y, CHANGED);
     164                 :          0 :       return(TRUE);
     165                 :            :     }
     166         [ #  # ]:          0 :     else if (random_range(m->dmg) > random_range(100)) {
     167                 :          0 :       mprint("You hear a door shattering.");
     168                 :          0 :       Level->site[x][y].locchar = RUBBLE;
     169                 :          0 :       lset(x, y, CHANGED);
     170                 :          0 :       return(TRUE);
     171                 :            :     }
     172                 :          0 :     else return(m_statusp(m,INTANGIBLE));
     173                 :            :   }
     174         [ -  + ]:        399 :   else if (Level->site[x][y].locchar == LAVA)
     175         [ #  # ]:          0 :     return((m_immunityp(m,FLAME) && 
     176         [ #  # ]:          0 :             m_statusp(m,SWIMMING)) ||
     177 [ #  # ][ #  # ]:          0 :            m_statusp(m,INTANGIBLE) ||
     178                 :          0 :            m_statusp(m,FLYING));
     179         [ -  + ]:        399 :   else if (Level->site[x][y].locchar == FIRE)
     180 [ #  # ][ #  # ]:          0 :     return(m_statusp(m,INTANGIBLE) ||
     181                 :          0 :            m_immunityp(m,FLAME));
     182 [ +  - ][ +  + ]:        399 :   else if ((Level->site[x][y].locchar == TRAP) ||
     183         [ -  + ]:         13 :            (Level->site[x][y].locchar == HEDGE) ||
     184                 :         13 :            (Level->site[x][y].locchar == ABYSS))
     185         [ +  - ]:        772 :     return((m->movef == M_MOVE_CONFUSED) ||
     186 [ +  - ][ -  + ]:        772 :            m_statusp(m,INTANGIBLE) ||
     187                 :        386 :            m_statusp(m,FLYING));
     188                 :         13 :   else return(TRUE);
     189                 :            : }
     190                 :            : 
     191                 :            : 
     192                 :            : 
     193                 :            : /* can you see through a spot? */
     194                 :      87091 : int view_unblocked(int x, int y)
     195                 :            : {
     196         [ -  + ]:      87091 :   if (! inbounds(x,y)) return(FALSE);
     197 [ +  + ][ +  - ]:      87091 :   else if ((Level->site[x][y].locchar == WALL) ||
     198         [ +  + ]:      72389 :            (Level->site[x][y].locchar == STATUE) ||
     199         [ +  - ]:      65753 :            (Level->site[x][y].locchar == HEDGE) ||
     200         [ +  + ]:      65753 :            (Level->site[x][y].locchar == FIRE) ||
     201         [ -  + ]:      65440 :            (Level->site[x][y].locchar == CLOSED_DOOR) ||
     202                 :      65440 :            loc_statusp(x,y,SECRET))
     203                 :      21651 :     return(FALSE);
     204                 :            :   else 
     205                 :      65440 :     return(TRUE);
     206                 :            : }
     207                 :            : 
     208                 :            : 
     209                 :            : #ifndef MSDOS_SUPPORTED_ANTIQUE
     210                 :            : /* 8 moves in Dirs */
     211                 :          1 : void initdirs(void)
     212                 :            : {
     213                 :          1 :   Dirs[0][0] = 1;
     214                 :          1 :   Dirs[0][1] = 1;
     215                 :          1 :   Dirs[0][2] = -1;
     216                 :          1 :   Dirs[0][3] = -1;
     217                 :          1 :   Dirs[0][4] = 1;
     218                 :          1 :   Dirs[0][5] = -1;
     219                 :          1 :   Dirs[0][6] = 0;
     220                 :          1 :   Dirs[0][7] = 0;
     221                 :          1 :   Dirs[0][8] = 0;
     222                 :          1 :   Dirs[1][0] = 1;
     223                 :          1 :   Dirs[1][1] = -1;
     224                 :          1 :   Dirs[1][2] = 1;
     225                 :          1 :   Dirs[1][3] = -1;
     226                 :          1 :   Dirs[1][4] = 0;
     227                 :          1 :   Dirs[1][5] = 0;
     228                 :          1 :   Dirs[1][6] = 1;
     229                 :          1 :   Dirs[1][7] = -1;
     230                 :          1 :   Dirs[1][8] = 0;
     231                 :          1 : }
     232                 :            : #endif
     233                 :            : 
     234                 :            : 
     235                 :            : 
     236                 :            : 
     237                 :            : 
     238                 :            : /* do_los moves pyx along a lineofsight from x1 to x2 */
     239                 :            : /* x1 and x2 are pointers because as a side effect they are changed */
     240                 :            : /* to the final location of the pyx */
     241                 :          0 : void do_los(Symbol pyx, int *x1, int *y1, int x2, int y2)
     242                 :            : {
     243                 :            :   int dx,dy,ox,oy;
     244                 :            :   int major, minor;
     245                 :            :   int error, delta, step;
     246                 :            :   int blocked;
     247                 :            : 
     248         [ #  # ]:          0 :   if (x2 - *x1 < 0) dx = 5;
     249         [ #  # ]:          0 :   else if (x2 - *x1 > 0) dx = 4;
     250                 :          0 :   else dx = -1;
     251         [ #  # ]:          0 :   if (y2 - *y1 < 0) dy = 7;
     252         [ #  # ]:          0 :   else if (y2 - *y1 > 0) dy = 6;
     253                 :          0 :   else dy = -1;
     254         [ #  # ]:          0 :   if (abs(x2 - *x1) > abs(y2 - *y1)) {
     255                 :          0 :     major = dx;
     256                 :          0 :     minor = dy;
     257                 :          0 :     step = abs(x2 - *x1);
     258                 :          0 :     delta = 2*abs(y2 - *y1);
     259                 :            :   }
     260                 :            :   else {
     261                 :          0 :     major = dy;
     262                 :          0 :     minor = dx;
     263                 :          0 :     step = abs(y2 - *y1);
     264                 :          0 :     delta = 2*abs(x2 - *x1);
     265                 :            :   }
     266         [ #  # ]:          0 :   if (major == -1)      /* x1,y2 already == x2,y2 */
     267                 :          0 :     return;
     268                 :          0 :   error = 0;
     269                 :            :   do {
     270                 :          0 :     ox = *x1; oy = *y1;
     271                 :          0 :     *x1 += Dirs[0][major];
     272                 :          0 :     *y1 += Dirs[1][major];
     273                 :          0 :     error += delta;
     274         [ #  # ]:          0 :     if (error > step) {      /* don't need to check that minor >= 0 */
     275                 :          0 :       *x1 += Dirs[0][minor];
     276                 :          0 :       *y1 += Dirs[1][minor];
     277                 :          0 :       error -= 2*step;
     278                 :            :     }
     279                 :          0 :     blocked = !unblocked(*x1,*y1);
     280 [ #  # ][ #  # ]:          0 :     if (error < 0 && (*x1 != x2 || *y1 != y2) && blocked) {
         [ #  # ][ #  # ]
     281                 :          0 :       *x1 -= Dirs[0][minor];
     282                 :          0 :       *y1 -= Dirs[1][minor];
     283                 :          0 :       error += 2*step;
     284                 :          0 :       blocked = !unblocked(*x1,*y1);
     285                 :            :     }
     286                 :          0 :     Level->site[*x1][*y1].showchar = pyx;
     287                 :          0 :     plotchar(pyx,*x1,*y1);
     288                 :          0 :     plotspot(ox,oy,TRUE);
     289                 :          0 :     usleep(50000);
     290 [ #  # ][ #  # ]:          0 :   } while ((*x1 != x2 || *y1 != y2) && !blocked);
                 [ #  # ]
     291                 :          0 :   plotspot(*x1,*y1,TRUE);
     292                 :          0 :   levelrefresh();
     293                 :            : }
     294                 :            : 
     295                 :            : 
     296                 :            : /* This is the same as do_los, except we stop before hitting nonliving
     297                 :            : obstructions */
     298                 :          0 : void do_object_los(Symbol pyx, int *x1, int *y1, int x2, int y2)
     299                 :            : {
     300                 :            :   int dx,dy,ox,oy;
     301                 :            :   int major, minor;
     302                 :            :   int error, delta, step;
     303                 :            :   int blocked;
     304                 :            : 
     305         [ #  # ]:          0 :   if (x2 - *x1 < 0) dx = 5;
     306         [ #  # ]:          0 :   else if (x2 - *x1 > 0) dx = 4;
     307                 :          0 :   else dx = -1;
     308         [ #  # ]:          0 :   if (y2 - *y1 < 0) dy = 7;
     309         [ #  # ]:          0 :   else if (y2 - *y1 > 0) dy = 6;
     310                 :          0 :   else dy = -1;
     311         [ #  # ]:          0 :   if (abs(x2 - *x1) > abs(y2 - *y1)) {
     312                 :          0 :     major = dx;
     313                 :          0 :     minor = dy;
     314                 :          0 :     step = abs(x2 - *x1);
     315                 :          0 :     delta = 2*abs(y2 - *y1);
     316                 :            :   }
     317                 :            :   else {
     318                 :          0 :     major = dy;
     319                 :          0 :     minor = dx;
     320                 :          0 :     step = abs(y2 - *y1);
     321                 :          0 :     delta = 2*abs(x2 - *x1);
     322                 :            :   }
     323         [ #  # ]:          0 :   if (major == -1)      /* x1,y2 already == x2,y2 */
     324                 :          0 :     return;
     325                 :          0 :   error = 0;
     326                 :            :   do {
     327                 :          0 :     ox = *x1; oy = *y1;
     328                 :          0 :     *x1 += Dirs[0][major];
     329                 :          0 :     *y1 += Dirs[1][major];
     330                 :          0 :     error += delta;
     331         [ #  # ]:          0 :     if (error > step) {      /* don't need to check that minor >= 0 */
     332                 :          0 :       *x1 += Dirs[0][minor];
     333                 :          0 :       *y1 += Dirs[1][minor];
     334                 :          0 :       error -= 2*step;
     335                 :            :     }
     336                 :          0 :     blocked = !unblocked(*x1,*y1);
     337 [ #  # ][ #  # ]:          0 :     if (error < 0 && (*x1 != x2 || *y1 != y2) && blocked) {
         [ #  # ][ #  # ]
     338                 :          0 :       *x1 -= Dirs[0][minor];
     339                 :          0 :       *y1 -= Dirs[1][minor];
     340                 :          0 :       error += 2*step;
     341                 :          0 :       blocked = !unblocked(*x1,*y1);
     342                 :            :     }
     343                 :          0 :     plotspot(ox,oy,TRUE);
     344         [ #  # ]:          0 :     if (unblocked(*x1,*y1)) {
     345                 :          0 :       plotchar(pyx,*x1,*y1);
     346                 :          0 :       Level->site[*x1][*y1].showchar = pyx;
     347                 :          0 :       usleep(50000);
     348                 :            :     }
     349 [ #  # ][ #  # ]:          0 :   } while ((*x1 != x2 || *y1 != y2) && !blocked);
                 [ #  # ]
     350 [ #  # ][ #  # ]:          0 :   if (Level->site[*x1][*y1].creature == NULL && blocked) {
     351                 :          0 :     *x1 = ox;
     352                 :          0 :     *y1 = oy;
     353                 :            :   }
     354                 :          0 :   plotspot(*x1,*y1,TRUE);
     355                 :          0 :   levelrefresh();
     356                 :            : }
     357                 :            : 
     358                 :            : 
     359                 :            : /* los_p checks to see whether there is an unblocked los from x1,y1 to x2,y2 */
     360                 :        174 : int los_p(int x1, int y1, int x2, int y2)
     361                 :            : {
     362                 :            :   int dx,dy;
     363                 :            :   int major, minor;
     364                 :            :   int error, delta, step;
     365                 :            :   int blocked;
     366                 :            : 
     367         [ +  + ]:        174 :   if (x2-x1 < 0) dx = 5;
     368         [ +  - ]:        121 :   else if (x2-x1 > 0) dx = 4;
     369                 :          0 :   else dx = -1;
     370         [ +  + ]:        174 :   if (y2-y1 < 0) dy = 7;
     371         [ +  + ]:        120 :   else if (y2-y1 > 0) dy = 6;
     372                 :         20 :   else dy = -1;
     373         [ +  - ]:        174 :   if (abs(x2-x1) > abs(y2-y1)) {
     374                 :        174 :     major = dx;
     375                 :        174 :     minor = dy;
     376                 :        174 :     step = abs(x2 - x1);
     377                 :        174 :     delta = 2*abs(y2 - y1);
     378                 :            :   }
     379                 :            :   else {
     380                 :          0 :     major = dy;
     381                 :          0 :     minor = dx;
     382                 :          0 :     step = abs(y2 - y1);
     383                 :          0 :     delta = 2*abs(x2 - x1);
     384                 :            :   }
     385         [ -  + ]:        174 :   if (major == -1)      /* x1,y2 already == x2,y2 */
     386                 :          0 :     return TRUE;
     387                 :        174 :   error = 0;
     388                 :            :   do {
     389                 :        687 :     x1 += Dirs[0][major];
     390                 :        687 :     y1 += Dirs[1][major];
     391                 :        687 :     error += delta;
     392         [ +  + ]:        687 :     if (error > step) {      /* don't need to check that minor >= 0 */
     393                 :        136 :       x1 += Dirs[0][minor];
     394                 :        136 :       y1 += Dirs[1][minor];
     395                 :        136 :       error -= 2*step;
     396                 :            :     }
     397                 :        687 :     blocked = !unblocked(x1,y1);
     398 [ +  + ][ -  + ]:        687 :     if (error < 0 && (x1 != x2 || y1 != y2) && blocked) {
         [ #  # ][ +  + ]
     399                 :         48 :       x1 -= Dirs[0][minor];
     400                 :         48 :       y1 -= Dirs[1][minor];
     401                 :         48 :       error += 2*step;
     402                 :         48 :       blocked = !unblocked(x1,y1);
     403                 :            :     }
     404 [ +  + ][ -  + ]:        687 :   } while ((x1 != x2 || y1 != y2) && !blocked);
                 [ +  + ]
     405 [ +  + ][ +  - ]:        174 :   return((x1==x2) && (y1==y2));
     406                 :            : }
     407                 :            : 
     408                 :            : 
     409                 :            : /* view_los_p sees through monsters */
     410                 :      11589 : int view_los_p(int x1, int y1, int x2, int y2)
     411                 :            : {
     412                 :            :   int dx,dy;
     413                 :            :   int major, minor;
     414                 :            :   int error, delta, step;
     415                 :            :   int blocked;
     416                 :            : 
     417         [ +  + ]:      11589 :   if (x2-x1 < 0) dx = 5;
     418         [ +  + ]:       5502 :   else if (x2-x1 > 0) dx = 4;
     419                 :        117 :   else dx = -1;
     420         [ +  + ]:      11589 :   if (y2-y1 < 0) dy = 7;
     421         [ +  + ]:       9433 :   else if (y2-y1 > 0) dy = 6;
     422                 :        526 :   else dy = -1;
     423         [ +  + ]:      11589 :   if (abs(x2-x1) > abs(y2-y1)) {
     424                 :       7087 :     major = dx;
     425                 :       7087 :     minor = dy;
     426                 :       7087 :     step = abs(x2 - x1);
     427                 :       7087 :     delta = 2*abs(y2 - y1);
     428                 :            :   }
     429                 :            :   else {
     430                 :       4502 :     major = dy;
     431                 :       4502 :     minor = dx;
     432                 :       4502 :     step = abs(y2 - y1);
     433                 :       4502 :     delta = 2*abs(x2 - x1);
     434                 :            :   }
     435         [ +  + ]:      11589 :   if (major == -1)      /* x1,y2 already == x2,y2 */
     436                 :          2 :     return TRUE;
     437                 :      11587 :   error = 0;
     438                 :            :   do {
     439                 :      76155 :     x1 += Dirs[0][major];
     440                 :      76155 :     y1 += Dirs[1][major];
     441                 :      76155 :     error += delta;
     442         [ +  + ]:      76155 :     if (error > step) {
     443                 :      23348 :       x1 += Dirs[0][minor];
     444                 :      23348 :       y1 += Dirs[1][minor];
     445                 :      23348 :       error -= 2*step;
     446                 :            :     }
     447                 :      76155 :     blocked = !view_unblocked(x1,y1);
     448 [ +  + ][ +  + ]:      76155 :     if (error < 0 && (x1 != x2 || y1 != y2) && blocked) {
         [ +  - ][ +  + ]
     449                 :      10936 :       x1 -= Dirs[0][minor];
     450                 :      10936 :       y1 -= Dirs[1][minor];
     451                 :      10936 :       error += 2*step;
     452                 :      10936 :       blocked = !view_unblocked(x1,y1);
     453                 :            :     }
     454 [ +  + ][ +  + ]:      76155 :   } while ((x1 != x2 || y1 != y2) && !blocked);
                 [ +  + ]
     455 [ +  + ][ +  + ]:      11587 :   return((x1==x2) && (y1==y2));
     456                 :            : }
     457                 :            : 
     458                 :            : #ifndef MSDOS_SUPPORTED_ANTIQUE
     459                 :            : /* returns the command direction from the index into Dirs */
     460                 :          0 : char inversedir(int dirindex)
     461                 :            : {
     462   [ #  #  #  #  :          0 :   switch (dirindex) {
             #  #  #  #  
                      # ]
     463                 :          0 :     case 0:return('n');
     464                 :          0 :     case 1:return('u');
     465                 :          0 :     case 2:return('b');
     466                 :          0 :     case 3:return('y');
     467                 :          0 :     case 4:return('l');
     468                 :          0 :     case 5:return('h');
     469                 :          0 :     case 6:return('j');
     470                 :          0 :     case 7:return('k');
     471                 :          0 :     default:return('\0');
     472                 :            :   }
     473                 :            : }
     474                 :            : #endif
     475                 :            : 
     476                 :            : 
     477                 :          0 : long calc_points(void)
     478                 :            : {
     479                 :            :   int i;
     480                 :          0 :   long points=0;
     481                 :            :   
     482         [ #  # ]:          0 :   if (gamestatusp(SPOKE_TO_DRUID)) points += 50;
     483         [ #  # ]:          0 :   if (gamestatusp(COMPLETED_CAVES)) points += 100;
     484         [ #  # ]:          0 :   if (gamestatusp(COMPLETED_SEWERS)) points += 200;
     485         [ #  # ]:          0 :   if (gamestatusp(COMPLETED_CASTLE)) points += 300;
     486         [ #  # ]:          0 :   if (gamestatusp(COMPLETED_ASTRAL)) points += 400;
     487         [ #  # ]:          0 :   if (gamestatusp(COMPLETED_VOLCANO)) points += 500;
     488         [ #  # ]:          0 :   if (gamestatusp(KILLED_DRAGONLORD)) points += 100;
     489         [ #  # ]:          0 :   if (gamestatusp(KILLED_EATER)) points += 100;
     490         [ #  # ]:          0 :   if (gamestatusp(KILLED_LAWBRINGER)) points += 100;
     491                 :            : 
     492                 :          0 :   points += Player.xp/50;
     493                 :            : 
     494                 :          0 :   points += Player.cash/500;
     495                 :            : 
     496         [ #  # ]:          0 :   for (i=0;i<MAXITEMS;i++) 
     497         [ #  # ]:          0 :     if (Player.possessions[i] != NULL)
     498                 :          0 :       points += Player.possessions[i]->level*(Player.possessions[i]->known+1);
     499                 :            : 
     500         [ #  # ]:          0 :   for (i=0;i<MAXPACK;i++) 
     501         [ #  # ]:          0 :     if (Player.pack[i] != NULL)
     502                 :          0 :       points += Player.pack[i]->level*(Player.pack[i]->known+1);
     503                 :            : 
     504         [ #  # ]:          0 :   for (i=0;i<NUMRANKS;i++) {
     505         [ #  # ]:          0 :     if (Player.rank[i] == 5) points += 500;
     506                 :          0 :     else points += 20*Player.rank[i];
     507                 :            :   }
     508                 :            :   
     509         [ #  # ]:          0 :   if (Player.hp < 1)
     510                 :          0 :     points = (points / 2);
     511                 :            :   
     512         [ #  # ]:          0 :   else if (Player.rank[ADEPT])
     513                 :          0 :     points *= 10;
     514                 :            :   
     515                 :          0 :   return(points);
     516                 :            : }
     517                 :            : 
     518                 :            : 
     519                 :            : /* returns the 24 hour clock hour */
     520                 :        218 : int hour(void)
     521                 :            : {
     522                 :        218 :   return((int)(((Time+720) / 60) % 24));
     523                 :            : }
     524                 :            : 
     525                 :            : /* returns 0, 10, 20, 30, 40, or 50 */
     526                 :         88 : int showminute(void)
     527                 :            : {
     528                 :         88 :   return((int)((Time % 60)/10)*10);
     529                 :            : }
     530                 :            : 
     531                 :            : /* returns the 12 hour clock hour */
     532                 :         44 : int showhour(void)
     533                 :            : {
     534                 :            :   int showtime;
     535 [ +  + ][ +  + ]:         44 :   if ((hour() == 0) || (hour() == 12)) showtime = 12;
     536                 :         41 :   else showtime = (hour() % 12);
     537                 :         44 :   return(showtime);
     538                 :            : }
     539                 :            : 
     540                 :            : /* nighttime is defined from 9 PM to 6AM */
     541                 :          7 : int nighttime(void)
     542                 :            : {
     543 [ +  - ][ +  + ]:          7 :   return((hour() > 20) || (hour() < 7));
     544                 :            : }
     545                 :            : 
     546                 :          5 : char *getarticle(char *str)
     547                 :            : {
     548 [ +  - ][ +  - ]:          5 :   if ((str[0]=='a') || (str[0]=='A') ||
                 [ +  - ]
     549 [ +  - ][ +  - ]:          5 :       (str[0]=='e') || (str[0]=='E') ||
     550 [ +  - ][ +  - ]:          5 :       (str[0]=='i') || (str[0]=='I') ||
     551 [ +  - ][ +  - ]:          5 :       (str[0]=='o') || (str[0]=='O') ||
     552 [ +  - ][ +  + ]:          5 :       (str[0]=='u') || (str[0]=='U') ||
     553 [ -  + ][ +  - ]:          5 :       (((str[0]=='h') || (str[0]=='H')) && 
     554         [ -  + ]:          1 :        ((str[1]=='i') || (str[1]=='e'))))
     555                 :          0 :     return("an ");
     556                 :          5 :   else return("a ");
     557                 :            : }
     558                 :            : 
     559                 :         88 : int day(void)
     560                 :            : {
     561                 :         88 :   return ((Date % 30) + 1);
     562                 :            : }
     563                 :            : 
     564                 :         44 : char *ordinal(int number)
     565                 :            : {
     566 [ +  - ][ +  - ]:         44 :   if ((number == 11) || (number == 12) || (number == 13)) return("th");
                 [ -  + ]
     567   [ +  -  -  + ]:         44 :   else  switch(number % 10) {
     568                 :         31 :     case 1:return("st");
     569                 :          0 :     case 2:return("nd");
     570                 :          0 :     case 3:return("rd");
     571                 :         13 :     default: return("th");
     572                 :            :   }
     573                 :            : }
     574                 :            :            
     575                 :         88 : char *month(void)
     576                 :            : {
     577   [ -  -  -  -  :         88 :   switch((Date % 360) / 30) {
          -  -  +  -  -  
             -  -  -  -  
                      - ]
     578                 :          0 :     case 0: return("Freeze");
     579                 :          0 :     case 1: return("Ice");
     580                 :          0 :     case 2: return("Mud");
     581                 :          0 :     case 3: return("Storm");
     582                 :          0 :     case 4: return("Breeze");
     583                 :          0 :     case 5: return("Light");
     584                 :         88 :     case 6: return("Flame");
     585                 :          0 :     case 7: return("Broil");
     586                 :          0 :     case 8: return("Cool");
     587                 :          0 :     case 9: return("Haunt");
     588                 :          0 :     case 10: return("Chill");
     589                 :          0 :     case 11: return("Dark");
     590                 :          0 :     case 12: return("Twixt");
     591                 :          0 :     default: return("***Error***");
     592                 :            :   }
     593                 :            : }
     594                 :            : 
     595                 :            : /* finds floor space on level with buildaux not equal to baux,
     596                 :            : sets x,y there. There must *be* floor space somewhere on level */
     597                 :            : 
     598                 :          2 : static int spaceok (int x_idx, int y_idx, int baux)
     599                 :            : {
     600         [ +  + ]:          2 :   if (FLOOR != Level->site[x_idx][y_idx].locchar) return FALSE;
     601         [ -  + ]:          1 :   if (Level->site[x_idx][y_idx].creature) return FALSE;
     602         [ -  + ]:          1 :   if (loc_statusp(x_idx, y_idx, SECRET)) return FALSE;
     603         [ -  + ]:          1 :   if (Level->site[x_idx][y_idx].buildaux == baux) return FALSE;
     604                 :            : 
     605                 :          1 :   return TRUE;
     606                 :            : }
     607                 :            : 
     608                 :          1 : static int findspace_method_one (int * x_idx, int * y_idx, struct level * lev, int baux)
     609                 :            : {
     610                 :          1 :   int count = 0;
     611                 :            : 
     612         [ +  - ]:          2 :   for (count = 0; count < (lev->level_width * lev->level_length / 4); ++count)
     613                 :            :     {
     614                 :          2 :       *x_idx = random_range(lev->level_width);
     615                 :          2 :       *y_idx = random_range(lev->level_length);
     616         [ +  + ]:          2 :       if (spaceok(*x_idx, *y_idx, baux))
     617                 :          1 :         return TRUE;
     618                 :            :     }
     619                 :            : 
     620                 :          0 :   return FALSE;
     621                 :            : }
     622                 :            : 
     623                 :          0 : static int findspace_method_two (int * x_out, int * y_out, struct level * lev, int baux)
     624                 :            : {
     625                 :            :   int x_start, x_idx;
     626                 :            :   int y_start, y_idx;
     627                 :            : 
     628                 :            :   int x_dir, y_dir;
     629                 :            : 
     630                 :          0 :   x_idx = x_start = random_range(lev->level_width);
     631                 :          0 :   y_idx = y_start = random_range(lev->level_length);
     632                 :            : 
     633                 :          0 :   x_dir = random_range(2);
     634                 :          0 :   y_dir = random_range(2);
     635                 :            : 
     636         [ #  # ]:          0 :   if (random_range(2))
     637                 :            :     {
     638         [ #  # ]:          0 :       if (x_dir)
     639                 :            :         {
     640         [ #  # ]:          0 :           if (y_dir)
     641                 :            :             {
     642                 :            :               // case 0: X in outer loop, decrement X, decrement Y
     643                 :            :               do
     644                 :            :                 {
     645                 :            :                   do
     646                 :            :                     {
     647         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     648                 :          0 :                         goto found_space;
     649                 :            : 
     650                 :          0 :                       --y_idx;
     651         [ #  # ]:          0 :                       if (y_idx == -1)
     652                 :          0 :                         y_idx = lev->level_length - 1;
     653                 :            :                     }
     654         [ #  # ]:          0 :                   while (y_idx != y_start);
     655                 :            : 
     656                 :          0 :                   --x_idx;
     657         [ #  # ]:          0 :                   if (x_idx == -1)
     658                 :          0 :                     x_idx = lev->level_width - 1;
     659                 :            :                 }
     660         [ #  # ]:          0 :               while (x_idx != x_start);
     661                 :            :             }
     662                 :            :           else
     663                 :            :             {
     664                 :            :               // case 1: X in outer loop, decrement X, increment Y
     665                 :            :               do
     666                 :            :                 {
     667                 :            :                   do
     668                 :            :                     {
     669         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     670                 :          0 :                         goto found_space;
     671                 :            : 
     672                 :          0 :                       ++y_idx;
     673         [ #  # ]:          0 :                       if (y_idx == lev->level_length)
     674                 :          0 :                         y_idx = 0;
     675                 :            :                     }
     676         [ #  # ]:          0 :                   while (y_idx != y_start);
     677                 :            : 
     678                 :          0 :                   --x_idx;
     679         [ #  # ]:          0 :                   if (x_idx == -1)
     680                 :          0 :                     x_idx = lev->level_width - 1;
     681                 :            :                 }
     682         [ #  # ]:          0 :               while (x_idx != x_start);
     683                 :            :             }
     684                 :            :         }
     685                 :            :       else
     686                 :            :         {
     687         [ #  # ]:          0 :           if (y_dir)
     688                 :            :             {
     689                 :            :               // case 2: X in outer loop, increment X, decrement Y
     690                 :            :               do
     691                 :            :                 {
     692                 :            :                   do
     693                 :            :                     {
     694         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     695                 :          0 :                         goto found_space;
     696                 :            : 
     697                 :          0 :                       --y_idx;
     698         [ #  # ]:          0 :                       if (y_idx == -1)
     699                 :          0 :                         y_idx = lev->level_length - 1;
     700                 :            :                     }
     701         [ #  # ]:          0 :                   while (y_idx != y_start);
     702                 :            : 
     703                 :          0 :                   ++x_idx;
     704         [ #  # ]:          0 :                   if (x_idx == lev->level_width)
     705                 :          0 :                     x_idx = 0;
     706                 :            :                 }
     707         [ #  # ]:          0 :               while (x_idx != x_start);
     708                 :            :             }
     709                 :            :           else
     710                 :            :             {
     711                 :            :               // case 3: X in outer loop, increment X, increment Y
     712                 :            :               do
     713                 :            :                 {
     714                 :            :                   do
     715                 :            :                     {
     716         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     717                 :          0 :                         goto found_space;
     718                 :            : 
     719                 :          0 :                       ++y_idx;
     720         [ #  # ]:          0 :                       if (y_idx == lev->level_length)
     721                 :          0 :                         y_idx = 0;
     722                 :            :                     }
     723         [ #  # ]:          0 :                   while (y_idx != y_start);
     724                 :            : 
     725                 :          0 :                   ++x_idx;
     726         [ #  # ]:          0 :                   if (x_idx == lev->level_width)
     727                 :          0 :                     x_idx = 0;
     728                 :            :                 }
     729         [ #  # ]:          0 :               while (x_idx != x_start);
     730                 :            :             }
     731                 :            :         }
     732                 :            :     }
     733                 :            :   else
     734                 :            :     {
     735         [ #  # ]:          0 :       if (y_dir)
     736                 :            :         {
     737         [ #  # ]:          0 :           if (x_dir)
     738                 :            :             {
     739                 :            :               // case 4: Y in outer loop, decrement X, decrement Y
     740                 :            :               do
     741                 :            :                 {
     742                 :            :                   do
     743                 :            :                     {
     744         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     745                 :          0 :                         goto found_space;
     746                 :            : 
     747                 :          0 :                       --x_idx;
     748         [ #  # ]:          0 :                       if (x_idx == -1)
     749                 :          0 :                         x_idx = lev->level_width - 1;
     750                 :            :                     }
     751         [ #  # ]:          0 :                   while (x_idx != x_start);
     752                 :            : 
     753                 :          0 :                   --y_idx;
     754         [ #  # ]:          0 :                   if (y_idx == -1)
     755                 :          0 :                     y_idx = lev->level_length - 1;
     756                 :            :                 }
     757         [ #  # ]:          0 :               while (y_idx != y_start);
     758                 :            :             }
     759                 :            :           else
     760                 :            :             {
     761                 :            :               // case 5: Y in outer loop, decrement X, increment Y
     762                 :            :               do
     763                 :            :                 {
     764                 :            :                   do
     765                 :            :                     {
     766         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     767                 :          0 :                         goto found_space;
     768                 :            : 
     769                 :          0 :                       ++x_idx;
     770         [ #  # ]:          0 :                       if (x_idx == lev->level_width)
     771                 :          0 :                         x_idx = 0;
     772                 :            :                     }
     773         [ #  # ]:          0 :                   while (x_idx != x_start);
     774                 :            : 
     775                 :          0 :                   --y_idx;
     776         [ #  # ]:          0 :                   if (y_idx == -1)
     777                 :          0 :                     y_idx = lev->level_length - 1;
     778                 :            :                 }
     779         [ #  # ]:          0 :               while (y_idx != y_start);
     780                 :            :             }
     781                 :            :         }
     782                 :            :       else
     783                 :            :         {
     784         [ #  # ]:          0 :           if (x_dir)
     785                 :            :             {
     786                 :            :               // case 6: Y in outer loop, increment X, decrement Y
     787                 :            :               do
     788                 :            :                 {
     789                 :            :                   do
     790                 :            :                     {
     791         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     792                 :          0 :                         goto found_space;
     793                 :            : 
     794                 :          0 :                       --x_idx;
     795         [ #  # ]:          0 :                       if (x_idx == -1)
     796                 :          0 :                         x_idx = lev->level_width - 1;
     797                 :            :                     }
     798         [ #  # ]:          0 :                   while (x_idx != x_start);
     799                 :            : 
     800                 :          0 :                   ++y_idx;
     801         [ #  # ]:          0 :                   if (y_idx == lev->level_length)
     802                 :          0 :                     y_idx = 0;
     803                 :            :                 }
     804         [ #  # ]:          0 :               while (y_idx != y_start);
     805                 :            :             }
     806                 :            :           else
     807                 :            :             {
     808                 :            :               // case 7: Y in outer loop, increment X, increment Y
     809                 :            :               do
     810                 :            :                 {
     811                 :            :                   do
     812                 :            :                     {
     813         [ #  # ]:          0 :                       if (spaceok(x_idx, y_idx, baux))
     814                 :          0 :                         goto found_space;
     815                 :            : 
     816                 :          0 :                       ++x_idx;
     817         [ #  # ]:          0 :                       if (x_idx == lev->level_width)
     818                 :          0 :                         x_idx = 0;
     819                 :            :                     }
     820         [ #  # ]:          0 :                   while (x_idx != x_start);
     821                 :            : 
     822                 :          0 :                   ++y_idx;
     823         [ #  # ]:          0 :                   if (y_idx == lev->level_length)
     824                 :          0 :                     y_idx = 0;
     825                 :            :                 }
     826         [ #  # ]:          0 :               while (y_idx != y_start);
     827                 :            :             }
     828                 :            :         }
     829                 :            :     }
     830                 :            : 
     831                 :          0 :   return FALSE;
     832                 :            : 
     833                 :            :  found_space:
     834                 :          0 :   *x_out = x_idx;
     835                 :          0 :   *y_out = y_idx;
     836                 :          0 :   return TRUE;
     837                 :            : }
     838                 :            : 
     839                 :          1 : void findspace (int * x_out, int * y_out, int baux)
     840                 :            : {
     841                 :            :   /* try to quickly find a space by sampling randomly */
     842         [ +  - ]:          1 :   if (findspace_method_one(x_out, y_out, Level, baux))
     843                 :          1 :     return;
     844                 :            : 
     845                 :            :   /* examine every space on the level */
     846         [ #  # ]:          0 :   if (findspace_method_two(x_out, y_out, Level, baux))
     847                 :          0 :     return;
     848                 :            : 
     849                 :            :   /* this could theoretically happen but if it does, it's an error */
     850                 :          0 :   assert(FALSE);
     851                 :            : }
     852                 :            : 
     853                 :            : /* finds floor space on level with buildaux not equal to baux,
     854                 :            : sets x,y there. Return false is no such space exists on the level. */
     855                 :          0 : int try_findspace (int * x_out, int * y_out, int baux)
     856                 :            : {
     857                 :            :   /* try to quickly find a space by sampling randomly */
     858         [ #  # ]:          0 :   if (findspace_method_one(x_out, y_out, Level, baux))
     859                 :          0 :     return TRUE;
     860                 :            : 
     861                 :            :   /* examine every space on the level */
     862         [ #  # ]:          0 :   if (findspace_method_two(x_out, y_out, Level, baux))
     863                 :          0 :     return TRUE;
     864                 :            : 
     865                 :          0 :   return FALSE;
     866                 :            : }
     867                 :            : 
     868                 :            : /* is prefix a prefix of s? */
     869                 :          0 : int strprefix(char *prefix, char *s)
     870                 :            : {
     871                 :          0 :   int i=0,matched=TRUE;
     872         [ #  # ]:          0 :   if (strlen(prefix) > strlen(s)) return(FALSE);
     873                 :            :   else {
     874 [ #  # ][ #  # ]:          0 :     while (matched && (i<strlen(prefix))) {
     875                 :          0 :       matched = (prefix[i] == s[i]);
     876                 :          0 :       i++;
     877                 :            :     }
     878                 :          0 :     return(matched);
     879                 :            :   }
     880                 :            : }
     881                 :            : 
     882                 :            : /* WSS - Maybe I'm not understanding something here, but isn't "strmem" just */
     883                 :            : /* WSS - a lame version of the standard library function strchr? */
     884                 :            : 
     885                 :            : /* is character c a member of string s */
     886                 :          0 : int strmem(char c, char *s)
     887                 :            : {
     888                 :          0 :   int i,found=FALSE;
     889 [ #  # ][ #  # ]:          0 :   for(i=0;((i<strlen(s)) && (! found));i++)
     890                 :          0 :     found = (s[i] == c);
     891                 :          0 :   return(found);
     892                 :            : }
     893                 :            : 
     894                 :         22 : void calc_weight(void)
     895                 :            : {
     896                 :         22 :   int i,weight=0;
     897                 :            : 
     898         [ +  + ]:        352 :   for(i=1;i<MAXITEMS;i++) 
     899         [ +  + ]:        330 :     if (Player.possessions[i] != NULL)
     900                 :        167 :       weight += Player.possessions[i]->weight *      Player.possessions[i]->number;
     901 [ +  - ][ -  + ]:         22 :   if ((Player.possessions[O_WEAPON_HAND] != NULL) &&
     902                 :         22 :       (Player.possessions[O_READY_HAND] == Player.possessions[O_WEAPON_HAND]))
     903                 :          0 :     weight -= Player.possessions[O_READY_HAND]->weight *
     904                 :          0 :       Player.possessions[O_READY_HAND]->number;
     905         [ +  + ]:        594 :   for(i=0;i<MAXPACK;i++) 
     906         [ -  + ]:        572 :     if (Player.pack[i] != NULL)
     907                 :          0 :       weight += Player.pack[i]->weight *
     908                 :          0 :         Player.pack[i]->number;
     909                 :         22 :   Player.itemweight = weight;
     910                 :         22 :   dataprint();
     911                 :         22 : }
     912                 :            : 
     913                 :            : char joinString[256], temp[256];
     914                 :          7 : char *strjoin(char*one, char*two)
     915                 :            : {
     916         [ -  + ]:          7 :   assert(one != two);
     917         [ -  + ]:          7 :   if (joinString == one) goto DirectJoin;
     918         [ -  + ]:          7 :   if (joinString == two) {strcpy(temp,two); two = temp;}
     919                 :          7 :   strcpy(joinString,one);
     920                 :            : DirectJoin:
     921                 :          7 :   strcat(joinString,two);
     922                 :          7 :   return joinString;
     923                 :            : }
     924                 :            : 
     925                 :            : /* returns true if its ok to get rid of a level */
     926                 :          4 : int ok_to_free(plv level)
     927                 :            : {
     928         [ +  + ]:          4 :   if (level == NULL) return(FALSE);
     929         [ -  + ]:          5 :   else return((level->environment != E_CITY) &&
     930 [ +  + ][ #  # ]:          5 :               (level->environment != E_VILLAGE) &&
     931                 :          0 :               (level->environment != Current_Dungeon));
     932                 :            : }
     933                 :            : 
     934                 :            : /* DAG frees object; if flag true, final free, free any allocated corpse string */
     935                 :         38 : void free_obj( pob obj, int flag )
     936                 :            : {
     937 [ +  - ][ +  + ]:         38 :   if ( flag && (obj->id == CORPSEID) && (obj->level & ALLOC) )
                 [ -  + ]
     938                 :          0 :     free( obj->objstr );
     939                 :         38 :   free( (char *) obj );
     940                 :         38 : }
     941                 :            : 
     942                 :          9 : pob copy_obj ( pob obj )
     943                 :            : {
     944                 :            :    pob new;
     945                 :          9 :    new = ((pob) checkmalloc(sizeof(objtype)));
     946                 :          9 :    *new = *obj;
     947 [ +  + ][ -  + ]:          9 :    if ( (obj->id == CORPSEID) && (obj->level & ALLOC) )
     948                 :            :    {
     949                 :          0 :      new->objstr = new->cursestr = new->truename = salloc( obj->objstr );
     950                 :            :    }
     951                 :          9 :    return new;
     952                 :            : }
     953                 :            : 
     954                 :         17 : void free_objlist(pol pobjlist)
     955                 :            : {
     956                 :            :   pol tmp;
     957                 :            : 
     958         [ +  + ]:         34 :   while (pobjlist) {
     959                 :         17 :     free_obj( (tmp = pobjlist)->thing, TRUE );
     960                 :         17 :     pobjlist = pobjlist->next;
     961                 :         17 :     free(tmp);
     962                 :            :   }
     963                 :         17 : }
     964                 :            : 
     965                 :          2 : void free_mons_and_objs(pml mlist)
     966                 :            : {
     967                 :            :   pml tmp;
     968                 :            : 
     969         [ +  + ]:         18 :   while (mlist) {
     970                 :         16 :     free_objlist((tmp = mlist)->m->possessions);
     971                 :            :     /* DAG free the monstring & corpsestr if allocated */
     972         [ -  + ]:         16 :     if ( m_statusp( tmp->m, ALLOC ) )
     973                 :            :     {
     974                 :          0 :       free( tmp->m->monstring );
     975                 :          0 :       free( tmp->m->corpsestr );
     976                 :            :     }
     977                 :         16 :     free(tmp->m);
     978                 :         16 :     mlist = mlist->next;
     979                 :         16 :     free(tmp);
     980                 :            :   }
     981                 :          2 : }
     982                 :            : 
     983                 :            : /* Free up monsters and items on a level*/
     984                 :          2 : void free_level(plv level)
     985                 :            : {
     986                 :            :   int i,j;
     987                 :            : 
     988                 :          2 :   free_mons_and_objs(level->mlist);
     989         [ +  + ]:        130 :   for (i = 0; i < level->level_width; i++)
     990         [ +  + ]:       2176 :     for (j = 0; j < level->level_length; j++)
     991         [ +  + ]:       2048 :       if (level->site[i][j].things) {
     992                 :          1 :         free_objlist(level->site[i][j].things);
     993                 :          1 :         level->site[i][j].things = NULL;
     994                 :            :       }
     995                 :            : #ifndef SAVE_LEVELS
     996                 :          2 :   free(level);
     997                 :            : #endif
     998                 :          2 : }
     999                 :            : 
    1000                 :            : /* malloc function that checks its return value - if NULL, tries to free */
    1001                 :            : /* some memory... */
    1002                 :        453 : void *checkmalloc(unsigned int bytes)
    1003                 :            : {
    1004                 :        453 :   void *ptr = malloc(bytes);
    1005                 :            :   struct level *curr, **prev, **oldest;
    1006                 :            : 
    1007         [ +  - ]:        453 :   if (ptr)
    1008                 :        453 :     return ptr;
    1009         [ #  # ]:          0 :   for (curr = Dungeon, oldest = prev = &Dungeon; curr; curr = curr->next) {
    1010         [ #  # ]:          0 :     if ((*oldest)->last_visited > curr->last_visited)
    1011                 :          0 :       oldest = prev;
    1012                 :          0 :     prev = &(curr->next);
    1013                 :            :   }
    1014 [ #  # ][ #  # ]:          0 :   if (*oldest && *oldest != Level) {
    1015                 :          0 :     curr = *oldest;
    1016                 :          0 :     *oldest = (*oldest)->next;
    1017                 :          0 :     free_level(curr);
    1018                 :          0 :     ptr = malloc(bytes);
    1019                 :            :   }
    1020         [ #  # ]:          0 :   if (ptr)
    1021                 :          0 :     return ptr;
    1022                 :            :   else {
    1023                 :          0 :     print1("Out of memory!  Saving and quitting.");
    1024                 :          0 :     morewait();
    1025                 :          0 :     save(FALSE, TRUE);
    1026                 :          0 :     endgraf();
    1027                 :          0 :     exit(0);
    1028                 :            :   }
    1029                 :            : }
    1030                 :            : 
    1031                 :            : /* alloc just enough string space for str, strcpy, and return pointer */
    1032                 :         11 : char *salloc(char *str)
    1033                 :            : {
    1034                 :         11 :   char *s=checkmalloc((unsigned)(strlen(str)+1));
    1035                 :         11 :   strcpy(s,str);
    1036                 :         11 :   return(s);
    1037                 :            : }
    1038                 :            : 
    1039                 :            : #ifdef MSDOS
    1040                 :            : /* ****Moved here from another file**** */
    1041                 :            : /* reads a string from a file. If it is a line with more than 80 char's,
    1042                 :            :    then remainder of line to \n is consumed */
    1043                 :            : void filescanstring(FILE *fd, char *fstr)
    1044                 :            : {
    1045                 :            :   int i= -1;
    1046                 :            :   int byte='x';
    1047                 :            :   while ((i<80) && (byte != '\n') && (byte != EOF)) {
    1048                 :            :     i++;
    1049                 :            :     byte=fgetc(fd);
    1050                 :            :     fstr[i] = byte;
    1051                 :            :   } 
    1052                 :            :   if (byte != '\n')
    1053                 :            :     while((byte!='\n') && (byte != EOF))
    1054                 :            :       byte=fgetc(fd);
    1055                 :            :   fstr[i]=0;
    1056                 :            : }
    1057                 :            : #endif
    1058                 :            : 
    1059                 :            : #ifdef MSDOS_SUPPORTED_ANTIQUE
    1060                 :            : /* ****Moved here from another file**** */
    1061                 :            : /* returns a "level of difficulty" based on current environment
    1062                 :            :    and depth in dungeon. Is somewhat arbitrary. value between 1 and 10.
    1063                 :            :    May not actually represent real difficulty, but instead level
    1064                 :            :    of items, monsters encountered.    */
    1065                 :            : int difficulty(void)
    1066                 :            : {
    1067                 :            :   int depth = 1;
    1068                 :            :   if (Level != NULL) depth = Level->depth;
    1069                 :            :   switch(Current_Environment) {
    1070                 :            :   case E_COUNTRYSIDE: return(7);
    1071                 :            :   case E_CITY: return(3);
    1072                 :            :   case E_VILLAGE: return(1);
    1073                 :            :   case E_TACTICAL_MAP: return(7);
    1074                 :            :   case E_SEWERS: return(depth/6)+3;
    1075                 :            :   case E_CASTLE: return(depth/4)+4;
    1076                 :            :   case E_CAVES: return(depth/3)+1;
    1077                 :            :   case E_VOLCANO: return(depth/4)+5;
    1078                 :            :   case E_ASTRAL: return(8);
    1079                 :            :   case E_ARENA: return(5);
    1080                 :            :   case E_HOVEL: return(3);
    1081                 :            :   case E_MANSION: return(7);
    1082                 :            :   case E_HOUSE: return(5);
    1083                 :            :   case E_DLAIR: return(9);
    1084                 :            :   case E_ABYSS: return(10);
    1085                 :            :   case E_STARPEAK: return(9);
    1086                 :            :   case E_CIRCLE: return(8);
    1087                 :            :   case E_MAGIC_ISLE: return(8);
    1088                 :            :   case E_TEMPLE: return(8);
    1089                 :            : 
    1090                 :            :     /* PGM why is this duplicated in lev.c ? */
    1091                 :            :   case E_PALACE:  /* varies by phase of moon */
    1092                 :            :     {
    1093                 :            :       int diff = 0;
    1094                 :            :       switch(Phase/2) {
    1095                 :            :       case 0: diff = 0; break;
    1096                 :            :       case 1: case 11: diff = 1; break;
    1097                 :            :       case 2: case 10: diff = 2; break;
    1098                 :            :       case 3: case 9:  diff = 3; break;
    1099                 :            :       case 4: case 8:  diff = 5; break;
    1100                 :            :       case 5: case 7:  diff = 6; break;
    1101                 :            :       case 6: diff = 7; break;
    1102                 :            :       }
    1103                 :            :       return( min( ((depth+diff)/3)+4,9));
    1104                 :            :     }
    1105                 :            :   default: return(3);
    1106                 :            :   }
    1107                 :            : }
    1108                 :            : #endif
    1109                 :            : 
    1110                 :          0 : char cryptkey(char *fname)
    1111                 :            : {
    1112                 :          0 :     int pos, key = 0;
    1113                 :            : 
    1114         [ #  # ]:          0 :     for (pos = 0; fname[pos]; pos++)
    1115                 :          0 :         key += 3*(fname[pos] - ' ');
    1116                 :          0 :     return (key&0xff);
    1117                 :            : }
    1118                 :            : 
    1119                 :            : int game_uid;
    1120                 :            : int user_uid;
    1121                 :            : 
    1122                 :          1 : void init_perms(void)
    1123                 :            : {
    1124                 :            : #if (defined(BSD) || defined(SYSV)) && !defined(__DJGPP__)
    1125                 :          1 :     user_uid = getuid();
    1126                 :          1 :     game_uid = geteuid();
    1127                 :            : #endif
    1128                 :          1 : }
    1129                 :            : 
    1130                 :            : /*
    1131                 :            : #ifdef BSD
    1132                 :            : void setreuid(int, int);
    1133                 :            : #endif
    1134                 :            : */
    1135                 :            : 
    1136                 :          3 : void change_to_user_perms(void)
    1137                 :            : {
    1138                 :            : #if (defined( BSD ) || defined( SYSV )) && !defined(__EMX__) && !defined(__DJGPP__)
    1139                 :            : #ifdef BSD
    1140                 :          3 :     setreuid(game_uid, user_uid);
    1141                 :            : #else /* SYSV */
    1142                 :            :     seteuid(user_uid);
    1143                 :            : #endif /* BSD */
    1144                 :            : #endif /* BSD || SYSV */
    1145                 :          3 : }
    1146                 :            : 
    1147                 :         16 : void change_to_game_perms(void)
    1148                 :            : {
    1149                 :            : #if (defined( BSD ) || defined( SYSV )) && !defined(__EMX__) && !defined(__DJGPP__)
    1150                 :            : #ifdef BSD
    1151                 :         16 :     setreuid(user_uid, game_uid);
    1152                 :            : #else /* SYSV */
    1153                 :            :     seteuid(game_uid);
    1154                 :            : #endif /* BSD */
    1155                 :            : #endif /* BSD || SYSV */
    1156                 :         16 : }
    1157                 :            : 
    1158                 :            : #ifdef NO_USLEEP
    1159                 :            : void usleep(int usecs)
    1160                 :            : {
    1161                 :            :   fd_set null;
    1162                 :            :   struct timeval timeout;
    1163                 :            : 
    1164                 :            :   FD_ZERO(&null);
    1165                 :            :   timeout.tv_usec = usecs;
    1166                 :            :   timeout.tv_sec = 0;
    1167                 :            :   select(0, &null, &null, &null, &timeout);
    1168                 :            : }
    1169                 :            : #endif

Generated by: LCOV version 1.11