home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- /* zap.c - version 1.0.3 */
-
- #include "hack.h"
-
- extern struct obj *mkobj_at();
- extern struct monst *makemon(), *mkmon_at(), youmonst;
- struct monst *bhit();
- char *exclam();
-
- char *fl[]= {
- "magic missile",
- "bolt of fire",
- "sleep ray",
- "bolt of cold",
- "death ray"
- };
-
- /* Routines for IMMEDIATE wands. */
- /* bhitm: monster mtmp was hit by the effect of wand otmp */
- bhitm(mtmp, otmp)
- register struct monst *mtmp;
- register struct obj *otmp;
- {
- wakeup(mtmp);
- switch(otmp->otyp) {
- case WAN_STRIKING:
- if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
- register int tmp = d(2,12);
- hit("wand", mtmp, exclam(tmp));
- mtmp->mhp -= tmp;
- if(mtmp->mhp < 1) killed(mtmp);
- } else miss("wand", mtmp);
- break;
- case WAN_SLOW_MONSTER:
- mtmp->mspeed = MSLOW;
- break;
- case WAN_SPEED_MONSTER:
- mtmp->mspeed = MFAST;
- break;
- case WAN_UNDEAD_TURNING:
- if(index(UNDEAD,mtmp->data->mlet)) {
- mtmp->mhp -= rnd(8);
- if(mtmp->mhp < 1) killed(mtmp);
- else mtmp->mflee = 1;
- }
- break;
- case WAN_POLYMORPH:
- if( newcham(mtmp,&mons[rn2(CMNUM)]) )
- objects[otmp->otyp].oc_name_known = 1;
- break;
- case WAN_CANCELLATION:
- mtmp->mcan = 1;
- break;
- case WAN_TELEPORTATION:
- rloc(mtmp);
- break;
- case WAN_MAKE_INVISIBLE:
- mtmp->minvis = 1;
- break;
- #ifdef WAN_PROBING
- case WAN_PROBING:
- mstatusline(mtmp);
- break;
- #endif WAN_PROBING
- default:
- impossible("What an interesting wand (%u)", otmp->otyp);
- }
- }
-
- bhito(obj, otmp) /* object obj was hit by the effect of wand otmp */
- register struct obj *obj, *otmp; /* returns TRUE if sth was done */
- {
- register int res = TRUE;
-
- if(obj == uball || obj == uchain)
- res = FALSE;
- else
- switch(otmp->otyp) {
- case WAN_POLYMORPH:
- /* preserve symbol and quantity, but turn rocks into gems */
- mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
- ? GEM_SYM : obj->olet,
- obj->ox, obj->oy) -> quan = obj->quan;
- delobj(obj);
- break;
- case WAN_STRIKING:
- if(obj->otyp == ENORMOUS_ROCK)
- fracture_rock(obj);
- else
- res = FALSE;
- break;
- case WAN_CANCELLATION:
- if(obj->spe && obj->olet != AMULET_SYM) {
- obj->known = 0;
- obj->spe = 0;
- }
- break;
- case WAN_TELEPORTATION:
- rloco(obj);
- break;
- case WAN_MAKE_INVISIBLE:
- obj->oinvis = 1;
- break;
- case WAN_UNDEAD_TURNING:
- res = revive(obj);
- break;
- case WAN_SLOW_MONSTER: /* no effect on objects */
- case WAN_SPEED_MONSTER:
- #ifdef WAN_PROBING
- case WAN_PROBING:
- #endif WAN_PROBING
- res = FALSE;
- break;
- default:
- impossible("What an interesting wand (%u)", otmp->otyp);
- }
- return(res);
- }
-
- dozap()
- {
- register struct obj *obj;
- xchar zx,zy;
-
- obj = getobj("/", "zap");
- if(!obj) return(0);
- if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
- pline("Nothing Happens.");
- return(1);
- }
- if(obj->spe == 0)
- pline("You wrest one more spell from the worn-out wand.");
- if(!(objects[obj->otyp].bits & NODIR) && !getdir(1))
- return(1); /* make him pay for knowing !NODIR */
- obj->spe--;
- if(objects[obj->otyp].bits & IMMEDIATE) {
- if(u.uswallow)
- bhitm(u.ustuck, obj);
- else if(u.dz) {
- if(u.dz > 0) {
- register struct obj *otmp = o_at(u.ux, u.uy);
- if(otmp)
- (void) bhito(otmp, obj);
- }
- } else
- (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
- } else {
- switch(obj->otyp){
- case WAN_LIGHT:
- litroom(TRUE);
- break;
- case WAN_SECRET_DOOR_DETECTION:
- if(!findit()) return(1);
- break;
- case WAN_CREATE_MONSTER:
- { register int cnt = 1;
- if(!rn2(23)) cnt += rn2(7) + 1;
- while(cnt--)
- (void) makemon((struct permonst *) 0, u.ux, u.uy);
- }
- break;
- case WAN_WISHING:
- { char buf[BUFSZ];
- register struct obj *otmp;
- extern struct obj *readobjnam(), *addinv();
- if(u.uluck + rn2(5) < 0) {
- pline("Unfortunately, nothing happens.");
- break;
- }
- pline("You may wish for an object. What do you want? ");
- getlin(buf);
- if(buf[0] == '\033') buf[0] = 0;
- otmp = readobjnam(buf);
- otmp = addinv(otmp);
- prinv(otmp);
- break;
- }
- case WAN_DIGGING:
- /* Original effect (approximately):
- * from CORR: dig until we pierce a wall
- * from ROOM: piece wall and dig until we reach
- * an ACCESSIBLE place.
- * Currently: dig for digdepth positions;
- * also down on request of Lennart Augustsson.
- */
- { register struct rm *room;
- register int digdepth;
- if(u.uswallow) {
- register struct monst *mtmp = u.ustuck;
-
- pline("You pierce %s's stomach wall!",
- mon_nam(mtmp));
- mtmp->mhp = 1; /* almost dead */
- unstuck(mtmp);
- mnexto(mtmp);
- break;
- }
- if(u.dz) {
- if(u.dz < 0) {
- pline("You loosen a rock from the ceiling.");
- pline("It falls on your head!");
- losehp(1, "falling rock");
- mksobj_at(ROCK, u.ux, u.uy);
- fobj->quan = 1;
- stackobj(fobj);
- if(Invisible) newsym(u.ux, u.uy);
- } else {
- dighole();
- }
- break;
- }
- zx = u.ux+u.dx;
- zy = u.uy+u.dy;
- digdepth = 8 + rn2(18);
- Tmp_at2(-1, '*'); /* open call */
- while(--digdepth >= 0) {
- if(!isok(zx,zy)) break;
- room = &levl[zx][zy];
- Tmp_at2(zx,zy);
- if(!xdnstair){
- if(zx < 3 || zx > COLNO-3 ||
- zy < 3 || zy > ROWNO-3)
- break;
- if(room->typ == HWALL ||
- room->typ == VWALL){
- room->typ = ROOM;
- break;
- }
- } else
- if(room->typ == HWALL || room->typ == VWALL ||
- room->typ == SDOOR || room->typ == LDOOR){
- room->typ = DOOR;
- digdepth -= 2;
- } else
- if(room->typ == SCORR || !room->typ) {
- room->typ = CORR;
- digdepth--;
- }
- mnewsym(zx,zy);
- zx += u.dx;
- zy += u.dy;
- }
- mnewsym(zx,zy); /* not always necessary */
- Tmp_at2(-1,-1); /* closing call */
- break;
- }
- default:
- buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
- u.ux, u.uy, u.dx, u.dy);
- break;
- }
- if(!objects[obj->otyp].oc_name_known) {
- objects[obj->otyp].oc_name_known = 1;
- more_experienced(0,10);
- }
- }
- return(1);
- }
-
- char *
- exclam(force)
- register int force;
- {
- /* force == 0 occurs e.g. with sleep ray */
- /* note that large force is usual with wands so that !! would
- require information about hand/weapon/wand */
- return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
- }
-
- hit(str,mtmp,force)
- register char *str;
- register struct monst *mtmp;
- register char *force; /* usually either "." or "!" */
- {
- if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str);
- else pline("The %s hits %s%s", str, mon_nam(mtmp), force);
- }
-
- miss(str,mtmp)
- register char *str;
- register struct monst *mtmp;
- {
- if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str);
- else pline("The %s misses %s.",str,mon_nam(mtmp));
- }
-
-