home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 1 / src / pri.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-26  |  12.7 KB  |  661 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.pri.c - version 1.0.3 */
  3.  
  4. #include "hack.h"
  5. #include <stdio.h>
  6. xchar scrlx, scrhx, scrly, scrhy;    /* corners of new area on screen */
  7.  
  8. extern char *hu_stat[];    /* in eat.c */
  9. extern char *CD;
  10.  
  11. swallowed()
  12. {
  13.     char *ulook = "|@|";
  14.     ulook[1] = u.usym;
  15.  
  16.     cls();
  17.     curs(u.ux-1, u.uy+1);
  18.     fputs("/-\\", stdout);
  19.     curx = u.ux+2;
  20.     curs(u.ux-1, u.uy+2);
  21.     fputs(ulook, stdout);
  22.     curx = u.ux+2;
  23.     curs(u.ux-1, u.uy+3);
  24.     fputs("\\-/", stdout);
  25.     curx = u.ux+2;
  26.     u.udispl = 1;
  27.     u.udisx = u.ux;
  28.     u.udisy = u.uy;
  29. }
  30.  
  31.  
  32. /*VARARGS1*/
  33. boolean panicking;
  34.  
  35. panic(str,a1,a2,a3,a4,a5,a6)
  36. char *str;
  37. {
  38.     if(panicking++) exit(1);    /* avoid loops - this should never happen*/
  39.     home();
  40.     puts(" Suddenly, the dungeon collapses.");
  41.     fputs(" ERROR:  ", stdout);
  42.     printf(str,a1,a2,a3,a4,a5,a6);
  43. #ifdef DEBUG
  44. #ifdef UNIX
  45.     if(!fork())
  46.         abort();    /* generate core dump */
  47. #endif UNIX
  48. #endif DEBUG
  49.     more();            /* contains a fflush() */
  50.     done("panicked");
  51. }
  52.  
  53. atl(x,y,ch)
  54. register x,y;
  55. {
  56.     register struct rm *crm = &levl[x][y];
  57.  
  58.     if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
  59.         impossible("atl(%d,%d,%c)",x,y,ch);
  60.         return;
  61.     }
  62.     if(crm->seen && crm->scrsym == ch) return;
  63.     crm->scrsym = ch;
  64.     crm->new = 1;
  65.     on_scr(x,y);
  66. }
  67.  
  68. on_scr(x,y)
  69. register x,y;
  70. {
  71.     if(x < scrlx) scrlx = x;
  72.     if(x > scrhx) scrhx = x;
  73.     if(y < scrly) scrly = y;
  74.     if(y > scrhy) scrhy = y;
  75. }
  76.  
  77. /* call: (x,y) - display
  78.     (-1,0) - close (leave last symbol)
  79.     (-1,-1)- close (undo last symbol)
  80.     (-1,let)-open: initialize symbol
  81.     (-2,let)-change let
  82. */
  83.  
  84. tmp_at(x,y) schar x,y; {
  85. static schar prevx, prevy;
  86. static char let;
  87.     if((int)x == -2){    /* change let call */
  88.         let = y;
  89.         return;
  90.     }
  91.     if((int)x == -1 && (int)y >= 0){    /* open or close call */
  92.         let = y;
  93.         prevx = -1;
  94.         return;
  95.     }
  96.     if(prevx >= 0 && cansee(prevx,prevy)) {
  97.         delay_output();
  98.         prl(prevx, prevy);    /* in case there was a monster */
  99.         at(prevx, prevy, levl[prevx][prevy].scrsym);
  100.     }
  101.     if(x >= 0){    /* normal call */
  102.         if(cansee(x,y)) at(x,y,let);
  103.         prevx = x;
  104.         prevy = y;
  105.     } else {    /* close call */
  106.         let = 0;
  107.         prevx = -1;
  108.     }
  109. }
  110.  
  111. /* like the previous, but the symbols are first erased on completion */
  112. Tmp_at(x,y) schar x,y; {
  113. static char let;
  114. static xchar cnt;
  115. static coord tc[COLNO];        /* but watch reflecting beams! */
  116. register xx,yy;
  117.     if((int)x == -1) {
  118.         if(y > 0) {    /* open call */
  119.             let = y;
  120.             cnt = 0;
  121.             return;
  122.         }
  123.         /* close call (do not distinguish y==0 and y==-1) */
  124.         while(cnt--) {
  125.             xx = tc[cnt].x;
  126.             yy = tc[cnt].y;
  127.             prl(xx, yy);
  128.             at(xx, yy, levl[xx][yy].scrsym);
  129.         }
  130.         cnt = let = 0;    /* superfluous */
  131.         return;
  132.     }
  133.     if((int)x == -2) {    /* change let call */
  134.         let = y;
  135.         return;
  136.     }
  137.     /* normal call */
  138.     if(cansee(x,y)) {
  139.         if(cnt) delay_output();
  140.         at(x,y,let);
  141.         tc[cnt].x = x;
  142.         tc[cnt].y = y;
  143.         if(++cnt >= COLNO) panic("Tmp_at overflow?");
  144.         levl[x][y].new = 0;    /* prevent pline-nscr erasing --- */
  145.     }
  146. }
  147.  
  148. setclipped(){
  149.     error("Hack needs a screen of size at least %d by %d.\n",
  150.         ROWNO+2, COLNO);
  151. }
  152.  
  153. at(x,y,ch)
  154. register xchar x,y;
  155. char ch;
  156. {
  157. #ifndef lint
  158.     /* if xchar is unsigned, lint will complain about  if(x < 0)  */
  159.     if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
  160.         impossible("At gets 0%o at %d %d.", ch, x, y);
  161.         return;
  162.     }
  163. #endif lint
  164.     if(!ch) {
  165.         impossible("At gets null at %d %d.", x, y);
  166.         return;
  167.     }
  168.     y += 2;
  169.     curs(x,y);
  170.     (void) putchar(ch);
  171.     curx++;
  172. }
  173.  
  174. prme(){
  175.     if(!Invisible) at(u.ux,u.uy,u.usym);
  176. }
  177.  
  178. doredraw()
  179. {
  180.     docrt();
  181.     return(0);
  182. }
  183.  
  184. docrt()
  185. {
  186.     register x,y;
  187.     register struct rm *room;
  188.     register struct monst *mtmp;
  189.  
  190.     if(u.uswallow) {
  191.         swallowed();
  192.         return;
  193.     }
  194.     cls();
  195.  
  196. /* Some ridiculous code to get display of @ and monsters (almost) right */
  197.     if(!Invisible) {
  198.         levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
  199.         levl[u.udisx][u.udisy].seen = 1;
  200.         u.udispl = 1;
  201.     } else    u.udispl = 0;
  202.  
  203.     seemons();    /* reset old positions */
  204.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  205.         mtmp->mdispl = 0;
  206.     seemons();    /* force new positions to be shown */
  207. /* This nonsense should disappear soon --------------------------------- */
  208.  
  209.     for(y = 0; y < ROWNO; y++)
  210.         for(x = 0; x < COLNO; x++)
  211.             if((room = &levl[x][y])->new) {
  212.                 room->new = 0;
  213.                 at(x,y,room->scrsym);
  214.             } else if(room->seen)
  215.                 at(x,y,room->scrsym);
  216.     scrlx = COLNO;
  217.     scrly = ROWNO;
  218.     scrhx = scrhy = 0;
  219.     flags.botlx = 1;
  220.     bot();
  221. }
  222.  
  223. docorner(xmin,ymax) register xmin,ymax; {
  224.     register x,y;
  225.     register struct rm *room;
  226.     register struct monst *mtmp;
  227.  
  228.     if(u.uswallow) {    /* Can be done more efficiently */
  229.         swallowed();
  230.         return;
  231.     }
  232.  
  233.     seemons();    /* reset old positions */
  234.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  235.         if(mtmp->mx >= xmin && mtmp->my < ymax)
  236.         mtmp->mdispl = 0;
  237.     seemons();    /* force new positions to be shown */
  238.  
  239.     for(y = 0; y < ymax; y++) {
  240.         if(y > ROWNO && CD) break;
  241.         curs(xmin,y+2);
  242.         cl_end();
  243.         if(y < ROWNO) {
  244.             for(x = xmin; x < COLNO; x++) {
  245.             if((room = &levl[x][y])->new) {
  246.                 room->new = 0;
  247.                 at(x,y,room->scrsym);
  248.             } else
  249.                 if(room->seen)
  250.                     at(x,y,room->scrsym);
  251.             }
  252.         }
  253.     }
  254.     if(ymax > ROWNO) {
  255.         cornbot(xmin-1);
  256.         if(ymax > ROWNO+1 && CD) {
  257.             curs(1,ROWNO+3);
  258.             cl_eos();
  259.         }
  260.     }
  261. }
  262.  
  263. curs_on_u(){
  264.     curs(u.ux, u.uy+2);
  265. }
  266.  
  267. pru()
  268. {
  269.     if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
  270.         /* if(! levl[u.udisx][u.udisy].new) */
  271.             if(!vism_at(u.udisx, u.udisy))
  272.                 newsym(u.udisx, u.udisy);
  273.     if(Invisible) {
  274.         u.udispl = 0;
  275.         prl(u.ux,u.uy);
  276.     } else
  277.     if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
  278.         atl(u.ux, u.uy, u.usym);
  279.         u.udispl = 1;
  280.         u.udisx = u.ux;
  281.         u.udisy = u.uy;
  282.     }
  283.     levl[u.ux][u.uy].seen = 1;
  284. }
  285.  
  286. #ifndef NOWORM
  287. #include    "def.wseg.h"
  288. extern struct wseg *m_atseg;
  289. #endif NOWORM
  290.  
  291. /* print a position that is visible for @ */
  292. prl(x,y)
  293. {
  294.     register struct rm *room;
  295.     register struct monst *mtmp;
  296.     register struct obj *otmp;
  297.  
  298.     if(x == u.ux && y == u.uy && (!Invisible)) {
  299.         pru();
  300.         return;
  301.     }
  302.     if(!isok(x,y)) return;
  303.     room = &levl[x][y];
  304.     if((!room->typ) ||
  305.        (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
  306.         return;
  307.     if((mtmp = m_at(x,y)) && !mtmp->mhide &&
  308.         (!mtmp->minvis || See_invisible)) {
  309. #ifndef NOWORM
  310.         if(m_atseg)
  311.             pwseg(m_atseg);
  312.         else
  313. #endif NOWORM
  314.         pmon(mtmp);
  315.     }
  316.     else if((otmp = o_at(x,y)) && room->typ != POOL)
  317.         atl(x,y,otmp->olet);
  318.     else if(mtmp && (!mtmp->minvis || See_invisible)) {
  319.         /* must be a hiding monster, but not hiding right now */
  320.         /* assume for the moment that long worms do not hide */
  321.         pmon(mtmp);
  322.     }
  323.     else if(g_at(x,y) && room->typ != POOL)
  324.         atl(x,y,'$');
  325.     else if(!room->seen || room->scrsym == ' ') {
  326.         room->new = room->seen = 1;
  327.         newsym(x,y);
  328.         on_scr(x,y);
  329.     }
  330.     room->seen = 1;
  331. }
  332.  
  333. char
  334. news0(x,y)
  335. register xchar x,y;
  336. {
  337.     register struct obj *otmp;
  338.     register struct trap *ttmp;
  339.     struct rm *room;
  340.     register char tmp;
  341.  
  342.     room = &levl[x][y];
  343.     if(!room->seen) tmp = ' ';
  344.     else if(room->typ == POOL) tmp = POOL_SYM;
  345.     else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
  346.     else if(!Blind && g_at(x,y)) tmp = '$';
  347.     else if(x == xupstair && y == yupstair) tmp = '<';
  348.     else if(x == xdnstair && y == ydnstair) tmp = '>';
  349.     else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = '^';
  350.     else switch(room->typ) {
  351.     case SCORR:
  352.     case SDOOR:
  353.         tmp = room->scrsym;    /* %% wrong after killing mimic ! */
  354.         break;
  355.     case HWALL:
  356.         tmp = '-';
  357.         break;
  358.     case VWALL:
  359.         tmp = '|';
  360.         break;
  361.     case LDOOR:
  362.     case DOOR:
  363.         tmp = '+';
  364.         break;
  365.     case CORR:
  366.         tmp = CORR_SYM;
  367.         break;
  368.     case ROOM:
  369.         if(room->lit || cansee(x,y) || Blind) tmp = '.';
  370.         else tmp = ' ';
  371.         break;
  372. /*
  373.     case POOL:
  374.         tmp = POOL_SYM;
  375.         break;
  376. */
  377.     default:
  378.         tmp = ERRCHAR;
  379.     }
  380.     return(tmp);
  381. }
  382.  
  383. newsym(x,y)
  384. register x,y;
  385. {
  386.     atl(x,y,news0(x,y));
  387. }
  388.  
  389. /* used with wand of digging (or pick-axe): fill scrsym and force display */
  390. /* also when a POOL evaporates */
  391. mnewsym(x,y)
  392. register x,y;
  393. {
  394.     register struct rm *room;
  395.     char newscrsym;
  396.  
  397.     if(!vism_at(x,y)) {
  398.         room = &levl[x][y];
  399.         newscrsym = news0(x,y);
  400.         if(room->scrsym != newscrsym) {
  401.             room->scrsym = newscrsym;
  402.             room->seen = 0;
  403.         }
  404.     }
  405. }
  406.  
  407. nosee(x,y)
  408. register x,y;
  409. {
  410.     register struct rm *room;
  411.  
  412.     if(!isok(x,y)) return;
  413.     room = &levl[x][y];
  414.     if(room->scrsym == '.' && !room->lit && !Blind) {
  415.         room->scrsym = ' ';
  416.         room->new = 1;
  417.         on_scr(x,y);
  418.     }
  419. }
  420.  
  421. #ifndef QUEST
  422. prl1(x,y)
  423. register x,y;
  424. {
  425.     if(u.dx) {
  426.         if(u.dy) {
  427.             prl(x-(2*u.dx),y);
  428.             prl(x-u.dx,y);
  429.             prl(x,y);
  430.             prl(x,y-u.dy);
  431.             prl(x,y-(2*u.dy));
  432.         } else {
  433.             prl(x,y-1);
  434.             prl(x,y);
  435.             prl(x,y+1);
  436.         }
  437.     } else {
  438.         prl(x-1,y);
  439.         prl(x,y);
  440.         prl(x+1,y);
  441.     }
  442. }
  443.  
  444. nose1(x,y)
  445. register x,y;
  446. {
  447.     if(u.dx) {
  448.         if(u.dy) {
  449.             nosee(x,u.uy);
  450.             nosee(x,u.uy-u.dy);
  451.             nosee(x,y);
  452.             nosee(u.ux-u.dx,y);
  453.             nosee(u.ux,y);
  454.         } else {
  455.             nosee(x,y-1);
  456.             nosee(x,y);
  457.             nosee(x,y+1);
  458.         }
  459.     } else {
  460.         nosee(x-1,y);
  461.         nosee(x,y);
  462.         nosee(x+1,y);
  463.     }
  464. }
  465. #endif QUEST
  466.  
  467. vism_at(x,y)
  468. register x,y;
  469. {
  470.     register struct monst *mtmp;
  471.  
  472.     return((x == u.ux && y == u.uy && !Invisible)
  473.             ? 1 :
  474.            (mtmp = m_at(x,y))
  475.             ? ((Blind && Telepat) || canseemon(mtmp)) :
  476.         0);
  477. }
  478.  
  479. #ifdef NEWSCR
  480. pobj(obj) register struct obj *obj; {
  481. register int show = (!obj->oinvis || See_invisible) &&
  482.         cansee(obj->ox,obj->oy);
  483.     if(obj->odispl){
  484.         if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
  485.         if(!vism_at(obj->odx,obj->ody)){
  486.             newsym(obj->odx, obj->ody);
  487.             obj->odispl = 0;
  488.         }
  489.     }
  490.     if(show && !vism_at(obj->ox,obj->oy)){
  491.         atl(obj->ox,obj->oy,obj->olet);
  492.         obj->odispl = 1;
  493.         obj->odx = obj->ox;
  494.         obj->ody = obj->oy;
  495.     }
  496. }
  497. #endif NEWSCR
  498.  
  499. unpobj(obj) register struct obj *obj; {
  500. /*     if(obj->odispl){
  501.         if(!vism_at(obj->odx, obj->ody))
  502.             newsym(obj->odx, obj->ody);
  503.         obj->odispl = 0;
  504.     }
  505. */
  506.     if(!vism_at(obj->ox,obj->oy))
  507.         newsym(obj->ox,obj->oy);
  508. }
  509.  
  510. seeobjs(){
  511. register struct obj *obj, *obj2;
  512.     for(obj = fobj; obj; obj = obj2) {
  513.         obj2 = obj->nobj;
  514.         if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
  515.             && obj->age + 250 < moves)
  516.                 delobj(obj);
  517.     }
  518.     for(obj = invent; obj; obj = obj2) {
  519.         obj2 = obj->nobj;
  520.         if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
  521.             && obj->age + 250 < moves)
  522.                 useup(obj);
  523.     }
  524. }
  525.  
  526. seemons(){
  527. register struct monst *mtmp;
  528.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
  529.         if(mtmp->data->mlet == ';')
  530.             mtmp->minvis = (u.ustuck != mtmp &&
  531.                     levl[mtmp->mx][mtmp->my].typ == POOL);
  532.         pmon(mtmp);
  533. #ifndef NOWORM
  534.         if(mtmp->wormno) wormsee(mtmp->wormno);
  535. #endif NOWORM
  536.     }
  537. }
  538.  
  539. pmon(mon) register struct monst *mon; {
  540. register int show = (Blind && Telepat) || canseemon(mon);
  541.     if(mon->mdispl){
  542.         if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
  543.             unpmon(mon);
  544.     }
  545.     if(show && !mon->mdispl){
  546.         atl(mon->mx,mon->my,
  547.          (!mon->mappearance
  548.           || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS)].p_flgs
  549.          ) ? mon->data->mlet : mon->mappearance);
  550.         mon->mdispl = 1;
  551.         mon->mdx = mon->mx;
  552.         mon->mdy = mon->my;
  553.     }
  554. }
  555.  
  556. unpmon(mon) register struct monst *mon; {
  557.     if(mon->mdispl){
  558.         newsym(mon->mdx, mon->mdy);
  559.         mon->mdispl = 0;
  560.     }
  561. }
  562.  
  563. nscr()
  564. {
  565.     register x,y;
  566.     register struct rm *room;
  567.  
  568.     if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
  569.     pru();
  570.     for(y = scrly; y <= scrhy; y++)
  571.         for(x = scrlx; x <= scrhx; x++)
  572.             if((room = &levl[x][y])->new) {
  573.                 room->new = 0;
  574.                 at(x,y,room->scrsym);
  575.             }
  576.     scrhx = scrhy = 0;
  577.     scrlx = COLNO;
  578.     scrly = ROWNO;
  579. }
  580.  
  581. /* 100 suffices for bot(); no relation with COLNO */
  582. char oldbot[100], newbot[100];
  583. cornbot(lth)
  584. register int lth;
  585. {
  586.     if(lth < sizeof(oldbot)) {
  587.         oldbot[lth] = 0;
  588.         flags.botl = 1;
  589.     }
  590. }
  591.  
  592. bot()
  593. {
  594. register char *ob = oldbot, *nb = newbot;
  595. register int i;
  596. extern char *eos();
  597.     if(flags.botlx) *ob = 0;
  598.     flags.botl = flags.botlx = 0;
  599. #ifdef GOLD_ON_BOTL
  600.     (void) sprintf(newbot,
  601.         "Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Str ",
  602.         dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
  603. #else
  604.     (void) sprintf(newbot,
  605.         "Level %-2d   Hp %3d(%d)   Ac %-2d   Str ",
  606.         dlevel,  u.uhp, u.uhpmax, u.uac);
  607. #endif GOLD_ON_BOTL
  608.     if(u.ustr>18) {
  609.         if(u.ustr>117)
  610.         (void) strcat(newbot,"18/**");
  611.         else
  612.         (void) sprintf(eos(newbot), "18/%02d",u.ustr-18);
  613.     } else
  614.         (void) sprintf(eos(newbot), "%-2d   ",u.ustr);
  615. #ifdef EXP_ON_BOTL
  616.     (void) sprintf(eos(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
  617. #else
  618.     (void) sprintf(eos(newbot), "   Exp %2u  ", u.ulevel);
  619. #endif EXP_ON_BOTL
  620.     (void) strcat(newbot, hu_stat[u.uhs]);
  621.     if(flags.time)
  622.         (void) sprintf(eos(newbot), "  %ld", moves);
  623.     if(strlen(newbot) >= COLNO) {
  624.         register char *bp0, *bp1;
  625.         bp0 = bp1 = newbot;
  626.         do {
  627.             if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
  628.                 *bp1++ = *bp0;
  629.         } while(*bp0++);
  630.     }
  631.     for(i = 1; i<COLNO; i++) {
  632.         if(*ob != *nb){
  633.             curs(i,ROWNO+2);
  634.             (void) putchar(*nb ? *nb : ' ');
  635.             curx++;
  636.         }
  637.         if(*ob) ob++;
  638.         if(*nb) nb++;
  639.     }
  640.     (void) strcpy(oldbot, newbot);
  641. }
  642.  
  643. #ifdef WAN_PROBING
  644. mstatusline(mtmp) register struct monst *mtmp; {
  645.     pline("Status of %s: ", monnam(mtmp));
  646.     pline("Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Dam %d",
  647.         mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax,
  648.         mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
  649. }
  650. #endif WAN_PROBING
  651.  
  652. cls(){
  653.     if(flags.toplin == 1)
  654.         more();
  655.     flags.toplin = 0;
  656.  
  657.     clear_screen();
  658.  
  659.     flags.botlx = 1;
  660. }
  661.