Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site mcvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!mcvax!play From: play@mcvax.UUCP (funhouse) Newsgroups: net.sources Subject: Hack sources (part 13 of 15) Message-ID: <6255@mcvax.UUCP> Date: Mon, 17-Dec-84 19:41:00 EST Article-I.D.: mcvax.6255 Posted: Mon Dec 17 19:41:00 1984 Date-Received: Wed, 19-Dec-84 02:18:25 EST Organization: CWI, Amsterdam Lines: 1105 # 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 #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= 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