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 12 of 15) Message-ID: <6254@mcvax.UUCP> Date: Mon, 17-Dec-84 19:39:46 EST Article-I.D.: mcvax.6254 Posted: Mon Dec 17 19:39:46 1984 Date-Received: Wed, 19-Dec-84 02:17:59 EST Organization: CWI, Amsterdam Lines: 1111 # This is part 12 (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.track.c hack.trap.c hack.tty.c hack.u_init.c hack.vault.c hack.version.c echo x - hack.track.c cat > "hack.track.c" << '//E*O*F hack.track.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" #ifdef TRACK #define UTSZ 50 coord utrack[UTSZ]; int utcnt = 0; int utpnt = 0; initrack(){ utcnt = utpnt = 0; } /* add to track */ settrack(){ if(utcnt < UTSZ) utcnt++; if(utpnt == UTSZ) utpnt = 0; utrack[utpnt].x = u.ux; utrack[utpnt].y = u.uy; utpnt++; } coord * gettrack(x,y) register x,y; { register int i,cnt; coord tc; cnt = utcnt; for(i = utpnt-1; cnt--; i--){ if(i == -1) i = UTSZ-1; tc = utrack[i]; if((x-tc.x)*(x-tc.x) + (y-tc.y)*(y-tc.y) < 3) return(&(utrack[i])); } return(0); } #endif TRACK //E*O*F hack.track.c// echo x - hack.trap.c cat > "hack.trap.c" << '//E*O*F hack.trap.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" #include "def.trap.h" extern struct monst *makemon(); char vowels[] = "aeiou"; char *traps[] = { " bear trap", "n arrow trap", " dart trap", " trapdoor", " teleportation trap", " pit", " sleeping gas trap", " piercer", " mimic" }; dotrap(trap) register struct gen *trap; { nomul(0); if(trap->gflag&SEEN && !rn2(5)) pline("You escape a%s.",traps[trap->gflag&037]); else { trap->gflag |= SEEN; switch(trap->gflag & ~SEEN) { case SLP_GAS_TRAP: pline("A cloud of gas puts you to sleep!"); nomul(-rnd(25)); break; case BEAR_TRAP: if(Levitation) { pline("You float over a bear trap."); break; } u.utrap = 4 + rn2(4); u.utraptype = TT_BEARTRAP; pline("A bear trap closes on your foot!"); break; case PIERC: deltrap(trap); if(makemon(PM_PIERC,u.ux,u.uy)) { pline("A piercer suddenly drops from the ceiling!"); if(uarmh) pline("Its blow glances off your helmet."); else (void) thitu(3,d(4,6),"falling piercer"); } break; case ARROW_TRAP: pline("An arrow shoots out at you!"); if(!thitu(8,rnd(6),"arrow")){ mksobj_at(WEAPON_SYM, ARROW, u.ux, u.uy); fobj->quan = 1; } break; case TRAPDOOR: if(!xdnstair) { pline("A trap door in the ceiling opens and a rock falls on your head!"); if(uarmh) pline("Fortunately, you are wearing a helmet!"); losehp(uarmh ? 2 : d(2,10),"falling rock"); } else { register int newlevel = dlevel + 1; while(!rn2(4) && newlevel < 29) newlevel++; pline("A trap door opens up under you!"); if(Levitation || u.ustuck) { pline("For some reason you don't fall in."); break; } goto_level(newlevel, FALSE); } break; case DART_TRAP: pline("A little dart shoots out at you!"); if(thitu(7,rnd(3),"little dart")) { if(!rn2(6)) poisoned("dart","poison dart"); } else { mksobj_at(WEAPON_SYM, DART, u.ux, u.uy); fobj->quan = 1; } break; case TELEP_TRAP: newsym(u.ux,u.uy); tele(); break; case PIT: if(Levitation) { pline("A pit opens up under you!"); pline("You don't fall in!"); break; } pline("You fall into a pit!"); u.utrap = rn1(6,2); u.utraptype = TT_PIT; losehp(rnd(6),"fall into a pit"); selftouch("Falling, you"); break; default: pline("You hit a trap of type %d",trap->gflag); impossible(); } } } mintrap(mtmp) register struct monst *mtmp; { register struct gen *gen = g_at(mtmp->mx, mtmp->my, ftrap); register int wasintrap = mtmp->mtrapped; if(!gen) { mtmp->mtrapped = 0; /* perhaps teleported? */ } else if(wasintrap) { if(!rn2(40)) mtmp->mtrapped = 0; } else { register int tt = (gen->gflag & ~SEEN); int in_sight = cansee(mtmp->mx,mtmp->my); extern char mlarge[]; if(mtmp->mtrapseen & (1 << tt)) { /* he has been in such a trap - perhaps he escapes */ if(rn2(4)) return(0); } mtmp->mtrapseen |= (1 << tt); switch (tt) { case BEAR_TRAP: if(index(mlarge, mtmp->data->mlet)) { if(in_sight) pline("%s is caught in a bear trap!", Monnam(mtmp)); else if(mtmp->data->mlet == 'o') pline("You hear the roaring of an angry bear!"); mtmp->mtrapped = 1; } break; case PIT: if(!index("Eyw", mtmp->data->mlet)) { mtmp->mtrapped = 1; if(in_sight) pline("%s falls in a pit!", Monnam(mtmp)); } break; case SLP_GAS_TRAP: if(!mtmp->msleep && !mtmp->mfroz) { mtmp->msleep = 1; if(in_sight) pline("%s suddenly falls asleep!", Monnam(mtmp)); } break; case TELEP_TRAP: rloc(mtmp); if(in_sight && !cansee(mtmp->mx,mtmp->my)) pline("%s suddenly disappears!", Monnam(mtmp)); break; case ARROW_TRAP: if(in_sight) { pline("%s is hit by an arrow!", Monnam(mtmp)); } mtmp->mhp -= 3; break; case DART_TRAP: if(in_sight) { pline("%s is hit by a dart!", Monnam(mtmp)); } mtmp->mhp -= 2; /* not mondied here !! */ break; case TRAPDOOR: if(!xdnstair) { mtmp->mhp -= 10; if(in_sight) pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp)); break; } if(mtmp->data->mlet != 'w'){ fall_down(mtmp); if(in_sight) pline("Suddenly, %s disappears out of sight.", monnam(mtmp)); return(2); /* no longer on this level */ } break; case PIERC: break; default: pline("Some monster encountered an impossible trap."); impossible(); } } return(mtmp->mtrapped); } selftouch(arg) char *arg; { if(uwep && uwep->otyp == DEAD_COCKATRICE){ pline("%s touch the dead cockatrice.", arg); pline("You turn to stone."); killer = objects[uwep->otyp].oc_name; done("died"); } } float_up(){ if(u.utrap) { if(u.utraptype == TT_PIT) { u.utrap = 0; pline("You float up, out of the pit!"); } else { pline("You float up, only your leg is still stuck."); } } else pline("You start to float in the air!"); } float_down(){ register struct gen *trap; pline("You float gently to the ground."); if(trap = g_at(u.ux,u.uy,ftrap)) switch(trap->gflag & 037) { case PIERC: break; case TRAPDOOR: if(!xdnstair || u.ustuck) break; /* fall into next case */ default: dotrap(trap); } pickup(); } tele() { extern coord getpos(); coord cc; register int nux,nuy; if(Teleport_control) { pline("To what position do you want to be teleported?"); cc = getpos(1, "the desired position"); /* 1: force valid */ /* possible extensions: introduce a small error if magic power is low; allow transfer to solid rock */ if(teleok(cc.x, cc.y)){ nux = cc.x; nuy = cc.y; goto gotpos; } pline("Sorry ..."); } do { nux = rnd(COLNO-1); nuy = rn2(ROWNO); } while(!teleok(nux, nuy)); gotpos: if(Punished) unplacebc(); unsee(); u.utrap = 0; u.ustuck = 0; u.ux = nux; u.uy = nuy; setsee(); if(Punished) placebc(1); if(u.uswallow){ u.uswldtim = u.uswallow = 0; docrt(); } nomul(0); (void) inshop(); pickup(); if(!Blind) read_engr_at(u.ux,u.uy); } teleok(x,y) register int x,y; { return( isok(x,y) && levl[x][y].typ > DOOR && !m_at(x,y) && !sobj_at(ENORMOUS_ROCK,x,y) && !g_at(x,y,ftrap) ); /* Note: gold is permitted (because of vaults) */ } placebc(attach) int attach; { if(!uchain || !uball){ pline("Where are your chain and ball??"); impossible(); return; } uball->ox = uchain->ox = u.ux; uball->oy = uchain->oy = u.uy; if(attach){ uchain->nobj = fobj; fobj = uchain; if(!carried(uball)){ uball->nobj = fobj; fobj = uball; } } } unplacebc(){ if(!carried(uball)){ freeobj(uball); unpobj(uball); } freeobj(uchain); unpobj(uchain); } level_tele() { register int newlevel = 5 + rn2(20); /* 5 - 24 */ if(dlevel == newlevel) if(!xdnstair) newlevel--; else newlevel++; goto_level(newlevel, FALSE); } //E*O*F hack.trap.c// echo x - hack.tty.c cat > "hack.tty.c" << '//E*O*F hack.tty.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" #include #include struct sgttyb inittyb, curttyb; extern short ospeed; gettty(){ (void) gtty(0, &inittyb); (void) gtty(0, &curttyb); ospeed = inittyb.sg_ospeed; /* if(ospeed <= B300) flags.oneline = 1; */ getioctls(); xtabs(); } /* reset terminal to original state */ settty(s) char *s; { clear_screen(); if(s) printf(s); (void) fflush(stdout); if(stty(0, &inittyb) == -1) puts("Cannot change tty"); flags.echo = (inittyb.sg_flags & ECHO) ? ON : OFF; flags.cbreak = (inittyb.sg_flags & CBREAK) ? ON : OFF; setioctls(); } setctty(){ if(stty(0, &curttyb) == -1) puts("Cannot change tty"); } setftty(){ register int ef = (flags.echo == ON) ? ECHO : 0; register int cf = (flags.cbreak == ON) ? CBREAK : 0; register int change = 0; if((curttyb.sg_flags & ECHO) != ef){ curttyb.sg_flags &= ~ECHO; curttyb.sg_flags |= ef; change++; } if((curttyb.sg_flags & CBREAK) != cf){ curttyb.sg_flags &= ~CBREAK; curttyb.sg_flags |= cf; change++; } if(change){ setctty(); } } echo(n) register n; { /* (void) gtty(0,&curttyb); */ if(n == ON) curttyb.sg_flags |= ECHO; else curttyb.sg_flags &= ~ECHO; setctty(); } /* always want to expand tabs, or to send a clear line char before printing something on topline */ xtabs() { /* (void) gtty(0, &curttyb); */ curttyb.sg_flags |= XTABS; setctty(); } #ifdef LONG_CMD cbreak(n) register n; { /* (void) gtty(0,&curttyb); */ if(n == ON) curttyb.sg_flags |= CBREAK; else curttyb.sg_flags &= ~CBREAK; setctty(); } #endif LONG_CMD getlin(bufp) register char *bufp; { register char *obufp = bufp; register int c; flags.topl = 2; /* nonempty, no --More-- required */ for(;;) { (void) fflush(stdout); if((c = getchar()) == EOF) { *bufp = 0; return; } if(c == '\b') { if(bufp != obufp) { bufp--; putstr("\b \b"); /* putsym converts \b */ } else bell(); } else if(c == '\n') { *bufp = 0; return; } else { *bufp = c; bufp[1] = 0; putstr(bufp); if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO) bufp++; } } } getret() { xgetret(TRUE); } cgetret() { xgetret(FALSE); } xgetret(spaceflag) boolean spaceflag; /* TRUE if space (return) required */ { printf("\nHit %s to continue: ", flags.cbreak ? "space" : "return"); xwaitforspace(spaceflag); } char morc; /* tell the outside world what char he used */ xwaitforspace(spaceflag) boolean spaceflag; { register int c; (void) fflush(stdout); morc = 0; while((c = getchar()) != '\n') { if(c == EOF) { settty("End of input?\n"); exit(0); } if(flags.cbreak) { if(c == ' ') break; if(!spaceflag && letter(c)) { morc = c; break; } } } } char * parse() { static char inline[COLNO]; register foo; flags.move = 1; if(!Invis) curs(u.ux,u.uy+2); else home(); (void) fflush(stdout); while((foo = getchar()) >= '0' && foo <= '9') multi += 10*multi+foo-'0'; if(multi) { multi--; save_cm = inline; } inline[0] = foo; inline[1] = 0; if(foo == EOF) { settty("End of input?\n"); exit(0); } if(foo == 'f' || foo == 'F'){ inline[1] = getchar(); #ifdef QUEST if(inline[1] == foo) inline[2] = getchar(); else #endif QUEST inline[2] = 0; } if(foo == 'm' || foo == 'M'){ inline[1] = getchar(); inline[2] = 0; } clrlin(); return(inline); } char readchar() { register int sym; (void) fflush(stdout); if((sym = getchar()) == EOF) { settty("End of input?\n"); exit(0); } if(flags.topl == 1) flags.topl = 2; return((char) sym); } //E*O*F hack.tty.c// echo x - hack.u_init.c cat > "hack.u_init.c" << '//E*O*F hack.u_init.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" #include #include #define Strcat (void) strcat #define UNDEF_TYP 0 #define UNDEF_SPE (-1) extern struct obj *addinv(); extern char plname[]; char pl_character[PL_CSIZ]; struct trobj { uchar trotyp; schar trspe; char trolet; Bitfield(trquan,6); Bitfield(trknown,1); }; #ifdef WIZARD struct trobj Extra_objs[] = { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; #endif WIZARD struct trobj Cave_man[] = { { MACE, 1, WEAPON_SYM, 1, 1 }, { BOW, 1, WEAPON_SYM, 1, 1 }, { ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */ { LEATHER_ARMOR, 2, ARMOR_SYM, 1, 1 }, { 0, 0, 0, 0, 0} }; struct trobj Fighter[] = { { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 }, { RING_MAIL, 3, ARMOR_SYM, 1, 1 }, { 0, 0, 0, 0, 0 } }; struct trobj Knight[] = { { LONG_SWORD, 0, WEAPON_SYM, 1, 1 }, { SPEAR, 2, WEAPON_SYM, 1, 1 }, { RING_MAIL, 4, ARMOR_SYM, 1, 1 }, { HELMET, 1, ARMOR_SYM, 1, 1 }, { SHIELD, 1, ARMOR_SYM, 1, 1 }, { PAIR_OF_GLOVES, 1, ARMOR_SYM, 1, 1 }, { 0, 0, 0, 0, 0 } }; struct trobj Speleologist[] = { { STUDDED_LEATHER_ARMOR, 3, ARMOR_SYM, 1, 1 }, { UNDEF_TYP, 0, POTION_SYM, 2, 0 }, { FOOD_RATION, 0, FOOD_SYM, 3, 1 }, { ICE_BOX, 0, TOOL_SYM, 1, 0 }, { 0, 0, 0, 0, 0} }; struct trobj Tourist[] = { { UNDEF_TYP, 0, FOOD_SYM, 10, 1 }, { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 }, { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 }, { DART, 2, WEAPON_SYM, 25, 1 }, /* quan is variable */ { 0, 0, 0, 0, 0 } }; struct trobj Wizard[] = { { ELVEN_CLOAK, 1, ARMOR_SYM, 1, 1 }, { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 }, { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 }, { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 }, { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 }, { 0, 0, 0, 0, 0 } }; #ifdef NEWS int u_in_infl; u_in_intrup(){ u_in_infl++; (void) signal(SIGINT, u_in_intrup); } #endif NEWS u_init(){ register int c,pc,i; #ifdef NEWS /* It is not unlikely that we get an interrupt here intended to kill the news; unfortunately this would also kill (part of) the following question */ int (*prevsig)() = signal(SIGINT, u_in_intrup); #endif NEWS register char *cp; char buf[256]; if(pc = pl_character[0]) goto got_suffix; buf[0] = 0; Strcat(buf, "\nTell me what kind of character you are:\n"); Strcat(buf, "Are you a Tourist, a Speleologist, a Fighter,\n"); Strcat(buf, "\ta Knight, a Cave-man or a Wizard? [TSFKCW] "); intrup: for(cp = buf; *cp; cp++){ #ifdef NEWS if(u_in_infl){ u_in_infl = 0; goto intrup; } #endif NEWS (void) putchar(*cp); } loop: (void) fflush(stdout); pc = 0; while((c = getchar()) != '\n') { if(c == EOF) { #ifdef NEWS if(u_in_infl) goto intrup; /* %% */ #endif NEWS settty("\nEnd of input?\n"); exit(0); } if(!pc) pc = c; } if(!pc || !index("TSFKCWtsfkcw", pc)){ printf("Answer with T,S,F,K,C or W. What are you? "); goto loop; } got_suffix: if('a' <= pc && pc <= 'z') pc += 'A'-'a'; #ifdef NEWS (void) signal(SIGINT,prevsig); #endif NEWS u.usym = '@'; u.ulevel = 1; init_uhunger(); u.uhpmax = u.uhp = 12; u.ustrmax = u.ustr = !rn2(20) ? 14 + rn2(7) : 16; #ifdef QUEST u.uhorizon = 6; #endif QUEST switch(pc) { case 'C': setpl_char("Cave-man"); Cave_man[2].trquan = 12 + rnd(9)*rnd(9); u.uhp = u.uhpmax = 16; u.ustr = u.ustrmax = 18; ini_inv(Cave_man); break; case 'T': setpl_char("Tourist"); Tourist[3].trquan = 20 + rnd(20); u.ugold = u.ugold0 = rnd(1000); u.uhp = u.uhpmax = 10; u.ustr = u.ustrmax = 8; ini_inv(Tourist); break; case 'W': setpl_char("Wizard"); for(i=1; i<=4; i++) if(!rn2(5)) Wizard[i].trquan += rn2(3) - 1; u.uhp = u.uhpmax = 15; u.ustr = u.ustrmax = 16; ini_inv(Wizard); break; case 'S': setpl_char("Speleologist"); Fast = INTRINSIC; Stealth = INTRINSIC; u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 10; ini_inv(Speleologist); break; case 'K': setpl_char("Knight"); u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 10; ini_inv(Knight); break; case 'F': setpl_char("Fighter"); u.uhp = u.uhpmax = 14; u.ustr = u.ustrmax = 17; ini_inv(Fighter); } find_ac(); /* make sure he can carry all he has - especially for T's */ while(inv_weight() > 0 && u.ustr < 118) u.ustr++, u.ustrmax++; #ifdef WIZARD if(wizard) wiz_inv(); #endif WIZARD } ini_inv(trop) register struct trobj *trop; { register struct obj *obj; extern struct obj *mkobj(); while(trop->trolet) { obj = mkobj(trop->trolet); obj->known = trop->trknown; obj->cursed = 0; if(obj->olet == WEAPON_SYM){ obj->quan = trop->trquan; trop->trquan = 1; } if(trop->trspe != UNDEF_SPE) obj->spe = trop->trspe; if(trop->trotyp != UNDEF_TYP) obj->otyp = trop->trotyp; obj->owt = weight(obj); /* defined after setting otyp+quan */ obj = addinv(obj); if(obj->olet == ARMOR_SYM){ switch(obj->otyp){ case SHIELD: if(!uarms) setworn(obj, W_ARMS); break; case HELMET: if(!uarmh) setworn(obj, W_ARMH); break; case PAIR_OF_GLOVES: if(!uarmg) setworn(obj, W_ARMG); break; case ELVEN_CLOAK: if(!uarm2) setworn(obj, W_ARM); break; default: if(!uarm) setworn(obj, W_ARM); } } if(obj->olet == WEAPON_SYM) if(!uwep) setuwep(obj); if(--trop->trquan) continue; /* make a similar object */ trop++; } } #ifdef WIZARD wiz_inv(){ register struct trobj *trop = &Extra_objs[0]; extern char *getenv(); register char *ep = getenv("INVENT"); register int type; while(ep && *ep) { type = atoi(ep); ep = index(ep, ','); if(ep) while(*ep == ',' || *ep == ' ') ep++; if(type <= 0 || type > NROFOBJECTS) continue; trop->trotyp = type; trop->trolet = objects[type].oc_olet; trop->trspe = 4; trop->trknown = 1; trop->trquan = 1; ini_inv(trop); } /* give him a wand of wishing by default */ trop->trotyp = WAN_WISHING; trop->trolet = WAND_SYM; trop->trspe = 20; trop->trknown = 1; trop->trquan = 1; ini_inv(trop); } #endif WIZARD setpl_char(plc) char *plc; { (void) strncpy(pl_character, plc, PL_CSIZ-1); pl_character[PL_CSIZ-1] = 0; } plnamesuffix() { register char *p; if(p = rindex(plname, '-')) { *p = 0; if(!plname[0]) { askname(); plnamesuffix(); } if(index("TSFKCWtsfkcw", p[1])) { pl_character[0] = p[1]; pl_character[1] = 0; } } } //E*O*F hack.u_init.c// echo x - hack.vault.c cat > "hack.vault.c" << '//E*O*F hack.vault.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" #ifdef QUEST setgd(/* mtmp */) /* struct monst *mtmp; */ {} gd_move() { return(2); } gddead(mtmp) struct monst *mtmp; {} invault(){} #else extern struct monst *makemon(); #define VAULT 6 #define FCSIZ (ROWNO+COLNO) struct fakecorr { xchar fx,fy,ftyp; }; struct egd { int fcbeg, fcend; /* fcend: first unused pos */ xchar gdx, gdy; /* goal of guard's walk */ unsigned gddone:1; struct fakecorr fakecorr[FCSIZ]; }; struct permonst pm_guard = { "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) }; struct monst *guard; int gdlevel; #define EGD ((struct egd *)(&(guard->mextra[0]))) restfakecorr(){ register fcx,fcy,fcbeg; register struct rm *crm; while((fcbeg = EGD->fcbeg) < EGD->fcend) { fcx = EGD->fakecorr[fcbeg].fx; fcy = EGD->fakecorr[fcbeg].fy; if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) || m_at(fcx,fcy)) return; crm = &levl[fcx][fcy]; crm->typ = EGD->fakecorr[fcbeg].ftyp; if(!crm->typ) crm->seen = 0; newsym(fcx,fcy); EGD->fcbeg++; } /* it seems he left the corridor - let the guard disappear */ mondead(guard); guard = 0; } setgd(){ register struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){ guard = mtmp; gdlevel = dlevel; return; } guard = 0; } invault(){ register tmp = inroom(u.ux, u.uy); if(tmp < 0 || rooms[tmp].rtype != VAULT) { u.uinvault = 0; return; } if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) { char buf[BUFSZ]; register x,y,dx,dy,gx,gy; /* first find the goal for the guard */ for(dy = 0; dy < ROWNO; dy++) for(y = u.uy-dy; y <= u.uy+dy; y++) { if(y > u.uy-dy) y = u.uy+dy; if(y < 0 || y > ROWNO-1) continue; for(x = u.ux; x < COLNO; x++) if(levl[x][y].typ == CORR) goto fnd; for(x = u.ux-1; x > 0; x--) if(levl[x][y].typ == CORR) goto fnd; } impossible(); tele(); return; fnd: gx = x; gy = y; /* next find a good place for a door in the wall */ x = u.ux; y = u.uy; while(levl[x][y].typ > DOOR) { dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; if(abs(gx-x) >= abs(gy-y)) x += dx; else y += dy; } /* make something interesting happen */ if(!(guard = makemon(&pm_guard,x,y))) return; guard->isgd = guard->mpeaceful = 1; EGD->gddone = 0; gdlevel = dlevel; if(!cansee(guard->mx, guard->my)) { mondead(guard); guard = 0; return; } EGD->gdx = gx; EGD->gdy = gy; EGD->fcbeg = 0; EGD->fakecorr[0].fx = x; EGD->fakecorr[0].fy = y; EGD->fakecorr[0].ftyp = levl[x][y].typ; levl[x][y].typ = DOOR; EGD->fcend = 1; pline("Suddenly one of the Vault's guards enters!"); pmon(guard); pline("\"Hello stranger, who are you?\" - "); getlin(buf); clrlin(); pline("\"I don't know you.\""); if(!u.ugold) pline("\"Please follow me.\""); else { pline("\"Most likely all that gold was stolen from this vault.\""); pline("\"Please drop your gold (say d$ ) and follow me.\""); } } } gd_move(){ register int x,y,dx,dy,gx,gy,nx,ny,tmp; register struct fakecorr *fcp; register struct rm *crm; if(!guard || gdlevel != dlevel){ pline("Where is the guard?"); impossible(); return(2); /* died */ } if(u.ugold || dist(guard->mx,guard->my) > 2 || EGD->gddone){ restfakecorr(); return(0); /* didnt move */ } x = guard->mx; y = guard->my; /* look around (hor & vert only) for accessible places */ for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) if(nx == x || ny == y) if(nx != x || ny != y) if(isok(nx,ny)) if((tmp = (crm = &levl[nx][ny])->typ) >= SDOOR) { register int i; for(i = EGD->fcbeg; i < EGD->fcend; i++) if(EGD->fakecorr[i].fx == nx && EGD->fakecorr[i].fy == ny) goto nextnxy; if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT) goto nextnxy; /* seems we found a good place to leave him alone */ EGD->gddone = 1; if(tmp >= DOOR) goto newpos; crm->typ = (tmp == SCORR) ? CORR : DOOR; goto proceed; nextnxy: ; } nx = x; ny = y; gx = EGD->gdx; gy = EGD->gdy; dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy; while((tmp = (crm = &levl[nx][ny])->typ) != 0) { /* in view of the above we must have tmp < SDOOR */ /* must be a wall here */ if(isok(nx+nx-x,ny+ny-y) && levl[nx+nx-x][ny+ny-y].typ > DOOR){ crm->typ = DOOR; goto proceed; } if(dy && nx != x) { nx = x; ny = y+dy; dx = 0; continue; } if(dx && ny != y) { ny = y; nx = x+dx; dy = 0; continue; } /* I don't like this, but ... */ crm->typ = DOOR; goto proceed; } crm->typ = CORR; proceed: fcp = &(EGD->fakecorr[EGD->fcend]); if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow"); fcp->fx = nx; fcp->fy = ny; fcp->ftyp = tmp; newpos: if(EGD->gddone) nx = ny = 0; guard->mx = nx; guard->my = ny; pmon(guard); restfakecorr(); return(1); } gddead(){ guard = 0; } #endif QUEST //E*O*F hack.vault.c// echo x - hack.version.c cat > "hack.version.c" << '//E*O*F hack.version.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "date.h" doversion(){ pline("%s 1.0 preliminary version - last edit %s.", #ifdef QUEST "Quest" #else "Hack" #endif QUEST , datestring); return(0); } //E*O*F hack.version.c// exit 0