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

bsd-games/2.17/hack/hack.pri.c

    1: /*      $NetBSD: hack.pri.c,v 1.8 2003/04/02 18:36:39 jsm Exp $      */
    2: 
    3: /*
    4:  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
    5:  * Amsterdam
    6:  * All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions are
   10:  * met:
   11:  *
   12:  * - Redistributions of source code must retain the above copyright notice,
   13:  * this list of conditions and the following disclaimer.
   14:  *
   15:  * - Redistributions in binary form must reproduce the above copyright
   16:  * notice, this list of conditions and the following disclaimer in the
   17:  * documentation and/or other materials provided with the distribution.
   18:  *
   19:  * - Neither the name of the Stichting Centrum voor Wiskunde en
   20:  * Informatica, nor the names of its contributors may be used to endorse or
   21:  * promote products derived from this software without specific prior
   22:  * written permission.
   23:  *
   24:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   25:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   26:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   27:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   28:  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   29:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   30:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   31:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   32:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35:  */
   36: 
   37: /*
   38:  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
   39:  * All rights reserved.
   40:  *
   41:  * Redistribution and use in source and binary forms, with or without
   42:  * modification, are permitted provided that the following conditions
   43:  * are met:
   44:  * 1. Redistributions of source code must retain the above copyright
   45:  *    notice, this list of conditions and the following disclaimer.
   46:  * 2. Redistributions in binary form must reproduce the above copyright
   47:  *    notice, this list of conditions and the following disclaimer in the
   48:  *    documentation and/or other materials provided with the distribution.
   49:  * 3. The name of the author may not be used to endorse or promote products
   50:  *    derived from this software without specific prior written permission.
   51:  *
   52:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   53:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   54:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   55:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   56:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   57:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   58:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   59:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   60:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   61:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62:  */
   63: 
   64: #include <sys/cdefs.h>
   65: #ifndef lint
   66: __RCSID("$NetBSD: hack.pri.c,v 1.8 2003/04/02 18:36:39 jsm Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include "hack.h"
   70: #include "extern.h"
   71: xchar           scrlx, scrhx, scrly, scrhy;     /* corners of new area on
   72:                                                  * screen */
   73: 
   74: void
   75: swallowed()
   76: {
   77:         char            ulook[] = "|@|";
   78:         ulook[1] = u.usym;
   79: 
   80:         cls();
   81:         curs(u.ux - 1, u.uy + 1);
   82:         fputs("/-\\", stdout);
   83:         curx = u.ux + 2;
   84:         curs(u.ux - 1, u.uy + 2);
   85:         fputs(ulook, stdout);
   86:         curx = u.ux + 2;
   87:         curs(u.ux - 1, u.uy + 3);
   88:         fputs("\\-/", stdout);
   89:         curx = u.ux + 2;
   90:         u.udispl = 1;
   91:         u.udisx = u.ux;
   92:         u.udisy = u.uy;
   93: }
   94: 
   95: 
   96: /* VARARGS1 */
   97: boolean         panicking;
   98: 
   99: void
  100: panic(const char *fmt, ...)
  101: {
  102:         va_list ap;
  103: 
  104:         va_start(ap, fmt);
  105:         if (panicking++)
  106:                 exit(1);      /* avoid loops - this should never happen */
  107:         home();
  108:         puts(" Suddenly, the dungeon collapses.");
  109:         fputs(" ERROR:  ", stdout);
  110:         vprintf(fmt, ap);
  111:         va_end(ap);
  112: #ifdef DEBUG
  113: #ifdef UNIX
  114:         if (!fork())
  115:                 abort();      /* generate core dump */
  116: #endif  /* UNIX */
  117: #endif  /* DEBUG */
  118:         more();                        /* contains a fflush() */
  119:         done("panicked");
  120: }
  121: 
  122: void
  123: atl(x, y, ch)
  124: int x, y, ch;
  125: {
  126:         struct rm      *crm = &levl[x][y];
  127: 
  128:         if (x < 0 || x > COLNO - 1 || y < 0 || y > ROWNO - 1) {
  129:                 impossible("atl(%d,%d,%c)", x, y, ch);
  130:                 return;
  131:         }
  132:         if (crm->seen && crm->scrsym == ch)
  133:                 return;
  134:         crm->scrsym = ch;
  135:         crm->new = 1;
  136:         on_scr(x, y);
  137: }
  138: 
  139: void
  140: on_scr(x, y)
  141: int x, y;
  142: {
  143:         if (x < scrlx)
  144:                 scrlx = x;
  145:         if (x > scrhx)
  146:                 scrhx = x;
  147:         if (y < scrly)
  148:                 scrly = y;
  149:         if (y > scrhy)
  150:                 scrhy = y;
  151: }
  152: 
  153: /*
  154:  * call: (x,y) - display (-1,0) - close (leave last symbol) (-1,-1)- close
  155:  * (undo last symbol) (-1,let)-open: initialize symbol (-2,let)-change let
  156:  */
  157: 
  158: void
  159: tmp_at(x, y)
  160:         schar           x, y;
  161: {
  162:         static schar    prevx, prevy;
  163:         static char     let;
  164:         if ((int) x == -2) {   /* change let call */
  165:                 let = y;
  166:                 return;
  167:         }
  168:         if ((int) x == -1 && (int) y >= 0) {   /* open or close call */
  169:                 let = y;
  170:                 prevx = -1;
  171:                 return;
  172:         }
  173:         if (prevx >= 0 && cansee(prevx, prevy)) {
  174:                 delay_output();
  175:                 prl(prevx, prevy);    /* in case there was a monster */
  176:                 at(prevx, prevy, levl[prevx][prevy].scrsym);
  177:         }
  178:         if (x >= 0) {          /* normal call */
  179:                 if (cansee(x, y))
  180:                         at(x, y, let);
  181:                 prevx = x;
  182:                 prevy = y;
  183:         } else {               /* close call */
  184:                 let = 0;
  185:                 prevx = -1;
  186:         }
  187: }
  188: 
  189: /* like the previous, but the symbols are first erased on completion */
  190: void
  191: Tmp_at(x, y)
  192:         schar           x, y;
  193: {
  194:         static char     let;
  195:         static xchar    cnt;
  196:         static coord    tc[COLNO];     /* but watch reflecting beams! */
  197:         int xx, yy;
  198:         if ((int) x == -1) {
  199:                 if (y > 0) {  /* open call */
  200:                         let = y;
  201:                         cnt = 0;
  202:                         return;
  203:                 }
  204:                 /* close call (do not distinguish y==0 and y==-1) */
  205:                 while (cnt--) {
  206:                         xx = tc[cnt].x;
  207:                         yy = tc[cnt].y;
  208:                         prl(xx, yy);
  209:                         at(xx, yy, levl[xx][yy].scrsym);
  210:                 }
  211:                 cnt = let = 0;        /* superfluous */
  212:                 return;
  213:         }
  214:         if ((int) x == -2) {   /* change let call */
  215:                 let = y;
  216:                 return;
  217:         }
  218:         /* normal call */
  219:         if (cansee(x, y)) {
  220:                 if (cnt)
  221:                         delay_output();
  222:                 at(x, y, let);
  223:                 tc[cnt].x = x;
  224:                 tc[cnt].y = y;
  225:                 if (++cnt >= COLNO)
  226:                         panic("Tmp_at overflow?");
  227:                 levl[x][y].new = 0;   /* prevent pline-nscr erasing --- */
  228:         }
  229: }
  230: 
  231: void
  232: setclipped()
  233: {
  234:         error("Hack needs a screen of size at least %d by %d.\n",
  235:               ROWNO + 2, COLNO);
  236: }
  237: 
  238: void
  239: at(x, y, ch)
  240:         xchar           x, y;
  241:         char            ch;
  242: {
  243: #ifndef lint
  244:         /* if xchar is unsigned, lint will complain about  if(x < 0)  */
  245:         if (x < 0 || x > COLNO - 1 || y < 0 || y > ROWNO - 1) {
  246:                 impossible("At gets 0%o at %d %d.", ch, x, y);
  247:                 return;
  248:         }
  249: #endif  /* lint */
  250:         if (!ch) {
  251:                 impossible("At gets null at %d %d.", x, y);
  252:                 return;
  253:         }
  254:         y += 2;
  255:         curs(x, y);
  256:         (void) putchar(ch);
  257:         curx++;
  258: }
  259: 
  260: void
  261: prme()
  262: {
  263:         if (!Invisible)
  264:                 at(u.ux, u.uy, u.usym);
  265: }
  266: 
  267: int
  268: doredraw()
  269: {
  270:         docrt();
  271:         return (0);
  272: }
  273: 
  274: void
  275: docrt()
  276: {
  277:         int x, y;
  278:         struct rm      *room;
  279:         struct monst   *mtmp;
  280: 
  281:         if (u.uswallow) {
  282:                 swallowed();
  283:                 return;
  284:         }
  285:         cls();
  286: 
  287:         /*
  288:          * Some ridiculous code to get display of @ and monsters (almost)
  289:          * right
  290:          */
  291:         if (!Invisible) {
  292:                 levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
  293:                 levl[u.udisx][u.udisy].seen = 1;
  294:                 u.udispl = 1;
  295:         } else
  296:                 u.udispl = 0;
  297: 
  298:         seemons();             /* reset old positions */
  299:         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  300:                 mtmp->mdispl = 0;
  301:         seemons();             /* force new positions to be shown */
  302:         /*
  303:          * This nonsense should disappear soon
  304:          * ---------------------------------
  305:          */
  306: 
  307:         for (y = 0; y < ROWNO; y++)
  308:                 for (x = 0; x < COLNO; x++)
  309:                         if ((room = &levl[x][y])->new) {
  310:                                 room->new = 0;
  311:                                 at(x, y, room->scrsym);
  312:                         } else if (room->seen)
  313:                                 at(x, y, room->scrsym);
  314:         scrlx = COLNO;
  315:         scrly = ROWNO;
  316:         scrhx = scrhy = 0;
  317:         flags.botlx = 1;
  318:         bot();
  319: }
  320: 
  321: void
  322: docorner(xmin, ymax)
  323:         int xmin, ymax;
  324: {
  325:         int x, y;
  326:         struct rm      *room;
  327:         struct monst   *mtmp;
  328: 
  329:         if (u.uswallow) {      /* Can be done more efficiently */
  330:                 swallowed();
  331:                 return;
  332:         }
  333:         seemons();             /* reset old positions */
  334:         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  335:                 if (mtmp->mx >= xmin && mtmp->my < ymax)
  336:                         mtmp->mdispl = 0;
  337:         seemons();             /* force new positions to be shown */
  338: 
  339:         for (y = 0; y < ymax; y++) {
  340:                 if (y > ROWNO && CD)
  341:                         break;
  342:                 curs(xmin, y + 2);
  343:                 cl_end();
  344:                 if (y < ROWNO) {
  345:                         for (x = xmin; x < COLNO; x++) {
  346:                                 if ((room = &levl[x][y])->new) {
  347:                                         room->new = 0;
  348:                                         at(x, y, room->scrsym);
  349:                                 } else if (room->seen)
  350:                                         at(x, y, room->scrsym);
  351:                         }
  352:                 }
  353:         }
  354:         if (ymax > ROWNO) {
  355:                 cornbot(xmin - 1);
  356:                 if (ymax > ROWNO + 1 && CD) {
  357:                         curs(1, ROWNO + 3);
  358:                         cl_eos();
  359:                 }
  360:         }
  361: }
  362: 
  363: void
  364: curs_on_u()
  365: {
  366:         curs(u.ux, u.uy + 2);
  367: }
  368: 
  369: void
  370: pru()
  371: {
  372:         if (u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
  373:                 /* if(! levl[u.udisx][u.udisy].new) */
  374:                 if (!vism_at(u.udisx, u.udisy))
  375:                         newsym(u.udisx, u.udisy);
  376:         if (Invisible) {
  377:                 u.udispl = 0;
  378:                 prl(u.ux, u.uy);
  379:         } else if (!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
  380:                 atl(u.ux, u.uy, u.usym);
  381:                 u.udispl = 1;
  382:                 u.udisx = u.ux;
  383:                 u.udisy = u.uy;
  384:         }
  385:         levl[u.ux][u.uy].seen = 1;
  386: }
  387: 
  388: #ifndef NOWORM
  389: #include        "def.wseg.h"
  390: #endif  /* NOWORM */
  391: 
  392: /* print a position that is visible for @ */
  393: void
  394: prl(int x, int y)
  395: {
  396:         struct rm      *room;
  397:         struct monst   *mtmp;
  398:         struct obj     *otmp;
  399: 
  400:         if (x == u.ux && y == u.uy && (!Invisible)) {
  401:                 pru();
  402:                 return;
  403:         }
  404:         if (!isok(x, y))
  405:                 return;
  406:         room = &levl[x][y];
  407:         if ((!room->typ) ||
  408:             (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
  409:                 return;
  410:         if ((mtmp = m_at(x, y)) && !mtmp->mhide &&
  411:             (!mtmp->minvis || See_invisible)) {
  412: #ifndef NOWORM
  413:                 if (m_atseg)
  414:                         pwseg(m_atseg);
  415:                 else
  416: #endif  /* NOWORM */
  417:                         pmon(mtmp);
  418:         } else if ((otmp = o_at(x, y)) && room->typ != POOL)
  419:                 atl(x, y, otmp->olet);
  420:         else if (mtmp && (!mtmp->minvis || See_invisible)) {
  421:                 /* must be a hiding monster, but not hiding right now */
  422:                 /* assume for the moment that long worms do not hide */
  423:                 pmon(mtmp);
  424:         } else if (g_at(x, y) && room->typ != POOL)
  425:                 atl(x, y, '$');
  426:         else if (!room->seen || room->scrsym == ' ') {
  427:                 room->new = room->seen = 1;
  428:                 newsym(x, y);
  429:                 on_scr(x, y);
  430:         }
  431:         room->seen = 1;
  432: }
  433: 
  434: char
  435: news0(x, y)
  436:         xchar           x, y;
  437: {
  438:         struct obj     *otmp;
  439:         struct trap    *ttmp;
  440:         struct rm      *room;
  441:         char            tmp;
  442: 
  443:         room = &levl[x][y];
  444:         if (!room->seen)
  445:                 tmp = ' ';
  446:         else if (room->typ == POOL)
  447:                 tmp = POOL_SYM;
  448:         else if (!Blind && (otmp = o_at(x, y)))
  449:                 tmp = otmp->olet;
  450:         else if (!Blind && g_at(x, y))
  451:                 tmp = '$';
  452:         else if (x == xupstair && y == yupstair)
  453:                 tmp = '<';
  454:         else if (x == xdnstair && y == ydnstair)
  455:                 tmp = '>';
  456:         else if ((ttmp = t_at(x, y)) && ttmp->tseen)
  457:                 tmp = '^';
  458:         else
  459:                 switch (room->typ) {
  460:                 case SCORR:
  461:                 case SDOOR:
  462:                         tmp = room->scrsym;  /* %% wrong after killing
  463:                                                  * mimic ! */
  464:                         break;
  465:                 case HWALL:
  466:                         tmp = '-';
  467:                         break;
  468:                 case VWALL:
  469:                         tmp = '|';
  470:                         break;
  471:                 case LDOOR:
  472:                 case DOOR:
  473:                         tmp = '+';
  474:                         break;
  475:                 case CORR:
  476:                         tmp = CORR_SYM;
  477:                         break;
  478:                 case ROOM:
  479:                         if (room->lit || cansee(x, y) || Blind)
  480:                                 tmp = '.';
  481:                         else
  482:                                 tmp = ' ';
  483:                         break;
  484:                         /*
  485:                                 case POOL:
  486:                                         tmp = POOL_SYM;
  487:                                         break;
  488:                         */
  489:                 default:
  490:                         tmp = ERRCHAR;
  491:                 }
  492:         return (tmp);
  493: }
  494: 
  495: void
  496: newsym(x, y)
  497:         int x, y;
  498: {
  499:         atl(x, y, news0(x, y));
  500: }
  501: 
  502: /* used with wand of digging (or pick-axe): fill scrsym and force display */
  503: /* also when a POOL evaporates */
  504: void
  505: mnewsym(x, y)
  506:         int x, y;
  507: {
  508:         struct rm      *room;
  509:         char            newscrsym;
  510: 
  511:         if (!vism_at(x, y)) {
  512:                 room = &levl[x][y];
  513:                 newscrsym = news0(x, y);
  514:                 if (room->scrsym != newscrsym) {
  515:                         room->scrsym = newscrsym;
  516:                         room->seen = 0;
  517:                 }
  518:         }
  519: }
  520: 
  521: void
  522: nosee(x, y)
  523:         int x, y;
  524: {
  525:         struct rm      *room;
  526: 
  527:         if (!isok(x, y))
  528:                 return;
  529:         room = &levl[x][y];
  530:         if (room->scrsym == '.' && !room->lit && !Blind) {
  531:                 room->scrsym = ' ';
  532:                 room->new = 1;
  533:                 on_scr(x, y);
  534:         }
  535: }
  536: 
  537: #ifndef QUEST
  538: void
  539: prl1(x, y)
  540:         int x, y;
  541: {
  542:         if (u.dx) {
  543:                 if (u.dy) {
  544:                         prl(x - (2 * u.dx), y);
  545:                         prl(x - u.dx, y);
  546:                         prl(x, y);
  547:                         prl(x, y - u.dy);
  548:                         prl(x, y - (2 * u.dy));
  549:                 } else {
  550:                         prl(x, y - 1);
  551:                         prl(x, y);
  552:                         prl(x, y + 1);
  553:                 }
  554:         } else {
  555:                 prl(x - 1, y);
  556:                 prl(x, y);
  557:                 prl(x + 1, y);
  558:         }
  559: }
  560: 
  561: void
  562: nose1(x, y)
  563:         int x, y;
  564: {
  565:         if (u.dx) {
  566:                 if (u.dy) {