# 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.cmd.c hack.do.c # hack.do_name.c hack.do_wear.c hack.dog.c echo x - hack.Decl.c cat > "hack.Decl.c" << '//E*O*F hack.Decl.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.Decl.c - version 1.0.2 */ #include "hack.h" char nul[40]; /* contains zeros */ char plname[PL_NSIZ]; /* player name */ char lock[32] = "1lock"; /* long enough for login name */ boolean in_mklev; #ifdef WIZARD boolean wizard; /* TRUE when called as hack -w */ #endif WIZARD struct rm levl[COLNO][ROWNO]; /* level map */ #ifndef QUEST #include "def.mkroom.h" struct mkroom rooms[MAXNROFROOMS+1]; coord doors[DOORMAX]; #endif QUEST struct monst *fmon = 0; struct trap *ftrap = 0; struct gold *fgold = 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; struct monst youmonst; /* dummy; used as return value for boomhit */ 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; char quitchars[] = " \r\n\033"; //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, 1985. */ /* hack.apply.c - version 1.0.2 */ #include "hack.h" #include "def.edog.h" #include "def.mkroom.h" extern struct monst *bchit(); extern struct obj *addinv(); extern struct trap *maketrap(); extern int (*occupation)(); extern char *occtxt; extern char quitchars[]; extern char pl_character[]; doapply() { register struct obj *obj; register int res = 1; 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 PICK_AXE: res = use_pick_axe(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."); nomul(0); return(0); } nomul(0); return(res); } /* ARGSUSED */ static 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) { pline("You take a picture of %s's stomach.", monnam(u.ustuck)); return; } if(u.dz) { pline("You take a picture of the %s.", (u.dz > 0) ? "floor" : "ceiling"); return; } if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) { if(mtmp->msleep){ mtmp->msleep = 0; pline("The flash awakens %s.", monnam(mtmp)); /* a3 */ } 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(rn2(4)) mtmp->mfleetim = rnd(100); } 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; } } } } static struct obj *current_ice_box; /* a local variable of use_ice_box, to be used by its local procedures in/ck_ice_box */ static 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); } static ck_ice_box(obj) register struct obj *obj; { return(obj->o_cnt_id == current_ice_box->o_id); } static 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); } static 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; } 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_at(-1, sym); /* open call */ while(range--) { bchx += ddx; bchy += ddy; if(mtmp = m_at(bchx,bchy)) break; if(!ZAP_POS(levl[bchx][bchy].typ)) { bchx -= ddx; bchy -= ddy; break; } if(sym) Tmp_at(bchx, bchy); } if(sym) Tmp_at(-1, -1); return(mtmp); } /* ARGSUSED */ static 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*20) { if(mtmp->msleep) mtmp->msleep = 0; if(mtmp->mtame) EDOG(mtmp)->whistletime = moves; } mtmp = mtmp->nmon; } } /* ARGSUSED */ static 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; } } static int dig_effort; /* effort expended on current pos */ static uchar dig_level; static coord dig_pos; static boolean dig_down; static dig() { register struct rm *lev; register dpx = dig_pos.x, dpy = dig_pos.y; /* 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); dig_effort += 10 + abon() + uwep->spe + rn2(5); if(dig_down) { if(!xdnstair) { pline("The floor here seems too hard to dig in."); return(0); } if(dig_effort > 250) { dighole(); 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; pline("You have dug a pit."); u.utrap = rn1(4,2); u.utraptype = TT_PIT; return(0); } } } else if(dig_effort > 100) { register char *digtxt; register struct obj *obj; lev = &levl[dpx][dpy]; if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) { fracture_rock(obj); digtxt = "The rock falls apart."; } else if(!lev->typ || lev->typ == SCORR) { lev->typ = CORR; digtxt = "You succeeded in cutting away some rock."; } else if(lev->typ == HWALL || lev->typ == VWALL || lev->typ == SDOOR) { lev->typ = xdnstair ? DOOR : ROOM; digtxt = "You just made an opening in the wall."; } else digtxt = "Now what exactly was it that you were digging in?"; mnewsym(dpx, dpy); prl(dpx, dpy); pline(digtxt); /* after mnewsym & prl */ return(0); } else { if(IS_WALL(levl[dpx][dpy].typ)) { register int rno = inroom(dpx,dpy); if(rno >= 0 && rooms[rno].rtype >= 8) { pline("This wall seems too hard to dig into."); return(0); } } pline("You hit the rock with all your might."); } return(1); } dighole() { register struct trap *ttmp = t_at(u.ux, u.uy); if(!xdnstair) { pline("The floor here seems too hard to dig in."); } else { if(ttmp) ttmp->ttyp = TRAPDOOR; else ttmp = maketrap(u.ux, u.uy, TRAPDOOR); ttmp->tseen = 1; pline("You've made a hole in the floor."); if(!u.ustuck) { pline("You fall through ..."); if(u.utraptype == TT_PIT) { u.utrap = 0; u.utraptype = 0; } goto_level(dlevel+1, FALSE); } } } static use_pick_axe(obj) struct obj *obj; { char dirsyms[12]; extern char sdir[]; register char *dsp = dirsyms, *sdp = sdir; register struct monst *mtmp; register struct rm *lev; register int rx, ry, res = 0; if(obj != uwep) { pline("You now wield %s.", doname(obj)); setuwep(obj); 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(ENORMOUS_ROCK, 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) pline("You cannot reach the ceiling."); else if(u.dz == 0) { if(Confusion) confdir(); rx = u.ux + u.dx; ry = u.uy + u.dy; if((mtmp = m_at(rx, ry)) && attack(mtmp)) return(1); if(!isok(rx, ry)) { pline("Clash!"); return(1); } lev = &levl[rx][ry]; if(lev->typ == DOOR) pline("Your %s against the door.", aobjnam(obj, "clang")); else if(!IS_ROCK(lev->typ) && !sobj_at(ENORMOUS_ROCK, rx, ry)) { /* ACCESSIBLE or POOL */ pline("You swing your %s through thin air.", aobjnam(obj, (char *) 0)); } 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; pline("You start digging."); } else pline("You continue digging."); occupation = dig; occtxt = "digging"; } } else if(Levitation) { pline("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; pline("You start digging in the floor."); } else pline("You continue digging in the floor."); occupation = dig; occtxt = "digging"; } return(1); } //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, 1985. */ /* hack.bones.c - version 1.0.2 */ #include "hack.h" extern char plname[PL_NSIZ]; extern long somegold(); extern struct monst *makemon(); extern struct permonst pm_ghost; char bones[] = "bones_xx"; /* save bones and possessions of a deceased adventurer */ savebones(){ register fd; register struct obj *otmp; register struct trap *ttmp; 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->olet == AMULET_SYM) otmp->spe = -1; /* no longer the actual amulet */ 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); for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ if(mtmp->mtame) { mtmp->mtame = 0; mtmp->mpeaceful = 0; } mtmp->mlstmv = 0; if(mtmp->mdispl) unpmon(mtmp); } for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) ttmp->tseen = 0; for(otmp = fobj; otmp; otmp = otmp->nobj) otmp->onamelth = 0; if((fd = creat(bones, FMASK)) < 0) return; savelev(fd,dlevel); (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){ getlev(fd, 0, dlevel); for(x = 0; x < COLNO; x++) for(y = 0; y < ROWNO; y++) levl[x][y].seen = levl[x][y].new = 0; } (void) close(fd); if(unlink(bones) < 0){ pline("Cannot unlink %s", bones); return(0); } return(ok); } //E*O*F hack.bones.c// echo x - hack.cmd.c cat > "hack.cmd.c" << '//E*O*F hack.cmd.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.cmd.c - version 1.0.2 */ #include "hack.h" #include "def.func_tab.h" int doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(),dopickup(), doversion(),doweararm(),dowearring(),doremarm(),doremring(),dopay(),doapply(), dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),doengrave(),dotele(), dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),doprwep(),doprarm(), doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(),doset(), doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(); #ifdef SHELL int dosh(); #endif SHELL #ifdef SUSPEND int dosuspend(); #endif SUSPEND struct func_tab cmdlist[]={ '\020', doredotopl, '\022', doredraw, '\024', dotele, #ifdef SUSPEND '\032', dosuspend, #endif SUSPEND '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', dotypeinv, /* Robert Viduya */ 'I', ddoinv, /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ /* 'o', doopen, */ 'O', doset, '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, ',', dopickup, ':', dolook, '^', doidtrap, '\\', dodiscovered, /* Robert Viduya */ WEAPON_SYM, doprwep, ARMOR_SYM, doprarm, RING_SYM, doprring, '$', doprgold, '#', doextcmd, 0,0,0 }; struct ext_func_tab extcmdlist[] = { "dip", dodip, (char *) 0, donull }; extern char *parse(), lowc(), unctrl(), quitchars[]; rhack(cmd) register char *cmd; { register struct func_tab *tlist = cmdlist; boolean firsttime = FALSE; register res; if(!cmd) { firsttime = TRUE; flags.nopick = 0; cmd = parse(); } if(!*cmd || *cmd == 0377 || (flags.no_rest_on_space && *cmd == ' ')){ bell(); flags.move = 0; return; /* probably we just had an interrupt */ } if(movecmd(*cmd)) { walk: if(multi) flags.mv = 1; domove(); return; } if(movecmd(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' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) { flags.run = 2; goto rush; } if(*cmd == 'F' && movecmd(lowc(cmd[1]))) { flags.run = 3; goto rush; } if(*cmd == 'm' && movecmd(cmd[1])) { flags.run = 0; flags.nopick = 1; goto walk; } if(*cmd == 'M' && movecmd(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++; } { char expcmd[10]; register char *cp = expcmd; while(*cmd && cp-expcmd < sizeof(expcmd)-2) { if(*cmd >= 040 && *cmd < 0177) *cp++ = *cmd++; else { *cp++ = '^'; *cp++ = *cmd++ ^ 0100; } } *cp++ = 0; pline("Unknown command '%s'", expcmd); } multi = flags.move = 0; } doextcmd() /* here after # - now read a full-word command */ { char buf[BUFSZ]; register struct ext_func_tab *efp = extcmdlist; pline("# "); getlin(buf); clrlin(); while(efp->ef_txt) { if(!strcmp(efp->ef_txt, buf)) return((*(efp->ef_funct))()); efp++; } pline("%s: unknown command.", buf); return(0); } char lowc(sym) char sym; { return( (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym ); } char unctrl(sym) char sym; { return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym ); } /* 'rogue'-like direction commands */ char sdir[] = "hykulnjb><"; schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 }; schar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 }; schar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,-1 }; movecmd(sym) /* also sets u.dz, but returns false for <> */ char sym; { register char *dp; u.dz = 0; if(!(dp = index(sdir, sym))) return(0); u.dx = xdir[dp-sdir]; u.dy = ydir[dp-sdir]; u.dz = zdir[dp-sdir]; return(!u.dz); } getdir(s) boolean s; { char dirsym; if(s) pline("In what direction?"); dirsym = readchar(); if(!movecmd(dirsym) && !u.dz) { if(!index(quitchars, dirsym)) pline("What a strange direction!"); return(0); } if(Confusion && !u.dz) confdir(); return(1); } confdir() { register x = rn2(8); u.dx = xdir[x]; u.dy = ydir[x]; } #ifdef QUEST finddir(){ register int i, ui = u.di; for(i = 0; i <= 8; i++){ if(flags.run & 1) ui++; else ui += 7; ui %= 8; if(i == 8){ pline("Not near a wall."); flags.move = multi = 0; return(0); } if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui])) break; } for(i = 0; i <= 8; i++){ if(flags.run & 1) ui += 7; else ui++; ui %= 8; if(i == 8){ pline("Not near a room."); flags.move = multi = 0; return(0); } if(isroom(u.ux+xdir[ui], u.uy+ydir[ui])) break; } u.di = ui; u.dx = xdir[ui]; u.dy = ydir[ui]; } isroom(x,y) register x,y; { /* what about POOL? */ return(isok(x,y) && (levl[x][y].typ == ROOM || (levl[x][y].typ >= LDOOR && flags.run >= 6))); } #endif QUEST isok(x,y) register x,y; { /* x corresponds to curx, so x==1 is the first column. Ach. %% */ return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1); } //E*O*F hack.cmd.c// echo x - hack.do.c cat > "hack.do.c" << '//E*O*F hack.do.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.do.c - version 1.0.2 */ /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */ #include "hack.h" extern struct obj *splitobj(), *addinv(); extern boolean hmon(); extern boolean level_exists[]; extern struct monst youmonst; extern char *Doname(); dodrop() { return(drop(getobj("0$#", "drop"))); } static drop(obj) register struct obj *obj; { if(!obj) return(0); if(obj->olet == '$') { /* pseudo object */ register long amount = OGOLD(obj); if(amount == 0) pline("You didn't drop any gold pieces."); else { mkgold(amount, u.ux, u.uy); pline("You dropped %ld gold piece%s.", amount, plur(amount)); if(Invis) newsym(u.ux, u.uy); } free((char *) obj); return(1); } 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); } /* Called in several places - should not produce texts */ dropx(obj) register struct obj *obj; { freeinv(obj); dropy(obj); } dropy(obj) register struct obj *obj; { if(obj->otyp == CRYSKNIFE) obj->otyp = WORM_TOOTH; 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)); } 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. * Another possibility is that the directory was not * writable. */ pline("A mysterious force prevents you from going %s.", up ? "up" : "down"); return; } if(Punished) unplacebc(); u.utrap = 0; /* needed in level_tele */ u.ustuck = 0; /* idem */ keepdogs(); seeoff(1); if(u.uswallow) /* idem */ u.uswldtim = u.uswallow = 0; flags.nscrinh = 1; u.ux = FAR; /* hack */ (void) inshop(); /* probably was a trapdoor */ savelev(fd,dlevel); (void) close(fd); dlevel = newlevel; if(maxdlevel < dlevel) maxdlevel = dlevel; glo(dlevel); if(!level_exists[dlevel]) mklev(); else { extern int hackpid; if((fd = open(lock,0)) < 0) { pline("Cannot open %s", lock); pline("Probably someone removed it."); more(); done("tricked"); } getlev(fd, hackpid, dlevel); (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"); } } { register struct monst *mtmp = m_at(u.ux, u.uy); if(mtmp) mnexto(mtmp); } } 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(); initrack(); losedogs(); flags.nscrinh = 0; setsee(); seeobjs(); /* make old cadavers disappear - riv05!a3 */ docrt(); { register struct monst *mtmp; if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */ } pickup(1); 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(1)) /* ask "in what direction?" */ 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(u.dz) { if(u.dz < 0) { pline("%s hits the ceiling, then falls back on top of your head.", Doname(obj)); /* note: obj->quan == 1 */ if(obj->olet == POTION_SYM) potionhit(&youmonst, obj); else { if(uarmh) pline("Fortunately, you are wearing a helmet!"); losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object"); dropy(obj); } } else { pline("%s hits the floor.", Doname(obj)); if(obj->otyp == EXPENSIVE_CAMERA) { pline("It is shattered in a thousand pieces!"); obfree(obj, Null(obj)); } else if(obj->otyp == EGG) { pline("\"Splash!\""); obfree(obj, Null(obj)); } else if(obj->olet == POTION_SYM) { pline("The flask breaks, and you smell a peculiar odor ..."); potionbreathe(obj); obfree(obj, Null(obj)); } else { dropy(obj); } } return(1); } else if(obj->otyp == BOOMERANG) { mon = boomhit(u.dx, u.dy); if(mon == &youmonst) { /* the thing was caught */ (void) addinv(obj); return(1); } } else { if(obj->otyp == PICK_AXE && shkcatch(obj)) return(1); mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 : (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, obj->olet, (int (*)()) 0, (int (*)()) 0, obj); } 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(obj->olet == POTION_SYM && u.ulevel > rn2(15)) { potionhit(mon, obj); return(1); } 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' && !mon->mtame){ 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); } } } } /* the code following might become part of dropy() */ if(obj->otyp == CRYSKNIFE) obj->otyp = WORM_TOOTH; 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 long 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); } /* 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); } more_experienced(exp,rexp) register int exp, rexp; { extern char pl_character[]; u.uexp += exp; u.urexp += 4*exp + rexp; if(exp) flags.botl = 1; if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000)) flags.beginner = 0; } //E*O*F hack.do.c// echo x - hack.do_name.c cat > "hack.do_name.c" << '//E*O*F hack.do_name.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.do_name.c - version 1.0.2 */ #include "hack.h" #include extern char plname[]; coord getpos(force,goal) int force; char *goal; { register cx,cy,i,c; extern char sdir[]; /* defined in hack.c */ extern schar xdir[], ydir[]; /* idem */ extern char *visctrl(); /* see below */ coord cc; pline("(For instructions type a ?)"); cx = u.ux; cy = u.uy; curs(cx,cy+2); while((c = readchar()) != '.'){ for(i=0; i<8; i++) if(sdir[i] == c){ if(1 <= cx + xdir[i] && cx + xdir[i] <= COLNO) cx += xdir[i]; if(0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO-1) cy += ydir[i]; goto nxtc; } if(c == '?'){ pline("Use [hjkl] to move the cursor to %s.", goal); pline("Type a . when you are at the right place."); } else { pline("unknown direction: '%s' (%s)", visctrl(c), force ? "use hjkl or ." : "aborted"); if(force) goto nxtc; cc.x = -1; cc.y = 0; return(cc); } nxtc: ; curs(cx,cy+2); } cc.x = cx; cc.y = cy; return(cc); } do_mname(){ char buf[BUFSZ]; coord cc; register int cx,cy,lth,i; register struct monst *mtmp, *mtmp2; extern char *lmonnam(); cc = getpos(0, "the monster you want to name"); cx = cc.x; cy = cc.y; if(cx < 0) return(0); mtmp = m_at(cx,cy); if(!mtmp){ if(cx == u.ux && cy == u.uy) pline("This ugly monster is called %s and cannot be renamed.", plname); else pline("There is no monster there."); return(1); } if(mtmp->mimic){ pline("I see no monster there."); return(1); } if(!cansee(cx,cy)) { pline("I cannot see a monster there."); return(1); } pline("What do you want to call %s? ", lmonnam(mtmp)); getlin(buf); clrlin(); if(!*buf) return(1); lth = strlen(buf)+1; if(lth > 63){ buf[62] = 0; lth = 63; } mtmp2 = newmonst(mtmp->mxlth + lth); *mtmp2 = *mtmp; for(i=0; imxlth; i++) ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i]; mtmp2->mnamelth = lth; (void) strcpy(NAME(mtmp2), buf); replmon(mtmp,mtmp2); return(1); } /* * This routine changes the address of obj . Be careful not to call it * when there might be pointers around in unknown places. For now: only * when obj is in the inventory. */ do_oname(obj) register struct obj *obj; { register struct obj *otmp, *otmp2; register lth; char buf[BUFSZ]; pline("What do you want to name %s? ", doname(obj)); getlin(buf); clrlin(); if(!*buf) return; lth = strlen(buf)+1; if(lth > 63){ buf[62] = 0; lth = 63; } otmp2 = newobj(lth); *otmp2 = *obj; otmp2->onamelth = lth; (void) strcpy(ONAME(otmp2), buf); setworn((struct obj *) 0, obj->owornmask); setworn(otmp2, otmp2->owornmask); /* do freeinv(obj); etc. by hand in order to preserve the position of this object in the inventory */ if(obj == invent) invent = otmp2; else for(otmp = invent; ; otmp = otmp->nobj){ if(!otmp) panic("Do_oname: cannot find obj."); if(otmp->nobj == obj){ otmp->nobj = otmp2; break; } } /* obfree(obj, otmp2); /* now unnecessary: no pointers on bill */ free((char *) obj); /* let us hope nobody else saved a pointer */ } ddocall() { register struct obj *obj; pline("Do you want to name an individual object? [yn] "); if(readchar() == 'y'){ obj = getobj("#", "name"); if(obj) do_oname(obj); } else { obj = getobj("?!=/", "call"); if(obj) docall(obj); } return(0); } docall(obj) register struct obj *obj; { char buf[BUFSZ]; struct obj otemp; register char **str1; extern char *xname(); register char *str; otemp = *obj; otemp.quan = 1; str = xname(&otemp); pline("Call %s %s: ", index(vowels,*str) ? "an" : "a", str); getlin(buf); clrlin(); if(!*buf) return; str = newstring(strlen(buf)+1); (void) strcpy(str,buf); str1 = &(objects[obj->otyp].oc_uname); if(*str1) free(*str1); *str1 = str; } char *ghostnames[] = { /* these names should have length < PL_NSIZ */ "adri", "andries", "david", "dirk", "emile", "fred", "hether", "jay", "jon", "kenny", "maud", "michiel", "mike", "robert", "ron", "tom", "wilmar" }; char * xmonnam(mtmp, vb) register struct monst *mtmp; int vb; { static char buf[BUFSZ]; /* %% */ extern char *shkname(); if(mtmp->mnamelth && !vb) { (void) strcpy(buf, NAME(mtmp)); return(buf); } switch(mtmp->data->mlet) { case ' ': { register char *gn = (char *) mtmp->mextra; if(!*gn) { /* might also look in scorefile */ gn = ghostnames[rn2(SIZE(ghostnames))]; if(!rn2(2)) (void) strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn); } (void) sprintf(buf, "%s's ghost", gn); } break; case '@': if(mtmp->isshk) { (void) strcpy(buf, shkname(mtmp)); break; } /* fall into next case */ default: (void) sprintf(buf, "the %s%s", mtmp->minvis ? "invisible " : "", mtmp->data->mname); } if(vb && mtmp->mnamelth) { (void) strcat(buf, " called "); (void) strcat(buf, NAME(mtmp)); } return(buf); } char * lmonnam(mtmp) register struct monst *mtmp; { return(xmonnam(mtmp, 1)); } char * monnam(mtmp) register struct monst *mtmp; { return(xmonnam(mtmp, 0)); } char * Monnam(mtmp) register struct monst *mtmp; { register char *bp = monnam(mtmp); if('a' <= *bp && *bp <= 'z') *bp += ('A' - 'a'); return(bp); } char * amonnam(mtmp,adj) register struct monst *mtmp; register char *adj; { register char *bp = monnam(mtmp); static char buf[BUFSZ]; /* %% */ if(!strncmp(bp, "the ", 4)) bp += 4; (void) sprintf(buf, "the %s %s", adj, bp); return(buf); } char * Amonnam(mtmp, adj) register struct monst *mtmp; register char *adj; { register char *bp = amonnam(mtmp,adj); *bp = 'T'; return(bp); } char * Xmonnam(mtmp) register struct monst *mtmp; { register char *bp = Monnam(mtmp); if(!strncmp(bp, "The ", 4)) { bp += 2; *bp = 'A'; } return(bp); } char * visctrl(c) char c; { static char ccc[3]; if(c < 040) { ccc[0] = '^'; ccc[1] = c + 0100; ccc[2] = 0; } else { ccc[0] = c; ccc[1] = 0; } return(ccc); } //E*O*F hack.do_name.c// echo x - hack.do_wear.c cat > "hack.do_wear.c" << '//E*O*F hack.do_wear.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.do_wear.c - version 1.0.2 */ #include "hack.h" #include extern char *nomovemsg; extern char quitchars[]; off_msg(otmp) register struct obj *otmp; { pline("You were wearing %s.", doname(otmp)); } doremarm() { register struct obj *otmp; if(!uarm && !uarmh && !uarms && !uarmg) { pline("Not wearing any armor."); return(0); } otmp = (!uarmh && !uarms && !uarmg) ? uarm : (!uarms && !uarm && !uarmg) ? uarmh : (!uarmh && !uarm && !uarmg) ? uarms : (!uarmh && !uarm && !uarms) ? uarmg : getobj("[", "take off"); if(!otmp) return(0); if(!(otmp->owornmask & (W_ARMOR - W_ARM2))) { pline("You can't take that off."); return(0); } (void) armoroff(otmp); return(1); } doremring() { if(!uleft && !uright){ pline("Not wearing any ring."); return(0); } if(!uleft) return(dorr(uright)); if(!uright) return(dorr(uleft)); if(uleft && uright) while(1) { char answer; pline("What ring, Right or Left? "); if(index(quitchars, (answer = readchar()))) return(0); switch(answer) { case 'l': case 'L': return(dorr(uleft)); case 'r': case 'R': return(dorr(uright)); } } /* NOTREACHED */ #ifdef lint return(0); #endif lint } dorr(otmp) register struct obj *otmp; { if(cursed(otmp)) return(0); ringoff(otmp); off_msg(otmp); return(1); } cursed(otmp) register struct obj *otmp; { if(otmp->cursed){ pline("You can't. It appears to be cursed."); return(1); } return(0); } armoroff(otmp) register struct obj *otmp; { register int delay = -objects[otmp->otyp].oc_delay; if(cursed(otmp)) return(0); setworn((struct obj *) 0, otmp->owornmask & W_ARMOR); if(delay) { nomul(delay); switch(otmp->otyp) { case HELMET: nomovemsg = "You finished taking off your helmet."; break; case PAIR_OF_GLOVES: nomovemsg = "You finished taking off your gloves"; break; default: nomovemsg = "You finished taking off your suit."; } } else { off_msg(otmp); } return(1); } doweararm() { register struct obj *otmp; register int delay; register int err = 0; long mask = 0; otmp = getobj("[", "wear"); if(!otmp) return(0); if(otmp->owornmask & W_ARMOR) { pline("You are already wearing that!"); return(0); } if(otmp->otyp == HELMET){ if(uarmh) { pline("You are already wearing a helmet."); err++; } else mask = W_ARMH; } else if(otmp->otyp == SHIELD){ if(uarms) pline("You are already wearing a shield."), err++; if(uwep && uwep->otyp == TWO_HANDED_SWORD) pline("You cannot wear a shield and wield a two-handed sword."), err++; if(!err) mask = W_ARMS; } else if(otmp->otyp == PAIR_OF_GLOVES) { if(uarmg) { pline("You are already wearing gloves."); err++; } else if(uwep && uwep->cursed) { pline("You cannot wear gloves over your weapon."); err++; } else mask = W_ARMG; } else { if(uarm) { if(otmp->otyp != ELVEN_CLOAK || uarm2) { pline("You are already wearing some armor."); err++; } } if(!err) mask = W_ARM; } if(err) return(0); setworn(otmp, mask); if(otmp == uwep) setuwep((struct obj *) 0); delay = -objects[otmp->otyp].oc_delay; if(delay){ nomul(delay); nomovemsg = "You finished your dressing manoeuvre."; } otmp->known = 1; return(1); } dowearring() { register struct obj *otmp; long mask = 0; long oldprop; if(uleft && uright){ pline("There are no more ring-fingers to fill."); return(0); } otmp = getobj("=", "wear"); if(!otmp) return(0); if(otmp->owornmask & W_RING) { pline("You are already wearing that!"); return(0); } if(otmp == uleft || otmp == uright) { pline("You are already wearing that."); return(0); } if(uleft) mask = RIGHT_RING; else if(uright) mask = LEFT_RING; else do { char answer; pline("What ring-finger, Right or Left? "); if(index(quitchars, (answer = readchar()))) return(0); switch(answer){ case 'l': case 'L': mask = LEFT_RING; break; case 'r': case 'R': mask = RIGHT_RING; break; } } while(!mask); setworn(otmp, mask); if(otmp == uwep) setuwep((struct obj *) 0); oldprop = u.uprops[PROP(otmp->otyp)].p_flgs; u.uprops[PROP(otmp->otyp)].p_flgs |= mask; switch(otmp->otyp){ case RIN_LEVITATION: if(!oldprop) float_up(); break; case RIN_PROTECTION_FROM_SHAPE_CHANGERS: rescham(); break; case RIN_GAIN_STRENGTH: u.ustr += otmp->spe; u.ustrmax += otmp->spe; if(u.ustr > 118) u.ustr = 118; if(u.ustrmax > 118) u.ustrmax = 118; flags.botl = 1; break; case RIN_INCREASE_DAMAGE: u.udaminc += otmp->spe; break; } prinv(otmp); return(1); } ringoff(obj) register struct obj *obj; { register long mask; mask = obj->owornmask & W_RING; setworn((struct obj *) 0, obj->owornmask); if(!(u.uprops[PROP(obj->otyp)].p_flgs & mask)) impossible("Strange... I didnt know you had that ring."); u.uprops[PROP(obj->otyp)].p_flgs &= ~mask; switch(obj->otyp) { case RIN_LEVITATION: if(!Levitation) { /* no longer floating */ float_down(); } break; case RIN_GAIN_STRENGTH: u.ustr -= obj->spe; u.ustrmax -= obj->spe; if(u.ustr > 118) u.ustr = 118; if(u.ustrmax > 118) u.ustrmax = 118; flags.botl = 1; break; case RIN_INCREASE_DAMAGE: u.udaminc -= obj->spe; break; } } find_ac(){ register int uac = 10; #define ARM_BONUS(obj) ((10 - objects[obj->otyp].a_ac) + obj->spe) if(uarm) uac -= ARM_BONUS(uarm); if(uarm2) uac -= ARM_BONUS(uarm2); if(uarmh) uac -= ARM_BONUS(uarmh); if(uarms) uac -= ARM_BONUS(uarms); if(uarmg) uac -= ARM_BONUS(uarmg); if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe; if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe; if(uac != u.uac){ u.uac = uac; flags.botl = 1; } } glibr(){ register struct obj *otmp; int xfl = 0; if(!uarmg) if(uleft || uright) { /* Note: at present also cursed rings fall off */ pline("Your %s off your fingers.", (uleft && uright) ? "rings slip" : "ring slips"); xfl++; if((otmp = uleft) != Null(obj)){ ringoff(uleft); dropx(otmp); } if((otmp = uright) != Null(obj)){ ringoff(uright); dropx(otmp); } } if((otmp = uwep) != Null(obj)){ /* Note: at present also cursed weapons fall */ setuwep((struct obj *) 0); dropx(otmp); pline("Your weapon %sslips from your hands.", xfl ? "also " : ""); } } struct obj * some_armor(){ register struct obj *otmph = uarm; if(uarmh && (!otmph || !rn2(4))) otmph = uarmh; if(uarmg && (!otmph || !rn2(4))) otmph = uarmg; if(uarms && (!otmph || !rn2(4))) otmph = uarms; return(otmph); } corrode_armor(){ register struct obj *otmph = some_armor(); if(otmph){ if(otmph->rustfree || otmph->otyp == ELVEN_CLOAK || otmph->otyp == LEATHER_ARMOR || otmph->otyp == STUDDED_LEATHER_ARMOR) { pline("Your %s not affected!", aobjnam(otmph, "are")); return; } pline("Your %s!", aobjnam(otmph, "corrode")); otmph->spe--; } } //E*O*F hack.do_wear.c// echo x - hack.dog.c cat > "hack.dog.c" << '//E*O*F hack.dog.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.dog.c - version 1.0.2 */ #include "hack.h" #include "hack.mfndpos.h" extern struct monst *makemon(); #include "def.edog.h" #include "def.mkroom.h" struct permonst li_dog = { "little dog", 'd',2,18,6,1,6,sizeof(struct edog) }; struct permonst dog = { "dog", 'd',4,16,5,1,6,sizeof(struct edog) }; struct permonst la_dog = { "large dog", 'd',6,15,4,2,4,sizeof(struct edog) }; makedog(){ register struct monst *mtmp = makemon(&li_dog,u.ux,u.uy); if(!mtmp) return; /* dogs were genocided */ initedog(mtmp); } initedog(mtmp) register struct monst *mtmp; { mtmp->mtame = mtmp->mpeaceful = 1; EDOG(mtmp)->hungrytime = 1000 + moves; EDOG(mtmp)->eattime = 0; EDOG(mtmp)->droptime = 0; EDOG(mtmp)->dropdist = 10000; EDOG(mtmp)->apport = 10; EDOG(mtmp)->whistletime = 0; } /* attach the monsters that went down (or up) together with @ */ struct monst *mydogs = 0; struct monst *fallen_down = 0; /* monsters that fell through a trapdoor */ losedogs(){ register struct monst *mtmp; while(mtmp = mydogs){ mydogs = mtmp->nmon; mtmp->nmon = fmon; fmon = mtmp; mnexto(mtmp); } while(mtmp = fallen_down){ fallen_down = mtmp->nmon; mtmp->nmon = fmon; fmon = mtmp; rloc(mtmp); } } keepdogs(){ register struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp)) { relmon(mtmp); mtmp->nmon = mydogs; mydogs = mtmp; unpmon(mtmp); keepdogs(); /* we destroyed the link, so use recursion */ return; /* (admittedly somewhat primitive) */ } } fall_down(mtmp) register struct monst *mtmp; { relmon(mtmp); mtmp->nmon = fallen_down; fallen_down = mtmp; unpmon(mtmp); mtmp->mtame = 0; } /* return quality of food; the lower the better */ #define DOGFOOD 0 #define CADAVER 1 #define ACCFOOD 2 #define MANFOOD 3 #define APPORT 4 #define POISON 5 #define UNDEF 6 dogfood(obj) register struct obj *obj; { switch(obj->olet) { case FOOD_SYM: return( (obj->otyp == TRIPE_RATION) ? DOGFOOD : (obj->otyp < CARROT) ? ACCFOOD : (obj->otyp < CORPSE) ? MANFOOD : (poisonous(obj) || obj->age + 50 <= moves || obj->otyp == DEAD_COCKATRICE) ? POISON : CADAVER ); default: if(!obj->cursed) return(APPORT); /* fall into next case */ case BALL_SYM: case CHAIN_SYM: case ROCK_SYM: return(UNDEF); } } /* return 0 (no move), 1 (move) or 2 (dead) */ dog_move(mtmp, after) register struct monst *mtmp; { register int nx,ny,omx,omy,appr,nearer,j; int udist,chi,i,whappr; register struct monst *mtmp2; register struct permonst *mdat = mtmp->data; register struct edog *edog = EDOG(mtmp); struct obj *obj; struct trap *trap; xchar cnt,chcnt,nix,niy; schar dogroom,uroom; xchar gx,gy,gtyp,otyp; /* current goal */ coord poss[9]; int info[9]; #define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy)) #define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy)) if(moves <= edog->eattime) return(0); /* dog is still eating */ omx = mtmp->mx; omy = mtmp->my; whappr = (moves - EDOG(mtmp)->whistletime < 5); if(moves > edog->hungrytime + 500 && !mtmp->mconf){ mtmp->mconf = 1; mtmp->mhpmax /= 3; if(mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; if(cansee(omx,omy)) pline("%s is confused from hunger", Monnam(mtmp)); else pline("You feel worried about %s.", monnam(mtmp)); } else if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){ if(cansee(omx,omy)) pline("%s dies from hunger", Monnam(mtmp)); else pline("You have a sad feeling for a moment, then it passes"); mondied(mtmp); return(2); } dogroom = inroom(omx,omy); uroom = inroom(u.ux,u.uy); udist = dist(omx,omy); /* if we are carrying sth then we drop it (perhaps near @) */ /* Note: if apport == 1 then our behaviour is independent of udist */ if(mtmp->minvent){ if(!rn2(udist) || !rn2((int) edog->apport)) if(rn2(10) < edog->apport){ relobj(mtmp, (int) mtmp->minvis); if(edog->apport > 1) edog->apport--; } } else { if(obj = o_at(omx,omy)) if(!index("0_", obj->olet)){ if((otyp = dogfood(obj)) <= CADAVER){ nix = omx; niy = omy; goto eatobj; } if(obj->owt < 10*mtmp->data->mlevel) if(rn2(20) < edog->apport+3) if(rn2(udist) || !rn2((int) edog->apport)){ freeobj(obj); unpobj(obj); /* if(levl[omx][omy].scrsym == obj->olet) newsym(omx,omy); */ mpickobj(mtmp,obj); } } } /* first we look for food */ gtyp = UNDEF; /* no goal as yet */ #ifdef LINT gx = gy = 0; /* suppress 'used before set' message */ #endif LINT for(obj = fobj; obj; obj = obj->nobj) { otyp = dogfood(obj); if(otyp > gtyp || otyp == UNDEF) continue; if(inroom(obj->ox,obj->oy) != dogroom) continue; if(otyp < MANFOOD && (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) { if(otyp < gtyp || (otyp == gtyp && DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){ gx = obj->ox; gy = obj->oy; gtyp = otyp; } } else if(gtyp == UNDEF && dogroom >= 0 && uroom == dogroom && !mtmp->minvent && edog->apport > rn2(8)){ gx = obj->ox; gy = obj->oy; gtyp = APPORT; } } if(gtyp == UNDEF || (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){ if(dogroom < 0 || dogroom == uroom){ gx = u.ux; gy = u.uy; #ifndef QUEST } else { int tmp = rooms[dogroom].fdoor; cnt = rooms[dogroom].doorct; gx = gy = FAR; /* random, far away */ while(cnt--){ if(dist(gx,gy) > dist(doors[tmp].x, doors[tmp].y)){ gx = doors[tmp].x; gy = doors[tmp].y; } tmp++; } /* here gx == FAR e.g. when dog is in a vault */ if(gx == FAR || (gx == omx && gy == omy)){ gx = u.ux; gy = u.uy; } #endif QUEST } appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0; if(after && udist <= 4 && gx == u.ux && gy == u.uy) return(0); if(udist > 1){ if(!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) || whappr || (mtmp->minvent && rn2((int) edog->apport))) appr = 1; } /* if you have dog food he'll follow you more closely */ if(appr == 0){ obj = invent; while(obj){ if(obj->otyp == TRIPE_RATION){ appr = 1; break; } obj = obj->nobj; } } } else appr = 1; /* gtyp != UNDEF */ if(mtmp->mconf) appr = 0; if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){ extern coord *gettrack(); register coord *cp; cp = gettrack(omx,omy); if(cp){ gx = cp->x; gy = cp->y; } } nix = omx; niy = omy; cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS); chcnt = 0; chi = -1; for(i=0; idata->mlevel >= mdat->mlevel+2 || mtmp2->data->mlet == 'c') continue; if(after) return(0); /* hit only once each move */ if(hitmm(mtmp, mtmp2) == 1 && rn2(4) && mtmp2->mlstmv != moves && hitmm(mtmp2,mtmp) == 2) return(2); return(0); } /* dog avoids traps */ /* but perhaps we have to pass a trap in order to follow @ */ if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){ if(!trap->tseen && rn2(40)) continue; if(rn2(10)) continue; } /* dog eschewes cursed objects */ /* but likes dog food */ obj = fobj; while(obj){ if(obj->ox != nx || obj->oy != ny) goto nextobj; if(obj->cursed) goto nxti; if(obj->olet == FOOD_SYM && (otyp = dogfood(obj)) < MANFOOD && (otyp < ACCFOOD || edog->hungrytime <= moves)){ /* Note: our dog likes the food so much that he might eat it even when it conceals a cursed object */ nix = nx; niy = ny; chi = i; eatobj: edog->eattime = moves + obj->quan * objects[obj->otyp].oc_delay; edog->hungrytime = moves + 5*obj->quan * objects[obj->otyp].nutrition; mtmp->mconf = 0; if(cansee(nix,niy)) pline("%s ate %s.", Monnam(mtmp), doname(obj)); /* perhaps this was a reward */ if(otyp != CADAVER) edog->apport += 200/(edog->dropdist+moves-edog->droptime); delobj(obj); goto newdogpos; } nextobj: obj = obj->nobj; } for(j=0; jmtrack[j].x && ny == mtmp->mtrack[j].y) if(rn2(4*(cnt-j))) goto nxti; /* Some stupid C compilers cannot compute the whole expression at once. */ nearer = GDIST(nx,ny); nearer -= GDIST(nix,niy); nearer *= appr; if((nearer == 0 && !rn2(++chcnt)) || nearer<0 || (nearer > 0 && !whappr && ((omx == nix && omy == niy && !rn2(3)) || !rn2(12)) )){ nix = nx; niy = ny; if(nearer < 0) chcnt = 0; chi = i; } nxti: ; } newdogpos: if(nix != omx || niy != omy){ if(info[chi] & ALLOW_U){ (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1); return(0); } mtmp->mx = nix; mtmp->my = niy; for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; mtmp->mtrack[0].x = omx; mtmp->mtrack[0].y = omy; } if(mintrap(mtmp) == 2) /* he died */ return(2); pmon(mtmp); return(1); } /* return roomnumber or -1 */ inroom(x,y) xchar x,y; { #ifndef QUEST register struct mkroom *croom = &rooms[0]; while(croom->hx >= 0){ if(croom->hx >= x-1 && croom->lx <= x+1 && croom->hy >= y-1 && croom->ly <= y+1) return(croom - rooms); croom++; } #endif QUEST return(-1); /* not in room or on door */ } tamedog(mtmp, obj) register struct monst *mtmp; register struct obj *obj; { register struct monst *mtmp2; if(flags.moonphase == FULL_MOON && night() && rn2(6)) return(0); /* If we cannot tame him, at least he's no longer afraid. */ mtmp->mflee = 0; mtmp->mfleetim = 0; if(mtmp->mtame || mtmp->mfroz || #ifndef NOWORM mtmp->wormno || #endif NOWORM mtmp->isshk || mtmp->isgd) return(0); /* no tame long worms? */ if(obj) { if(dogfood(obj) >= MANFOOD) return(0); if(cansee(mtmp->mx,mtmp->my)){ pline("%s devours the %s.", Monnam(mtmp), objects[obj->otyp].oc_name); } obfree(obj, (struct obj *) 0); } mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth); *mtmp2 = *mtmp; mtmp2->mxlth = sizeof(struct edog); if(mtmp->mnamelth) (void) strcpy(NAME(mtmp2), NAME(mtmp)); initedog(mtmp2); replmon(mtmp,mtmp2); return(1); } //E*O*F hack.dog.c// exit 0