home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / nethack2.3 / part12 / vault.c < prev    next >
C/C++ Source or Header  |  1988-10-17  |  6KB  |  264 lines

  1. /*    SCCS Id: @(#)vault.c    2.1    87/10/17
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include    "hack.h"
  5. #ifdef QUEST
  6. setgd(/* mtmp */) /* struct monst *mtmp; */ {}
  7. gd_move() { return(2); }
  8. gddead(mtmp) struct monst *mtmp; {}
  9. replgd(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
  10. invault(){}
  11.  
  12. #else
  13.  
  14.  
  15. #include "mkroom.h"
  16. extern struct monst *makemon();
  17. #define    FCSIZ    (ROWNO+COLNO)
  18. struct fakecorridor {
  19.     xchar fx,fy,ftyp;
  20. };
  21.  
  22. struct egd {
  23.     int fcbeg, fcend;    /* fcend: first unused pos */
  24.     xchar gdx, gdy;        /* goal of guard's walk */
  25.     unsigned gddone:1;
  26.     struct fakecorridor fakecorr[FCSIZ];
  27. };
  28.  
  29. struct permonst pm_guard =
  30.     { "guard", '@', 12, 12, -1, 40, 4, 10, sizeof(struct egd) };
  31.  
  32. static struct monst *guard;
  33. static int gdlevel;
  34. #define    EGD    ((struct egd *)(&(guard->mextra[0])))
  35.  
  36. static
  37. restfakecorr()
  38. {
  39.     register fcx,fcy,fcbeg;
  40.     register struct rm *crm;
  41.  
  42.     while((fcbeg = EGD->fcbeg) < EGD->fcend) {
  43.         fcx = EGD->fakecorr[fcbeg].fx;
  44.         fcy = EGD->fakecorr[fcbeg].fy;
  45.         if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
  46.            m_at(fcx,fcy))
  47.             return;
  48.         crm = &levl[fcx][fcy];
  49.         crm->typ = EGD->fakecorr[fcbeg].ftyp;
  50.         if(!crm->typ) crm->seen = 0;
  51.         newsym(fcx,fcy);
  52.         EGD->fcbeg++;
  53.     }
  54.     /* it seems he left the corridor - let the guard disappear */
  55.     mondead(guard);
  56.     guard = 0;
  57. }
  58.  
  59. static
  60. goldincorridor()
  61. {
  62.     register int fci;
  63.  
  64.     for(fci = EGD->fcbeg; fci < EGD->fcend; fci++)
  65.         if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
  66.             return(1);
  67.     return(0);
  68. }
  69.  
  70. setgd(){
  71. register struct monst *mtmp;
  72.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
  73.         guard = mtmp;
  74.         gdlevel = dlevel;
  75.         return;
  76.     }
  77.     guard = 0;
  78. }
  79.  
  80. invault(){
  81. register tmp = inroom(u.ux, u.uy);
  82.     if(tmp < 0 || rooms[tmp].rtype != VAULT) {
  83.     u.uinvault = 0;
  84.     return;
  85.     }
  86.     if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
  87.     char buf[BUFSZ];
  88.     register x,y,dd,gx,gy;
  89.  
  90.     /* first find the goal for the guard */
  91.     for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
  92.       for(y = u.uy-dd; y <= u.uy+dd; y++) {
  93.         if(y < 0 || y > ROWNO-1) continue;
  94.         for(x = u.ux-dd; x <= u.ux+dd; x++) {
  95.           if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
  96.         x = u.ux+dd;
  97.           if(x < 0 || x > COLNO-1) continue;
  98.           if(levl[x][y].typ == CORR) goto fnd;
  99.         }
  100.       }
  101.     }
  102.     impossible("Not a single corridor on this level??");
  103.     tele();
  104.     return;
  105. fnd:
  106.     gx = x; gy = y;
  107.  
  108.     /* next find a good place for a door in the wall */
  109.     x = u.ux; y = u.uy;
  110.     while(levl[x][y].typ == ROOM) {
  111.         register int dx,dy;
  112.  
  113.         dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  114.         dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  115.         if(abs(gx-x) >= abs(gy-y))
  116.             x += dx;
  117.         else
  118.             y += dy;
  119.     }
  120.  
  121.     /* make something interesting happen */
  122.     if(!(guard = makemon(&pm_guard,x,y))) return;
  123.     guard->isgd = guard->mpeaceful = 1;
  124.     EGD->gddone = 0;
  125.     gdlevel = dlevel;
  126.     if(!cansee(guard->mx, guard->my)) {
  127.         mondead(guard);
  128.         guard = 0;
  129.         return;
  130.     }
  131.  
  132.     pline("Suddenly one of the Vault's guards enters!");
  133.     pmon(guard);
  134.     do {
  135.         pline("\"Hello stranger, who are you?\" - ");
  136.         getlin(buf);
  137.     } while (!letter(buf[0]));
  138.  
  139.     if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
  140.         pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
  141.         mondead(guard);
  142.         guard = 0;
  143.         return;
  144.     }
  145.     clrlin();
  146.     pline("\"I don't know you.\"");
  147.     if(!u.ugold)
  148.         pline("\"Please follow me.\"");
  149.     else {
  150.         pline("\"Most likely all that gold was stolen from this vault.\"");
  151.         pline("\"Please drop your gold (say d$ ) and follow me.\"");
  152.     }
  153.     EGD->gdx = gx;
  154.     EGD->gdy = gy;
  155.     EGD->fcbeg = 0;
  156.     EGD->fakecorr[0].fx = x;
  157.     EGD->fakecorr[0].fy = y;
  158.     EGD->fakecorr[0].ftyp = levl[x][y].typ;
  159.     levl[x][y].typ = DOOR;
  160.     EGD->fcend = 1;
  161.     }
  162. }
  163.  
  164. gd_move(){
  165. register int x,y,dx,dy,gx,gy,nx,ny,typ;
  166. register struct fakecorridor *fcp;
  167. register struct rm *crm;
  168.     if(!guard || gdlevel != dlevel){
  169.         impossible("Where is the guard?");
  170.         return(2);    /* died */
  171.     }
  172.     if(u.ugold || goldincorridor())
  173.         return(0);    /* didnt move */
  174.     if(dist(guard->mx,guard->my) > 1 || EGD->gddone) {
  175.         restfakecorr();
  176.         return(0);    /* didnt move */
  177.     }
  178.     x = guard->mx;
  179.     y = guard->my;
  180.     /* look around (hor & vert only) for accessible places */
  181.     for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
  182.         if(nx == x || ny == y) if(nx != x || ny != y)
  183.         if(isok(nx,ny))
  184.         if(!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
  185.         register int i;
  186.         for(i = EGD->fcbeg; i < EGD->fcend; i++)
  187.             if(EGD->fakecorr[i].fx == nx &&
  188.                EGD->fakecorr[i].fy == ny)
  189.                 goto nextnxy;
  190.         if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
  191.             goto nextnxy;
  192.         /* seems we found a good place to leave him alone */
  193.         EGD->gddone = 1;
  194.         if(ACCESSIBLE(typ)) goto newpos;
  195.         crm->typ = (typ == SCORR) ? CORR : DOOR;
  196.         goto proceed;
  197.         }
  198.     nextnxy:    ;
  199.     }
  200.     nx = x;
  201.     ny = y;
  202.     gx = EGD->gdx;
  203.     gy = EGD->gdy;
  204.     dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  205.     dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  206.     if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
  207.  
  208.     while((typ = (crm = &levl[nx][ny])->typ) != 0) {
  209.     /* in view of the above we must have IS_WALL(typ) or typ == POOL */
  210.     /* must be a wall here */
  211.         if(isok(nx+nx-x,ny+ny-y) && typ != POOL &&
  212. #ifdef RPH
  213.             SPACE_POS(levl[nx+nx-x][ny+ny-y].typ)){
  214. #else
  215.             ZAP_POS(levl[nx+nx-x][ny+ny-y].typ)){
  216. #endif
  217.             crm->typ = DOOR;
  218.             goto proceed;
  219.         }
  220.         if(dy && nx != x) {
  221.             nx = x; ny = y+dy;
  222.             continue;
  223.         }
  224.         if(dx && ny != y) {
  225.             ny = y; nx = x+dx; dy = 0;
  226.             continue;
  227.         }
  228.         /* I don't like this, but ... */
  229.         crm->typ = DOOR;
  230.         goto proceed;
  231.     }
  232.     crm->typ = CORR;
  233. proceed:
  234.     if(cansee(nx,ny)) {
  235.         mnewsym(nx,ny);
  236.         prl(nx,ny);
  237.     }
  238.     fcp = &(EGD->fakecorr[EGD->fcend]);
  239.     if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
  240.     fcp->fx = nx;
  241.     fcp->fy = ny;
  242.     fcp->ftyp = typ;
  243. newpos:
  244.     if(EGD->gddone) nx = ny = 0;
  245.     guard->mx = nx;
  246.     guard->my = ny;
  247.     pmon(guard);
  248.     restfakecorr();
  249.     return(1);
  250. }
  251.  
  252. gddead(){
  253.     guard = 0;
  254. }
  255.  
  256. replgd(mtmp,mtmp2)
  257. register struct monst *mtmp, *mtmp2;
  258. {
  259.     if(mtmp == guard)
  260.         guard = mtmp2;
  261. }
  262.  
  263. #endif /* QUEST /**/
  264.