Repost of Hack(13)
Ed Friedman
ed at gargoyle.UChicago.UUCP
Sun Jan 13 13:21:52 AEST 1985
# This is part 13 (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.whatis.c hack.wield.c hack.worm.c hack.worn.c hack.zap.c makedefs.c
echo x - hack.whatis.c
cat > "hack.whatis.c" << '//E*O*F hack.whatis.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include <stdio.h>
#include "hack.h"
dowhatis(str)
register char *str;
{
FILE *fp;
char bufr[BUFSZ];
register char *ep, q;
pline("Specify what? ");
getlin(bufr);
str = bufr;
while(*str == ' ') str++;
q = *str;
if(*(str+1)) pline("One character please.");
else if(!(fp = fopen("data","r"))) pline("Cannot open data file!");
else {
while(fgets(bufr,BUFSZ,fp))
if(*bufr == q) {
ep = index(bufr, '\n');
if(ep) *ep = 0;
else impossible();
pline(bufr);
if(ep[-1] == ';') morewhat(fp);
goto fnd;
}
pline("Unknown symbol.");
fnd:
(void) fclose(fp);
}
}
morewhat(fp) FILE *fp; {
char bufr[BUFSZ];
register char *ep;
pline("More info? ");
if(readchar() != 'y') return;
cls();
while(fgets(bufr,BUFSZ,fp) && *bufr == '\t'){
ep = index(bufr, '\n');
if(!ep) break;
*ep = 0;
puts(bufr+1);
}
more();
docrt();
}
//E*O*F hack.whatis.c//
echo x - hack.wield.c
cat > "hack.wield.c" << '//E*O*F hack.wield.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
setuwep(obj) register struct obj *obj; {
setworn(obj, W_WEP);
}
dowield()
{
register struct obj *wep;
register int res = 0;
multi = 0;
if(!(wep = getobj("#-)", "wield"))) /* nothing */;
else if(uwep == wep)
pline("You are already wielding that!");
else if(uwep && uwep->cursed)
pline("The %s welded to your hand!",
aobjnam(uwep, "are"));
else if((int) wep == -1) {
if(uwep == 0){
pline("You are already empty handed.");
} else {
setuwep((struct obj *) 0);
res++;
pline("You are empty handed.");
}
} else if(uarms && wep->otyp == TWO_HANDED_SWORD)
pline("You cannot wield a two-handed sword and wear a shield.");
else if(wep->owornmask & (W_ARMOR | W_RING))
pline("You cannot wield that!");
else {
setuwep(wep);
res++;
if(uwep->cursed) pline("The %s itself to your hand!",
aobjnam(uwep, "weld"));
else prinv(uwep);
}
return(res);
}
corrode_weapon(){
if(!uwep || uwep->olet != WEAPON_SYM) return; /* %% */
if(uwep->rustfree)
pline("Your %s not affected.", aobjnam(uwep, "are"));
else {
pline("Your %s!", aobjnam(uwep, "corrode"));
uwep->spe--;
}
}
chwepon(otmp,amount)
register struct obj *otmp;
register amount;
{
register char *color = (amount < 0) ? "black" : "green";
register char *time;
if(!uwep || uwep->olet != WEAPON_SYM) {
strange_feeling(otmp);
return(0);
}
if(uwep->otyp == WORM_TOOTH && amount > 0) {
uwep->otyp = CRYSKNIFE;
pline("Your weapon seems sharper now.");
uwep->cursed = 0;
return(1);
}
if(uwep->otyp == CRYSKNIFE && amount < 0) {
uwep->otyp = WORM_TOOTH;
pline("Your weapon looks duller now.");
return(1);
}
/* there is a (soft) upper limit to uwep->spe */
if(amount > 0 && uwep->spe > 5 && rn2(3)) {
pline("Your %s violently green for a while and then evaporates.",
aobjnam(uwep, "glow"));
useup(uwep);
return(1);
}
if(!rn2(6)) amount *= 2;
time = (amount*amount == 1) ? "moment" : "while";
pline("Your %s %s for a %s.",
aobjnam(uwep, "glow"), color, time);
uwep->spe += amount;
if(amount > 0) uwep->cursed = 0;
return(1);
}
//E*O*F hack.wield.c//
echo x - hack.worm.c
cat > "hack.worm.c" << '//E*O*F hack.worm.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#ifndef NOWORM
#include "def.wseg.h"
struct wseg *wsegs[32]; /* linked list, tail first */
struct wseg *wheads[32];
long wgrowtime[32];
getwn(mtmp) struct monst *mtmp; {
register tmp;
for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) {
mtmp->wormno = tmp;
return(1);
}
return(0); /* level infested with worms */
}
/* called to initialize a worm unless cut in half */
initworm(mtmp) struct monst *mtmp; {
register struct wseg *wtmp;
register tmp = mtmp->wormno;
if(!tmp) return;
wheads[tmp] = wsegs[tmp] = wtmp = newseg();
wgrowtime[tmp] = 0;
wtmp->wx = mtmp->mx;
wtmp->wy = mtmp->my;
/* wtmp->wdispl = 0;*/
wtmp->nseg = 0;
}
worm_move(mtmp) struct monst *mtmp; {
register struct wseg *wtmp, *whd;
register tmp = mtmp->wormno;
wtmp = newseg();
wtmp->wx = mtmp->mx;
wtmp->wy = mtmp->my;
wtmp->nseg = 0;
/* wtmp->wdispl = 0;*/
(whd = wheads[tmp])->nseg = wtmp;
wheads[tmp] = wtmp;
if(cansee(whd->wx,whd->wy)){
unpmon(mtmp);
atl(whd->wx, whd->wy, '~');
whd->wdispl = 1;
} else whd->wdispl = 0;
if(wgrowtime[tmp] <= moves) {
if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5);
else wgrowtime[tmp] += 2+rnd(15);
mtmp->orig_hp++;
mtmp->mhp++;
return;
}
whd = wsegs[tmp];
wsegs[tmp] = whd->nseg;
remseg(whd);
}
worm_nomove(mtmp) register struct monst *mtmp; {
register tmp;
register struct wseg *wtmp;
tmp = mtmp->wormno;
wtmp = wsegs[tmp];
if(wtmp == wheads[tmp]) return;
if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?");
wsegs[tmp] = wtmp->nseg;
remseg(wtmp);
mtmp->mhp--; /* orig_hp not changed ! */
}
wormdead(mtmp) register struct monst *mtmp; {
register tmp = mtmp->wormno;
register struct wseg *wtmp, *wtmp2;
if(!tmp) return;
mtmp->wormno = 0;
for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
wtmp2 = wtmp->nseg;
remseg(wtmp);
}
wsegs[tmp] = 0;
}
wormhit(mtmp) register struct monst *mtmp; {
register tmp = mtmp->wormno;
register struct wseg *wtmp;
if(!tmp) return; /* worm without tail */
for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
(void) hitu(mtmp,1);
}
wormsee(tmp) register unsigned tmp; {
register struct wseg *wtmp = wsegs[tmp];
if(!wtmp) panic("wormsee: wtmp==0");
for(; wtmp->nseg; wtmp = wtmp->nseg)
if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){
newsym(wtmp->wx, wtmp->wy);
wtmp->wdispl = 0;
}
}
pwseg(wtmp) register struct wseg *wtmp; {
if(!wtmp->wdispl){
atl(wtmp->wx, wtmp->wy, '~');
wtmp->wdispl = 1;
}
}
cutworm(mtmp,x,y,weptyp)
register struct monst *mtmp;
register xchar x,y;
register uchar weptyp; /* uwep->otyp or 0 */
{
register struct wseg *wtmp, *wtmp2;
register struct monst *mtmp2;
register tmp,tmp2;
if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */
/* cutting goes best with axe or sword */
tmp = rnd(20);
if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
weptyp == AXE) tmp += 5;
if(tmp < 12) return;
/* if tail then worm just loses a tail segment */
tmp = mtmp->wormno;
wtmp = wsegs[tmp];
if(wtmp->wx == x && wtmp->wy == y){
wsegs[tmp] = wtmp->nseg;
remseg(wtmp);
return;
}
/* cut the worm in two halves */
mtmp2 = newmonst(0);
*mtmp2 = *mtmp;
mtmp2->mxlth = mtmp2->mnamelth = 0;
/* sometimes the tail end dies */
if(rn2(3) || !getwn(mtmp2)){
monfree(mtmp2);
tmp2 = 0;
} else {
tmp2 = mtmp2->wormno;
wsegs[tmp2] = wsegs[tmp];
wgrowtime[tmp2] = 0;
}
do {
if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){
if(tmp2) wheads[tmp2] = wtmp;
wsegs[tmp] = wtmp->nseg->nseg;
remseg(wtmp->nseg);
wtmp->nseg = 0;
if(tmp2){
pline("You cut the worm in half.");
mtmp2->orig_hp = mtmp2->mhp =
d(mtmp2->data->mlevel, 8);
mtmp2->mx = wtmp->wx;
mtmp2->my = wtmp->wy;
mtmp2->nmon = fmon;
fmon = mtmp2;
pmon(mtmp2);
} else {
pline("You cut off part of the worm's tail.");
remseg(wtmp);
}
mtmp->mhp /= 2;
return;
}
wtmp2 = wtmp->nseg;
if(!tmp2) remseg(wtmp);
wtmp = wtmp2;
} while(wtmp->nseg);
panic("Cannot find worm segment");
}
remseg(wtmp) register struct wseg *wtmp; {
if(wtmp->wdispl)
newsym(wtmp->wx, wtmp->wy);
free((char *) wtmp);
}
#endif NOWORM
//E*O*F hack.worm.c//
echo x - hack.worn.c
cat > "hack.worn.c" << '//E*O*F hack.worn.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
struct worn {
long w_mask;
struct obj **w_obj;
} worn[] = {
{ W_ARM, &uarm },
{ W_ARM2, &uarm2 },
{ W_ARMH, &uarmh },
{ W_ARMS, &uarms },
{ W_ARMG, &uarmg },
{ W_RINGL, &uleft },
{ W_RINGR, &uright },
{ W_WEP, &uwep },
{ W_BALL, &uball },
{ W_CHAIN, &uchain },
{ 0, 0 }
};
setworn(obj, mask)
register struct obj *obj;
long mask;
{
register struct worn *wp;
register struct obj *oobj;
for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
oobj = *(wp->w_obj);
if(oobj && !(oobj->owornmask & wp->w_mask)){
pline("Setworn: mask = %d.", wp->w_mask);
impossible();
}
if(oobj) oobj->owornmask &= ~wp->w_mask;
if(obj && oobj && wp->w_mask == W_ARM){
if(uarm2) {
pline("Setworn: uarm2 set?");
impossible();
} else
setworn(uarm, W_ARM2);
}
*(wp->w_obj) = obj;
if(obj) obj->owornmask |= wp->w_mask;
}
if(uarm2 && !uarm) {
uarm = uarm2;
uarm2 = 0;
uarm->owornmask ^= (W_ARM | W_ARM2);
}
}
/* called e.g. when obj is destroyed */
setnotworn(obj) register struct obj *obj; {
register struct worn *wp;
for(wp = worn; wp->w_mask; wp++)
if(obj == *(wp->w_obj)) {
*(wp->w_obj) = 0;
obj->owornmask &= ~wp->w_mask;
}
if(uarm2 && !uarm) {
uarm = uarm2;
uarm2 = 0;
uarm->owornmask ^= (W_ARM | W_ARM2);
}
}
//E*O*F hack.worn.c//
echo x - hack.zap.c
cat > "hack.zap.c" << '//E*O*F hack.zap.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
extern struct monst *makemon();
struct monst *bhit();
char *exclam();
char *fl[]= {
"magic missile",
"bolt of fire",
"sleep ray",
"bolt of cold",
"death ray"
};
dozap()
{
register struct obj *obj;
register struct monst *mtmp;
xchar zx,zy;
register num;
obj = getobj("/", "zap");
if(!obj) return(0);
if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
pline("Nothing Happens");
return(1);
}
if(obj->spe == 0)
pline("You wrest one more spell from the worn-out wand.");
if(!(objects[obj->otyp].bits & NODIR) && !getdir())
return(1); /* make him pay for knowing !NODIR */
obj->spe--;
if(objects[obj->otyp].bits & IMMEDIATE) {
if((u.uswallow && (mtmp = u.ustuck)) ||
(mtmp = bhit(u.dx,u.dy,rn1(8,6),0))) {
wakeup(mtmp);
switch(obj->otyp) {
case WAN_STRIKING:
if(rnd(20) < 10+mtmp->data->ac) {
register int tmp = d(2,12);
hit("wand", mtmp, exclam(tmp));
mtmp->mhp -= tmp;
if(mtmp->mhp < 1) killed(mtmp);
} else miss("wand", mtmp);
break;
case WAN_SLOW_MONSTER:
mtmp->mspeed = MSLOW;
break;
case WAN_SPEED_MONSTER:
mtmp->mspeed = MFAST;
break;
case WAN_UNDEAD_TURNING:
if(index("WVZ&",mtmp->data->mlet)) {
mtmp->mhp -= rnd(8);
if(mtmp->mhp<1) killed(mtmp);
else mtmp->mflee = 1;
}
break;
case WAN_POLYMORPH:
if( newcham(mtmp,&mons[rn2(CMNUM)]) )
objects[obj->otyp].oc_name_known = 1;
break;
case WAN_CANCELLATION:
mtmp->mcan = 1;
break;
case WAN_TELEPORT_MONSTER:
rloc(mtmp);
break;
case WAN_MAKE_INVISIBLE:
mtmp->minvis = 1;
break;
#ifdef WAN_PROBING
case WAN_PROBING:
mstatusline(mtmp);
break;
#endif WAN_PROBING
default:
pline("What an interesting wand (%d)",
obj->otyp);
impossible();
}
}
} else {
switch(obj->otyp){
case WAN_LIGHT:
litroom(TRUE);
break;
case WAN_SECRET_DOOR_DETECTION:
if(!findit()) return(1);
break;
case WAN_CREATE_MONSTER:
{ register int cnt = 1;
if(!rn2(23)) cnt += rn2(7) + 1;
while(cnt--)
(void) makemon((struct permonst *) 0, u.ux, u.uy);
}
break;
case WAN_WISHING:
{ char buf[BUFSZ];
register struct obj *otmp;
extern struct obj *readobjnam(), *addinv();
if(u.uluck + rn2(5) < 0) {
pline("Unfortunately, nothing happens.");
break;
}
pline("You may wish for an object. What do you want? ");
getlin(buf);
otmp = readobjnam(buf);
otmp = addinv(otmp);
prinv(otmp);
break;
}
case WAN_DIGGING:
{ register struct rm *room;
register int digdepth;
if(u.uswallow) {
pline("You pierce %s's stomach wall!",
monnam(u.ustuck));
u.uswallow = 0;
mnexto(u.ustuck);
u.ustuck->mhp = 1; /* almost dead */
u.ustuck = 0;
setsee();
docrt();
break;
}
zx = u.ux+u.dx;
zy = u.uy+u.dy;
if(!isok(zx,zy)) break;
digdepth = 4 + rn2(10);
if(levl[zx][zy].typ == CORR) num = CORR;
else num = ROOM;
Tmp_at(-1, '*'); /* open call */
while(digdepth--) {
if(zx == 0 || zx == COLNO-1 ||
zy == 0 || zy == ROWNO-1)
break;
room = &levl[zx][zy];
Tmp_at(zx,zy);
if(!xdnstair){
if(zx < 3 || zx > COLNO-3 ||
zy < 3 || zy > ROWNO-3)
break;
if(room->typ == HWALL ||
room->typ == VWALL){
room->typ = ROOM;
break;
}
} else if(num == ROOM || num == 10){
if(room->typ != ROOM && room->typ) {
if(room->typ != CORR)
room->typ = DOOR;
if(num == 10) break;
num = 10;
} else if(!room->typ)
room->typ = CORR;
} else {
if(room->typ != CORR && room->typ) {
room->typ = DOOR;
break;
} else room->typ = CORR;
}
mnewsym(zx,zy);
zx += u.dx;
zy += u.dy;
}
mnewsym(zx,zy); /* not always necessary */
Tmp_at(-1,-1); /* closing call */
break;
}
default:
buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
u.ux, u.uy, u.dx, u.dy);
break;
}
if(!objects[obj->otyp].oc_name_known) {
u.urexp += 10;
objects[obj->otyp].oc_name_known = 1;
}
}
return(1);
}
char *
exclam(force)
register int force;
{
/* force == 0 occurs e.g. with sleep ray */
/* note that large force is usual with wands so that !! would
require information about hand/weapon/wand */
return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
}
hit(str,mtmp,force)
register char *str;
register struct monst *mtmp;
register char *force; /* usually either "." or "!" */
{
if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str);
else pline("The %s hits %s%s", str, monnam(mtmp), force);
}
miss(str,mtmp)
register char *str;
register struct monst *mtmp;
{
if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str);
else pline("The %s misses %s.",str,monnam(mtmp));
}
/* sets bhitpos to the final position of the weapon thrown */
/* coord bhitpos; */
/* check !u.uswallow before calling bhit() */
struct monst *
bhit(ddx,ddy,range,sym)
register ddx,ddy,range;
char sym;
{
register struct monst *mtmp;
bhitpos.x = u.ux;
bhitpos.y = u.uy;
if(sym) tmp_at(-1, sym); /* open call */
while(range--) {
bhitpos.x += ddx;
bhitpos.y += ddy;
if(mtmp = m_at(bhitpos.x,bhitpos.y)){
if(sym) tmp_at(-1, -1); /* close call */
return(mtmp);
}
if(levl[bhitpos.x][bhitpos.y].typ<CORR) {
bhitpos.x -= ddx;
bhitpos.y -= ddy;
break;
}
if(sym) tmp_at(bhitpos.x, bhitpos.y);
}
if(sym) tmp_at(-1, 0); /* leave last symbol */
return(0);
}
struct monst *
boomhit(dx,dy) {
register int i, ct;
register struct monst *mtmp;
char sym = ')';
extern schar xdir[], ydir[];
bhitpos.x = u.ux;
bhitpos.y = u.uy;
for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
tmp_at(-1, sym); /* open call */
for(ct=0; ct<10; ct++) {
if(i == 8) i = 0;
sym = ')' + '(' - sym;
tmp_at(-2, sym); /* change let call */
dx = xdir[i];
dy = ydir[i];
bhitpos.x += dx;
bhitpos.y += dy;
if(mtmp = m_at(bhitpos.x, bhitpos.y)){
tmp_at(-1,-1);
return(mtmp);
}
if(levl[bhitpos.x][bhitpos.y].typ<CORR) {
bhitpos.x -= dx;
bhitpos.y -= dy;
break;
}
if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
if(rn2(20) >= 10+u.ulevel){ /* we hit ourselves */
(void) thitu(10, rnd(10), "boomerang");
break;
} else { /* we catch it */
tmp_at(-1,-1);
pline("Skillfully, you catch the boomerang.");
return((struct monst *) -1);
}
}
tmp_at(bhitpos.x, bhitpos.y);
if(ct % 5 != 0) i++;
}
tmp_at(-1, -1); /* do not leave last symbol */
return(0);
}
char
dirlet(dx,dy) register dx,dy; {
return
(dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
}
/* type < 0: monster spitting fire at you */
buzz(type,sx,sy,dx,dy)
register int type;
register xchar sx,sy;
register int dx,dy;
{
register char *fltxt = (type < 0) ? "blaze of fire" : fl[type];
struct rm *lev;
xchar range;
struct monst *mon;
if(u.uswallow) {
register int tmp;
if(type < 0) return;
tmp = zhit(u.ustuck, type);
pline("The %s rips into %s%s",
fltxt, monnam(u.ustuck), exclam(tmp));
return;
}
if(type < 0) pru();
range = rn1(7,7);
Tmp_at(-1, dirlet(dx,dy)); /* open call */
while(range-- > 0) {
sx += dx;
sy += dy;
if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy);
else {
int bounce = 0;
if(cansee(sx-dx,sy-dy)) pline("The %s bounces!",fltxt);
if(levl[sx][sy-dy].typ > DOOR) bounce = 1;
if(levl[sx-dx][sy].typ > DOOR) {
if(!bounce || rn2(2)) bounce = 2;
}
switch(bounce){
case 0:
dx = -dx;
dy = -dy;
continue;
case 1:
dy = -dy;
sx -= dx;
break;
case 2:
dx = -dx;
sy -= dy;
break;
}
Tmp_at(-2,dirlet(dx,dy));
continue;
}
if((mon = m_at(sx,sy)) &&
(type >= 0 || mon->data->mlet != 'D')) {
wakeup(mon);
if(rnd(20) < 18 + mon->data->ac) {
register int tmp = zhit(mon,type);
if(mon->mhp < 1) {
if(type < 0) {
if(cansee(mon->mx,mon->my))
pline("%s is killed by the %s!",
Monnam(mon), fltxt);
mondied(mon);
} else
killed(mon);
} else
hit(fltxt, mon, exclam(tmp));
range -= 2;
} else
miss(fltxt,mon);
} else if(sx == u.ux && sy == u.uy) {
if(rnd(20) < 18+u.uac) {
register int dam = 0;
range -= 2;
pline("The %s hits you!",fltxt);
switch(type) {
case 0:
dam = d(2,6);
break;
case -1: /* dragon fire */
case 1:
if(Fire_resistance)
pline("You don't feel hot!");
else dam = d(6,6);
break;
case 2:
nomul(-rnd(25)); /* sleep ray */
break;
case 3:
if(Cold_resistance)
pline("You don't feel cold!");
else dam = d(6,6);
break;
case 4:
u.uhp = -1;
}
losehp(dam,fltxt);
} else pline("The %s whizzes by you!",fltxt);
}
if(lev->typ <= DOOR) {
int bounce = 0, rmn;
if(cansee(sx,sy)) pline("The %s bounces!",fltxt);
range--;
if(!dx || !dy || !rn2(20)){
dx = -dx;
dy = -dy;
} else {
if((rmn = levl[sx][sy-dy].typ) > DOOR &&
(
rmn >= ROOM ||
levl[sx+dx][sy-dy].typ > DOOR)){
bounce = 1;
}
if((rmn = levl[sx-dx][sy].typ) > DOOR &&
(
rmn >= ROOM ||
levl[sx-dx][sy+dy].typ > DOOR)){
if(!bounce || rn2(2)){
bounce = 2;
}
}
switch(bounce){
case 0:
dy = -dy;
dx = -dx;
break;
case 1:
dy = -dy;
break;
case 2:
dx = -dx;
break;
}
Tmp_at(-2, dirlet(dx,dy));
}
}
}
Tmp_at(-1,-1);
}
zhit(mon,type) /* returns damage to mon */
register struct monst *mon;
register type;
{
register int tmp = 0;
switch(type) {
case 0: /* magic missile */
tmp = d(2,6);
break;
case -1: /* Dragon blazing fire */
case 1: /* fire */
if(index("Dg", mon->data->mlet)) break;
tmp = d(6,6);
if(mon->data->mlet == 'Y') tmp += 7;
break;
case 2: /* sleep*/
mon->mfroz = 1;
break;
case 3: /* cold */
if(index("YFgf", mon->data->mlet)) break;
tmp = d(6,6);
if(mon->data->mlet == 'D') tmp += 7;
break;
case 4: /* death*/
if(index("WVZ",mon->data->mlet)) break;
tmp = mon->mhp+1;
break;
}
mon->mhp -= tmp;
return(tmp);
}
//E*O*F hack.zap.c//
echo x - makedefs.c
cat > "makedefs.c" << '//E*O*F makedefs.c//'
/* construct definitions of object constants */
#define DEF_FILE "def.objects.h"
#define LINSZ 1000
#define STRSZ 40
int fd;
char string[STRSZ];
main(){
register int index = 0;
register int propct = 0;
register char *sp;
fd = open(DEF_FILE, 0);
if(fd < 0) {
perror(DEF_FILE);
exit(1);
}
skipuntil("objects[] = {");
while(getentry()) {
if(!*string){
index++;
continue;
}
for(sp = string; *sp; sp++)
if(*sp == ' ' || *sp == '\t')
*sp = '_';
if(!strncmp(string, "RIN_", 4)){
capitalize(string+4);
printf("#define %s u.uprops[%d].p_flgs\n",
string+4, propct++);
}
for(sp = string; *sp; sp++) capitalize(sp);
/* avoid trouble with stupid C preprocessors */
if(!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
printf("/* #define %s %d */\n", string, index);
else
printf("#define %s %d\n", string, index);
index++;
}
printf("\n#define CORPSE DEAD_HUMAN\n");
printf("#define LAST_GEM (JADE+1)\n");
printf("#define LAST_RING %d\n", propct);
printf("#define NROFOBJECTS %d\n", index-1);
}
char line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
int eof;
readline(){
register int n = read(fd, lp0, (line+LINSZ)-lp0);
if(n < 0){
printf("Input error.\n");
exit(1);
}
if(n == 0) eof++;
lpe = lp0+n;
}
char
nextchar(){
if(lp == lpe){
readline();
lp = lp0;
}
return((lp == lpe) ? 0 : *lp++);
}
skipuntil(s) char *s; {
register char *sp0, *sp1;
loop:
while(*s != nextchar())
if(eof) {
printf("Cannot skipuntil %s\n", s);
exit(1);
}
if(strlen(s) > lpe-lp+1){
register char *lp1, *lp2;
lp2 = lp;
lp1 = lp = lp0;
while(lp2 != lpe) *lp1++ = *lp2++;
lp2 = lp0; /* save value */
lp0 = lp1;
readline();
lp0 = lp2;
if(strlen(s) > lpe-lp+1) {
printf("error in skipuntil");
exit(1);
}
}
sp0 = s+1;
sp1 = lp;
while(*sp0 && *sp0 == *sp1) sp0++, sp1++;
if(!*sp0){
lp = sp1;
return(1);
}
goto loop;
}
getentry(){
int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
int prefix = 0;
char ch;
#define NSZ 10
char identif[NSZ], *ip;
string[0] = string[4] = 0;
/* read until {...} or XXX(...) followed by ,
skip comment and #define lines
deliver 0 on failure
*/
while(1) {
ch = nextchar();
swi:
if(letter(ch)){
ip = identif;
do {
if(ip < identif+NSZ-1) *ip++ = ch;
ch = nextchar();
} while(letter(ch) || digit(ch));
*ip = 0;
while(ch == ' ' || ch == '\t') ch = nextchar();
if(ch == '(' && !inparens && !stringseen)
if(!strcmp(identif, "WAND") ||
!strcmp(identif, "RING") ||
!strcmp(identif, "POTION") ||
!strcmp(identif, "SCROLL"))
(void) strncpy(string, identif, 3),
string[3] = '_',
prefix = 4;
}
switch(ch) {
case '/':
/* watch for comment */
if((ch = nextchar()) == '*')
skipuntil("*/");
goto swi;
case '{':
inbraces++;
continue;
case '(':
inparens++;
continue;
case '}':
inbraces--;
if(inbraces < 0) return(0);
continue;
case ')':
inparens--;
if(inparens < 0) {
printf("too many ) ?");
exit(1);
}
continue;
case '\n':
/* watch for #define at begin of line */
if((ch = nextchar()) == '#'){
register char pch;
/* skip until '\n' not preceded by '\\' */
do {
pch = ch;
ch = nextchar();
} while(ch != '\n' || pch == '\\');
continue;
}
goto swi;
case ',':
if(!inparens && !inbraces){
if(prefix && !string[prefix])
string[0] = 0;
if(stringseen) return(1);
printf("unexpected ,\n");
exit(1);
}
commaseen++;
continue;
case '\'':
if((ch = nextchar()) == '\\') ch = nextchar();
if(nextchar() != '\''){
printf("strange character denotation?\n");
exit(1);
}
continue;
case '"':
{
register char *sp = string + prefix;
register char pch;
register int store = (inbraces || inparens)
&& !stringseen++ && !commaseen;
do {
pch = ch;
ch = nextchar();
if(store && sp < string+STRSZ)
*sp++ = ch;
} while(ch != '"' || pch == '\\');
if(store) *--sp = 0;
continue;
}
}
}
}
capitalize(sp) register char *sp; {
if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a';
}
letter(ch) register char ch; {
return( ('a' <= ch && ch <= 'z') ||
('A' <= ch && ch <= 'Z') );
}
digit(ch) register char ch; {
return( '0' <= ch && ch <= '9' );
}
//E*O*F makedefs.c//
exit 0
More information about the Comp.sources.unix
mailing list