(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hunt/huntd/expl.c

    1: /*      $NetBSD: expl.c,v 1.4 2004/01/27 20:30:29 jsm Exp $  */
    2: /*
    3:  * Copyright (c) 1983-2003, Regents of the University of California.
    4:  * All rights reserved.
    5:  * 
    6:  * Redistribution and use in source and binary forms, with or without 
    7:  * modification, are permitted provided that the following conditions are 
    8:  * met:
    9:  * 
   10:  * + Redistributions of source code must retain the above copyright 
   11:  *   notice, this list of conditions and the following disclaimer.
   12:  * + Redistributions in binary form must reproduce the above copyright 
   13:  *   notice, this list of conditions and the following disclaimer in the 
   14:  *   documentation and/or other materials provided with the distribution.
   15:  * + Neither the name of the University of California, San Francisco nor 
   16:  *   the names of its contributors may be used to endorse or promote 
   17:  *   products derived from this software without specific prior written 
   18:  *   permission.
   19:  * 
   20:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
   21:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
   22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
   23:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   24:  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
   25:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   26:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
   27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   30:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31:  */
   32: 
   33: #include <sys/cdefs.h>
   34: #ifndef lint
   35: __RCSID("$NetBSD: expl.c,v 1.4 2004/01/27 20:30:29 jsm Exp $");
   36: #endif /* not lint */
   37: 
   38: # include       <stdlib.h>
   39: # include       "hunt.h"
   40: 
   41: static  void     remove_wall(int, int);
   42: 
   43: 
   44: /*
   45:  * showexpl:
   46:  *      Show the explosions as they currently are
   47:  */
   48: void
   49: showexpl(y, x, type)
   50:         int    y, x;
   51:         char   type;
   52: {
   53:         PLAYER *pp;
   54:         EXPL   *ep;
   55: 
   56:         if (y < 0 || y >= HEIGHT)
   57:                 return;
   58:         if (x < 0 || x >= WIDTH)
   59:                 return;
   60:         ep = (EXPL *) malloc(sizeof (EXPL));   /* NOSTRICT */
   61:         if (ep == NULL) {
   62: # ifdef LOG
   63:                 syslog(LOG_ERR, "Out of memory");
   64: # else
   65:                 warnx("Out of memory");
   66: # endif
   67:                 cleanup(1);
   68:         }
   69:         ep->e_y = y;
   70:         ep->e_x = x;
   71:         ep->e_char = type;
   72:         ep->e_next = NULL;
   73:         if (Last_expl == NULL)
   74:                 Expl[0] = ep;
   75:         else
   76:                 Last_expl->e_next = ep;
   77:         Last_expl = ep;
   78:         for (pp = Player; pp < End_player; pp++) {
   79:                 if (pp->p_maze[y][x] == type)
   80:                         continue;
   81:                 pp->p_maze[y][x] = type;
   82:                 cgoto(pp, y, x);
   83:                 outch(pp, type);
   84:         }
   85: # ifdef MONITOR
   86:         for (pp = Monitor; pp < End_monitor; pp++) {
   87:                 if (pp->p_maze[y][x] == type)
   88:                         continue;
   89:                 pp->p_maze[y][x] = type;
   90:                 cgoto(pp, y, x);
   91:                 outch(pp, type);
   92:         }
   93: # endif
   94:         switch (Maze[y][x]) {
   95:           case WALL1:
   96:           case WALL2:
   97:           case WALL3:
   98: # ifdef RANDOM
   99:           case DOOR:
  100: # endif
  101: # ifdef REFLECT
  102:           case WALL4:
  103:           case WALL5:
  104: # endif
  105:                 if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
  106:                         remove_wall(y, x);
  107:                 break;
  108:         }
  109: }
  110: 
  111: /*
  112:  * rollexpl:
  113:  *      Roll the explosions over, so the next one in the list is at the
  114:  *      top
  115:  */
  116: void
  117: rollexpl()
  118: {
  119:         EXPL   *ep;
  120:         PLAYER *pp;
  121:         int    y, x;
  122:         char   c;
  123:         EXPL   *nextep;
  124: 
  125:         for (ep = Expl[EXPLEN - 1]; ep != NULL; ep = nextep) {
  126:                 nextep = ep->e_next;
  127:                 y = ep->e_y;
  128:                 x = ep->e_x;
  129:                 if (y < UBOUND || y >= DBOUND || x < LBOUND || x >= RBOUND)
  130:                         c = Maze[y][x];
  131:                 else
  132:                         c = SPACE;
  133:                 for (pp = Player; pp < End_player; pp++)
  134:                         if (pp->p_maze[y][x] == ep->e_char) {
  135:                                 pp->p_maze[y][x] = c;
  136:                                 cgoto(pp, y, x);
  137:                                 outch(pp, c);
  138:                         }
  139: # ifdef MONITOR
  140:                 for (pp = Monitor; pp < End_monitor; pp++)
  141:                         check(pp, y, x);
  142: # endif
  143:                 free((char *) ep);
  144:         }
  145:         for (x = EXPLEN - 1; x > 0; x--)
  146:                 Expl[x] = Expl[x - 1];
  147:         Last_expl = Expl[0] = NULL;
  148: }
  149: 
  150: /* There's about 700 walls in the initial maze.  So we pick a number
  151:  * that keeps the maze relatively full. */
  152: # define MAXREMOVE      40
  153: 
  154: static  REGEN    removed[MAXREMOVE];
  155: static  REGEN    *rem_index = removed;
  156: 
  157: /*
  158:  * remove_wall - add a location where the wall was blown away.
  159:  *               if there is no space left over, put the a wall at
  160:  *               the location currently pointed at.
  161:  */
  162: static void
  163: remove_wall(y, x)
  164:         int    y, x;
  165: {
  166:         REGEN  *r;
  167: # if defined(MONITOR) || defined(FLY)
  168:         PLAYER *pp;
  169: # endif
  170: # ifdef FLY
  171:         char   save_char = 0;
  172: # endif
  173: 
  174:         r = rem_index;
  175:         while (r->r_y != 0) {
  176: # ifdef FLY
  177:                 switch (Maze[r->r_y][r->r_x]) {
  178:                   case SPACE:
  179:                   case LEFTS:
  180:                   case RIGHT:
  181:                   case ABOVE:
  182:                   case BELOW:
  183:                   case FLYER:
  184:                         save_char = Maze[r->r_y][r->r_x];
  185:                         goto found;
  186:                 }
  187: # else
  188:                 if (Maze[r->r_y][r->r_x] == SPACE)
  189:                         break;
  190: # endif
  191:                 if (++r >= &removed[MAXREMOVE])
  192:                         r = removed;
  193:         }
  194: 
  195: found:
  196:         if (r->r_y != 0) {
  197:                 /* Slot being used, put back this wall */
  198: # ifdef FLY
  199:                 if (save_char == SPACE)
  200:                         Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
  201:                 else {
  202:                         pp = play_at(r->r_y, r->r_x);
  203:                         if (pp->p_flying >= 0)
  204:                                 pp->p_flying += rand_num(10);
  205:                         else {
  206:                                 pp->p_flying = rand_num(20);
  207:                                 pp->p_flyx = 2 * rand_num(6) - 5;
  208:                                 pp->p_flyy = 2 * rand_num(6) - 5;
  209:                         }
  210:                         pp->p_over = Orig_maze[r->r_y][r->r_x];
  211:                         pp->p_face = FLYER;
  212:                         Maze[r->r_y][r->r_x] = FLYER;
  213:                         showexpl(r->r_y, r->r_x, FLYER);
  214:                 }
  215: # else
  216:                 Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
  217: # endif
  218: # ifdef RANDOM
  219:                 if (rand_num(100) == 0)
  220:                         Maze[r->r_y][r->r_x] = DOOR;
  221: # endif
  222: # ifdef REFLECT
  223:                 if (rand_num(100) == 0)               /* one percent of the time */
  224:                         Maze[r->r_y][r->r_x] = WALL4;
  225: # endif
  226: # ifdef MONITOR
  227:                 for (pp = Monitor; pp < End_monitor; pp++)
  228:                         check(pp, r->r_y, r->r_x);
  229: # endif
  230:         }
  231: 
  232:         r->r_y = y;
  233:         r->r_x = x;
  234:         if (++r >= &removed[MAXREMOVE])
  235:                 rem_index = removed;
  236:         else
  237:                 rem_index = r;
  238: 
  239:         Maze[y][x] = SPACE;
  240: # ifdef MONITOR
  241:         for (pp = Monitor; pp < End_monitor; pp++)
  242:                 check(pp, y, x);
  243: # endif
  244: }
  245: 
  246: /*
  247:  * clearwalls:
  248:  *      Clear out the walls array
  249:  */
  250: void
  251: clearwalls()
  252: {
  253:         REGEN  *rp;
  254: 
  255:         for (rp = removed; rp < &removed[MAXREMOVE]; rp++)
  256:                 rp->r_y = 0;
  257:         rem_index = removed;
  258: }
Syntax (Markdown)