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 5 of 15) Message-ID: <6247@mcvax.UUCP> Date: Mon, 17-Dec-84 19:31:40 EST Article-I.D.: mcvax.6247 Posted: Mon Dec 17 19:31:40 1984 Date-Received: Wed, 19-Dec-84 02:14:18 EST Organization: CWI, Amsterdam Lines: 1310 # This is part 5 (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.do_name.c hack.do_wear.c hack.dog.c hack.eat.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, 1984. */ #include "hack.h" #include 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){ extern char plname[]; 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); if(mtmp2->isshk) setshk(); /* redefine shopkeeper and bill */ if(mtmp2->isgd) setgd( /* 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]; register char **str1; extern char *xname(); register char *str = xname(obj); 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 * xmonnam(mtmp, vb) register struct monst *mtmp; int vb; { static char buf[BUFSZ]; /* %% */ extern char *shkname(); if(mtmp->mnamelth && !vb) return(NAME(mtmp)); switch(mtmp->data->mlet) { case ' ': (void) sprintf(buf, "%s's ghost", (char *) mtmp->mextra); break; case '@': if(mtmp->isshk) { (void) strcpy(buf, shkname()); 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, 1984. */ #include "hack.h" #include extern char *nomovemsg; 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) { pline("What ring, Right or Left? "); switch(readchar()) { case ' ': case '\n': case '\033': return(0); 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."); else if(uwep && uwep->cursed) pline("You cannot wear gloves over your weapon."); 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 { pline("What ring-finger, Right or Left? "); switch(readchar()){ case 'l': case 'L': mask = LEFT_RING; break; case 'r': case 'R': mask = RIGHT_RING; break; case ' ': case '\n': case '\033': return(0); } } 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; flags.botl=1; break; case RIN_INCREASE_DAMAGE: u.udaminc += otmp->spe; break; } prinv(otmp); return(1); } ringoff(obj) register struct obj *obj; { register unsigned mask; mask = obj->owornmask & W_RING; setworn((struct obj *) 0, obj->owornmask); if(!(u.uprops[PROP(obj->otyp)].p_flgs & mask)){ pline("Strange... I didnt know you had that ring."); impossible(); } 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; flags.botl = 1; break; case RIN_INCREASE_DAMAGE: u.udaminc -= obj->spe; break; } } find_ac(){ register int uac = 10; if(uarm) uac -= uarm->spe; if(uarm2) uac -= uarm2->spe; if(uarmh) uac -= uarmh->spe; if(uarms) uac -= uarms->spe; if(uarmg) uac -= uarmg->spe; 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){ ringoff(uleft); dropx(otmp); } if(otmp = uright){ ringoff(uright); dropx(otmp); } } if(otmp = uwep){ /* 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, 1984. */ #include "hack.h" #include "hack.mfndpos.h" extern char POISONOUS[]; extern struct monst *makemon(); #include "def.edog.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(mtmp->mtame) { if(dist(mtmp->mx,mtmp->my) > 2) { mtmp->mtame = 0; /* dog becomes wild */ mtmp->mpeaceful = 0; continue; } 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 : (index(POISONOUS, obj->spe) || 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 gen *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->orig_hp /= 3; if(mtmp->mhp > mtmp->orig_hp) mtmp->mhp = mtmp->orig_hp; if(cansee(omx,omy)) pline("%s is confused from hunger", Monnam(mtmp)); else pline("You feel worried about your %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,0); 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; #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(levl[u.ux][u.uy].typ < ROOM || !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; #ifdef TRACK 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; } } #endif TRACK 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 = g_at(nx,ny,ftrap))){ if(!(trap->gflag & SEEN) && 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 + objects[obj->otyp].oc_delay; edog->hungrytime = moves + 5*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(mtmp->mtame || #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// echo x - hack.eat.c cat > "hack.eat.c" << '//E*O*F hack.eat.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #include "hack.h" char POISONOUS[] = "ADKSVabhks"; extern char *nomovemsg; extern int (*afternmv)(); /* hunger texts used on bottom line (each 8 chars long) */ #define SATIATED 0 #define NOT_HUNGRY 1 #define HUNGRY 2 #define WEAK 3 #define FAINTING 4 char *hu_stat[5] = { "Satiated", " ", "Hungry ", "Weak ", "Fainting" }; init_uhunger(){ u.uhunger = 900; u.uhs = NOT_HUNGRY; } struct { char *txt; int nut; } tintxts[] = { "It contains first quality peaches - what a surprise!", 40, "It contains salmon - not bad!", 60, "It contains apple juice - perhaps not what you hoped for.", 20, "It contains some nondescript substance, tasting awfully.", 500, "It contains rotten meat. You vomit.", -50, "It turns out to be empty.", 0 }; tinopen(){ #define TTSZ (sizeof(tintxts)/sizeof(tintxts[0])) register int r = rn2(2*TTSZ); if(r < TTSZ){ pline(tintxts[r].txt); lesshungry(tintxts[r].nut); if(r == 1) /* SALMON */ { Glib = rnd(15); pline("Eating salmon made your fingers very slippery."); } } else { pline("It contains spinach - this makes you feel like Popeye!"); lesshungry(600); if(u.ustr < 118) u.ustr += rnd( ((u.ustr < 17) ? 19 : 118) - u.ustr); if(u.ustr > u.ustrmax) u.ustrmax = u.ustr; flags.botl = 1; } } Meatdone(){ u.usym = '@'; prme(); } doeat(){ register struct obj *otmp; register struct objclass *ftmp; register tmp; otmp = getobj("%", "eat"); if(!otmp) return(0); if(otmp->otyp == TIN){ if(uwep && (uwep->otyp == AXE || uwep->otyp == DAGGER || uwep->otyp == CRYSKNIFE)){ pline("Using your %s you try to open the tin", aobjnam(uwep, (char *) 0)); tmp = 3; } else { pline("It is not so easy to open this tin."); if(Glib) { pline("The tin slips out of your hands."); dropx(otmp); return(1); } tmp = 2 + rn2(1 + 500/((int)(u.ulevel + u.ustr))); } if(tmp > 50){ nomul(-50); nomovemsg="You give up your attempt to open the tin."; } else { nomul(-tmp); nomovemsg = "You succeed in opening the tin."; afternmv = tinopen; useup(otmp); } return(1); } ftmp = &objects[otmp->otyp]; if(otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx; if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE) { pline("Blecch! Rotten food!"); if(!rn2(4)) { pline("You feel rather light headed."); Confusion += d(2,4); } else if(!rn2(4)&& !Blind) { pline("Everything suddenly goes dark."); Blind = d(2,10); seeoff(0); } else if(!rn2(3)) { if(Blind) pline("The world spins and you slap against the floor."); else pline("The world spins and goes dark."); nomul(-rnd(10)); nomovemsg = "You are conscious again."; } lesshungry(ftmp->nutrition / 4); } else { multi = -ftmp->oc_delay; if(u.uhunger >= 1500) { pline("You choke over your food."); pline("You die..."); killer = ftmp->oc_name; done("choked"); } switch(otmp->otyp){ case FOOD_RATION: if(u.uhunger <= 200) pline("That food really hit the spot!"); else if(u.uhunger <= 700) pline("That satiated your stomach!"); else { pline("You're having a hard time getting all that food down."); multi -= 2; } lesshungry(ftmp->nutrition); if(multi < 0) nomovemsg = "You finished your meal."; break; case TRIPE_RATION: pline("Yak - dog food!"); u.uexp++; u.urexp += 4; flags.botl = 1; if(rn2(2)){ pline("You vomit."); lesshungry(-20); } else lesshungry(ftmp->nutrition); break; default: if(otmp->otyp >= CORPSE) pline("That %s tasted terrible!",ftmp->oc_name); else pline("That %s was delicious!",ftmp->oc_name); lesshungry(ftmp->nutrition); #ifdef QUEST if(otmp->otyp == CARROT && !Blind){ u.uhorizon++; setsee(); pline("Your vision improves."); } #endif QUEST if(otmp->otyp == FORTUNE_COOKIE) { if(Blind) { pline("This cookie has a scrap of paper inside!"); pline("What a pity, that you cannot read it!"); } else outrumor(); } break; } } eatx: if(multi<0 && !nomovemsg){ static char msgbuf[BUFSZ]; (void) sprintf(msgbuf, "You finished eating the %s.", ftmp->oc_name); nomovemsg = msgbuf; } useup(otmp); return(1); } lesshungry(num) register num; { /* called after eating something (and after drinking fruit juice) */ register int newhunger; newhunger = u.uhunger + num; if(u.uhunger <= 1000 && newhunger > 1000) { flags.botl = 1; u.uhs = SATIATED; } else if(u.uhunger <= 150 && newhunger > 150) { if(u.uhunger <= 50 && u.ustr < u.ustrmax) losestr(-1); flags.botl = 1; u.uhs = NOT_HUNGRY; } else if(u.uhunger <= 50 && newhunger > 50) { pline("You only feel hungry now."); if(u.ustr < u.ustrmax) losestr(-1); flags.botl = 1; u.uhs = HUNGRY; } else if(u.uhunger <= 0 && newhunger < 50) { pline("You feel weak now."); flags.botl = 1; u.uhs = WEAK; } u.uhunger = newhunger; } /* called in hack.main.c */ gethungry(){ --u.uhunger; if((Regeneration || Hunger) && moves%2) u.uhunger--; if(u.uhunger <= 1000 && u.uhs == SATIATED) { u.uhs = NOT_HUNGRY; flags.botl = 1; } else if(u.uhunger <= 150 && u.uhs == NOT_HUNGRY) { pline("You are beginning to feel hungry."); u.uhs = HUNGRY; flags.botl = 1; } else if(u.uhunger <= 50 && u.uhs == HUNGRY) { pline("You are beginning to feel weak."); u.uhs = WEAK; losestr(1); flags.botl = 1; } else if(u.uhunger < 1 && (u.uhs == WEAK || rn2(20-u.uhunger/10) >= 19)) { if(multi >= 0) /* not fainted already */ { pline("You faint from lack of food."); nomul(-10+(u.uhunger/10)); } if(u.uhs != FAINTING) { u.uhs = FAINTING; flags.botl = 1; } } else if(u.uhunger < -(int)(200 + 25*u.ulevel)) { pline("You die from starvation."); done("starved"); } } /* returns 1 if some text was printed */ eatcorpse(otmp) register struct obj *otmp; { register schar let = otmp->spe; register tp = 0; if(moves > otmp->age + 50 + rn2(100)) { tp++; pline("Ulch -- that meat was tainted!"); pline("You get very sick."); Sick = 10 + rn2(10); u.usick_cause = objects[otmp->otyp].oc_name; } else if(index(POISONOUS, let) && rn2(5)){ tp++; pline("Ecch -- that must have been poisonous!"); if(!Poison_resistance){ losehp(rnd(15), "poisonous corpse"); losestr(rnd(4)); } else pline("You don't seem affected by the poison."); } else if(index("ELNOPQRUuxz", let) && rn2(5)){ tp++; pline("You feel sick."); losehp(rnd(8), "cadaver"); } switch(let) { case 'L': case 'N': case 't': Teleportation |= INTRINSIC; break; case 'W': pluslvl(); break; case 'n': u.uhp = u.uhpmax; flags.botl = 1; /* fall into next case */ case '@': pline("You cannibal! You will be sorry for this!"); /* not tp++; */ /* fall into next case */ case 'd': Aggravate_monster |= INTRINSIC; break; case 'I': See_invisible |= INTRINSIC; if(!Invis) newsym(u.ux, u.uy); Invis += 50; /* fall into next case */ case 'y': #ifdef QUEST u.uhorizon++; #endif QUEST /* fall into next case */ case 'B': Confusion = 50; break; case 'D': Fire_resistance |= INTRINSIC; break; case 'E': Telepat |= INTRINSIC; break; case 'F': case 'Y': Cold_resistance |= INTRINSIC; break; case 'k': case 's': Poison_resistance |= INTRINSIC; break; case 'c': pline("You turn to stone."); killer = "dead cockatrice"; done("died"); case 'M': pline("You cannot resist the temptation to mimic a treasure chest."); tp++; nomul(-30); afternmv = Meatdone; nomovemsg = "You now again prefer mimicking a human."; u.usym = '$'; prme(); break; } return(tp); } //E*O*F hack.eat.c// exit 0