This is apply.c in view mode; [Download] [Up]
/* SCCS Id: @(#)apply.c 3.0 88/10/24 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ #define MONATTK_H /* comment line for pre-compiled headers */ /* block some unused #defines to avoid overloading some cpp's */ #include "hack.h" #include "edog.h" #ifdef MUSIC #define IS_INSTRUMENT(typ) ((typ) >= FLUTE && (typ) <= DRUM_OF_EARTHQUAKE) #endif /* MUSIC /**/ #ifdef OVLB static const char tools[] = { TOOL_SYM, 0 }; static boolean did_dig_msg; static struct monst *FDECL(bchit, (int, int, int, CHAR_P)); static void FDECL(use_camera, (struct obj *)); static void FDECL(use_stethoscope, (struct obj *)); static void FDECL(use_whistle, (struct obj *)); static void FDECL(use_magic_whistle, (struct obj *)); #ifdef WALKIES static void FDECL(use_leash, (struct obj *)); #endif OSTATIC int NDECL(dig); static boolean FDECL(wield_tool, (struct obj *)); static int FDECL(use_pick_axe, (struct obj *)); #ifdef MEDUSA static void FDECL(use_mirror, (struct obj *)); #endif static void FDECL(use_lamp, (struct obj *)); static void FDECL(use_crystal_ball, (struct obj *)); static void FDECL(use_tinning_kit, (struct obj *)); /* version of bhit for cameras and mirrors */ static struct monst * bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; { register struct monst *mtmp = (struct monst *) 0; register int bchx = u.ux, bchy = u.uy; if(sym) { Tmp_at2(-1, sym); /* open call */ #ifdef TEXTCOLOR Tmp_at2(-3, WHITE); #endif } while(range--) { bchx += ddx; bchy += ddy; if(MON_AT(bchx, bchy)) { mtmp = m_at(bchx,bchy); break; } if(!ZAP_POS(levl[bchx][bchy].typ) || closed_door(bchx, bchy)) { bchx -= ddx; bchy -= ddy; break; } if(sym) Tmp_at2(bchx, bchy); } if(sym) Tmp_at2(-1, -1); return(mtmp); } static void use_camera(obj) /* register */ struct obj *obj; { register struct monst *mtmp; if(!getdir(1)){ /* ask: in what direction? */ flags.move = multi = 0; return; } if(u.uswallow) { You("take a picture of %s's %s.", mon_nam(u.ustuck), is_animal(u.ustuck->data)? "stomach" : "interior"); return; } if(obj->cursed && !rn2(2)) goto blindu; if(u.dz) { You("take a picture of the %s.", (u.dz > 0) ? "floor" : "ceiling"); return; } if(!u.dx && !u.dy && !u.dz) { blindu: if(!Blind) { You("are blinded by the flash!"); make_blinded((long)rnd(25),FALSE); } return; } if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) { if(mtmp->msleep){ mtmp->msleep = 0; pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */ } else if(mtmp->data->mlet != S_YLIGHT) if(mtmp->mcansee || mtmp->mblinded){ register int tmp = dist(mtmp->mx,mtmp->my); register int tmp2; if(cansee(mtmp->mx,mtmp->my)) pline("%s is blinded by the flash!", Monnam(mtmp)); if(mtmp->data == &mons[PM_GREMLIN]) { /* Rule #1: Keep them out of the light. */ kludge("%s cries out in pain!", Monnam(mtmp)); if (mtmp->mhp > 1) mtmp->mhp--; } setmangry(mtmp); if(tmp < 9 && !mtmp->isshk && rn2(4)) { mtmp->mflee = 1; if(rn2(4)) mtmp->mfleetim = rnd(100); } if(tmp < 3) { mtmp->mcansee = 0; mtmp->mblinded = 0; } else { tmp2 = mtmp->mblinded; tmp2 += rnd(1 + 50/tmp); if(tmp2 > 127) tmp2 = 127; mtmp->mblinded = tmp2; mtmp->mcansee = 0; } } } } /* Strictly speaking it makes no sense for usage of a stethoscope to not take any time; however, unless it did, the stethoscope would be almost useless. */ static void use_stethoscope(obj) register struct obj *obj; { register struct monst *mtmp; register struct rm *lev; register int rx, ry; if(!freehand()) { You("have no free %s!", body_part(HAND)); return; } if (!getdir(1)) { flags.move=multi=0; return; } if(u.dz < 0 || (u.dz && Levitation)) { You("can't reach the %s!", u.dz<0 ? "ceiling" : "floor"); return; } if(obj->cursed && !rn2(2)) { You("hear your heart beat."); return; } if(u.dz) { #ifdef STRONGHOLD if (dlevel == stronghold_level) You("hear the crackling of hellfire."); else #endif pline("The floor seems healthy enough."); return; } if (Stunned || (Confusion && !rn2(5))) confdir(); if (!u.dx && !u.dy && !u.dz) { ustatusline(); return; } rx = u.ux + u.dx; ry = u.uy + u.dy; if(u.uswallow) { mstatusline(u.ustuck); return; } if (!isok(rx,ry)) { You("hear a faint typing noise."); return; } lev = &levl[rx][ry]; if(MON_AT(rx, ry)) { mtmp = m_at(rx,ry); mstatusline(mtmp); if (mtmp->mundetected) { mtmp->mundetected = 0; if (cansee(rx,ry)) pmon(mtmp); } return; } if(lev->typ == SDOOR) { You("hear a hollow sound! This must be a secret door!"); lev->typ = DOOR; lev->seen = 0; /* force prl */ prl(rx,ry); return; } if(lev->typ == SCORR) { You("hear a hollow sound! This must be a secret passage!"); lev->typ = CORR; lev->seen = 0; /* force prl */ prl(rx,ry); return; } You("hear nothing special."); } /* ARGSUSED */ static void use_whistle(obj) struct obj *obj; { You("produce a high whistling sound."); wake_nearby(); } static void use_magic_whistle(obj) struct obj *obj; { register struct monst *mtmp = fmon; if(obj->cursed && !rn2(2)) { You("produce a high-pitched humming noise."); wake_nearby(); } else { You("produce a %s whistling sound.", Hallucination ? "normal" : "strange"); while(mtmp) { if(mtmp->mtame) mnexto(mtmp); mtmp = mtmp->nmon; } } } boolean um_dist(x,y,n) register xchar x, y, n; { return(abs(u.ux - x) > n || abs(u.uy - y) > n); } #endif /* OVLB */ #ifdef WALKIES #define MAXLEASHED 2 #ifdef OVLB int number_leashed() { register int i = 0; register struct obj *obj; for(obj = invent; obj; obj = obj->nobj) if(obj->otyp == LEASH && obj->leashmon != 0) i++; return(i); } void o_unleash(otmp) /* otmp is about to be destroyed or stolen */ register struct obj *otmp; { register struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->m_id == (unsigned)otmp->leashmon) mtmp->mleashed = 0; otmp->leashmon = 0; } void m_unleash(mtmp) /* mtmp is about to die, or become untame */ register struct monst *mtmp; { register struct obj *otmp; for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id) otmp->leashmon = 0; mtmp->mleashed = 0; } void unleash_all() /* player is about to die (for bones) */ { register struct obj *otmp; register struct monst *mtmp; for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp->otyp == LEASH) otmp->leashmon = 0; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->mtame) mtmp->mleashed = 0; } /* ARGSUSED */ static void use_leash(obj) struct obj *obj; { register int x, y; register struct monst *mtmp; if(!obj->leashmon && number_leashed() >= MAXLEASHED) { You("can't leash additional pets."); return; } if(!getdir(1)) return; x = u.ux + u.dx; y = u.uy + u.dy; if((x == u.ux) && (y == u.uy)) { pline("Leash yourself? Very funny..."); return; } if(!MON_AT(x, y)) { pline("There is no creature here."); return; } mtmp = m_at(x, y); if(!mtmp->mtame) { pline("%s is not %s!", Monnam(mtmp), (!obj->leashmon) ? "leashable" : "leashed"); return; } if(!obj->leashmon) { if(mtmp->mleashed) { pline("This %s is already leashed!", lmonnam(mtmp)+4); return; } You("slip the leash around your %s.", lmonnam(mtmp)+4); mtmp->mleashed = 1; obj->leashmon = (int)mtmp->m_id; if(mtmp->msleep) mtmp->msleep = 0; return; } if(obj->leashmon != (int)mtmp->m_id) { pline("This leash is not attached to that creature!"); return; } else { if(obj->cursed) { pline("The leash wouldn't come off!"); return; } mtmp->mleashed = 0; obj->leashmon = 0; You("remove the leash from your %s.", /* a hack to include the dogs full name. +4 eliminates */ /* the 'the' at the start of the name */ lmonnam(mtmp)+4); } return; } boolean next_to_u() { register struct monst *mtmp; register struct obj *otmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->mleashed) { if(dist(mtmp->mx,mtmp->my) > 2) mnexto(mtmp); if(dist(mtmp->mx,mtmp->my) > 2) { for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id) { if(otmp->cursed) return(FALSE); You("feel %s leash go slack.", (number_leashed() > 1) ? "a" : "the"); mtmp->mleashed = 0; otmp->leashmon = 0; } } } return(TRUE); } struct obj * get_mleash(mtmp) /* assuming mtmp->mleashed has been checked */ register struct monst *mtmp; { register struct obj *otmp; otmp = invent; while(otmp) { if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id) return(otmp); otmp = otmp->nobj; } return((struct obj *)0); } #endif /* WALKIES */ #endif /* OVLB */ #ifdef OVL0 #ifdef WALKIES void check_leash(x, y) register xchar x, y; { register struct obj *otmp; register struct monst *mtmp = fmon; for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp->otyp == LEASH && otmp->leashmon != 0) { while(mtmp) { if((int)mtmp->m_id == otmp->leashmon && (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) > dist2(x,y,mtmp->mx,mtmp->my)) ) { if(otmp->cursed) { if(um_dist(mtmp->mx, mtmp->my, 5)) { pline("%s chokes to death!",Monnam(mtmp)); mondied(mtmp); } else if(um_dist(mtmp->mx, mtmp->my, 3)) pline("%s chokes on the leash!", Monnam(mtmp)); } else { if(um_dist(mtmp->mx, mtmp->my, 5)) { pline("%s's leash snaps loose!",Monnam(mtmp)); m_unleash(mtmp); } else { if(um_dist(mtmp->mx, mtmp->my, 3)) { You("pull on the leash."); # ifdef SOUNDS if (mtmp->data->msound != MS_SILENT) switch(rn2(3)) { case 0: growl(mtmp); break; case 1: yelp(mtmp); break; default: whimper(mtmp); break; } # endif } } } } mtmp = mtmp->nmon; } } } #endif /* WALKIES */ #endif /* OVL0 */ #ifdef OVLB XSTATIC int dig() { register struct rm *lev; register int dpx = dig_pos.x, dpy = dig_pos.y; lev = &levl[dpx][dpy]; /* perhaps a nymph stole his pick-axe while he was busy digging */ /* or perhaps he teleported away */ if(u.uswallow || !uwep || uwep->otyp != PICK_AXE || dig_level != dlevel || ((dig_down && (dpx != u.ux || dpy != u.uy)) || (!dig_down && dist(dpx,dpy) > 2))) return(0); if(dig_down && is_maze_lev) { pline("The floor here is too hard to dig in."); return(0); } if(!dig_down && IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) { pline("This wall is too hard to dig into."); return(0); } if(Fumbling && !rn2(3)) { switch(rn2(3)) { case 0: if(!welded(uwep)) { You("fumble and drop your %s.", xname(uwep)); dropx(uwep); setuwep((struct obj *)0); } else { pline("Ouch! Your %s bounces and hits you!", xname(uwep)); set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); } break; case 1: pline("Bang! You hit with the broad side of the %s!", xname(uwep)); break; default: Your("swing misses its mark."); break; } return(0); } dig_effort += 10 + abon() + uwep->spe + rn2(5); if(dig_down) { if(dig_effort > 250) { dighole(); dig_level = -1; return(0); /* done with digging */ } if(dig_effort > 50) { register struct trap *ttmp = t_at(dpx,dpy); if(!ttmp) { ttmp = maketrap(dpx,dpy,PIT); ttmp->tseen = 1; if(Invisible) newsym(ttmp->tx,ttmp->ty); You("have dug a pit."); u.utrap = rn1(4,2); u.utraptype = TT_PIT; dig_level = -1; return(0); } } } else if(dig_effort > 100) { register const char *digtxt; register struct obj *obj; if(obj = sobj_at(STATUE, dpx, dpy)) { if (break_statue(obj)) digtxt = "The statue shatters."; else /* it was a statue trap; break_statue() * printed a message and updated the screen */ digtxt = NULL; } else if(obj = sobj_at(BOULDER, dpx, dpy)) { fracture_rock(obj); digtxt = "The boulder falls apart."; } else if(!lev->typ || lev->typ == SCORR) { lev->typ = CORR; digtxt = "You succeeded in cutting away some rock."; } else if(IS_WALL(lev->typ)) { #ifdef STUPID if (is_maze_lev) lev->typ = ROOM; else lev->typ = DOOR; #else lev->typ = is_maze_lev ? ROOM : DOOR; #endif digtxt = "You just made an opening in the wall."; } else if(lev->typ == SDOOR) { lev->typ = DOOR; digtxt = "You just broke through a secret door."; if(!(lev->doormask & D_TRAPPED)) lev->doormask = D_BROKEN; } else if(closed_door(dpx, dpy)) { digtxt = "You just broke a hole through the door."; if(!(lev->doormask & D_TRAPPED)) lev->doormask = D_BROKEN; } else return(0); /* statue or boulder got taken */ mnewsym(dpx, dpy); prl(dpx, dpy); if (digtxt) pline(digtxt); /* after mnewsym & prl */ if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) { b_trapped("door"); lev->doormask = D_NODOOR; mnewsym(dpx, dpy); prl(dpx, dpy); } dig_level = -1; return(0); } else { if(IS_WALL(lev->typ) || closed_door(dpx, dpy)) { register int rno = inroom(dpx,dpy); if(rno >= 0 && rooms[rno].rtype >= SHOPBASE) { pline("This %s seems too hard to dig into.", IS_DOOR(lev->typ) ? "door" : "wall"); return(0); } } else if (!IS_ROCK(lev->typ) && !sobj_at(STATUE, dpx, dpy) && !sobj_at(BOULDER, dpx, dpy)) return(0); /* statue or boulder got taken */ if(!did_dig_msg) { You("hit the %s with all your might.", sobj_at(STATUE, dpx, dpy) ? "statue" : sobj_at(BOULDER, dpx, dpy) ? "boulder" : IS_DOOR(lev->typ) ? "door" : "rock"); did_dig_msg = TRUE; } } return(1); } /* When will hole be finished? Very rough indication used by shopkeeper. */ int holetime() { if(occupation != dig || !in_shop(u.ux, u.uy)) return(-1); return((250 - dig_effort)/20); } void dighole() { register struct trap *ttmp = t_at(u.ux, u.uy); if(is_maze_lev #ifdef ENDGAME || dlevel == ENDLEVEL #endif ) { pline("The floor here seems too hard to dig in."); } else { if(IS_FURNITURE(levl[u.ux][u.uy].typ)) { #if defined(ALTARS) && defined(THEOLOGY) if(IS_ALTAR(levl[u.ux][u.uy].typ)) { altar_wrath(u.ux, u.uy); if(in_temple(u.ux, u.uy)) angry_priest(); } #endif levl[u.ux][u.uy].typ = ROOM; levl[u.ux][u.uy].altarmask = 0; } if(ttmp) ttmp->ttyp = TRAPDOOR; else ttmp = maketrap(u.ux, u.uy, TRAPDOOR); ttmp->tseen = 1; if(Invisible) newsym(ttmp->tx,ttmp->ty); pline("You've made a hole in the floor."); if(!u.ustuck && !Levitation) { /* KAA */ if(in_shop(u.ux, u.uy)) shopdig(1); #ifdef WALKIES if(!next_to_u()) You("are jerked back by your pet!"); else { #endif You("fall through..."); if(u.utraptype == TT_PIT) { u.utrap = 0; u.utraptype = 0; } unsee(); goto_level(dlevel+1, FALSE, TRUE); #ifdef WALKIES } #endif } } } static boolean wield_tool(obj) struct obj *obj; { if(uwep && uwep->cursed) { /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */ if(flags.verbose) { pline("Since your weapon is welded to your %s,", bimanual(uwep) ? makeplural(body_part(HAND)) : body_part(HAND)); pline("you cannot wield that %s.", xname(obj)); } return(FALSE); } # ifdef POLYSELF if(cantwield(uasmon)) { You("can't hold it strongly enough."); return(FALSE); } # endif unweapon = TRUE; You("now wield %s.", doname(obj)); setuwep(obj); if (uwep != obj) return(FALSE); /* rewielded old object after dying */ return(TRUE); } static int use_pick_axe(obj) struct obj *obj; { char dirsyms[12]; register char *dsp = dirsyms; register const char *sdp = flags.num_pad ? ndir : sdir; register struct rm *lev; register int rx, ry, res = 0; register boolean isclosedoor = FALSE; if(obj != uwep) if (!wield_tool(obj)) return(0); else res = 1; while(*sdp) { (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */ rx = u.ux + u.dx; ry = u.uy + u.dy; if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) && (IS_ROCK(levl[rx][ry].typ) || sobj_at(STATUE, rx, ry) || sobj_at(BOULDER, rx, ry)))) *dsp++ = *sdp; sdp++; } *dsp = 0; pline("In what direction do you want to dig? [%s] ", dirsyms); if(!getdir(0)) /* no txt */ return(res); if(u.uswallow && attack(u.ustuck)) /* return(1) */; else if(u.dz < 0) You("cannot reach the ceiling."); else if(!u.dx && !u.dy && !u.dz) { char buf[BUFSZ]; int dam; dam = rnd(2) + dbon() + obj->spe; if (dam <= 0) dam = 1; You("hit yourself with your own pick-axe."); /* self_pronoun() won't work twice in a sentence */ Strcpy(buf, self_pronoun("killed %sself with %%s own pick-axe", "him")); losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX); flags.botl=1; return(1); } else if(u.dz == 0) { if(Stunned || (Confusion && !rn2(5))) confdir(); rx = u.ux + u.dx; ry = u.uy + u.dy; lev = &levl[rx][ry]; if(MON_AT(rx, ry) && attack(m_at(rx, ry))) return(1); if(!isok(rx, ry)) { pline("Clash!"); return(1); } isclosedoor = closed_door(rx, ry); if(!IS_ROCK(lev->typ) && !isclosedoor && !sobj_at(STATUE, rx, ry) && !sobj_at(BOULDER, rx, ry)) { /* ACCESSIBLE or POOL */ You("swing your %s through thin air.", aobjnam(obj, NULL)); } else { if(dig_pos.x != rx || dig_pos.y != ry || dig_level != dlevel || dig_down) { dig_down = FALSE; dig_pos.x = rx; dig_pos.y = ry; dig_level = dlevel; dig_effort = 0; You("start %s.", sobj_at(STATUE, rx, ry) ? "chipping the statue" : sobj_at(BOULDER, rx, ry) ? "hitting the boulder" : isclosedoor ? "chopping at the door" : "digging"); } else You("continue %s.", sobj_at(STATUE, rx, ry) ? "chipping the statue" : sobj_at(BOULDER, rx, ry) ? "hitting the boulder" : isclosedoor ? "chopping at the door" : "digging"); did_dig_msg = FALSE; set_occupation(dig, "digging", 0); } } else if(Levitation) { You("cannot reach the floor."); } else { if(dig_pos.x != u.ux || dig_pos.y != u.uy || dig_level != dlevel || !dig_down) { dig_down = TRUE; dig_pos.x = u.ux; dig_pos.y = u.uy; dig_level = dlevel; dig_effort = 0; You("start digging in the floor."); if(in_shop(u.ux, u.uy)) shopdig(0); } else You("continue digging in the floor."); did_dig_msg = FALSE; set_occupation(dig, "digging", 0); } return(1); } #define WEAK 3 /* from eat.c */ #ifdef MEDUSA static void use_mirror(obj) struct obj *obj; { register struct monst *mtmp; register char mlet; if(!getdir(1)){ /* ask: in what direction? */ flags.move = multi = 0; return; } if(obj->cursed && !rn2(2)) { if (!Blind) pline("The mirror gets foggy and doesn't reflect!"); return; } if(!u.dx && !u.dy && !u.dz) { if(!Blind && !Invisible) { #ifdef POLYSELF if(u.umonnum == PM_FLOATING_EYE) { pline("Yikes! You've frozen yourself!"); nomul(-rnd((MAXULEV+6) - (int)u.ulevel)); } else if (u.usym == S_VAMPIRE || u.usym == S_DEMON) You("don't seem to reflect anything."); else if(u.umonnum == PM_UMBER_HULK) { pline("Huh? That doesn't look like you!"); make_confused(HConfusion + d(3,4),FALSE); } else #endif if (Hallucination) You("look %s.", hcolor()); else if (Sick) You("look peaked."); else if (u.uhs >= WEAK) You("look undernourished."); #ifdef POLYSELF else if (u.usym == S_NYMPH #ifdef INFERNO || u.umonnum==PM_SUCCUBUS #endif ) You("look beautiful in the mirror."); #ifdef INFERNO else if (u.umonnum == PM_INCUBUS) You("look handsome in the mirror."); #endif #endif else You("look as %s as ever.", ACURR(A_CHA) > 14 ? (poly_gender()==1 ? "beautiful" : "handsome") : "ugly"); } else { if (Luck <= 10 && rn2(4-Luck/3) || !HTelepat || (u.ukilled_medusa #ifdef HARD && u.udemigod #endif )) { You("can't see your %s %s.", ACURR(A_CHA) > 14 ? (poly_gender()==1 ? "beautiful" : "handsome") : "ugly", body_part(FACE)); } else { static char buf[35]; const char *tm, *tl; int ll; if (!u.ukilled_medusa && rn2(4)) { tm = "n ugly snake-headed monster"; ll = dlevel - medusa_level; } else { tm = " powerful wizard"; ll = dlevel - wiz_level; } if (ll < -10) tl = "far below you"; else if (ll < -1) tl = "below you"; else if (ll == -1) { Sprintf(buf, "under your %s", makeplural( body_part(FOOT))); tl = buf; } else if (ll == 0) tl = "very close to you"; else if (ll == 1) { Sprintf(buf, "above your %s", body_part(HEAD)); tl = buf; } else if (ll > 10) tl = "far above you"; else tl = "above you"; You("get an impression that a%s lives %s.", tm, tl); } } return; } if(u.uswallow) { You("reflect %s's %s.", mon_nam(u.ustuck), is_animal(u.ustuck->data)? "stomach" : "interior"); return; } if(u.dz) { You("reflect the %s.", (u.dz > 0) ? "floor" : "ceiling"); return; } if(!(mtmp = bchit(u.dx, u.dy, COLNO, 0)) || !haseyes(mtmp->data)) return; mlet = mtmp->data->mlet; if(mtmp->msleep) { if(!Blind) pline ("%s is tired and doesn't look at your mirror.", Monnam(mtmp)); mtmp->msleep = 0; } else if (!mtmp->mcansee) { if (!Blind) pline("%s can't see anything at the moment.", Monnam(mtmp)); /* some monsters do special things */ } else if (mlet == S_VAMPIRE || mlet == S_DEMON || mlet == S_GHOST || (mtmp->minvis && !perceives(mtmp->data) && !See_invisible)) { if (!Blind) pline ("%s doesn't seem to reflect anything.", Monnam(mtmp)); } else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) { if (!Blind) pline("%s is turned to stone!", Monnam(mtmp)); stoned = TRUE; killed(mtmp); } else if(!mtmp->mcan && !mtmp->minvis && mtmp->data == &mons[PM_FLOATING_EYE]) { int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd); if (!rn2(4)) tmp = 120; /* Note: floating eyes cannot use their abilities while invisible, * but medusas and umber hulks can. */ if (!Blind) pline("%s is frozen by its reflection.",Monnam(mtmp)); mtmp->mcanmove = 0; if (mtmp->mfrozen + tmp > 127) mtmp->mfrozen = 127; else mtmp->mfrozen += tmp; } else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) { if (!Blind) pline ("%s has confused itself!", Monnam(mtmp)); mtmp->mconf = 1; } else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH #ifdef INFERNO || mtmp->data==&mons[PM_SUCCUBUS] #endif )) { if (!Blind) { pline ("%s looks beautiful in your mirror.",Monnam(mtmp)); pline ("She decides to take it!"); } else pline ("It steals your mirror!"); setnotworn(obj); /* in case mirror was wielded */ freeinv(obj); mpickobj(mtmp,obj); rloc(mtmp); } else if (mlet != S_UNICORN && !humanoid(mtmp->data) && (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) { if (!Blind) pline ("%s is frightened by its reflection%s.", Monnam(mtmp), (mtmp->minvis && !See_invisible && !Telepat) ? ", though you see nothing" : ""); mtmp->mflee = 1; mtmp->mfleetim += d(2,4); } else if (!Blind) { if (mtmp->minvis && !See_invisible) pline("%s doesn't seem to reflect anything.", Monnam(mtmp)); else if (mtmp->minvis && !perceives(mtmp->data)) pline("%s doesn't seem to be aware of its reflection.", Monnam(mtmp)); else pline("%s doesn't seem to mind %s reflection.", Monnam(mtmp), (is_female(mtmp) ? "her" : is_human(mtmp->data) ? "his" : "its")); } }/* use_mirror */ #endif static void use_lamp(obj) struct obj *obj; { if(obj->spe <= 0 || obj->otyp == MAGIC_LAMP ) { pline("This lamp has no oil."); return; } if(obj->cursed && !rn2(2)) pline("The lamp flickers on for a moment and dies."); else litroom(TRUE); obj->spe -= 1; } static void use_crystal_ball(obj) struct obj *obj; { char buf[BUFSZ]; int oops, ret; if (Blind) { pline("Too bad you can't see the crystal ball."); return; } oops = (rnd(20) > ACURR(A_INT) || obj->cursed); if (oops && (obj->spe > 0)) { switch(rnd(5)) { case 1 : pline("The crystal ball is too much to comprehend!"); break; case 2 : pline("The crystal ball confuses you!"); make_confused(HConfusion + rnd(100),FALSE); break; case 3 : pline("The crystal ball damages your vision!"); make_blinded(Blinded + rnd(100),FALSE); break; case 4 : pline("The crystal ball zaps your mind!"); make_hallucinated(Hallucination + rnd(100),FALSE); break; case 5 : pline("The crystal ball explodes!"); useup(obj); losehp(rnd(30), "exploding crystal ball", KILLED_BY_AN); break; } obj->spe -= 1; return; } pline("What do you want to look for? "); getlin(buf); clrlin(); if (!buf[0] || buf[0] == '\033') { if(flags.verbose) pline("Never mind."); return; } You("peer into the crystal ball."); nomul(-rnd(10)); nomovemsg = ""; if(obj->spe <= 0) pline("The vision is unclear."); else { obj->spe -= 1; switch(buf[0]) { case GOLD_SYM : ret = gold_detect((struct obj *)0); break; case '^' : ret = trap_detect((struct obj *)0); break; case FOOD_SYM : ret = food_detect((struct obj *)0); break; case POTION_SYM : case GEM_SYM : case TOOL_SYM : case WEAPON_SYM : case WAND_SYM : case SCROLL_SYM : #ifdef SPELLS case SPBOOK_SYM : #endif case ARMOR_SYM : ret = object_detect((struct obj *)0); break; default : lcase(buf); if (!strncmp(buf,"gold",4) || !strncmp(buf,"money",5)) ret = gold_detect((struct obj *)0); else if (!strncmp(buf,"trap",4)) ret = trap_detect((struct obj *)0); else if (!strncmp(buf,"food",4) || !strncmp(buf,"dead",4) || !strncmp(buf,"corpse",6)) ret = food_detect((struct obj *)0); else if (!strncmp(buf,"obj",3) || !strncmp(buf,"the",3) || !strncmp(buf,"a ",2) || !strncmp(buf,"an ",3)) /* || strstr(buf, " of") */ ret = object_detect((struct obj *)0); else ret = monster_detect((struct obj *)0); break; } if (ret) if (!rn2(100)) /* make them nervous */ You("see the Wizard of Yendor gazing out at you."); else pline("The vision is unclear."); } return; } static const char cuddly[] = { TOOL_SYM, 0 }; int dorub() { struct obj *obj = getobj(cuddly, "rub"); if(!obj || (obj != uwep && !wield_tool(obj))) return 0; /* now uwep is obj */ if (uwep->otyp == MAGIC_LAMP) { if (uwep->spe > 0 && !rn2(3)) { uwep->spe = 0; djinni_from_bottle(uwep); makeknown(MAGIC_LAMP); } else if (rn2(2) && !Blind) You("see a puff of smoke."); else pline(nothing_happens); } else pline(nothing_happens); return 1; } int dojump() { coord cc; register struct monst *mtmp; if (!Jumping) { You("can't jump very far."); return 0; } else if (u.uswallow) { pline("You've got to be kidding!"); return 0; } else if (u.ustuck) { kludge("You cannot escape from %s!", mon_nam(u.ustuck)); return 0; } else if (inv_weight() > -5) { You("are carrying too much to jump!"); return 0; } else if (u.uhunger <= 100 || ACURR(A_STR) < 6) { You("lack the strength to jump!"); return 0; } pline("Where do you want to jump?"); cc.x = u.ux; cc.y = u.uy; getpos(&cc, 1, "the desired position"); if (dist(cc.x, cc.y) > 9) { pline("Too far!"); return 0; } else if (!cansee(cc.x, cc.y)) { You("cannot see where to land!"); return 0; } else if (MON_AT(cc.x, cc.y)) { mtmp = m_at(cc.x, cc.y); You("cannot trample %s!", mon_nam(mtmp)); return 0; } else if (!isok(cc.x, cc.y) || #ifdef POLYSELF (IS_ROCK(levl[cc.x][cc.y].typ) && !passes_walls(uasmon)) || #else IS_ROCK(levl[cc.x][cc.y].typ) || #endif sobj_at(BOULDER, cc.x, cc.x) ) { You("cannot jump there!"); return 0; } else { teleds(cc.x, cc.y); nomul(-1); nomovemsg = ""; morehungry(rnd(25)); return 1; } } static void use_tinning_kit(obj) register struct obj *obj; { register struct obj *corpse, *can; /* This takes only 1 move. If this is to be changed to take many * moves, we've got to deal with decaying corpses... */ if (!(corpse = floorfood("can", 1))) return; if (corpse->oeaten) { You("cannot tin something which is partly eaten."); return; } if ((corpse->corpsenm == PM_COCKATRICE) #ifdef POLYSELF && !resists_ston(uasmon) #endif && !uarmg) { pline("Tinning a cockatrice corpse without gloves was not a very wise move..."); You("turn to stone..."); killer_format = KILLED_BY; killer = "trying to tin a cockatrice without gloves"; done(STONING); } if (mons[corpse->corpsenm].cnutrit == 0) { You("can't tin something that insubstantial!"); return; } can = mksobj(TIN,FALSE); can->corpsenm = corpse->corpsenm; can->quan = 1; /* Defeat the occasional creation of pairs of tins */ can->owt = weight(can); can->known = 1; can->spe = 0; /* No spinach allowed... */ can->cursed = obj->cursed; can->blessed = obj->blessed; can = addinv(can); You("now have %s.", doname(can)); if (carried(corpse)) useup(corpse); else useupf(corpse); } int use_unicorn_horn(obj) struct obj *obj; { boolean blessed = (obj && obj->blessed); boolean did_something = FALSE; if (obj && obj->cursed) { switch (rn2(6)) { static char buf[BUFSZ]; case 0: make_sick(Sick ? 1L : (long)(20 + rn2(20)), TRUE); Strcpy(buf, xname(obj)); u.usick_cause = (const char *)buf; break; case 1: make_blinded(Blinded + (long) rnd(100), TRUE); break; case 2: if (!Confusion) You("suddenly feel %s.", Hallucination ? "trippy" : "confused"); make_confused(HConfusion + (long) rnd(100), TRUE); break; case 3: make_stunned(HStun + (long) rnd(100), TRUE); break; case 4: adjattrib(rn2(6), -1, FALSE); break; case 5: make_hallucinated(Hallucination + (long) rnd(100), TRUE); break; } return 1; } if (Sick) { make_sick(0L, TRUE); did_something++; } if (Blinded && (!did_something || blessed)) { make_blinded(0L, TRUE); did_something++; } if (Hallucination && (!did_something || blessed)) { make_hallucinated(0L, TRUE); did_something++; } if (Vomiting && (!did_something || blessed)) { make_vomiting(0L, TRUE); did_something++; } if (HConfusion && (!did_something || blessed)) { make_confused(0L, TRUE); did_something++; } if (HStun && (!did_something || blessed)) { make_stunned(0L, TRUE); did_something++; } if (!did_something || blessed) { register int j; int did_stat = 0; int i = rn2(A_MAX); for(j=0; j<A_MAX; j++) { if ((blessed || j==i) && ABASE(i) < AMAX(i)) { did_something++; /* They may have to use it several times... */ if (!did_stat) { did_stat++; pline("This makes you feel good!"); } ABASE(i)++; flags.botl = 1; } } } if (!did_something) pline(nothing_happens); return !!did_something; } int doapply() { register struct obj *obj; register int res = 1; obj = getobj(tools, "use or apply"); if(!obj) return 0; check_unpaid(obj); #ifdef MUSIC if (IS_INSTRUMENT(obj->otyp)) { res = do_play_instrument(obj); return (res); } #endif /* MUSIC /**/ switch(obj->otyp){ case EXPENSIVE_CAMERA: use_camera(obj); break; case CREDIT_CARD: case LOCK_PICK: case SKELETON_KEY: case KEY: (void) pick_lock(obj); break; case BAG_OF_TRICKS: if(obj->spe > 0) { register int cnt = 1; obj->spe -= 1; if(!rn2(23)) cnt += rn2(7) + 1; while(cnt--) (void) makemon((struct permonst *) 0, u.ux, u.uy); makeknown(BAG_OF_TRICKS); } break; case LARGE_BOX: case CHEST: case ICE_BOX: case SACK: case BAG_OF_HOLDING: use_container(obj, 1); break; case PICK_AXE: res = use_pick_axe(obj); break; case TINNING_KIT: use_tinning_kit(obj); break; case MAGIC_WHISTLE: if(pl_character[0] == 'W' || u.ulevel > (MAXULEV/3)) { use_magic_whistle(obj); break; } /* fall into next case */ case WHISTLE: use_whistle(obj); break; #ifdef MEDUSA case MIRROR: use_mirror(obj); break; #endif case LAMP: case MAGIC_LAMP: use_lamp(obj); break; case CRYSTAL_BALL: use_crystal_ball(obj); break; #ifdef WALKIES case LEASH: use_leash(obj); break; #endif case MAGIC_MARKER: dowrite(obj); break; case TIN_OPENER: if(!carrying(TIN)) { You("have no tin to open."); goto xit; } You("cannot open a tin without eating or discarding its contents."); if(flags.verbose) pline("In order to eat, use the 'e' command."); if(obj != uwep) pline("Opening the tin will be much easier if you wield the tin opener."); goto xit; case STETHOSCOPE: res = 0; use_stethoscope(obj); break; case FIGURINE: You("set the figurine on the ground and it transforms."); make_familiar(obj); useup(obj); break; case BLINDFOLD: if (obj == ublindf) { if(cursed(obj)) break; else Blindf_off(obj); } else if (!ublindf) Blindf_on(obj); else You("are already wearing a blindfold!"); break; case UNICORN_HORN: res = use_unicorn_horn(obj); break; default: pline("Sorry, I don't know how to use that."); xit: nomul(0); return 0; } nomul(0); return res; } #endif /* OVLB */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.