home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v16i058: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part50/108
- Message-ID: <4361@master.CNA.TEK.COM>
- Date: 1 Feb 93 19:42:38 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2248
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1608
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 58
- Archive-name: nethack31/Part50
- Supersedes: nethack3p9: Volume 10, Issue 46-102
- Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 50 (of 108)."
- # Contents: src/dogmove.c util/lev_comp.y
- # Wrapped by billr@saab on Wed Jan 27 16:09:06 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/dogmove.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/dogmove.c'\"
- else
- echo shar: Extracting \"'src/dogmove.c'\" \(17769 characters\)
- sed "s/^X//" >'src/dogmove.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)dogmove.c 3.1 92/11/26 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X
- X#include "mfndpos.h"
- X#include "edog.h"
- X
- X#ifdef OVL0
- X
- Xstatic boolean FDECL(dog_hunger,(struct monst *,struct edog *));
- Xstatic boolean FDECL(dog_invent,(struct monst *,struct edog *,int));
- Xstatic int FDECL(dog_goal,(struct monst *,struct edog *,int,int,int));
- X
- X#ifndef MUSE
- X#define DROPPABLES(mtmp) mtmp->minvent
- X#else
- Xstatic struct obj *FDECL(DROPPABLES, (struct monst *));
- X
- Xstatic struct obj *
- XDROPPABLES(mon)
- Xregister struct monst *mon;
- X{
- X register struct obj *obj;
- X struct obj *wep = MON_WEP(mon);
- X
- X for(obj = mon->minvent; obj; obj = obj->nobj)
- X if (!obj->owornmask && obj != wep) return obj;
- X return (struct obj *)0;
- X}
- X#endif
- X
- Xstatic const char NEARDATA nofetch[] = { BALL_CLASS, CHAIN_CLASS, ROCK_CLASS, 0 };
- X
- X#endif /* OVL0 */
- X
- XSTATIC_VAR xchar gtyp, gx, gy; /* type and position of dog's current goal */
- X
- XSTATIC_DCL void FDECL(dog_eat, (struct monst *, struct obj *, int, int));
- XSTATIC_PTR void FDECL(wantdoor, (int, int, genericptr_t));
- X
- X#ifdef OVLB
- X
- XSTATIC_OVL void
- Xdog_eat(mtmp, obj, x, y)
- Xregister struct monst *mtmp;
- Xregister struct obj * obj;
- Xint x, y;
- X{
- X register struct edog *edog = EDOG(mtmp);
- X int nutrit;
- X
- X if(edog->hungrytime < moves)
- X edog->hungrytime = moves;
- X /*
- X * It is arbitrary that the pet takes the same length of time to eat
- X * as a human, but gets more nutritional value.
- X */
- X if (obj->oclass == FOOD_CLASS) {
- X if(obj->otyp == CORPSE) {
- X mtmp->meating = 3 + (mons[obj->corpsenm].cwt >> 6);
- X nutrit = mons[obj->corpsenm].cnutrit;
- X } else {
- X mtmp->meating = objects[obj->otyp].oc_delay;
- X nutrit = objects[obj->otyp].oc_nutrition;
- X }
- X switch(mtmp->data->msize) {
- X case MZ_TINY: nutrit *= 8; break;
- X case MZ_SMALL: nutrit *= 6; break;
- X default:
- X case MZ_MEDIUM: nutrit *= 5; break;
- X case MZ_LARGE: nutrit *= 4; break;
- X case MZ_HUGE: nutrit *= 3; break;
- X case MZ_GIGANTIC: nutrit *= 2; break;
- X }
- X if(obj->oeaten) {
- X mtmp->meating = eaten_stat(mtmp->meating, obj);
- X nutrit = eaten_stat(nutrit, obj);
- X }
- X } else if (obj->oclass == GOLD_CLASS) {
- X mtmp->meating = ((int)obj->quan/2000) + 1;
- X nutrit = ((int)obj->quan/20);
- X } else {
- X /* Unusual pet such as gelatinous cube eating odd stuff.
- X * meating made consistent with wild monsters in mon.c.
- X * nutrit made consistent with polymorphed player nutrit in
- X * eat.c. (This also applies to pets eating gold.)
- X */
- X mtmp->meating = obj->owt/20 + 1;
- X nutrit = 5*objects[obj->otyp].oc_nutrition;
- X }
- X edog->hungrytime += nutrit;
- X mtmp->mconf = 0;
- X if (mtmp->mtame < 20) mtmp->mtame++;
- X if(cansee(x,y))
- X pline("%s eats %s.", Monnam(mtmp), (obj->oclass==FOOD_CLASS)
- X ? singular(obj, doname) : doname(obj));
- X /* It's a reward if it's DOGFOOD and the player dropped/threw it. */
- X /* We know the player had it if invlet is set -dlc */
- X if(dogfood(mtmp,obj) == DOGFOOD && obj->invlet)
- X#ifdef LINT
- X edog->apport = 0;
- X#else
- X edog->apport += (unsigned)(200L/
- X ((long)edog->dropdist+moves-edog->droptime));
- X#endif
- X if (obj == uball) {
- X unpunish();
- X delobj(obj);
- X } else if (obj == uchain)
- X unpunish();
- X else if (obj->quan > 1L && obj->oclass == FOOD_CLASS)
- X obj->quan--;
- X else
- X delobj(obj);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL0
- X
- X/* hunger effects -- returns TRUE on starvation */
- Xstatic boolean
- Xdog_hunger(mtmp, edog)
- Xregister struct monst *mtmp;
- Xregister struct edog *edog;
- X{
- X if(moves > edog->hungrytime + 500) {
- X if(!carnivorous(mtmp->data) && !herbivorous(mtmp->data)) {
- X edog->hungrytime = moves + 500;
- X /* but not too high; it might polymorph */
- X } else if (!mtmp->mconf) {
- X mtmp->mconf = 1;
- X mtmp->mhpmax /= 3;
- X if(mtmp->mhp > mtmp->mhpmax)
- X mtmp->mhp = mtmp->mhpmax;
- X if(mtmp->mhp < 1) goto dog_died;
- X if(cansee(mtmp->mx, mtmp->my))
- X pline("%s is confused from hunger.", Monnam(mtmp));
- X else {
- X char buf[BUFSZ];
- X
- X Strcpy(buf, "the ");
- X You("feel worried about %s.", mtmp->mnamelth ?
- X NAME(mtmp) : strcat(buf, Hallucination
- X ? rndmonnam() : mtmp->data->mname));
- X }
- X } else if(moves > edog->hungrytime + 750 || mtmp->mhp < 1) {
- X dog_died:
- X#ifdef WALKIES
- X if(mtmp->mleashed)
- X Your("leash goes slack.");
- X#endif
- X if(cansee(mtmp->mx, mtmp->my))
- X pline("%s dies%s.", Monnam(mtmp),
- X (mtmp->mhp >= 1) ? "" : " from hunger");
- X else
- X You("have a sad feeling for a moment, then it passes.");
- X mondied(mtmp);
- X return(TRUE);
- X }
- X }
- X return(FALSE);
- X}
- X
- X/* do something with object (drop, pick up, eat) at current position
- X * returns TRUE if object eaten (since that counts as dog's move)
- X */
- Xstatic boolean
- Xdog_invent(mtmp, edog, udist)
- Xregister struct monst *mtmp;
- Xregister struct edog *edog;
- Xint udist;
- X{
- X register int omx, omy;
- X struct obj *obj;
- X
- X omx = mtmp->mx;
- X omy = mtmp->my;
- X
- X /* if we are carrying sth then we drop it (perhaps near @) */
- X /* Note: if apport == 1 then our behaviour is independent of udist */
- X if(DROPPABLES(mtmp) || mtmp->mgold) {
- X if(!rn2(udist) || !rn2((int) edog->apport))
- X if(rn2(10) < edog->apport){
- X relobj(mtmp, (int)mtmp->minvis, TRUE);
- X if(edog->apport > 1) edog->apport--;
- X edog->dropdist = udist; /* hpscdi!jon */
- X edog->droptime = moves;
- X }
- X } else {
- X if((obj=level.objects[omx][omy]) && !index(nofetch,obj->oclass)
- X#ifdef MAIL
- X && obj->otyp != SCR_MAIL
- X#endif
- X ){
- X if (dogfood(mtmp, obj) <= CADAVER) {
- X dog_eat(mtmp, obj, omx, omy);
- X return TRUE;
- X }
- X if(can_carry(mtmp, obj) && !obj->cursed)
- X if(rn2(20) < edog->apport+3)
- X if(rn2(udist) || !rn2((int) edog->apport)) {
- X if (cansee(omx, omy) && flags.verbose)
- X pline("%s picks up %s.", Monnam(mtmp),
- X distant_name(obj, doname));
- X freeobj(obj);
- X newsym(omx,omy);
- X mpickobj(mtmp,obj);
- X }
- X }
- X }
- X return FALSE;
- X}
- X
- X/* set dog's goal -- gtyp, gx, gy
- X * returns -1/0/1 (dog's desire to approach player) or -2 (abort move)
- X */
- Xstatic int
- Xdog_goal(mtmp, edog, after, udist, whappr)
- Xregister struct monst *mtmp;
- Xstruct edog *edog;
- Xint after, udist, whappr;
- X{
- X register int omx, omy;
- X boolean in_masters_sight;
- X register struct obj *obj;
- X xchar otyp;
- X int appr;
- X
- X omx = mtmp->mx;
- X omy = mtmp->my;
- X
- X in_masters_sight = couldsee(omx, omy);
- X
- X if (!edog
- X#ifdef WALKIES
- X || mtmp->mleashed /* he's not going anywhere... */
- X#endif
- X ) {
- X gtyp = APPORT;
- X gx = u.ux;
- X gy = u.uy;
- X } else {
- X#define DDIST(x,y) (dist2(x,y,omx,omy))
- X#define SQSRCHRADIUS 5
- X int min_x, max_x, min_y, max_y;
- X register int nx, ny;
- X
- X gtyp = UNDEF; /* no goal as yet */
- X gx = gy = 0; /* suppress 'used before set' message */
- X
- X if ((min_x = omx - SQSRCHRADIUS) < 0) min_x = 0;
- X if ((max_x = omx + SQSRCHRADIUS) >= COLNO) max_x = COLNO - 1;
- X if ((min_y = omy - SQSRCHRADIUS) < 0) min_y = 0;
- X if ((max_y = omy + SQSRCHRADIUS) >= ROWNO) max_y = ROWNO - 1;
- X
- X /* nearby food is the first choice, then other objects */
- X for (obj = fobj; obj; obj = obj->nobj) {
- X nx = obj->ox;
- X ny = obj->oy;
- X if (nx >= min_x && nx <= max_x && ny >= min_y && ny <= max_y) {
- X otyp = dogfood(mtmp, obj);
- X if (otyp > gtyp || otyp == UNDEF)
- X continue;
- X if (otyp < MANFOOD) {
- X if (otyp < gtyp || DDIST(nx,ny) < DDIST(gx,gy)) {
- X gx = nx;
- X gy = ny;
- X gtyp = otyp;
- X }
- X } else if(gtyp == UNDEF && in_masters_sight &&
- X !mtmp->minvent &&
- X (!levl[omx][omy].lit || levl[u.ux][u.uy].lit) &&
- X (otyp == MANFOOD || m_cansee(mtmp, nx, ny)) &&
- X edog->apport > rn2(8) &&
- X can_carry(mtmp,obj)) {
- X gx = nx;
- X gy = ny;
- X gtyp = APPORT;
- X }
- X }
- X }
- X }
- X
- X /* follow player if appropriate */
- X if (gtyp == UNDEF ||
- X (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)) {
- X gx = u.ux;
- X gy = u.uy;
- X if (after && udist <= 4 && gx == u.ux && gy == u.uy)
- X return(-2);
- X appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0;
- X if (udist > 1) {
- X if (!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
- X whappr ||
- X (mtmp->minvent && rn2((int) edog->apport)))
- X appr = 1;
- X }
- X /* if you have dog food it'll follow you more closely */
- X if (appr == 0) {
- X obj = invent;
- X while (obj) {
- X if(dogfood(mtmp, obj) == DOGFOOD) {
- X appr = 1;
- X break;
- X }
- X obj = obj->nobj;
- X }
- X }
- X } else
- X appr = 1; /* gtyp != UNDEF */
- X if(mtmp->mconf)
- X appr = 0;
- X
- X#define FARAWAY (COLNO + 2) /* position outside screen */
- X if (gx == u.ux && gy == u.uy && !in_masters_sight) {
- X register coord *cp;
- X
- X cp = gettrack(omx,omy);
- X if (cp) {
- X gx = cp->x;
- X gy = cp->y;
- X if(edog) edog->ogoal.x = 0;
- X } else {
- X /* assume master hasn't moved far, and reuse previous goal */
- X if(edog && edog->ogoal.x &&
- X ((edog->ogoal.x != omx) || (edog->ogoal.y != omy))) {
- X gx = edog->ogoal.x;
- X gy = edog->ogoal.y;
- X edog->ogoal.x = 0;
- X } else {
- X int fardist = FARAWAY * FARAWAY;
- X gx = gy = FARAWAY; /* random */
- X do_clear_area(omx, omy, 9, wantdoor,
- X (genericptr_t)&fardist);
- X
- X /* here gx == FARAWAY e.g. when dog is in a vault */
- X if (gx == FARAWAY || (gx == omx && gy == omy)) {
- X gx = u.ux;
- X gy = u.uy;
- X } else if(edog) {
- X edog->ogoal.x = gx;
- X edog->ogoal.y = gy;
- X }
- X }
- X }
- X } else if(edog) {
- X edog->ogoal.x = 0;
- X }
- X return appr;
- X}
- X
- X/* return 0 (no move), 1 (move) or 2 (dead) */
- Xint
- Xdog_move(mtmp, after)
- Xregister struct monst *mtmp;
- Xregister int after; /* this is extra fast monster movement */
- X{
- X int omx, omy; /* original mtmp position */
- X int appr, whappr, udist;
- X int i, j;
- X register struct edog *edog = EDOG(mtmp);
- X struct obj *obj = (struct obj *) 0;
- X xchar otyp;
- X boolean has_edog, cursemsg = FALSE, do_eat = FALSE;
- X xchar nix, niy; /* position mtmp is (considering) moving to */
- X register int nx, ny; /* temporary coordinates */
- X xchar cnt, uncursedcnt, chcnt;
- X int chi = -1, nidist, ndist;
- X coord poss[9];
- X long info[9], allowflags;
- X#define GDIST(x,y) (dist2(x,y,gx,gy))
- X
- X /*
- X * Tame Angels have isminion set and an ispriest structure instead of
- X * an edog structure. Fortunately, guardian Angels need not worry
- X * about mundane things like eating and fetching objects, and can
- X * spend all their energy defending the player. (They are the only
- X * monsters with other structures that can be tame.)
- X */
- X has_edog = !mtmp->isminion;
- X
- X omx = mtmp->mx;
- X omy = mtmp->my;
- X if (has_edog && dog_hunger(mtmp, edog)) return(2); /* starved */
- X
- X udist = distu(omx,omy);
- X /* maybe we tamed him while being swallowed --jgm */
- X if (!udist) return(0);
- X
- X nix = omx; /* set before newdogpos */
- X niy = omy;
- X
- X if (has_edog && dog_invent(mtmp, edog, udist)) /* eating something */
- X goto newdogpos;
- X
- X if (has_edog)
- X whappr = (moves - edog->whistletime < 5);
- X else
- X whappr = 0;
- X
- X appr = dog_goal(mtmp, has_edog ? edog : (struct edog *)0,
- X after, udist, whappr);
- X if (appr == -2) return(0);
- X
- X allowflags = ALLOW_M | ALLOW_TRAPS | ALLOW_SSM | ALLOW_SANCT;
- X if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
- X if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
- X if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
- X allowflags |= ALLOW_U;
- X if (!has_edog) {
- X coord mm;
- X /* Guardian angel refuses to be conflicted; rather,
- X * it disappears, angrily, and sends in some nasties
- X */
- X if (canseemon(mtmp) || sensemon(mtmp)) {
- X pline("%s rebukes you, saying:", Monnam(mtmp));
- X verbalize("Since you desire conflict, have some more!");
- X }
- X mongone(mtmp);
- X i = rnd(4);
- X while(i--) {
- X mm.x = u.ux;
- X mm.y = u.uy;
- X if(enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]))
- X (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type,
- X mm.x, mm.y, FALSE);
- X }
- X return(2);
- X
- X }
- X }
- X if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
- X allowflags |= OPENDOOR;
- X if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
- X }
- X if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
- X if (tunnels(mtmp->data) && !needspick(mtmp->data))
- X allowflags |= ALLOW_DIG;
- X cnt = mfndpos(mtmp, poss, info, allowflags);
- X
- X /* Normally dogs don't step on cursed items, but if they have no
- X * other choice they will. This requires checking ahead of time
- X * to see how many cursed item squares are around.
- X */
- X uncursedcnt = 0;
- X for (i = 0; i < cnt; i++) {
- X nx = poss[i].x; ny = poss[i].y;
- X if (MON_AT(nx,ny)) continue;
- X for (obj = level.objects[nx][ny]; obj; obj = obj->nexthere)
- X if (obj->cursed) goto skipu;
- X uncursedcnt++;
- Xskipu:;
- X }
- X
- X chcnt = 0;
- X chi = -1;
- X nidist = GDIST(nix,niy);
- X
- X for (i = 0; i < cnt; i++) {
- X nx = poss[i].x;
- X ny = poss[i].y;
- X#ifdef WALKIES
- X /* if leashed, we drag him along. */
- X if (mtmp->mleashed && distu(nx, ny) > 4) continue;
- X#endif
- X /* if a guardian, try to stay close by choice */
- X if (!has_edog &&
- X (j = distu(nx, ny)) > 16 && j >= udist) continue;
- X
- X if ((info[i] & ALLOW_M) && MON_AT(nx, ny)) {
- X int stat;
- X register struct monst *mtmp2 = m_at(nx,ny);
- X
- X if ((int)mtmp2->m_lev >= (int)mtmp->m_lev+2 ||
- X (mtmp2->data == &mons[PM_FLOATING_EYE] && rn2(10) &&
- X mtmp->mcansee && haseyes(mtmp->data) && mtmp2->mcansee
- X && (perceives(mtmp->data) || !mtmp2->minvis)) ||
- X (mtmp2->data==&mons[PM_GELATINOUS_CUBE] && rn2(10)) ||
- X (max_passive_dmg(mtmp2, mtmp) >= mtmp->mhp) ||
- X (mtmp->mhp*4 < mtmp->mhpmax &&
- X mtmp2->mpeaceful && !Conflict) ||
- X (mtmp2->data->mlet == S_COCKATRICE &&
- X !resists_ston(mtmp->data)))
- X continue;
- X
- X if (after) return(0); /* hit only once each move */
- X
- X stat = mattackm(mtmp, mtmp2);
- X
- X /* aggressor (pet) died */
- X if (stat & MM_AGR_DIED) return 2;
- X
- X if ((stat & MM_HIT) && !(stat & MM_DEF_DIED) &&
- X rn2(4) && mtmp2->mlstmv != monstermoves) {
- X stat = mattackm(mtmp2, mtmp); /* return attack */
- X if (stat & MM_DEF_DIED) return 2;
- X }
- X
- X return 0;
- X }
- X
- X { /* dog avoids traps, but perhaps it has to pass a trap
- X * in order to follow player
- X */
- X struct trap *trap;
- X
- X if ((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))) {
- X if ((trap->ttyp == RUST_TRAP
- X && mtmp->data != &mons[PM_IRON_GOLEM])
- X || trap->ttyp == STATUE_TRAP
- X || ((trap->ttyp == PIT
- X || trap->ttyp == SPIKED_PIT
- X || (trap->ttyp == TRAPDOOR &&
- X !Can_fall_thru(&u.uz)))
- X && (is_flyer(mtmp->data) ||
- X is_clinger(mtmp->data)))
- X || (trap->ttyp == SLP_GAS_TRAP &&
- X resists_sleep(mtmp->data)))
- X if(!trap->tseen || rn2(3)) continue;
- X#ifdef WALKIES
- X if (!mtmp->mleashed) {
- X#endif
- X if (!trap->tseen && rn2(40)) continue;
- X if (rn2(10)) continue;
- X#ifdef WALKIES
- X }
- X# ifdef SOUNDS
- X else if (flags.soundok)
- X whimper(mtmp);
- X# endif
- X#endif
- X }
- X }
- X
- X /* dog eschews cursed objects, but likes dog food */
- X for (obj = level.objects[nx][ny]; obj; obj = obj->nexthere) {
- X if (obj->cursed && !mtmp->mleashed && uncursedcnt)
- X goto nxti;
- X if (obj->cursed) cursemsg = TRUE;
- X if (has_edog && (otyp = dogfood(mtmp, obj)) < MANFOOD &&
- X (otyp < ACCFOOD || edog->hungrytime <= moves)){
- X /* Note: our dog likes the food so much that he
- X * might eat it even when it conceals a cursed object */
- X nix = nx;
- X niy = ny;
- X chi = i;
- X do_eat = TRUE;
- X goto newdogpos;
- X }
- X }
- X
- X for (j = 0; j < MTSZ && j < cnt-1; j++)
- X if (nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
- X if (rn2(4*(cnt-j))) goto nxti;
- X
- X j = ((ndist = GDIST(nx,ny)) - nidist) * appr;
- X if ((j == 0 && !rn2(++chcnt)) || j < 0 ||
- X (j > 0 && !whappr &&
- X ((omx == nix && omy == niy && !rn2(3))
- X || !rn2(12))
- X )) {
- X nix = nx;
- X niy = ny;
- X nidist = ndist;
- X if(j < 0) chcnt = 0;
- X chi = i;
- X }
- X nxti: ;
- X }
- Xnewdogpos:
- X if (nix != omx || niy != omy) {
- X if (info[chi] & ALLOW_U) {
- X#ifdef WALKIES
- X if (mtmp->mleashed) { /* play it safe */
- X pline("%s breaks loose of %s leash!",
- X Monnam(mtmp),
- X humanoid(mtmp->data)
- X ? (mtmp->female ? "her" : "his")
- X : "its");
- X m_unleash(mtmp);
- X }
- X#endif
- X (void) mattacku(mtmp);
- X return(0);
- X }
- X /* insert a worm_move() if worms ever begin to eat things */
- X remove_monster(omx, omy);
- X place_monster(mtmp, nix, niy);
- X if (cursemsg && (cansee(omx,omy) || cansee(nix,niy)))
- X pline("%s moves only reluctantly.", Monnam(mtmp));
- X for (j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
- X mtmp->mtrack[0].x = omx;
- X mtmp->mtrack[0].y = omy;
- X /* We have to know if the pet's gonna do a combined eat and
- X * move before moving it, but it can't eat until after being
- X * moved. Thus the do_eat flag.
- X */
- X if (do_eat)
- X dog_eat(mtmp, obj, nix, niy);
- X }
- X#ifdef WALKIES
- X /* an incredible kludge, but the only way to keep pooch near
- X * after it spends time eating or in a trap, etc.
- X */
- X else if (mtmp->mleashed && distu(omx, omy) > 4) {
- X coord cc;
- X
- X nx = sgn(omx - u.ux);
- X ny = sgn(omy - u.uy);
- X cc.x = u.ux + nx;
- X cc.y = u.uy + ny;
- X if (goodpos(cc.x, cc.y, mtmp, mtmp->data)) goto dognext;
- X
- X i = xytod(nx, ny);
- X for (j = (i + 7)%8; j < (i + 1)%8; j++) {
- X dtoxy(&cc, j);
- X if (goodpos(cc.x, cc.y, mtmp, mtmp->data)) goto dognext;
- X }
- X for (j = (i + 6)%8; j < (i + 2)%8; j++) {
- X dtoxy(&cc, j);
- X if (goodpos(cc.x, cc.y, mtmp, mtmp->data)) goto dognext;
- X }
- X cc.x = mtmp->mx;
- X cc.y = mtmp->my;
- Xdognext:
- X remove_monster(mtmp->mx, mtmp->my);
- X place_monster(mtmp, cc.x, cc.y);
- X newsym(cc.x,cc.y);
- X set_apparxy(mtmp);
- X }
- X#endif
- X return(1);
- X}
- X
- X#endif /* OVL0 */
- X#ifdef OVLB
- X
- X/*ARGSUSED*/ /* do_clear_area client */
- XSTATIC_PTR void
- Xwantdoor(x, y, distance)
- Xint x, y;
- Xgenericptr_t distance;
- X{
- X register ndist;
- X
- X if (*(int*)distance > (ndist = distu(x, y))) {
- X gx = x;
- X gy = y;
- X *(int*)distance = ndist;
- X }
- X}
- X
- X#endif /* OVLB */
- X
- X/*dogmove.c*/
- END_OF_FILE
- if test 17769 -ne `wc -c <'src/dogmove.c'`; then
- echo shar: \"'src/dogmove.c'\" unpacked with wrong size!
- fi
- # end of 'src/dogmove.c'
- fi
- if test -f 'util/lev_comp.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/lev_comp.y'\"
- else
- echo shar: Extracting \"'util/lev_comp.y'\" \(35847 characters\)
- sed "s/^X//" >'util/lev_comp.y' <<'END_OF_FILE'
- X%{
- X/* SCCS Id: @(#)lev_comp.c 3.1 92/07/12 */
- X/* Copyright (c) 1989 by Jean-Christophe Collet */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X/*
- X * This file contains the Level Compiler code
- X * It may handle special mazes & special room-levels
- X */
- X
- X/* In case we're using bison in AIX. This definition must be
- X * placed before any other C-language construct in the file
- X * excluding comments and preprocessor directives (thanks IBM
- X * for this wonderful feature...).
- X *
- X * Note: some cpps barf on this 'undefined control' (#pragma).
- X * Addition of the leading space seems to prevent barfage for now,
- X * and AIX will still see the directive in its non-standard locale.
- X */
- X
- X#ifdef _AIX
- X #pragma alloca /* keep leading space! */
- X#endif
- X
- X#include "hack.h"
- X#include "sp_lev.h"
- X#ifndef O_WRONLY
- X# include <fcntl.h>
- X#endif
- X#ifndef O_CREAT /* some older BSD systems do not define O_CREAT in <fcntl.h> */
- X# include <sys/file.h>
- X#endif
- X#ifndef O_BINARY /* used for micros, no-op for others */
- X# define O_BINARY 0
- X#endif
- X
- X#ifdef MICRO
- X# define OMASK FCMASK
- X#else
- X# define OMASK 0644
- X#endif
- X
- X#define MAX_REGISTERS 10
- X#define ERR (-1)
- X
- X#define New(type) (type *) alloc(sizeof(type))
- X#define NewTab(type, size) (type **) alloc(sizeof(type *) * size)
- X
- X#ifdef MICRO
- X# undef exit
- Xextern void FDECL(exit, (int));
- X#endif
- X
- Xextern void FDECL(yyerror, (char *));
- Xextern void FDECL(yywarning, (char *));
- Xextern int NDECL(yylex);
- Xint NDECL(yyparse);
- X
- Xextern char *FDECL(dup_string,(char *));
- Xextern int FDECL(get_floor_type, (CHAR_P));
- Xextern int FDECL(get_room_type, (char *));
- Xextern int FDECL(get_trap_type, (char *));
- Xextern int FDECL(get_monster_id, (char *, CHAR_P));
- Xextern int FDECL(get_object_id, (char *));
- Xextern boolean FDECL(check_monster_char, (CHAR_P));
- Xextern boolean FDECL(check_object_char, (CHAR_P));
- Xextern char FDECL(what_map_char, (CHAR_P));
- Xextern void FDECL(scan_map, (char *));
- Xextern void NDECL(wallify_map);
- Xextern boolean NDECL(check_subrooms);
- Xextern void FDECL(check_coord, (int, int, char *));
- Xextern void NDECL(store_part);
- Xextern void NDECL(store_room);
- Xextern void FDECL(write_maze, (int, specialmaze *));
- Xextern void FDECL(write_lev, (int, splev *));
- Xextern void FDECL(free_rooms, (room **, int));
- X
- Xstatic struct reg {
- X int x1, y1;
- X int x2, y2;
- X} current_region;
- X
- Xstatic struct coord {
- X int x;
- X int y;
- X} current_coord, current_align;
- X
- Xstatic struct size {
- X int height;
- X int width;
- X} current_size;
- X
- Xchar tmpmessage[256];
- Xaltar *tmpaltar[256];
- Xlad *tmplad[256];
- Xstair *tmpstair[256];
- Xdigpos *tmpdig[256];
- Xchar *tmpmap[ROWNO];
- Xregion *tmpreg[256];
- Xlev_region *tmplreg[32];
- Xdoor *tmpdoor[256];
- Xroom_door *tmprdoor[256];
- Xtrap *tmptrap[256];
- Xmonster *tmpmonst[256];
- Xobject *tmpobj[256];
- Xdrawbridge *tmpdb[256];
- Xwalk *tmpwalk[256];
- Xgold *tmpgold[256];
- Xfountain *tmpfountain[256];
- Xsink *tmpsink[256];
- Xpool *tmppool[256];
- Xengraving *tmpengraving[256];
- Xmazepart *tmppart[10];
- Xroom *tmproom[MAXNROFROOMS*2];
- Xcorridor *tmpcor[256];
- X
- Xstatic specialmaze maze;
- Xstatic splev special_lev;
- Xstatic lev_init init_lev;
- X
- Xstatic char olist[MAX_REGISTERS], mlist[MAX_REGISTERS];
- Xstatic struct coord plist[MAX_REGISTERS];
- X
- Xint n_olist = 0, n_mlist = 0, n_plist = 0;
- X
- Xunsigned int nlreg = 0, nreg = 0, ndoor = 0, ntrap = 0, nmons = 0, nobj = 0;
- Xunsigned int ndb = 0, nwalk = 0, npart = 0, ndig = 0, nlad = 0, nstair = 0;
- Xunsigned int naltar = 0, ncorridor = 0, nrooms = 0, ngold = 0, nengraving = 0;
- Xunsigned int nfountain = 0, npool = 0, nsink = 0;
- X
- Xstatic unsigned long lev_flags = 0;
- X
- Xunsigned int max_x_map, max_y_map;
- X
- Xstatic xchar in_room;
- X
- Xextern int fatal_error;
- Xextern int want_warnings;
- Xextern char* fname;
- X
- X%}
- X
- X%union
- X{
- X int i;
- X char* map;
- X struct {
- X xchar room;
- X xchar wall;
- X xchar door;
- X } corpos;
- X}
- X
- X
- X%token <i> CHAR INTEGER BOOLEAN
- X%token <i> MESSAGE_ID MAZE_ID LEVEL_ID LEV_INIT_ID GEOMETRY_ID NOMAP_ID
- X%token <i> OBJECT_ID MONSTER_ID TRAP_ID DOOR_ID DRAWBRIDGE_ID
- X%token <i> MAZEWALK_ID WALLIFY_ID REGION_ID FILLING
- X%token <i> RANDOM_OBJECTS_ID RANDOM_MONSTERS_ID RANDOM_PLACES_ID
- X%token <i> ALTAR_ID LADDER_ID STAIR_ID NON_DIGGABLE_ID ROOM_ID
- X%token <i> PORTAL_ID TELEPRT_ID BRANCH_ID LEV CHANCE_ID
- X%token <i> CORRIDOR_ID GOLD_ID ENGRAVING_ID FOUNTAIN_ID POOL_ID SINK_ID NONE
- X%token <i> RAND_CORRIDOR_ID DOOR_STATE LIGHT_STATE CURSE_TYPE ENGRAVING_TYPE
- X%token <i> DIRECTION RANDOM_TYPE O_REGISTER M_REGISTER P_REGISTER A_REGISTER
- X%token <i> ALIGNMENT LEFT_OR_RIGHT CENTER TOP_OR_BOT ALTAR_TYPE UP_OR_DOWN
- X%token <i> SUBROOM_ID NAME_ID FLAGS_ID FLAG_TYPE MON_ATTITUDE MON_ALERTNESS
- X%token <i> MON_APPEARANCE
- X%token <i> ',' ':' '(' ')' '[' ']'
- X%token <map> STRING MAP_ID
- X%type <i> h_justif v_justif trap_name room_type door_state light_state
- X%type <i> alignment altar_type a_register roomfill filling door_pos
- X%type <i> door_wall walled secret curse_state enchantment amount
- X%type <i> engraving_type flags flag_list prefilled lev_region lev_init
- X%type <i> monster monster_c m_register object object_c o_register
- X%type <map> string maze_def level_def m_name o_name art_name
- X%type <corpos> corr_spec
- X%start file
- X
- X%%
- Xfile : /* nothing */
- X | levels
- X ;
- X
- Xlevels : level
- X | level levels
- X ;
- X
- Xlevel : maze_level
- X | room_level
- X ;
- X
- Xmaze_level : maze_def flags lev_init messages regions
- X {
- X int fout, i;
- X
- X if (fatal_error > 0) {
- X fprintf(stderr,
- X "%s : %d errors detected. No output created!\n",
- X fname, fatal_error);
- X } else {
- X char lbuf[20];
- X Strcpy(lbuf, $1);
- X Strcat(lbuf, LEV_EXT);
- X#ifdef MAC_THINKC5
- X fout = open(lbuf, O_WRONLY|O_CREAT|O_BINARY);
- X#else
- X fout = open(lbuf, O_WRONLY|O_CREAT|O_BINARY, OMASK);
- X#endif
- X if (fout < 0) {
- X yyerror("Can't open output file!!");
- X exit(1);
- X }
- X maze.flags = $2;
- X memcpy(&(maze.init_lev), &(init_lev),
- X sizeof(lev_init));
- X maze.numpart = npart;
- X maze.parts = NewTab(mazepart, npart);
- X for(i=0;i<npart;i++)
- X maze.parts[i] = tmppart[i];
- X write_maze(fout, &maze);
- X (void) close(fout);
- X npart = 0;
- X }
- X }
- X ;
- X
- Xroom_level : level_def flags lev_init messages rreg_init rooms corridors_def
- X {
- X int fout, i;
- X
- X if (fatal_error > 0) {
- X fprintf(stderr,
- X "%s : %d errors detected. No output created!\n",
- X fname, fatal_error);
- X } else {
- X char lbuf[20];
- X Strcpy(lbuf, $1);
- X Strcat(lbuf, LEV_EXT);
- X#ifdef MAC_THINKC5
- X fout = open(lbuf, O_WRONLY|O_CREAT|O_BINARY);
- X#else
- X fout = open(lbuf, O_WRONLY|O_CREAT|O_BINARY, OMASK);
- X#endif
- X if (fout < 0) {
- X yyerror("Can't open output file!!");
- X exit(1);
- X }
- X special_lev.flags = $2;
- X memcpy(&(special_lev.init_lev), &(init_lev),
- X sizeof(lev_init));
- X special_lev.nroom = nrooms;
- X special_lev.rooms = NewTab(room, nrooms);
- X for(i=0; i<nrooms; i++)
- X special_lev.rooms[i] = tmproom[i];
- X special_lev.ncorr = ncorridor;
- X special_lev.corrs = NewTab(corridor, ncorridor);
- X for(i=0; i<ncorridor; i++)
- X special_lev.corrs[i] = tmpcor[i];
- X if (check_subrooms())
- X write_lev(fout, &special_lev);
- X free_rooms(special_lev.rooms,special_lev.nroom);
- X nrooms = 0;
- X ncorridor = 0;
- X (void) close(fout);
- X }
- X }
- X ;
- X
- Xlevel_def : LEVEL_ID ':' string
- X {
- X if (index($3, '.'))
- X yyerror("Invalid dot ('.') in level name.");
- X if (strlen($3) > 8)
- X yyerror("Level names limited to 8 characters.");
- X $$ = $3;
- X special_lev.nrobjects = 0;
- X special_lev.nrmonst = 0;
- X }
- X ;
- X
- Xlev_init : /* nothing */
- X {
- X init_lev.init_present = FALSE;
- X $$ = 0;
- X }
- X | LEV_INIT_ID ':' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled
- X {
- X init_lev.init_present = TRUE;
- X if((init_lev.fg = what_map_char($3)) == INVALID_TYPE)
- X yyerror("Invalid foreground type.");
- X if((init_lev.bg = what_map_char($5)) == INVALID_TYPE)
- X yyerror("Invalid background type.");
- X init_lev.smoothed = $7;
- X init_lev.joined = $9;
- X init_lev.lit = $11;
- X init_lev.walled = $13;
- X $$ = 1;
- X }
- X ;
- X
- Xwalled : BOOLEAN
- X | RANDOM_TYPE
- X ;
- X
- Xflags : /* nothing */
- X {
- X $$ = 0;
- X }
- X | FLAGS_ID ':' flag_list
- X {
- X $$ = lev_flags;
- X }
- X ;
- X
- Xflag_list : FLAG_TYPE
- X {
- X lev_flags |= $1;
- X }
- X | FLAG_TYPE ',' flag_list
- X {
- X lev_flags |= $3;
- X }
- X ;
- X
- Xmessages : /* nothing */
- X | message messages
- X ;
- X
- Xmessage : MESSAGE_ID ':' STRING
- X {
- X int i, j;
- X
- X i = strlen($3) + 1;
- X j = tmpmessage[0] ? strlen(tmpmessage) : 0;
- X if(i+j > 255) {
- X yyerror("Message string too long (>256 characters)");
- X } else {
- X if(j) tmpmessage[j++] = '\n';
- X strncpy(tmpmessage+j, $3, i-1);
- X tmpmessage[j+i-1] = 0;
- X }
- X }
- X ;
- X
- Xrreg_init : /* nothing */
- X | rreg_init init_rreg
- X ;
- X
- Xinit_rreg : RANDOM_OBJECTS_ID ':' object_list
- X {
- X if(special_lev.nrobjects) {
- X yyerror("Object registers already initialized!");
- X } else {
- X special_lev.nrobjects = n_olist;
- X special_lev.robjects = (char *) alloc(n_olist);
- X (void) memcpy((genericptr_t)special_lev.robjects,
- X (genericptr_t)olist, n_olist);
- X }
- X }
- X | RANDOM_MONSTERS_ID ':' monster_list
- X {
- X if(special_lev.nrmonst) {
- X yyerror("Monster registers already initialized!");
- X } else {
- X special_lev.nrmonst = n_mlist;
- X special_lev.rmonst = (char *) alloc(n_mlist);
- X (void) memcpy((genericptr_t)special_lev.rmonst,
- X (genericptr_t)mlist, n_mlist);
- X }
- X }
- X ;
- X
- Xrooms : /* Nothing - dummy room for use with INIT_MAP */
- X {
- X tmproom[nrooms] = New(room);
- X (void) memset((genericptr_t) tmproom[nrooms], 0,
- X sizeof *tmproom[nrooms]);
- X tmproom[nrooms]->name = (char *) 0;
- X tmproom[nrooms]->parent = (char *) 0;
- X tmproom[nrooms]->rtype = 0;
- X tmproom[nrooms]->rlit = 0;
- X tmproom[nrooms]->xalign = ERR;
- X tmproom[nrooms]->yalign = ERR;
- X tmproom[nrooms]->x = 0;
- X tmproom[nrooms]->y = 0;
- X tmproom[nrooms]->w = 2;
- X tmproom[nrooms]->h = 2;
- X in_room = 1;
- X }
- X | roomlist
- X ;
- X
- Xroomlist : aroom
- X | aroom roomlist
- X ;
- X
- Xcorridors_def : random_corridors
- X | corridors
- X ;
- X
- Xrandom_corridors: RAND_CORRIDOR_ID
- X {
- X tmpcor[0] = New(corridor);
- X tmpcor[0]->src.room = -1;
- X ncorridor = 1;
- X }
- X ;
- X
- Xcorridors : /* nothing */
- X | corridors corridor
- X ;
- X
- Xcorridor : CORRIDOR_ID ':' corr_spec ',' corr_spec
- X {
- X tmpcor[ncorridor] = New(corridor);
- X tmpcor[ncorridor]->src.room = $3.room;
- X tmpcor[ncorridor]->src.wall = $3.wall;
- X tmpcor[ncorridor]->src.door = $3.door;
- X tmpcor[ncorridor]->dest.room = $5.room;
- X tmpcor[ncorridor]->dest.wall = $5.wall;
- X tmpcor[ncorridor]->dest.door = $5.door;
- X ncorridor++;
- X }
- X | CORRIDOR_ID ':' corr_spec ',' INTEGER
- X {
- X tmpcor[ncorridor]->src.room = $3.room;
- X tmpcor[ncorridor]->src.wall = $3.wall;
- X tmpcor[ncorridor]->src.door = $3.door;
- X tmpcor[ncorridor]->dest.room = -1;
- X tmpcor[ncorridor]->dest.wall = $5;
- X ncorridor++;
- X }
- X ;
- X
- Xcorr_spec : '(' INTEGER ',' DIRECTION ',' door_pos ')'
- X {
- X if ($2 >= nrooms)
- X yyerror("Wrong room number!");
- X $$.room = $2;
- X $$.wall = $4;
- X $$.door = $6;
- X }
- X ;
- X
- Xaroom : room_def room_details
- X {
- X store_room();
- X }
- X | subroom_def room_details
- X {
- X store_room();
- X }
- X ;
- X
- Xsubroom_def : SUBROOM_ID ':' room_type ',' light_state ',' subroom_pos ',' room_size ',' string roomfill
- X {
- X tmproom[nrooms] = New(room);
- X (void) memset((genericptr_t) tmproom[nrooms], 0,
- X sizeof *tmproom[nrooms]);
- X tmproom[nrooms]->parent = dup_string($11);
- X tmproom[nrooms]->name = (char *) 0;
- X tmproom[nrooms]->rtype = $3;
- X tmproom[nrooms]->rlit = $5;
- X tmproom[nrooms]->filled = $12;
- X tmproom[nrooms]->xalign = ERR;
- X tmproom[nrooms]->yalign = ERR;
- X tmproom[nrooms]->x = current_coord.x;
- X tmproom[nrooms]->y = current_coord.y;
- X tmproom[nrooms]->w = current_size.width;
- X tmproom[nrooms]->h = current_size.height;
- X in_room = 1;
- X }
- X ;
- X
- Xroom_def : ROOM_ID ':' room_type ',' light_state ',' room_pos ',' room_align ',' room_size roomfill
- X {
- X tmproom[nrooms] = New(room);
- X (void) memset((genericptr_t) tmproom[nrooms], 0,
- X sizeof *tmproom[nrooms]);
- X tmproom[nrooms]->name = (char *) 0;
- X tmproom[nrooms]->parent = (char *) 0;
- X tmproom[nrooms]->rtype = $3;
- X tmproom[nrooms]->rlit = $5;
- X tmproom[nrooms]->filled = $12;
- X tmproom[nrooms]->xalign = current_align.x;
- X tmproom[nrooms]->yalign = current_align.y;
- X tmproom[nrooms]->x = current_coord.x;
- X tmproom[nrooms]->y = current_coord.y;
- X tmproom[nrooms]->w = current_size.width;
- X tmproom[nrooms]->h = current_size.height;
- X in_room = 1;
- X }
- X ;
- X
- Xroomfill : /* nothing */
- X {
- X $$ = 1;
- X }
- X | ',' BOOLEAN
- X {
- X $$ = $2;
- X }
- X ;
- X
- Xroom_pos : '(' INTEGER ',' INTEGER ')'
- X {
- X if ( $2 < 1 || $2 > 5 ||
- X $4 < 1 || $4 > 5 ) {
- X yyerror("Room position should be between 1 & 5!");
- X } else {
- X current_coord.x = $2;
- X current_coord.y = $4;
- X }
- X }
- X | RANDOM_TYPE
- X {
- X current_coord.x = current_coord.y = ERR;
- X }
- X ;
- X
- Xsubroom_pos : '(' INTEGER ',' INTEGER ')'
- X {
- X if ( $2 < 0 || $4 < 0) {
- X yyerror("Invalid subroom position !");
- X } else {
- X current_coord.x = $2;
- X current_coord.y = $4;
- X }
- X }
- X | RANDOM_TYPE
- X {
- X current_coord.x = current_coord.y = ERR;
- X }
- X ;
- X
- Xroom_align : '(' h_justif ',' v_justif ')'
- X {
- X current_align.x = $2;
- X current_align.y = $4;
- X }
- X | RANDOM_TYPE
- X {
- X current_align.x = current_align.y = ERR;
- X }
- X ;
- X
- Xroom_size : '(' INTEGER ',' INTEGER ')'
- X {
- X current_size.width = $2;
- X current_size.height = $4;
- X }
- X | RANDOM_TYPE
- X {
- X current_size.height = current_size.width = ERR;
- X }
- X ;
- X
- Xroom_details : /* nothing */
- X | room_details room_detail
- X ;
- X
- Xroom_detail : room_name
- X | room_chance
- X | room_door
- X | monster_detail
- X | object_detail
- X | trap_detail
- X | altar_detail
- X | fountain_detail
- X | sink_detail
- X | pool_detail
- X | gold_detail
- X | engraving_detail
- X | stair_detail
- X ;
- X
- Xroom_name : NAME_ID ':' string
- X {
- X if (tmproom[nrooms]->name)
- X yyerror("This room already has a name!");
- X else
- X tmproom[nrooms]->name = dup_string($3);
- X }
- X ;
- X
- Xroom_chance : CHANCE_ID ':' INTEGER
- X {
- X if (tmproom[nrooms]->chance)
- X yyerror("This room already assigned a chance!");
- X else if (tmproom[nrooms]->rtype == OROOM)
- X yyerror("Only typed rooms can have a chance!");
- X else if ($3 < 1 || $3 > 99)
- X yyerror("The chance is supposed to be precentile.");
- X else
- X tmproom[nrooms]->chance = $3;
- X }
- X ;
- X
- Xroom_door : DOOR_ID ':' secret ',' door_state ',' door_wall ',' door_pos
- X {
- X /* ERR means random here */
- X if ($7 == ERR && $9 != ERR) {
- X yyerror("If the door wall is random, so must be its pos!");
- X } else {
- X tmprdoor[ndoor] = New(room_door);
- X tmprdoor[ndoor]->secret = $3;
- X tmprdoor[ndoor]->mask = $5;
- X tmprdoor[ndoor]->wall = $7;
- X tmprdoor[ndoor]->pos = $9;
- X ndoor++;
- X }
- X }
- X ;
- X
- Xsecret : BOOLEAN
- X | RANDOM_TYPE
- X ;
- X
- Xdoor_wall : DIRECTION
- X | RANDOM_TYPE
- X ;
- X
- Xdoor_pos : INTEGER
- X | RANDOM_TYPE
- X ;
- X
- Xmaze_def : MAZE_ID ':' string ',' filling
- X {
- X maze.filling = $5;
- X if (index($3, '.'))
- X yyerror("Invalid dot ('.') in level name.");
- X if (strlen($3) > 8)
- X yyerror("Level names limited to 8 characters.");
- X $$ = $3;
- X in_room = 0;
- X }
- X ;
- X
- Xfilling : CHAR
- X {
- X $$ = get_floor_type((char)$1);
- X }
- X | RANDOM_TYPE
- X {
- X $$ = -1;
- X }
- X ;
- X
- Xregions : aregion
- X | aregion regions
- X ;
- X
- Xaregion : map_definition reg_init map_details
- X {
- X store_part();
- X }
- X ;
- X
- Xmap_definition : NOMAP_ID
- X {
- X tmppart[npart] = New(mazepart);
- X tmppart[npart]->halign = 1;
- X tmppart[npart]->valign = 1;
- X tmppart[npart]->nrobjects = 0;
- X tmppart[npart]->nloc = 0;
- X tmppart[npart]->nrmonst = 0;
- X tmppart[npart]->xsize = 1;
- X tmppart[npart]->ysize = 1;
- X tmppart[npart]->map = (char **) alloc(sizeof(char *));
- X tmppart[npart]->map[0] = (char *) alloc(1);
- X tmppart[npart]->map[0][0] = STONE;
- X max_x_map = COLNO-1;
- X max_y_map = ROWNO;
- X }
- X | map_geometry MAP_ID
- X {
- X tmppart[npart] = New(mazepart);
- X tmppart[npart]->halign = $<i>1 % 10;
- X tmppart[npart]->valign = $<i>1 / 10;
- X tmppart[npart]->nrobjects = 0;
- X tmppart[npart]->nloc = 0;
- X tmppart[npart]->nrmonst = 0;
- X scan_map($2);
- X }
- X ;
- X
- Xmap_geometry : GEOMETRY_ID ':' h_justif ',' v_justif
- X {
- X $<i>$ = $<i>3 + ($<i>5 * 10);
- X }
- X ;
- X
- Xh_justif : LEFT_OR_RIGHT
- X | CENTER
- X ;
- X
- Xv_justif : TOP_OR_BOT
- X | CENTER
- X ;
- X
- Xreg_init : /* nothing */
- X | reg_init init_reg
- X ;
- X
- Xinit_reg : RANDOM_OBJECTS_ID ':' object_list
- X {
- X if (tmppart[npart]->nrobjects) {
- X yyerror("Object registers already initialized!");
- X } else {
- X tmppart[npart]->robjects = (char *)alloc(n_olist);
- X (void) memcpy((genericptr_t)tmppart[npart]->robjects,
- X (genericptr_t)olist, n_olist);
- X tmppart[npart]->nrobjects = n_olist;
- X }
- X }
- X | RANDOM_PLACES_ID ':' place_list
- X {
- X if (tmppart[npart]->nloc) {
- X yyerror("Location registers already initialized!");
- X } else {
- X register int i;
- X tmppart[npart]->rloc_x = (char *) alloc(n_plist);
- X tmppart[npart]->rloc_y = (char *) alloc(n_plist);
- X for(i=0;i<n_plist;i++) {
- X tmppart[npart]->rloc_x[i] = plist[i].x;
- X tmppart[npart]->rloc_y[i] = plist[i].y;
- X }
- X tmppart[npart]->nloc = n_plist;
- X }
- X }
- X | RANDOM_MONSTERS_ID ':' monster_list
- X {
- X if (tmppart[npart]->nrmonst) {
- X yyerror("Monster registers already initialized!");
- X } else {
- X tmppart[npart]->rmonst = (char *) alloc(n_mlist);
- X (void) memcpy((genericptr_t)tmppart[npart]->rmonst,
- X (genericptr_t)mlist, n_mlist);
- X tmppart[npart]->nrmonst = n_mlist;
- X }
- X }
- X ;
- X
- Xobject_list : object
- X {
- X if (n_olist < MAX_REGISTERS)
- X olist[n_olist++] = $<i>1;
- X else
- X yyerror("Object list too long!");
- X }
- X | object ',' object_list
- X {
- X if (n_olist < MAX_REGISTERS)
- X olist[n_olist++] = $<i>1;
- X else
- X yyerror("Object list too long!");
- X }
- X ;
- X
- Xmonster_list : monster
- X {
- X if (n_mlist < MAX_REGISTERS)
- X mlist[n_mlist++] = $<i>1;
- X else
- X yyerror("Monster list too long!");
- X }
- X | monster ',' monster_list
- X {
- X if (n_mlist < MAX_REGISTERS)
- X mlist[n_mlist++] = $<i>1;
- X else
- X yyerror("Monster list too long!");
- X }
- X ;
- X
- Xplace_list : place
- X {
- X if (n_plist < MAX_REGISTERS)
- X plist[n_plist++] = current_coord;
- X else
- X yyerror("Location list too long!");
- X }
- X | place
- X {
- X if (n_plist < MAX_REGISTERS)
- X plist[n_plist++] = current_coord;
- X else
- X yyerror("Location list too long!");
- X }
- X ',' place_list
- X ;
- X
- Xmap_details : /* nothing */
- X | map_details map_detail
- X ;
- X
- Xmap_detail : monster_detail
- X | object_detail
- X | door_detail
- X | trap_detail
- X | drawbridge_detail
- X | region_detail
- X | stair_region
- X | portal_region
- X | teleprt_region
- X | branch_region
- X | altar_detail
- X | fountain_detail
- X | mazewalk_detail
- X | wallify_detail
- X | ladder_detail
- X | stair_detail
- X | gold_detail
- X | engraving_detail
- X | diggable_detail
- X ;
- X
- Xmonster_detail : MONSTER_ID ':' monster_c ',' m_name ',' coordinate
- X {
- X tmpmonst[nmons] = New(monster);
- X tmpmonst[nmons]->x = current_coord.x;
- X tmpmonst[nmons]->y = current_coord.y;
- X tmpmonst[nmons]->class = $<i>3;
- X tmpmonst[nmons]->peaceful = -1; /* no override */
- X tmpmonst[nmons]->asleep = -1;
- X tmpmonst[nmons]->align = - MAX_REGISTERS - 2;
- X tmpmonst[nmons]->name = (char *) 0;
- X tmpmonst[nmons]->appear = 0;
- X tmpmonst[nmons]->appear_as = (char *) 0;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Monster");
- X if (!$5)
- X tmpmonst[nmons]->id = -1;
- X else {
- X int token = get_monster_id($5, (char) $<i>3);
- X if (token == ERR) {
- X yywarning("Illegal monster name! Making random monster.");
- X tmpmonst[nmons]->id = -1;
- X } else
- X tmpmonst[nmons]->id = token;
- X }
- X }
- X monster_infos
- X {
- X nmons++;
- X }
- X ;
- X
- Xmonster_infos : /* nothing */
- X | monster_infos monster_info
- X ;
- X
- Xmonster_info : ',' string
- X {
- X tmpmonst[nmons]->name = dup_string($2);
- X }
- X | ',' MON_ATTITUDE
- X {
- X tmpmonst[nmons]->peaceful = $<i>2;
- X }
- X | ',' MON_ALERTNESS
- X {
- X tmpmonst[nmons]->asleep = $<i>2;
- X }
- X | ',' alignment
- X {
- X tmpmonst[nmons]->align = $<i>2;
- X }
- X | ',' MON_APPEARANCE string
- X {
- X tmpmonst[nmons]->appear = $<i>2;
- X tmpmonst[nmons]->appear_as = dup_string($3);
- X }
- X ;
- X
- Xobject_detail : OBJECT_ID ':' object_c ',' o_name ',' coordinate
- X {
- X tmpobj[nobj] = New(object);
- X tmpobj[nobj]->x = current_coord.x;
- X tmpobj[nobj]->y = current_coord.y;
- X tmpobj[nobj]->class = $<i>3;
- X tmpobj[nobj]->corpsenm = -1; /* init as none */
- X tmpobj[nobj]->curse_state = -1;
- X tmpobj[nobj]->name = (char *) 0;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Object");
- X if (!$5)
- X tmpobj[nobj]->id = -1;
- X else {
- X int token = get_object_id($5);
- X if (token == ERR) {
- X yywarning("Illegal object name! Making random object.");
- X tmpobj[nobj]->id = -1;
- X } else
- X tmpobj[nobj]->id = token;
- X }
- X }
- X object_infos
- X {
- X nobj++;
- X }
- X ;
- X
- Xobject_infos : /* nothing */
- X {
- X tmpobj[nobj]->spe = -127;
- X }
- X | ',' STRING ',' enchantment
- X {
- X int token = get_monster_id($2, (char)0);
- X if (token == ERR) /* "random" */
- X tmpobj[nobj]->corpsenm = -2;
- X else
- X tmpobj[nobj]->corpsenm = token;
- X tmpobj[nobj]->spe = $<i>4;
- X }
- X | ',' curse_state ',' enchantment ',' art_name
- X {
- X tmpobj[nobj]->curse_state = $<i>2;
- X tmpobj[nobj]->spe = $<i>4;
- X if ($6)
- X tmpobj[nobj]->name = dup_string($6);
- X else
- X tmpobj[nobj]->name = (char *) 0;
- X }
- X ;
- X
- Xcurse_state : RANDOM_TYPE
- X | CURSE_TYPE
- X ;
- X
- Xenchantment : INTEGER
- X | RANDOM_TYPE
- X {
- X $<i>$ = -127;
- X }
- X ;
- X
- Xdoor_detail : DOOR_ID ':' door_state ',' coordinate
- X {
- X tmpdoor[ndoor] = New(door);
- X tmpdoor[ndoor]->x = current_coord.x;
- X tmpdoor[ndoor]->y = current_coord.y;
- X tmpdoor[ndoor]->mask = $<i>3;
- X if(current_coord.x >= 0 && current_coord.y >= 0 &&
- X tmpmap[current_coord.y][current_coord.x] != DOOR &&
- X tmpmap[current_coord.y][current_coord.x] != SDOOR)
- X yyerror("Door decl doesn't match the map");
- X ndoor++;
- X }
- X ;
- X
- Xtrap_detail : TRAP_ID ':' trap_name ',' coordinate
- X {
- X tmptrap[ntrap] = New(trap);
- X tmptrap[ntrap]->x = current_coord.x;
- X tmptrap[ntrap]->y = current_coord.y;
- X tmptrap[ntrap]->type = $<i>3;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Trap");
- X ntrap++;
- X }
- X ;
- X
- Xdrawbridge_detail: DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state
- X {
- X int x, y, dir;
- X
- X tmpdb[ndb] = New(drawbridge);
- X x = tmpdb[ndb]->x = current_coord.x;
- X y = tmpdb[ndb]->y = current_coord.y;
- X /* convert dir from a DIRECTION to a DB_DIR */
- X dir = $5;
- X switch(dir) {
- X case W_NORTH: dir = DB_NORTH; y--; break;
- X case W_SOUTH: dir = DB_SOUTH; y++; break;
- X case W_EAST: dir = DB_EAST; x++; break;
- X case W_WEST: dir = DB_WEST; x--; break;
- X default:
- X yyerror("Invalid drawbridge direction");
- X break;
- X }
- X tmpdb[ndb]->dir = dir;
- X if (current_coord.x >= 0 && current_coord.y >= 0 &&
- X !IS_WALL(tmpmap[y][x])) {
- X char ebuf[60];
- X Sprintf(ebuf,
- X "Wall needed for drawbridge (%02d, %02d)",
- X current_coord.x, current_coord.y);
- X yyerror(ebuf);
- X }
- X
- X if ( $<i>7 == D_ISOPEN )
- X tmpdb[ndb]->db_open = 1;
- X else if ( $<i>7 == D_CLOSED )
- X tmpdb[ndb]->db_open = 0;
- X else
- X yyerror("A drawbridge can only be open or closed!");
- X ndb++;
- X }
- X ;
- X
- Xmazewalk_detail : MAZEWALK_ID ':' coordinate ',' DIRECTION
- X {
- X tmpwalk[nwalk] = New(walk);
- X tmpwalk[nwalk]->x = current_coord.x;
- X tmpwalk[nwalk]->y = current_coord.y;
- X tmpwalk[nwalk]->dir = $5;
- X nwalk++;
- X }
- X ;
- X
- Xwallify_detail : WALLIFY_ID
- X {
- X wallify_map();
- X }
- X ;
- X
- Xladder_detail : LADDER_ID ':' coordinate ',' UP_OR_DOWN
- X {
- X tmplad[nlad] = New(lad);
- X tmplad[nlad]->x = current_coord.x;
- X tmplad[nlad]->y = current_coord.y;
- X tmplad[nlad]->up = $<i>5;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Ladder");
- X nlad++;
- X }
- X ;
- X
- Xstair_detail : STAIR_ID ':' coordinate ',' UP_OR_DOWN
- X {
- X tmpstair[nstair] = New(stair);
- X tmpstair[nstair]->x = current_coord.x;
- X tmpstair[nstair]->y = current_coord.y;
- X tmpstair[nstair]->up = $<i>5;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Stairway");
- X nstair++;
- X }
- X ;
- X
- Xstair_region : STAIR_ID ':' lev_region
- X {
- X tmplreg[nlreg] = New(lev_region);
- X tmplreg[nlreg]->in_islev = $3;
- X tmplreg[nlreg]->inarea.x1 = current_region.x1;
- X tmplreg[nlreg]->inarea.y1 = current_region.y1;
- X tmplreg[nlreg]->inarea.x2 = current_region.x2;
- X tmplreg[nlreg]->inarea.y2 = current_region.y2;
- X }
- X ',' lev_region ',' UP_OR_DOWN
- X {
- X tmplreg[nlreg]->del_islev = $6;
- X tmplreg[nlreg]->delarea.x1 = current_region.x1;
- X tmplreg[nlreg]->delarea.y1 = current_region.y1;
- X tmplreg[nlreg]->delarea.x2 = current_region.x2;
- X tmplreg[nlreg]->delarea.y2 = current_region.y2;
- X if($8)
- X tmplreg[nlreg]->rtype = LR_UPSTAIR;
- X else
- X tmplreg[nlreg]->rtype = LR_DOWNSTAIR;
- X tmplreg[nlreg]->rname = 0;
- X nlreg++;
- X }
- X ;
- X
- Xportal_region : PORTAL_ID ':' lev_region
- X {
- X tmplreg[nlreg] = New(lev_region);
- X tmplreg[nlreg]->in_islev = $3;
- X tmplreg[nlreg]->inarea.x1 = current_region.x1;
- X tmplreg[nlreg]->inarea.y1 = current_region.y1;
- X tmplreg[nlreg]->inarea.x2 = current_region.x2;
- X tmplreg[nlreg]->inarea.y2 = current_region.y2;
- X }
- X ',' lev_region ',' string
- X {
- X tmplreg[nlreg]->del_islev = $6;
- X tmplreg[nlreg]->delarea.x1 = current_region.x1;
- X tmplreg[nlreg]->delarea.y1 = current_region.y1;
- X tmplreg[nlreg]->delarea.x2 = current_region.x2;
- X tmplreg[nlreg]->delarea.y2 = current_region.y2;
- X tmplreg[nlreg]->rtype = LR_PORTAL;
- X tmplreg[nlreg]->rname = $8;
- X nlreg++;
- X }
- X ;
- X
- Xteleprt_region : TELEPRT_ID ':' lev_region
- X {
- X tmplreg[nlreg] = New(lev_region);
- X tmplreg[nlreg]->in_islev = $3;
- X tmplreg[nlreg]->inarea.x1 = current_region.x1;
- X tmplreg[nlreg]->inarea.y1 = current_region.y1;
- X tmplreg[nlreg]->inarea.x2 = current_region.x2;
- X tmplreg[nlreg]->inarea.y2 = current_region.y2;
- X }
- X ',' lev_region
- X {
- X tmplreg[nlreg]->del_islev = $6;
- X tmplreg[nlreg]->delarea.x1 = current_region.x1;
- X tmplreg[nlreg]->delarea.y1 = current_region.y1;
- X tmplreg[nlreg]->delarea.x2 = current_region.x2;
- X tmplreg[nlreg]->delarea.y2 = current_region.y2;
- X }
- X teleprt_detail
- X {
- X switch($<i>8) {
- X case -1: tmplreg[nlreg]->rtype = LR_TELE; break;
- X case 0: tmplreg[nlreg]->rtype = LR_DOWNTELE; break;
- X case 1: tmplreg[nlreg]->rtype = LR_UPTELE; break;
- X }
- X tmplreg[nlreg]->rname = 0;
- X nlreg++;
- X }
- X ;
- X
- Xbranch_region : BRANCH_ID ':' lev_region
- X {
- X tmplreg[nlreg] = New(lev_region);
- X tmplreg[nlreg]->in_islev = $3;
- X tmplreg[nlreg]->inarea.x1 = current_region.x1;
- X tmplreg[nlreg]->inarea.y1 = current_region.y1;
- X tmplreg[nlreg]->inarea.x2 = current_region.x2;
- X tmplreg[nlreg]->inarea.y2 = current_region.y2;
- X }
- X ',' lev_region
- X {
- X tmplreg[nlreg]->del_islev = $6;
- X tmplreg[nlreg]->delarea.x1 = current_region.x1;
- X tmplreg[nlreg]->delarea.y1 = current_region.y1;
- X tmplreg[nlreg]->delarea.x2 = current_region.x2;
- X tmplreg[nlreg]->delarea.y2 = current_region.y2;
- X tmplreg[nlreg]->rtype = LR_BRANCH;
- X tmplreg[nlreg]->rname = 0;
- X nlreg++;
- X }
- X ;
- X
- Xteleprt_detail : /* empty */
- X {
- X $<i>$ = -1;
- X }
- X | ',' UP_OR_DOWN
- X {
- X $<i>$ = $2;
- X }
- X ;
- X
- Xlev_region : region
- X {
- X $$ = 0;
- X }
- X | LEV '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
- X {
- X/* This series of if statements is a hack for MSC 5.1. It seems that its
- X tiny little brain cannot compile if these are all one big if statement. */
- X if ($3 <= 0 || $3 >= COLNO)
- X yyerror("Region out of level range!");
- X else if ($5 < 0 || $5 >= ROWNO)
- X yyerror("Region out of level range!");
- X else if ($7 <= 0 || $7 >= COLNO)
- X yyerror("Region out of level range!");
- X else if ($9 < 0 || $9 >= ROWNO)
- X yyerror("Region out of level range!");
- X current_region.x1 = $3;
- X current_region.y1 = $5;
- X current_region.x2 = $7;
- X current_region.y2 = $9;
- X $$ = 1;
- X }
- X ;
- X
- Xfountain_detail : FOUNTAIN_ID ':' coordinate
- X {
- X tmpfountain[nfountain] = New(fountain);
- X tmpfountain[nfountain]->x = current_coord.x;
- X tmpfountain[nfountain]->y = current_coord.y;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Fountain");
- X nfountain++;
- X }
- X ;
- X
- Xsink_detail : SINK_ID ':' coordinate
- X {
- X tmpsink[nsink] = New(sink);
- X tmpsink[nsink]->x = current_coord.x;
- X tmpsink[nsink]->y = current_coord.y;
- X nsink++;
- X }
- X ;
- X
- Xpool_detail : POOL_ID ':' coordinate
- X {
- X tmppool[npool] = New(pool);
- X tmppool[npool]->x = current_coord.x;
- X tmppool[npool]->y = current_coord.y;
- X npool++;
- X }
- X ;
- X
- Xdiggable_detail : NON_DIGGABLE_ID ':' region
- X {
- X tmpdig[ndig] = New(digpos);
- X tmpdig[ndig]->x1 = current_region.x1;
- X tmpdig[ndig]->y1 = current_region.y1;
- X tmpdig[ndig]->x2 = current_region.x2;
- X tmpdig[ndig]->y2 = current_region.y2;
- X ndig++;
- X }
- X ;
- X
- Xregion_detail : REGION_ID ':' region ',' light_state ',' room_type prefilled
- X {
- X tmpreg[nreg] = New(region);
- X tmpreg[nreg]->x1 = current_region.x1;
- X tmpreg[nreg]->y1 = current_region.y1;
- X tmpreg[nreg]->x2 = current_region.x2;
- X tmpreg[nreg]->y2 = current_region.y2;
- X tmpreg[nreg]->rlit = $<i>5;
- X tmpreg[nreg]->rtype = $<i>7;
- X if($<i>8 & 1) tmpreg[nreg]->rtype += MAXRTYPE+1;
- X tmpreg[nreg]->rirreg = (($<i>8 & 2) != 0);
- X if(current_region.x1 > current_region.x2 ||
- X current_region.y1 > current_region.y2)
- X yyerror("Region start > end!");
- X if(tmpreg[nreg]->rtype == VAULT &&
- X (tmpreg[nreg]->rirreg ||
- X (tmpreg[nreg]->x2 - tmpreg[nreg]->x1 != 1) ||
- X (tmpreg[nreg]->y2 - tmpreg[nreg]->y1 != 1)))
- X yyerror("Vaults must be exactly 2x2!");
- X if(want_warnings && !tmpreg[nreg]->rirreg &&
- X current_region.x1 > 0 && current_region.y1 > 0 &&
- X current_region.x2 < max_x_map &&
- X current_region.y2 < max_y_map) {
- X /* check for walls in the room */
- X char ebuf[60];
- X register int x, y, nrock = 0;
- X
- X for(y=current_region.y1; y<=current_region.y2; y++)
- X for(x=current_region.x1;
- X x<=current_region.x2; x++)
- X if(IS_ROCK(tmpmap[y][x]) ||
- X IS_DOOR(tmpmap[y][x])) nrock++;
- X if(nrock) {
- X Sprintf(ebuf,
- X "Rock in room (%02d,%02d,%02d,%02d)?!",
- X current_region.x1, current_region.y1,
- X current_region.x2, current_region.y2);
- X yywarning(ebuf);
- X }
- X if (
- X !IS_ROCK(tmpmap[current_region.y1-1][current_region.x1-1]) ||
- X !IS_ROCK(tmpmap[current_region.y2+1][current_region.x1-1]) ||
- X !IS_ROCK(tmpmap[current_region.y1-1][current_region.x2+1]) ||
- X !IS_ROCK(tmpmap[current_region.y2+1][current_region.x2+1])) {
- X Sprintf(ebuf,
- X "NonRock edge in room (%02d,%02d,%02d,%02d)?!",
- X current_region.x1, current_region.y1,
- X current_region.x2, current_region.y2);
- X yywarning(ebuf);
- X }
- X } else if(tmpreg[nreg]->rirreg &&
- X !IS_ROOM(tmpmap[current_region.y1][current_region.x1])) {
- X char ebuf[60];
- X Sprintf(ebuf,
- X "Rock in irregular room (%02d,%02d)?!",
- X current_region.x1, current_region.y1);
- X yyerror(ebuf);
- X }
- X nreg++;
- X }
- X ;
- X
- Xaltar_detail : ALTAR_ID ':' coordinate ',' alignment ',' altar_type
- X {
- X tmpaltar[naltar] = New(altar);
- X tmpaltar[naltar]->x = current_coord.x;
- X tmpaltar[naltar]->y = current_coord.y;
- X tmpaltar[naltar]->align = $<i>5;
- X tmpaltar[naltar]->shrine = $<i>7;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Altar");
- X naltar++;
- X }
- X ;
- X
- Xgold_detail : GOLD_ID ':' amount ',' coordinate
- X {
- X tmpgold[ngold] = New(gold);
- X tmpgold[ngold]->x = current_coord.x;
- X tmpgold[ngold]->y = current_coord.y;
- X tmpgold[ngold]->amount = $<i>3;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Gold");
- X ngold++;
- X }
- X ;
- X
- Xengraving_detail: ENGRAVING_ID ':' coordinate ',' engraving_type ',' string
- X {
- X tmpengraving[nengraving] = New(engraving);
- X tmpengraving[nengraving]->x = current_coord.x;
- X tmpengraving[nengraving]->y = current_coord.y;
- X tmpengraving[nengraving]->e.text = $7;
- X tmpengraving[nengraving]->etype = $<i>5;
- X if (!in_room)
- X check_coord(current_coord.x, current_coord.y,
- X "Engraving");
- X nengraving++;
- X }
- X ;
- X
- Xmonster_c : monster
- X | RANDOM_TYPE
- X {
- X $<i>$ = - MAX_REGISTERS - 1;
- X }
- X | m_register
- X ;
- X
- Xobject_c : object
- X | RANDOM_TYPE
- X {
- X $<i>$ = - MAX_REGISTERS - 1;
- X }
- X | o_register
- X ;
- X
- Xm_name : string
- X | RANDOM_TYPE
- X {
- X $$ = (char *) 0;
- X }
- X ;
- X
- Xo_name : string
- X | RANDOM_TYPE
- X {
- X $$ = (char *) 0;
- X }
- X ;
- X
- Xtrap_name : string
- X {
- X int token = get_trap_type($1);
- X if (token == ERR)
- X yyerror("Unknown trap type!");
- X $<i>$ = token;
- X }
- X | RANDOM_TYPE
- X ;
- X
- Xroom_type : string
- X {
- X int token = get_room_type($1);
- X if (token == ERR) {
- X yywarning("Unknown room type! Making ordinary room...");
- X $<i>$ = OROOM;
- X } else
- X $<i>$ = token;
- X }
- X | RANDOM_TYPE
- X ;
- X
- Xprefilled : /* empty */
- X {
- X $<i>$ = 0;
- X }
- X | ',' FILLING
- X {
- X $<i>$ = $2;
- X }
- X | ',' FILLING ',' BOOLEAN
- X {
- X $<i>$ = $2 + ($4 << 1);
- X }
- X ;
- X
- Xcoordinate : coord
- X | p_register
- X | RANDOM_TYPE
- X {
- X current_coord.x = current_coord.y = -MAX_REGISTERS-1;
- X }
- X ;
- X
- Xdoor_state : DOOR_STATE
- X | RANDOM_TYPE
- X ;
- X
- Xlight_state : LIGHT_STATE
- X | RANDOM_TYPE
- X ;
- X
- Xalignment : ALIGNMENT
- X | a_register
- X | RANDOM_TYPE
- X {
- X $<i>$ = - MAX_REGISTERS - 1;
- X }
- X ;
- X
- Xaltar_type : ALTAR_TYPE
- X | RANDOM_TYPE
- X ;
- X
- Xp_register : P_REGISTER '[' INTEGER ']'
- X {
- X if ( $3 >= MAX_REGISTERS )
- X yyerror("Register Index overflow!");
- X else
- X current_coord.x = current_coord.y = - $3 - 1;
- X }
- X ;
- X
- Xo_register : O_REGISTER '[' INTEGER ']'
- X {
- X if ( $3 >= MAX_REGISTERS )
- X yyerror("Register Index overflow!");
- X else
- X $<i>$ = - $3 - 1;
- X }
- X ;
- X
- Xm_register : M_REGISTER '[' INTEGER ']'
- X {
- X if ( $3 >= MAX_REGISTERS )
- X yyerror("Register Index overflow!");
- X else
- X $<i>$ = - $3 - 1;
- X }
- X ;
- X
- Xa_register : A_REGISTER '[' INTEGER ']'
- X {
- X if ( $3 >= 3 )
- X yyerror("Register Index overflow!");
- X else
- X $<i>$ = - $3 - 1;
- X }
- X ;
- X
- Xplace : coord
- X ;
- X
- Xmonster : CHAR
- X {
- X if (check_monster_char((char) $1))
- X $<i>$ = $1 ;
- X else {
- X yyerror("Unknown monster class!");
- X $<i>$ = ERR;
- X }
- X }
- X ;
- X
- Xobject : CHAR
- X {
- X char c = $1;
- X if (check_object_char(c))
- X $<i>$ = c;
- X else {
- X yyerror("Unknown char class!");
- X $<i>$ = ERR;
- X }
- X }
- X ;
- X
- Xstring : STRING
- X ;
- X
- Xart_name : STRING
- X | NONE
- X {
- X $$ = (char *) 0;
- X }
- X ;
- X
- Xamount : INTEGER
- X | RANDOM_TYPE
- X ;
- X
- Xengraving_type : ENGRAVING_TYPE
- X | RANDOM_TYPE
- X ;
- X
- Xcoord : '(' INTEGER ',' INTEGER ')'
- X {
- X if (!in_room && !init_lev.init_present &&
- X ($2 < 0 || $2 > max_x_map ||
- X $4 < 0 || $4 > max_y_map))
- X yyerror("Coordinates out of map range!");
- X current_coord.x = $2;
- X current_coord.y = $4;
- X }
- X ;
- X
- Xregion : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
- X {
- X/* This series of if statements is a hack for MSC 5.1. It seems that its
- X tiny little brain cannot compile if these are all one big if statement. */
- X if ($2 < 0 || $2 > max_x_map)
- X yyerror("Region out of map range!");
- X else if ($4 < 0 || $4 > max_y_map)
- X yyerror("Region out of map range!");
- X else if ($6 < 0 || $6 > max_x_map)
- X yyerror("Region out of map range!");
- X else if ($8 < 0 || $8 > max_y_map)
- X yyerror("Region out of map range!");
- X current_region.x1 = $2;
- X current_region.y1 = $4;
- X current_region.x2 = $6;
- X current_region.y2 = $8;
- X }
- X ;
- X
- X%%
- END_OF_FILE
- if test 35847 -ne `wc -c <'util/lev_comp.y'`; then
- echo shar: \"'util/lev_comp.y'\" unpacked with wrong size!
- fi
- # end of 'util/lev_comp.y'
- fi
- echo shar: End of archive 50 \(of 108\).
- cp /dev/null ark50isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
- 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
- 101 102 103 104 105 106 107 108 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 108 archives.
- echo "Now execute 'rebuild.sh'"
- rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-