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

Hack 1.0.2 - part 3 of 10

1 view
Skip to first unread message

Andries Brouwer

unread,
Apr 4, 1985, 1:20:20 PM4/4/85
to

# 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 <stdio.h>
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; i<mtmp->mxlth; 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 <stdio.h>
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; 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 = 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; 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(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

0 new messages