home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / misc / 40 / zap1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-07-17  |  6.8 KB  |  288 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* zap.c - version 1.0.3 */
  3.  
  4. #include "hack.h"
  5.  
  6. extern struct obj *mkobj_at();
  7. extern struct monst *makemon(), *mkmon_at(), youmonst;
  8. struct monst *bhit();
  9. char *exclam();
  10.  
  11. char *fl[]= {
  12.     "magic missile",
  13.     "bolt of fire",
  14.     "sleep ray",
  15.     "bolt of cold",
  16.     "death ray"
  17. };
  18.  
  19. /* Routines for IMMEDIATE wands. */
  20. /* bhitm: monster mtmp was hit by the effect of wand otmp */
  21. bhitm(mtmp, otmp)
  22. register struct monst *mtmp;
  23. register struct obj *otmp;
  24. {
  25.     wakeup(mtmp);
  26.     switch(otmp->otyp) {
  27.     case WAN_STRIKING:
  28.         if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
  29.             register int tmp = d(2,12);
  30.             hit("wand", mtmp, exclam(tmp));
  31.             mtmp->mhp -= tmp;
  32.             if(mtmp->mhp < 1) killed(mtmp);
  33.         } else miss("wand", mtmp);
  34.         break;
  35.     case WAN_SLOW_MONSTER:
  36.         mtmp->mspeed = MSLOW;
  37.         break;
  38.     case WAN_SPEED_MONSTER:
  39.         mtmp->mspeed = MFAST;
  40.         break;
  41.     case WAN_UNDEAD_TURNING:
  42.         if(index(UNDEAD,mtmp->data->mlet)) {
  43.             mtmp->mhp -= rnd(8);
  44.             if(mtmp->mhp < 1) killed(mtmp);
  45.             else mtmp->mflee = 1;
  46.         }
  47.         break;
  48.     case WAN_POLYMORPH:
  49.         if( newcham(mtmp,&mons[rn2(CMNUM)]) )
  50.             objects[otmp->otyp].oc_name_known = 1;
  51.         break;
  52.     case WAN_CANCELLATION:
  53.         mtmp->mcan = 1;
  54.         break;
  55.     case WAN_TELEPORTATION:
  56.         rloc(mtmp);
  57.         break;
  58.     case WAN_MAKE_INVISIBLE:
  59.         mtmp->minvis = 1;
  60.         break;
  61. #ifdef WAN_PROBING
  62.     case WAN_PROBING:
  63.         mstatusline(mtmp);
  64.         break;
  65. #endif WAN_PROBING
  66.     default:
  67.         impossible("What an interesting wand (%u)", otmp->otyp);
  68.     }
  69. }
  70.  
  71. bhito(obj, otmp)    /* object obj was hit by the effect of wand otmp */
  72. register struct obj *obj, *otmp;    /* returns TRUE if sth was done */
  73. {
  74.     register int res = TRUE;
  75.  
  76.     if(obj == uball || obj == uchain)
  77.         res = FALSE;
  78.     else
  79.     switch(otmp->otyp) {
  80.     case WAN_POLYMORPH:
  81.         /* preserve symbol and quantity, but turn rocks into gems */
  82.         mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
  83.             ? GEM_SYM : obj->olet,
  84.             obj->ox, obj->oy) -> quan = obj->quan;
  85.         delobj(obj);
  86.         break;
  87.     case WAN_STRIKING:
  88.         if(obj->otyp == ENORMOUS_ROCK)
  89.             fracture_rock(obj);
  90.         else
  91.             res = FALSE;
  92.         break;
  93.     case WAN_CANCELLATION:
  94.         if(obj->spe && obj->olet != AMULET_SYM) {
  95.             obj->known = 0;
  96.             obj->spe = 0;
  97.         }
  98.         break;
  99.     case WAN_TELEPORTATION:
  100.         rloco(obj);
  101.         break;
  102.     case WAN_MAKE_INVISIBLE:
  103.         obj->oinvis = 1;
  104.         break;
  105.     case WAN_UNDEAD_TURNING:
  106.         res = revive(obj);
  107.         break;
  108.     case WAN_SLOW_MONSTER:        /* no effect on objects */
  109.     case WAN_SPEED_MONSTER:
  110. #ifdef WAN_PROBING
  111.     case WAN_PROBING:
  112. #endif WAN_PROBING
  113.         res = FALSE;
  114.         break;
  115.     default:
  116.         impossible("What an interesting wand (%u)", otmp->otyp);
  117.     }
  118.     return(res);
  119. }
  120.  
  121. dozap()
  122. {
  123.     register struct obj *obj;
  124.     xchar zx,zy;
  125.  
  126.     obj = getobj("/", "zap");
  127.     if(!obj) return(0);
  128.     if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
  129.         pline("Nothing Happens.");
  130.         return(1);
  131.     }
  132.     if(obj->spe == 0)
  133.         pline("You wrest one more spell from the worn-out wand.");
  134.     if(!(objects[obj->otyp].bits & NODIR) && !getdir(1))
  135.         return(1);    /* make him pay for knowing !NODIR */
  136.     obj->spe--;
  137.     if(objects[obj->otyp].bits & IMMEDIATE) {
  138.         if(u.uswallow)
  139.             bhitm(u.ustuck, obj);
  140.         else if(u.dz) {
  141.             if(u.dz > 0) {
  142.                 register struct obj *otmp = o_at(u.ux, u.uy);
  143.                 if(otmp)
  144.                     (void) bhito(otmp, obj);
  145.             }
  146.         } else
  147.             (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
  148.     } else {
  149.         switch(obj->otyp){
  150.         case WAN_LIGHT:
  151.             litroom(TRUE);
  152.             break;
  153.         case WAN_SECRET_DOOR_DETECTION:
  154.             if(!findit()) return(1);
  155.             break;
  156.         case WAN_CREATE_MONSTER:
  157.             { register int cnt = 1;
  158.             if(!rn2(23)) cnt += rn2(7) + 1;
  159.             while(cnt--)
  160.                 (void) makemon((struct permonst *) 0, u.ux, u.uy);
  161.             }
  162.             break;
  163.         case WAN_WISHING:
  164.             { char buf[BUFSZ];
  165.               register struct obj *otmp;
  166.               extern struct obj *readobjnam(), *addinv();
  167.               if(u.uluck + rn2(5) < 0) {
  168.             pline("Unfortunately, nothing happens.");
  169.             break;
  170.               }
  171.               pline("You may wish for an object. What do you want? ");
  172.               getlin(buf);
  173.               if(buf[0] == '\033') buf[0] = 0;
  174.               otmp = readobjnam(buf);
  175.               otmp = addinv(otmp);
  176.               prinv(otmp);
  177.               break;
  178.             }
  179.         case WAN_DIGGING:
  180.             /* Original effect (approximately):
  181.              * from CORR: dig until we pierce a wall
  182.              * from ROOM: piece wall and dig until we reach
  183.              * an ACCESSIBLE place.
  184.              * Currently: dig for digdepth positions;
  185.              * also down on request of Lennart Augustsson.
  186.              */
  187.             { register struct rm *room;
  188.               register int digdepth;
  189.             if(u.uswallow) {
  190.                 register struct monst *mtmp = u.ustuck;
  191.  
  192.                 pline("You pierce %s's stomach wall!",
  193.                     mon_nam(mtmp));
  194.                 mtmp->mhp = 1;    /* almost dead */
  195.                 unstuck(mtmp);
  196.                 mnexto(mtmp);
  197.                 break;
  198.             }
  199.             if(u.dz) {
  200.                 if(u.dz < 0) {
  201.                 pline("You loosen a rock from the ceiling.");
  202.                 pline("It falls on your head!");
  203.                 losehp(1, "falling rock");
  204.                 mksobj_at(ROCK, u.ux, u.uy);
  205.                 fobj->quan = 1;
  206.                 stackobj(fobj);
  207.                 if(Invisible) newsym(u.ux, u.uy);
  208.                 } else {
  209.                 dighole();
  210.                 }
  211.                 break;
  212.             }
  213.             zx = u.ux+u.dx;
  214.             zy = u.uy+u.dy;
  215.             digdepth = 8 + rn2(18);
  216.             Tmp_at2(-1, '*');    /* open call */
  217.             while(--digdepth >= 0) {
  218.                 if(!isok(zx,zy)) break;
  219.                 room = &levl[zx][zy];
  220.                 Tmp_at2(zx,zy);
  221.                 if(!xdnstair){
  222.                     if(zx < 3 || zx > COLNO-3 ||
  223.                         zy < 3 || zy > ROWNO-3)
  224.                         break;
  225.                     if(room->typ == HWALL ||
  226.                         room->typ == VWALL){
  227.                         room->typ = ROOM;
  228.                         break;
  229.                     }
  230.                 } else
  231.                 if(room->typ == HWALL || room->typ == VWALL ||
  232.                    room->typ == SDOOR || room->typ == LDOOR){
  233.                     room->typ = DOOR;
  234.                     digdepth -= 2;
  235.                 } else
  236.                 if(room->typ == SCORR || !room->typ) {
  237.                     room->typ = CORR;
  238.                     digdepth--;
  239.                 }
  240.                 mnewsym(zx,zy);
  241.                 zx += u.dx;
  242.                 zy += u.dy;
  243.             }
  244.             mnewsym(zx,zy);    /* not always necessary */
  245.             Tmp_at2(-1,-1);    /* closing call */
  246.             break;
  247.             }
  248.         default:
  249.             buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
  250.                 u.ux, u.uy, u.dx, u.dy);
  251.             break;
  252.         }
  253.         if(!objects[obj->otyp].oc_name_known) {
  254.             objects[obj->otyp].oc_name_known = 1;
  255.             more_experienced(0,10);
  256.         }
  257.     }
  258.     return(1);
  259. }
  260.  
  261. char *
  262. exclam(force)
  263. register int force;
  264. {
  265.     /* force == 0 occurs e.g. with sleep ray */
  266.     /* note that large force is usual with wands so that !! would
  267.         require information about hand/weapon/wand */
  268.     return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
  269. }
  270.  
  271. hit(str,mtmp,force)
  272. register char *str;
  273. register struct monst *mtmp;
  274. register char *force;        /* usually either "." or "!" */
  275. {
  276.     if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str);
  277.     else pline("The %s hits %s%s", str, mon_nam(mtmp), force);
  278. }
  279.  
  280. miss(str,mtmp)
  281. register char *str;
  282. register struct monst *mtmp;
  283. {
  284.     if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str);
  285.     else pline("The %s misses %s.",str,mon_nam(mtmp));
  286. }
  287.  
  288.