Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Hack sources (part 5 of 15)

11 views
Skip to first unread message

funhouse

unread,
Dec 17, 1984, 7:31:40 PM12/17/84
to
# 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 <stdio.h>

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; i<mtmp->mxlth; 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 <stdio.h>
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; i<cnt; i++){
nx = poss[i].x;
ny = poss[i].y;
if(info[i] & ALLOW_M){
mtmp2 = m_at(nx,ny);
if(mtmp2->data->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; j<MTSZ && j<cnt-1; j++)
if(nx == mtmp->mtrack[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

0 new messages