home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 1 / GoldFishApril1994_CD1.img / d1xx / d190 / nethack / een.zoo / vault.c < prev    next >
C/C++ Source or Header  |  1988-07-11  |  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.     RM_SET_TYP(*crm, EGD->fakecorr[fcbeg].ftyp);
  50.     if(!RM_TYP(*crm)) RM_CLR_SEEN(*crm);
  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(RM_TYP(levl[x][y]) == 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(RM_TYP(levl[x][y]) == 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 = RM_TYP(levl[x][y]);
  159.     RM_SET_TYP(levl[x][y], 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 = RM_TYP(*(crm = &levl[nx][ny]))) && 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.         RM_SET_TYP(*crm, (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 = RM_TYP(*(crm = &levl[nx][ny]))) != 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(RM_TYP(levl[nx+nx-x][ny+ny-y]))){
  214. #else
  215.         ZAP_POS(RM_TYP(levl[nx+nx-x][ny+ny-y]))){
  216. #endif
  217.         RM_SET_TYP(*crm, 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.     RM_SET_TYP(*crm, DOOR);
  230.     goto proceed;
  231.     }
  232.     RM_SET_TYP(*crm, 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.