Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site mcvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!mcvax!play From: play@mcvax.UUCP (funhouse) Newsgroups: net.sources Subject: Hack sources (part 4 of 15) Message-ID: <6246@mcvax.UUCP> Date: Mon, 17-Dec-84 19:30:32 EST Article-I.D.: mcvax.6246 Posted: Mon Dec 17 19:30:32 1984 Date-Received: Wed, 19-Dec-84 02:13:51 EST Organization: CWI, Amsterdam Lines: 1156 # This is part 4 (of 15) of the Hack sources. Send complaints to # mcvax!play . # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # hack.Decl.c hack.apply.c hack.bones.c hack.cmdlist.c hack.do.c echo x - hack.Decl.c cat > "hack.Decl.c" << '//E*O*F hack.Decl.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" char nul[40]; /* contains zeros */ char plname[PL_NSIZ] = "player";/* player name */ char lock[32] = "1lock"; /* long enough for login name */ #ifdef WIZARD boolean wizard; /* TRUE when called as hack -w */ #endif WIZARD struct rm levl[COLNO][ROWNO]; /* level map */ #ifndef QUEST struct mkroom rooms[MAXNROFROOMS+1]; coord doors[DOORMAX]; #endif QUEST struct monst *fmon = 0; struct gen *fgold = 0, *ftrap = 0; struct obj *fobj = 0, *fcobj = 0, *invent = 0, *uwep = 0, *uarm = 0, *uarm2 = 0, *uarmh = 0, *uarms = 0, *uarmg = 0, *uright = 0, *uleft = 0, *uchain = 0, *uball = 0; struct flag flags; struct you u; xchar dlevel = 1; xchar xupstair, yupstair, xdnstair, ydnstair; char *save_cm = 0, *killer, *nomovemsg; long moves = 1; long wailmsg = 0; int multi = 0; char genocided[60]; char fut_geno[60]; xchar curx,cury; xchar seelx, seehx, seely, seehy; /* corners of lit room */ coord bhitpos; //E*O*F hack.Decl.c// echo x - hack.apply.c cat > "hack.apply.c" << '//E*O*F hack.apply.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" extern struct monst *bchit(); extern struct obj *addinv(); extern char pl_character[]; doapply() { register struct obj *obj; obj = getobj("(", "use or apply"); if(!obj) return(0); switch(obj->otyp){ case EXPENSIVE_CAMERA: use_camera(obj); break; case ICE_BOX: use_ice_box(obj); break; case MAGIC_WHISTLE: if(pl_character[0] == 'W' || u.ulevel > 9) { use_magic_whistle(obj); break; } /* fall into next case */ case WHISTLE: use_whistle(obj); break; default: pline("Sorry, I don't know how to use that."); return(0); } return(1); } /* ARGSUSED */ use_camera(obj) /* register */ struct obj *obj; { register struct monst *mtmp; if(!getdir()){ flags.move = multi = 0; return; } if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) { if(mtmp->msleep){ mtmp->msleep = 0; pline("The flash awakens the %s.", monnam(mtmp)); } else if(mtmp->data->mlet != 'y') 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)); setmangry(mtmp); if(tmp < 9 && !mtmp->isshk && !rn2(4)) mtmp->mflee = 1; if(tmp < 3) mtmp->mcansee = mtmp->mblinded = 0; else { tmp2 = mtmp->mblinded; tmp2 += rnd(1 + 50/tmp); if(tmp2 > 127) tmp2 = 127; mtmp->mblinded = tmp2; mtmp->mcansee = 0; } } } } struct obj *current_ice_box; /* a local variable of use_ice_box, to be used by its local procedures in/ck_ice_box */ in_ice_box(obj) register struct obj *obj; { if(obj == current_ice_box || (Punished && (obj == uball || obj == uchain))){ pline("You must be kidding."); return(0); } if(obj->owornmask & (W_ARMOR | W_RING)) { pline("You cannot refrigerate something you are wearing."); return(0); } if(obj->owt + current_ice_box->owt > 70) { pline("It won't fit."); return(1); /* be careful! */ } if(obj == uwep) { if(uwep->cursed) { pline("Your weapon is welded to your hand!"); return(0); } setuwep((struct obj *) 0); } current_ice_box->owt += obj->owt; freeinv(obj); obj->o_cnt_id = current_ice_box->o_id; obj->nobj = fcobj; fcobj = obj; obj->age = moves - obj->age; /* actual age */ return(1); } ck_ice_box(obj) register struct obj *obj; { return(obj->o_cnt_id == current_ice_box->o_id); } out_ice_box(obj) register struct obj *obj; { register struct obj *otmp; if(obj == fcobj) fcobj = fcobj->nobj; else { for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj) if(!otmp->nobj) panic("out_ice_box"); otmp->nobj = obj->nobj; } current_ice_box->owt -= obj->owt; obj->age = moves - obj->age; /* simulated point of time */ (void) addinv(obj); } use_ice_box(obj) register struct obj *obj; { register int cnt = 0; register struct obj *otmp; current_ice_box = obj; /* for use by in/out_ice_box */ for(otmp = fcobj; otmp; otmp = otmp->nobj) if(otmp->o_cnt_id == obj->o_id) cnt++; if(!cnt) pline("Your ice-box is empty."); else { pline("Do you want to take something out of the ice-box? [yn] "); if(readchar() == 'y') if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0)) return; pline("That was all. Do you wish to put something in? [yn] "); if(readchar() != 'y') return; } /* call getobj: 0: allow cnt; #: allow all types; %: expect food */ otmp = getobj("0#%", "put in"); if(!otmp || !in_ice_box(otmp)) flags.move = multi = 0; } 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_at(-1, sym); /* open call */ while(range--) { bchx += ddx; bchy += ddy; if(mtmp = m_at(bchx,bchy)) break; if(levl[bchx][bchy].typ < CORR) { bchx -= ddx; bchy -= ddy; break; } if(sym) Tmp_at(bchx, bchy); } if(sym) Tmp_at(-1, -1); return(mtmp); } #include "def.edog.h" /* ARGSUSED */ use_whistle(obj) struct obj *obj; { register struct monst *mtmp = fmon; pline("You produce a high whistling sound."); while(mtmp) { if(dist(mtmp->mx,mtmp->my) < u.ulevel*10) { if(mtmp->msleep) mtmp->msleep = 0; if(mtmp->mtame) EDOG(mtmp)->whistletime = moves; } mtmp = mtmp->nmon; } } /* ARGSUSED */ use_magic_whistle(obj) struct obj *obj; { register struct monst *mtmp = fmon; pline("You produce a strange whistling sound."); while(mtmp) { if(mtmp->mtame) mnexto(mtmp); mtmp = mtmp->nmon; } } //E*O*F hack.apply.c// echo x - hack.bones.c cat > "hack.bones.c" << '//E*O*F hack.bones.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" extern char plname[PL_NSIZ]; extern struct monst *makemon(); struct permonst pm_ghost = { "ghost", ' ', 10, 3, -5, 1, 1, sizeof(plname) }; char bones[] = "bones_xx"; /* save bones and possessions of a deceased adventurer */ savebones(){ register fd; register struct obj *otmp; register struct gen *gtmp; register struct monst *mtmp; if(!rn2(1 + dlevel/2)) return; /* not so many ghosts on low levels */ bones[6] = '0' + (dlevel/10); bones[7] = '0' + (dlevel%10); if((fd = open(bones,0)) >= 0){ (void) close(fd); return; } /* drop everything; the corpse's possessions are usually cursed */ otmp = invent; while(otmp){ otmp->ox = u.ux; otmp->oy = u.uy; otmp->known = 0; otmp->age = 0; /* very long ago */ otmp->owornmask = 0; if(rn2(5)) otmp->cursed = 1; if(!otmp->nobj){ otmp->nobj = fobj; fobj = invent; invent = 0; /* superfluous */ break; } otmp = otmp->nobj; } if(!(mtmp = makemon(&pm_ghost, u.ux, u.uy))) return; mtmp->mx = u.ux; mtmp->my = u.uy; mtmp->msleep = 1; (void) strcpy((char *) mtmp->mextra, plname); mkgold(somegold() + d(dlevel,30), u.ux, u.uy); u.ux = FAR; /* avoid animals standing next to us */ keepdogs(); /* all tame animals become wild again */ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ mtmp->mlstmv = 0; if(mtmp->mdispl) unpmon(mtmp); } for(gtmp = ftrap; gtmp; gtmp = gtmp->ngen) gtmp->gflag &= ~SEEN; for(otmp = fobj; otmp; otmp = otmp->nobj) otmp->onamelth = 0; if((fd = creat(bones, FMASK)) < 0) return; savelev(fd); (void) close(fd); } getbones(){ register fd,x,y,ok; if(rn2(3)) return(0); /* only once in three times do we find bones */ bones[6] = '0' + dlevel/10; bones[7] = '0' + dlevel%10; if((fd = open(bones, 0)) < 0) return(0); if((ok = uptodate(fd)) != 0){ (void) getlev(fd); (void) close(fd); for(x = 0; x < COLNO; x++) for(y = 0; y < ROWNO; y++) levl[x][y].seen = levl[x][y].new = 0; } if(unlink(bones) < 0){ pline("Cannot unlink %s", bones); return(0); } return(ok); } //E*O*F hack.bones.c// echo x - hack.cmdlist.c cat > "hack.cmdlist.c" << '//E*O*F hack.cmdlist.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "config.h" #include "def.objclass.h" #include "def.func_tab.h" int doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(), doversion(),doweararm(),dowearring(),doremarm(),doremring(),dopay(),doapply(), dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),doengrave(), dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),doprwep(),doprarm(),doprring(); #ifdef SHELL int dosh(); #endif SHELL #ifdef OPTIONS int doset(); #endif OPTIONS int doup(), dodown(), done1(), donull(); int dothrow(); struct func_tab list[]={ '\022', doredraw, '\020', doredotopl, 'a', doapply, /* 'A' : UNUSED */ /* 'b', 'B' : go sw */ 'c', ddocall, 'C', do_mname, 'd', dodrop, 'D', doddrop, 'e', doeat, 'E', doengrave, /* 'f', 'F' : multiple go (might become 'fight') */ /* 'g', 'G' : UNUSED */ /* 'h', 'H' : go west */ 'i', ddoinv, /* 'I' : UNUSED */ /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ #ifdef OPTIONS 'o', doset, #endif OPTIONS /* 'O' : UNUSED */ 'p', dopay, 'P', dowearring, 'q', dodrink, 'Q', done1, 'r', doread, 'R', doremring, 's', dosearch, 'S', dosave, 't', dothrow, 'T', doremarm, /* 'u', 'U' : go ne */ 'v', doversion, /* 'V' : UNUSED */ 'w', dowield, 'W', doweararm, /* 'x', 'X' : UNUSED */ /* 'y', 'Y' : go nw */ 'z', dozap, /* 'Z' : UNUSED */ '<', doup, '>', dodown, '/', dowhatis, '?', dohelp, #ifdef SHELL '!', dosh, #endif SHELL '.', donull, ' ', donull, '^', doidtrap, WEAPON_SYM, doprwep, ARMOR_SYM, doprarm, RING_SYM, doprring, 0,0,0 }; //E*O*F hack.cmdlist.c// echo x - hack.do.c cat > "hack.do.c" << '//E*O*F hack.do.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include #include #include "hack.h" #include "def.func_tab.h" extern char *getenv(),*parse(),*getlogin(),*lowc(),*unctrl(); extern int float_down(); extern char *nomovemsg, *catmore; extern struct obj *splitobj(), *addinv(); extern boolean hmon(); /* Routines to do various user commands */ int done1(); dodrink() { register struct obj *otmp,*objs; register struct monst *mtmp; register int unkn = 0, nothing = 0; otmp = getobj("!", "drink"); if(!otmp) return(0); switch(otmp->otyp){ case POT_RESTORE_STRENGTH: unkn++; pline("Wow! This makes you feel great!"); if(u.ustr < u.ustrmax) { u.ustr = u.ustrmax; flags.botl = 1; } break; case POT_BOOZE: unkn++; pline("Ooph! This tastes like liquid fire!"); Confusion += d(3,8); /* the whiskey makes us feel better */ if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey"); if(!rn2(4)) { pline("You pass out."); multi = -rnd(15); nomovemsg = "You awake with a headache."; } break; case POT_INVISIBILITY: if(Invis) nothing++; else { if(!Blind) pline("Gee! All of a sudden, you can't see yourself."); else pline("You feel rather airy."), unkn++; newsym(u.ux,u.uy); } Invis += rn1(15,31); break; case POT_FRUIT_JUICE: pline("This tastes like fruit juice."); lesshungry(20); break; case POT_HEALING: pline("You begin to feel better."); flags.botl = 1; u.uhp += rnd(10); if(u.uhp > u.uhpmax) u.uhp = ++u.uhpmax; if(Blind) Blind = 1; /* see on next move */ if(Sick) Sick = 0; break; case POT_PARALYSIS: pline("Your feet are frozen to the floor!"); nomul(-(rn1(10,25))); break; case POT_MONSTER_DETECTION: if(!fmon) { strange_feeling(otmp); return(1); } else { cls(); for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->mx > 0) at(mtmp->mx,mtmp->my,mtmp->data->mlet); prme(); pline("You sense the presence of monsters."); more(); docrt(); } break; case POT_OBJECT_DETECTION: if(!fobj) { strange_feeling(otmp); return(1); } else { for(objs = fobj; objs; objs = objs->nobj) if(objs->ox != u.ux || objs->oy != u.uy) goto outobjmap; pline("You sense the presence of objects close nearby."); break; outobjmap: cls(); for(objs = fobj; objs; objs = objs->nobj) at(objs->ox,objs->oy,objs->olet); prme(); pline("You sense the presence of objects."); more(); docrt(); } break; case POT_SICKNESS: pline("Yech! This stuff tastes like poison."); if(Poison_resistance) pline("(But in fact it was biologically contaminated orange juice.)"); losestr(rn1(4,3)); losehp(rnd(10), "poison potion"); break; case POT_CONFUSION: if(!Confusion) pline("Huh, What? Where am I?"); else nothing++; Confusion += rn1(7,16); break; case POT_GAIN_STRENGTH: pline("Wow do you feel strong!"); if(u.ustr == 118) break; if(u.ustr > 17) u.ustr += rnd(118-u.ustr); else u.ustr++; if(u.ustr > u.ustrmax) u.ustrmax = u.ustr; flags.botl = 1; break; case POT_SPEED: if(Wounded_legs) { if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) pline("Your legs feel somewhat better."); else pline("Your leg feels somewhat better."); Wounded_legs = 0; unkn++; break; } if(!(Fast & ~INTRINSIC)) pline("You are suddenly moving much faster."); else pline("Your legs get new energy."), unkn++; Fast += rn1(10,100); break; case POT_BLINDNESS: if(!Blind) pline("A cloud of darkness falls upon you."); else nothing++; Blind += rn1(100,250); seeoff(0); break; case POT_GAIN_LEVEL: pluslvl(); break; case POT_EXTRA_HEALING: pline("You feel much better."); flags.botl = 1; u.uhp += d(2,20)+1; if(u.uhp > u.uhpmax) u.uhp = (u.uhpmax += 2); if(Blind) Blind = 1; if(Sick) Sick = 0; break; case POT_LEVITATION: if(!Levitation) float_up(); else nothing++; Levitation += rnd(100); u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; break; default: pline("What a funny potion! (%d)", otmp->otyp); impossible(); return(0); } if(nothing) { unkn++; pline("You have a peculiar feeling for a moment, then it passes."); } if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { if(!unkn) { objects[otmp->otyp].oc_name_known = 1; u.urexp += 10; } else if(!objects[otmp->otyp].oc_uname) docall(otmp); } useup(otmp); return(1); } pluslvl() { register num; pline("You feel more experienced."); num = rnd(10); u.uhpmax += num; u.uhp += num; u.uexp = (10*pow(u.ulevel-1))+1; pline("Welcome to level %d.", ++u.ulevel); flags.botl = 1; } strange_feeling(obj) register struct obj *obj; { pline("You have a strange feeling for a moment, then it passes."); if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname) docall(obj); useup(obj); } dodrop() { register struct obj *obj; obj = getobj("0$#", "drop"); if(!obj) return(0); if(obj->olet == '$') { if(obj->quan == 0) pline("You didn't drop any gold pieces."); else { mkgold((int) obj->quan, u.ux, u.uy); pline("You dropped %u gold piece%s.", obj->quan, plur(obj->quan)); if(Invis) newsym(u.ux, u.uy); } free((char *) obj); return(1); } return(drop(obj)); } drop(obj) register struct obj *obj; { if(obj->owornmask & (W_ARMOR | W_RING)){ pline("You cannot drop something you are wearing."); return(0); } if(obj == uwep) { if(uwep->cursed) { pline("Your weapon is welded to your hand!"); return(0); } setuwep((struct obj *) 0); } pline("You dropped %s.", doname(obj)); dropx(obj); return(1); } dropx(obj) register struct obj *obj; { if(obj->otyp == CRYSKNIFE) obj->otyp = WORM_TOOTH; freeinv(obj); obj->ox = u.ux; obj->oy = u.uy; obj->nobj = fobj; fobj = obj; if(Invis) newsym(u.ux,u.uy); subfrombill(obj); stackobj(obj); } /* drop several things */ doddrop() { return(ggetobj("drop", drop, 0)); } rhack(cmd) register char *cmd; { register struct func_tab *tlist = list; boolean firsttime = FALSE; register res; if(!cmd) { firsttime = TRUE; flags.nopick = 0; cmd = parse(); } if(!*cmd || *cmd == 0377) return; /* probably we just had an interrupt */ if(movecm(cmd)) { walk: if(multi) flags.mv = 1; domove(); return; } if(movecm(lowc(cmd))) { flags.run = 1; rush: if(firsttime){ if(!multi) multi = COLNO; u.last_str_turn = 0; } flags.mv = 1; #ifdef QUEST if(flags.run >= 4) finddir(); if(firsttime){ u.ux0 = u.ux + u.dx; u.uy0 = u.uy + u.dy; } #endif QUEST domove(); return; } if((*cmd == 'f' && movecm(cmd+1)) || movecm(unctrl(cmd))) { flags.run = 2; goto rush; } if(*cmd == 'F' && movecm(lowc(cmd+1))) { flags.run = 3; goto rush; } if(*cmd == 'm' && movecm(cmd+1)) { flags.run = 0; flags.nopick = 1; goto walk; } if(*cmd == 'M' && movecm(lowc(cmd+1))) { flags.run = 1; flags.nopick = 1; goto rush; } #ifdef QUEST if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) { flags.run = 4; if(*cmd == 'F') flags.run += 2; if(cmd[2] == '-') flags.run += 1; goto rush; } #endif QUEST while(tlist->f_char) { if(*cmd == tlist->f_char){ res = (*(tlist->f_funct))(0); if(!res) { flags.move = 0; multi = 0; } return; } tlist++; } pline("Unknown command '%s'",cmd); multi = flags.move = 0; } doredraw() { docrt(); return(0); } dohelp() { if(child(1)){ execl(catmore,"more","help",(char *)0); exit(1); } return(0); } #ifdef SHELL dosh(){ register char *str; if(child(0)) { (void) chdir(getenv("HOME")); if(str = getenv("SHELL")) execl(str,str,(char *) 0); if(strcmp("player", getlogin())) execl("/bin/sh","sh",(char *) 0); pline("sh: cannot execute."); exit(1); } return(0); } #endif SHELL #ifdef BSD #include #else #include #endif BSD child(wt) { register int f = fork(); if(f == 0){ /* child */ settty((char *) 0); (void) setuid(getuid()); return(1); } if(f == -1) { /* cannot fork */ pline("Fork failed. Try again."); return(0); } /* fork succeeded; wait for child to exit */ (void) signal(SIGINT,SIG_IGN); (void) signal(SIGQUIT,SIG_IGN); (void) wait((union wait *) 0); setctty(); (void) signal(SIGINT,done1); #ifdef WIZARD if(wizard) (void) signal(SIGQUIT,SIG_DFL); #endif WIZARD if(wt) getret(); docrt(); return(0); } dodown() { if(u.ux != xdnstair || u.uy != ydnstair) { pline("You can't go down here."); return(0); } if(u.ustuck) { pline("You are being held, and cannot go down."); return(1); } if(Levitation) { pline("You're floating high above the stairs."); return(0); } goto_level(dlevel+1, TRUE); return(1); } doup() { if(u.ux != xupstair || u.uy != yupstair) { pline("You can't go up here."); return(0); } if(u.ustuck) { pline("You are being held, and cannot go up."); return(1); } if(inv_weight() + 5 > 0) { pline("Your load is too heavy to climb the stairs."); return(1); } goto_level(dlevel-1, TRUE); return(1); } goto_level(newlevel, at_stairs) register int newlevel; register boolean at_stairs; { register fd; register boolean up = (newlevel < dlevel); if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */ if(newlevel == dlevel) return; /* this cannot happen either */ glo(dlevel); fd = creat(lock,FMASK); if(fd < 0) { /* * This is not quite impossible: e.g., we may have * exceeded our quota. If that is the case then we * cannot leave this level, and cannot save either. */ pline("A mysterious force prevents you from going %d.", up ? "up" : "down"); return; } if(Punished) unplacebc(); keepdogs(); seeoff(1); flags.nscrinh = 1; u.ux = FAR; /* hack */ (void) inshop(); /* probably was a trapdoor */ savelev(fd); (void) close(fd); dlevel = newlevel; if(maxdlevel < dlevel) maxdlevel = dlevel; glo(dlevel); if((fd = open(lock,0)) < 0) mklev(); else { (void) getlev(fd); (void) close(fd); } if(at_stairs) { if(up) { u.ux = xdnstair; u.uy = ydnstair; if(!u.ux) { /* entering a maze from below? */ u.ux = xupstair; /* this will confuse the player! */ u.uy = yupstair; } if(Punished){ pline("With great effort you climb the stairs"); placebc(1); } } else { u.ux = xupstair; u.uy = yupstair; if(inv_weight() + 5 > 0 || Punished){ pline("You fall down the stairs."); losehp(rnd(3), "fall"); if(Punished) { if(uwep != uball && rn2(3)){ pline("... and are hit by the iron ball"); losehp(rnd(20), "iron ball"); } placebc(1); } selftouch("Falling, you"); } } } else { /* trapdoor or level_tele */ do { u.ux = rnd(COLNO-1); u.uy = rn2(ROWNO); } while(levl[u.ux][u.uy].typ != ROOM || m_at(u.ux,u.uy)); if(Punished){ if(uwep != uball && !up /* %% */ && rn2(5)){ pline("The iron ball falls on your head."); losehp(rnd(25), "iron ball"); } placebc(1); } selftouch("Falling, you"); } (void) inshop(); #ifdef TRACK initrack(); #endif TRACK losedogs(); flags.nscrinh = 0; setsee(); docrt(); pickup(); read_engr_at(u.ux,u.uy); } donull() { return(1); /* Do nothing, but let other things happen */ } struct monst *bhit(), *boomhit(); dothrow() { register struct obj *obj; register struct monst *mon; register tmp; obj = getobj("#)", "throw"); /* it is also possible to throw food */ /* (or jewels, or iron balls ... ) */ if(!obj || !getdir()) return(0); if(obj->owornmask & (W_ARMOR | W_RING)){ pline("You can't throw something you are wearing"); return(0); } if(obj == uwep){ if(obj->cursed){ pline("Your weapon is welded to your hand"); return(1); } if(obj->quan > 1) setuwep(splitobj(obj, 1)); else setuwep((struct obj *) 0); } else if(obj->quan > 1) (void) splitobj(obj, 1); freeinv(obj); if(u.uswallow) { mon = u.ustuck; bhitpos.x = mon->mx; bhitpos.y = mon->my; } else if(obj->otyp == BOOMERANG) { mon = boomhit(u.dx,u.dy); /* boomhit delivers -1 if the thing was caught */ if((int) mon == -1) { (void) addinv(obj); return(1); } } else mon = bhit(u.dx,u.dy, (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, obj->olet); if(mon) { /* awake monster if sleeping */ wakeup(mon); if(obj->olet == WEAPON_SYM) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(obj->otyp < ROCK) { if(!uwep || uwep->otyp != obj->otyp+(BOW-ARROW)) tmp -= 4; else { tmp += uwep->spe; } } else if(obj->otyp == BOOMERANG) tmp += 4; tmp += obj->spe; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == TRUE){ /* mon still alive */ #ifndef NOWORM cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); #endif NOWORM } else mon = 0; /* weapons thrown disappear sometimes */ if(obj->otyp < BOOMERANG && rn2(3)) { /* check bill; free */ obfree(obj, (struct obj *) 0); return(1); } } else miss(objects[obj->otyp].oc_name, mon); } else if(obj->otyp == HEAVY_IRON_BALL) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(!Punished || obj != uball) tmp += 2; if(u.utrap) tmp -= 2; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == FALSE) mon = 0; /* he died */ } else miss("iron ball", mon); } else { if(cansee(bhitpos.x,bhitpos.y)) pline("You miss %s.",monnam(mon)); else pline("You miss it."); if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') if(tamedog(mon,obj)) return(1); if(obj->olet == GEM_SYM && mon->data->mlet == 'u'){ if(obj->dknown && objects[obj->otyp].oc_name_known){ if(objects[obj->otyp].g_val > 0){ u.uluck += 5; goto valuable; } else { pline("%s is not interested in your junk.", Monnam(mon)); } } else { /* value unknown to @ */ u.uluck++; valuable: pline("%s graciously accepts your gift.", Monnam(mon)); mpickobj(mon, obj); rloc(mon); return(1); } } } } obj->ox = bhitpos.x; obj->oy = bhitpos.y; obj->nobj = fobj; fobj = obj; /* prevent him from throwing articles to the exit and escaping */ /* subfrombill(obj); */ stackobj(obj); if(Punished && obj == uball && (bhitpos.x != u.ux || bhitpos.y != u.uy)){ freeobj(uchain); unpobj(uchain); if(u.utrap){ if(u.utraptype == TT_PIT) pline("The ball pulls you out of the pit!"); else { register int side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; pline("The ball pulls you out of the bear trap."); pline("Your %s leg is severely damaged.", (side == LEFT_SIDE) ? "left" : "right"); Wounded_legs |= side + rnd(1000); losehp(2, "thrown ball"); } u.utrap = 0; } unsee(); uchain->nobj = fobj; fobj = uchain; u.ux = uchain->ox = bhitpos.x - u.dx; u.uy = uchain->oy = bhitpos.y - u.dy; setsee(); (void) inshop(); } if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); return(1); } getdir() { char buf[2]; pline("What direction?"); buf[0] = readchar(); buf[1] = 0; return(movecm(buf)); } /* split obj so that it gets size num */ /* remainder is put in the object structure delivered by this call */ struct obj * splitobj(obj, num) register struct obj *obj; register int num; { register struct obj *otmp; otmp = newobj(0); *otmp = *obj; /* copies whole structure */ otmp->o_id = flags.ident++; otmp->onamelth = 0; obj->quan = num; obj->owt = weight(obj); otmp->quan -= num; otmp->owt = weight(otmp); /* -= obj->owt ? */ obj->nobj = otmp; if(obj->unpaid) splitbill(obj,otmp); return(otmp); } char * lowc(str) register char *str; { static char buf[2]; if(*str >= 'A' && *str <= 'Z') *buf = *str+'a'-'A'; else *buf = *str; buf[1] = 0; return(buf); } char * unctrl(str) register char *str; { static char buf[2]; if(*str >= ('A' & 037) && *str <= ('Z' & 037)) *buf = *str + 0140; else *buf = *str; buf[1] = 0; return(buf); } //E*O*F hack.do.c// exit 0