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: v16i034: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part34/108
- Message-ID: <4322@master.CNA.TEK.COM>
- Date: 29 Jan 93 20:47:05 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1942
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1591
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 34
- Archive-name: nethack31/Part34
- 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 34 (of 108)."
- # Contents: src/hack.c sys/os2/Install.os2
- # Wrapped by billr@saab on Wed Jan 27 16:08:59 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/hack.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/hack.c'\"
- else
- echo shar: Extracting \"'src/hack.c'\" \(39188 characters\)
- sed "s/^X//" >'src/hack.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)hack.c 3.1 92/12/04 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X
- XSTATIC_DCL int NDECL(moverock);
- X#ifdef POLYSELF
- XSTATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P));
- X#endif
- X#ifdef SINKS
- XSTATIC_DCL void NDECL(dosinkfall);
- X#endif
- XSTATIC_DCL boolean FDECL(bad_rock,(XCHAR_P,XCHAR_P));
- XSTATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int));
- X
- Xstatic void FDECL(move_update, (BOOLEAN_P));
- X
- X#define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
- X
- X#ifdef OVL2
- X
- Xboolean
- Xrevive_nasty(x, y, msg)
- Xint x,y;
- Xconst char *msg;
- X{
- X register struct obj *otmp, *otmp2;
- X struct monst *mtmp;
- X coord cc;
- X boolean revived = FALSE;
- X
- X /* prevent freeobj() of revivable corpses */
- X for(otmp = level.objects[x][y]; otmp; otmp = otmp2) {
- X otmp2 = otmp->nexthere;
- X if (otmp->otyp == CORPSE &&
- X (is_rider(&mons[otmp->corpsenm]) ||
- X otmp->corpsenm == PM_WIZARD_OF_YENDOR)) {
- X /* move any living monster already at that location */
- X if((mtmp = m_at(x,y)) && enexto(&cc, x, y, mtmp->data))
- X rloc_to(mtmp, cc.x, cc.y);
- X if(msg) Norep("%s", msg);
- X revive_corpse(otmp, 0, FALSE);
- X revived = MON_AT(x,y);
- X }
- X }
- X
- X /* this location might not be safe, if not, move revived monster */
- X if (revived) {
- X mtmp = m_at(x,y);
- X if (mtmp && !goodpos(x, y, mtmp, mtmp->data) &&
- X enexto(&cc, x, y, mtmp->data)) {
- X rloc_to(mtmp, cc.x, cc.y);
- X }
- X /* else impossible? */
- X }
- X
- X return (revived);
- X}
- X
- XSTATIC_OVL int
- Xmoverock()
- X{
- X register xchar rx, ry;
- X register struct obj *otmp, *otmp2;
- X register struct trap *ttmp;
- X register struct monst *mtmp;
- X
- X while ((otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) != 0) {
- X rx = u.ux+2*u.dx;
- X ry = u.uy+2*u.dy;
- X nomul(0);
- X if (Levitation || Is_airlevel(&u.uz)) {
- X if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy);
- X You("don't have enough leverage to push %s.", the(xname(otmp)));
- X /* Give them a chance to climb over it? */
- X return -1;
- X }
- X#ifdef POLYSELF
- X if (verysmall(uasmon)) {
- X if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy);
- X pline("You're too small to push that %s.", xname(otmp));
- X goto cannot_push;
- X }
- X#endif
- X if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
- X (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || (
- X#ifdef REINCARNATION
- X !Is_rogue_level(&u.uz) &&
- X#endif
- X (levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) &&
- X !sobj_at(BOULDER, rx, ry)) {
- X ttmp = t_at(rx, ry);
- X mtmp = m_at(rx, ry);
- X
- X if (revive_nasty(rx, ry, "You sense movement on the other side."))
- X return (-1);
- X
- X if (mtmp && (!mtmp->mtrapped ||
- X !(ttmp && ((ttmp->ttyp == PIT) ||
- X (ttmp->ttyp == SPIKED_PIT))))) {
- X if (canseemon(mtmp))
- X pline("There's %s on the other side.", mon_nam(mtmp));
- X else {
- X if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy);
- X You("hear a monster behind %s.", the(xname(otmp)));
- X }
- X if (flags.verbose)
- X pline("Perhaps that's why you cannot move it.");
- X goto cannot_push;
- X }
- X
- X if (ttmp)
- X switch(ttmp->ttyp) {
- X case SPIKED_PIT:
- X case PIT:
- X freeobj(otmp);
- X if (!flooreffects(otmp, rx, ry, "fall")) {
- X place_object(otmp, rx, ry);
- X otmp->nobj = fobj;
- X fobj = otmp;
- X }
- X continue;
- X case TRAPDOOR:
- X pline("%s falls into and plugs a hole in the ground!",
- X The(xname(otmp)));
- X deltrap(ttmp);
- X delobj(otmp);
- X delallobj(rx, ry);
- X if (cansee(rx,ry)) newsym(rx,ry);
- X continue;
- X case LEVEL_TELEP:
- X case TELEP_TRAP:
- X You("push %s and suddenly it disappears!",
- X the(xname(otmp)));
- X rloco(otmp);
- X continue;
- X }
- X if (closed_door(rx, ry))
- X goto nopushmsg;
- X if (boulder_hits_pool(otmp, rx, ry, TRUE))
- X continue;
- X /*
- X * Re-link at top of fobj chain so that pile order is preserved
- X * when level is restored.
- X */
- X if (otmp != fobj) {
- X otmp2 = fobj;
- X while (otmp2->nobj && otmp2->nobj != otmp)
- X otmp2 = otmp2->nobj;
- X if (!otmp2->nobj) {
- X impossible("moverock: error in fobj chain");
- X } else {
- X otmp2->nobj = otmp->nobj;
- X otmp->nobj = fobj;
- X fobj = otmp;
- X }
- X }
- X
- X {
- X#ifdef LINT /* static long lastmovetime; */
- X long lastmovetime;
- X lastmovetime = 0;
- X#else
- X static long NEARDATA lastmovetime;
- X#endif
- X /* note: this var contains garbage initially and
- X after a restore */
- X if (moves > lastmovetime+2 || moves < lastmovetime)
- X pline("With great effort you move %s.", the(xname(otmp)));
- X exercise(A_STR, TRUE);
- X lastmovetime = moves;
- X }
- X
- X /* Move the boulder *after* the message. */
- X move_object(otmp, rx, ry);
- X if (Blind) {
- X feel_location(rx,ry);
- X feel_location(u.ux+u.dx, u.uy+u.dy);
- X } else {
- X newsym(rx,ry);
- X newsym(u.ux+u.dx, u.uy+u.dy);
- X }
- X } else {
- X nopushmsg:
- X You("try to move %s, but in vain.", the(xname(otmp)));
- X if (Blind) feel_location(u.ux+u.dx, u.uy+u.dy);
- X cannot_push:
- X#ifdef POLYSELF
- X if (throws_rocks(uasmon)) {
- X if (!flags.pickup)
- X pline("However, you easily can push it aside.");
- X else
- X pline("However, you easily can pick it up.");
- X break;
- X }
- X#endif
- X if (((!invent || inv_weight() <= -850) &&
- X (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
- X && IS_ROCK(levl[u.ux+u.dx][u.uy].typ))))
- X#ifdef POLYSELF
- X || verysmall(uasmon)
- X#endif
- X ) {
- X pline("However, you can squeeze yourself into a small opening.");
- X break;
- X } else
- X return (-1);
- X }
- X }
- X return (0);
- X}
- X
- X#ifdef POLYSELF
- X/*
- X * still_chewing()
- X *
- X * Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE
- X * when done.
- X */
- XSTATIC_OVL int
- Xstill_chewing(x,y)
- X xchar x, y;
- X{
- X struct rm *lev = &(levl[x][y]);
- X struct obj *boulder = sobj_at(BOULDER,x,y);
- X
- X if (dig_pos.x != x || dig_pos.y != y ||
- X !on_level(&dig_level, &u.uz) || dig_down) {
- X if (!boulder && (lev->diggable & W_NONDIGGABLE))
- X You("hurt your teeth on the hard stone.");
- X else {
- X dig_down = FALSE;
- X dig_pos.x = x;
- X dig_pos.y = y;
- X assign_level(&dig_level, &u.uz);
- X dig_effort = IS_ROCK(lev->typ) ? 30 : 60; /* rock takes more time */
- X if (boulder)
- X You("start chewing on a boulder.");
- X else
- X You("start chewing a hole in the %s.",
- X IS_ROCK(lev->typ) ? "rock" : "door");
- X }
- X return 1;
- X } else if ((dig_effort += 30) < 100) {
- X if (flags.verbose)
- X You("continue chewing on the %s.", boulder ? "boulder" :
- X (IS_ROCK(lev->typ) ? "rock" : "door"));
- X return 1;
- X }
- X
- X if (boulder) {
- X You("eat the boulder."); /* yum */
- X delobj(boulder); /* boulder goes bye-bye */
- X
- X /*
- X * The location could still block because of
- X * 1. More than one boulder
- X * 2. Boulder stuck in a wall/stone/door.
- X *
- X * [perhaps use does_block() below (from vision.c)]
- X */
- X if (IS_ROCK(lev->typ) || closed_door(x,y) || sobj_at(BOULDER,x,y)) {
- X block_point(x,y); /* delobj will unblock the point */
- X dig_pos.x = 0; /* reset dig messages */
- X return 1;
- X }
- X
- X } else if (IS_WALL(lev->typ)) {
- X You("chew a hole in the wall.");
- X if (level.flags.is_maze_lev) {
- X lev->typ = ROOM;
- X } else if (level.flags.is_cavernous_lev) {
- X lev->typ = CORR;
- X } else {
- X lev->typ = DOOR;
- X lev->doormask = D_NODOOR;
- X }
- X } else if (lev->typ == SDOOR) {
- X if (lev->doormask & D_TRAPPED) {
- X b_trapped("secret door");
- X lev->doormask = D_NODOOR;
- X } else {
- X You("chew through the secret door.");
- X lev->doormask = D_BROKEN;
- X }
- X lev->typ = DOOR;
- X
- X } else if (IS_DOOR(lev->typ)) {
- X if (lev->doormask & D_TRAPPED) {
- X b_trapped("door");
- X lev->doormask = D_NODOOR;
- X } else {
- X You("chew through the door.");
- X lev->doormask = D_BROKEN;
- X }
- X
- X } else { /* STONE or SCORR */
- X You("chew a passage through the rock.");
- X lev->typ = CORR;
- X }
- X
- X unblock_point(x, y); /* vision */
- X newsym(x, y);
- X dig_level.dnum = 0;
- X dig_level.dlevel = -1;
- X return 0;
- X}
- X#endif /* POLYSELF */
- X
- X#endif /* OVL2 */
- X#ifdef OVLB
- X
- Xvoid
- Xmovobj(obj, ox, oy)
- Xregister struct obj *obj;
- Xregister xchar ox, oy;
- X{
- X remove_object(obj);
- X newsym(obj->ox, obj->oy);
- X place_object(obj, ox, oy);
- X newsym(ox, oy);
- X}
- X
- X#ifdef SINKS
- XSTATIC_OVL void
- Xdosinkfall()
- X{
- X register struct obj *obj;
- X
- X# ifdef POLYSELF
- X if (is_floater(uasmon)) {
- X You("wobble unsteadily for a moment.");
- X } else {
- X# endif
- X You("crash to the floor!");
- X losehp((rn1(10, 20 - (int)ACURR(A_CON))),
- X "fell onto a sink", NO_KILLER_PREFIX);
- X exercise(A_DEX, FALSE);
- X for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
- X if(obj->oclass == WEAPON_CLASS) {
- X You("fell on %s.",doname(obj));
- X losehp(rn2(3),"fell onto a sink", NO_KILLER_PREFIX);
- X exercise(A_CON, FALSE);
- X }
- X# ifdef POLYSELF
- X }
- X# endif
- X
- X HLevitation = (HLevitation & ~TIMEOUT) + 1;
- X if(uleft && uleft->otyp == RIN_LEVITATION) {
- X obj = uleft;
- X Ring_off(obj);
- X off_msg(obj);
- X }
- X if(uright && uright->otyp == RIN_LEVITATION) {
- X obj = uright;
- X Ring_off(obj);
- X off_msg(obj);
- X }
- X if(uarmf && uarmf->otyp == LEVITATION_BOOTS) {
- X obj = uarmf;
- X (void)Boots_off();
- X off_msg(obj);
- X }
- X HLevitation--;
- X}
- X#endif
- X
- X#endif /* OVLB */
- X
- X#ifdef OVLB
- X
- Xboolean
- Xmay_dig(x,y)
- Xregister xchar x,y;
- X/* intended to be called only on ROCKs */
- X{
- Xreturn (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE)));
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL1
- X
- XSTATIC_OVL boolean
- Xbad_rock(x,y)
- Xregister xchar x,y;
- X{
- X return(IS_ROCK(levl[x][y].typ)
- X#ifdef POLYSELF
- X && !passes_walls(uasmon)
- X && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y))
- X#endif
- X );
- X}
- X
- Xboolean
- Xinvocation_pos(x, y)
- Xxchar x, y;
- X{
- X return(Invocation_lev(&u.uz) && x == inv_pos.x && y == inv_pos.y);
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVL3
- X
- Xvoid
- Xdomove()
- X{
- X register struct monst *mtmp;
- X register struct rm *tmpr,*ust;
- X register xchar x,y;
- X struct trap *trap;
- X int wtcap;
- X boolean on_ice;
- X xchar chainx, chainy, ballx, bally; /* ball&chain new positions */
- X int bc_control; /* control for ball&chain */
- X
- X u_wipe_engr(rnd(5));
- X
- X if(((wtcap = near_capacity()) >= OVERLOADED
- X || (wtcap > SLT_ENCUMBER && (u.uhp < 10 && u.uhp != u.uhpmax)))
- X && !Is_airlevel(&u.uz)) {
- X if(wtcap < OVERLOADED) {
- X You("don't have enough stamina to move.");
- X exercise(A_CON, FALSE);
- X } else
- X You("collapse under your load.");
- X nomul(0);
- X return;
- X }
- X if(u.uswallow) {
- X u.dx = u.dy = 0;
- X u.ux = x = u.ustuck->mx;
- X u.uy = y = u.ustuck->my;
- X mtmp = u.ustuck;
- X } else {
- X if(Is_airlevel(&u.uz) && rn2(4) && !Levitation
- X#ifdef POLYSELF
- X && !is_flyer(uasmon)
- X#endif
- X ) {
- X switch(rn2(3)) {
- X case 0:
- X You("tumble in place.");
- X exercise(A_DEX, FALSE);
- X break;
- X case 1:
- X You("can't control your movements very well."); break;
- X case 2:
- X pline("It's hard to walk in thin air.");
- X exercise(A_DEX, TRUE);
- X break;
- X }
- X return;
- X }
- X
- X /* check slippery ice */
- X on_ice = !Levitation && is_ice(u.ux, u.uy);
- X if (on_ice) {
- X static int skates = 0;
- X if (!skates) skates = find_skates();
- X if ((uarmf && uarmf->otyp == skates)
- X#ifdef POLYSELF
- X || resists_cold(uasmon) || is_flyer(uasmon)
- X || is_floater(uasmon) || is_clinger(uasmon)
- X || is_whirly(uasmon)
- X#endif
- X ) on_ice = FALSE;
- X else if (!rn2(Cold_resistance ? 3 : 2)) {
- X Fumbling |= FROMOUTSIDE;
- X if (!(Fumbling & TIMEOUT)) Fumbling += rnd(20);
- X }
- X }
- X if (!on_ice && (Fumbling & FROMOUTSIDE)) {
- X Fumbling &= ~FROMOUTSIDE;
- X if (!(Fumbling & ~TIMEOUT)) Fumbling = 0;
- X }
- X
- X x = u.ux + u.dx;
- X y = u.uy + u.dy;
- X if(Stunned || (Confusion && !rn2(5))) {
- X register int tries = 0;
- X
- X do {
- X if(tries++ > 50) {
- X nomul(0);
- X return;
- X }
- X confdir();
- X x = u.ux + u.dx;
- X y = u.uy + u.dy;
- X } while(!isok(x, y) || bad_rock(x, y));
- X }
- X if(!isok(x, y)) {
- X nomul(0);
- X return;
- X }
- X if((trap = t_at(x, y)) && trap->tseen) {
- X if(flags.run >= 2) {
- X nomul(0);
- X flags.move = 0;
- X return;
- X } else
- X nomul(0);
- X }
- X
- X if(u.ustuck && (x != u.ustuck->mx ||
- X y != u.ustuck->my)) {
- X if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
- X /* perhaps it fled (or was teleported or ... ) */
- X u.ustuck = 0;
- X } else {
- X#ifdef POLYSELF
- X /* If polymorphed into a sticking monster,
- X * u.ustuck means it's stuck to you, not you
- X * to it.
- X */
- X if (sticks(uasmon)) {
- X You("release %s.", mon_nam(u.ustuck));
- X u.ustuck = 0;
- X } else {
- X#endif
- X You("cannot escape from %s!",
- X mon_nam(u.ustuck));
- X nomul(0);
- X return;
- X#ifdef POLYSELF
- X }
- X#endif
- X }
- X }
- X mtmp = m_at(x,y);
- X if (mtmp) {
- X /* Don't attack if you're running, and can see it */
- X if (flags.run &&
- X ((!Blind && mon_visible(mtmp) &&
- X ((mtmp->m_ap_type != M_AP_FURNITURE &&
- X mtmp->m_ap_type != M_AP_OBJECT) ||
- X Protection_from_shape_changers)) ||
- X sensemon(mtmp))) {
- X nomul(0);
- X flags.move = 0;
- X return;
- X }
- X }
- X }
- X
- X u.ux0 = u.ux;
- X u.uy0 = u.uy;
- X bhitpos.x = x;
- X bhitpos.y = y;
- X tmpr = &levl[x][y];
- X
- X /* attack monster */
- X if(mtmp) {
- X nomul(0);
- X /* only attack if we know it's there */
- X /* or if it hides_under, in which case we call attack() to print
- X * the Wait! message.
- X * This is different from ceiling hiders, who aren't handled in
- X * attack().
- X */
- X if(!mtmp->mundetected || sensemon(mtmp) ||
- X (hides_under(mtmp->data) && !is_safepet(mtmp))){
- X gethungry();
- X if(wtcap >= HVY_ENCUMBER && moves%3) {
- X if(u.uhp > 1)
- X u.uhp--;
- X else {
- X pline("You pass out from exertion!");
- X exercise(A_CON, FALSE);
- X nomul(-10);
- X u.usleep = 1;
- X }
- X }
- X if(multi < 0) return; /* we just fainted */
- X
- X /* try to attack; note that it might evade */
- X /* also, we don't attack tame when _safepet_ */
- X if(attack(mtmp)) return;
- X }
- X }
- X
- X /* not attacking an animal, so we try to move */
- X#ifdef POLYSELF
- X if(!uasmon->mmove) {
- X You("are rooted %s.",
- X Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
- X "in place" : "to the ground");
- X nomul(0);
- X return;
- X }
- X#endif
- X if(u.utrap) {
- X if(u.utraptype == TT_PIT) {
- X if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
- X Your("%s gets stuck in a crevice.", body_part(LEG));
- X display_nhwindow(WIN_MESSAGE, FALSE);
- X clear_nhwindow(WIN_MESSAGE);
- X You("free your %s.", body_part(LEG));
- X } else if (!(--u.utrap)) {
- X You("crawl to the edge of the pit.");
- X fill_pit(u.ux, u.uy);
- X vision_full_recalc = 1; /* vision limits change */
- X } else if (flags.verbose)
- X Norep( (Hallucination && !rn2(5)) ?
- X "You've fallen, and you can't get up." :
- X "You are still in a pit." );
- X } else if (u.utraptype == TT_LAVA) {
- X if(flags.verbose)
- X Norep("You are stuck in the lava.");
- X if(!is_lava(x,y)) {
- X u.utrap--;
- X if((u.utrap & 0xff) == 0) {
- X You("pull yourself to the edge of the lava.");
- X u.utrap = 0;
- X }
- X }
- X u.umoved = TRUE;
- X } else if (u.utraptype == TT_WEB) {
- X if(--u.utrap) {
- X if(flags.verbose)
- X Norep("You are stuck to the web.");
- X } else You("disentangle yourself.");
- X } else if (u.utraptype == TT_INFLOOR) {
- X if(--u.utrap) {
- X if(flags.verbose)
- X Norep("You are stuck in the floor.");
- X } else You("finally wiggle free.");
- X } else {
- X if(flags.verbose)
- X Norep("You are caught in a bear trap.");
- X if((u.dx && u.dy) || !rn2(5)) u.utrap--;
- X }
- X return;
- X }
- X
- X
- X /*
- X * Check for physical obstacles. First, the place we are going.
- X */
- X if (IS_ROCK(tmpr->typ)) {
- X if (Blind) feel_location(x,y);
- X#ifdef POLYSELF
- X if (passes_walls(uasmon)) {
- X ; /* do nothing */
- X } else if (tunnels(uasmon) && !needspick(uasmon)) {
- X /* Eat the rock. */
- X if (still_chewing(x,y)) return;
- X } else {
- X#endif
- X if (Is_stronghold(&u.uz) && is_db_wall(x,y))
- X pline("The drawbridge is up!");
- X flags.move = 0;
- X nomul(0);
- X return;
- X#ifdef POLYSELF
- X }
- X#endif
- X } else if (IS_DOOR(tmpr->typ)) {
- X if (closed_door(x,y)) {
- X if (Blind) feel_location(x,y);
- X#ifdef POLYSELF
- X if (passes_walls(uasmon))
- X ; /* do nothing */
- X else if (amorphous(uasmon))
- X You("ooze under the door.");
- X else if (tunnels(uasmon) && !needspick(uasmon)) {
- X /* Eat the door. */
- X if (still_chewing(x,y)) return;
- X } else {
- X#endif
- X flags.move = 0;
- X if (x == u.ux || y == u.uy) {
- X if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) {
- X pline("Ouch! You bump into a door.");
- X exercise(A_DEX, FALSE);
- X } else pline("That door is closed.");
- X }
- X nomul(0);
- X return;
- X#ifdef POLYSELF
- X }
- X#endif
- X } else if (u.dx && u.dy
- X#ifdef POLYSELF
- X && !passes_walls(uasmon)
- X#endif
- X && ((tmpr->doormask & ~D_BROKEN)
- X#ifdef REINCARNATION
- X || Is_rogue_level(&u.uz)
- X#endif
- X || block_door(x,y))) {
- X /* Diagonal moves into a door are not allowed. */
- X if (Blind) feel_location(x,y); /* ?? */
- X flags.move = 0;
- X nomul(0);
- X return;
- X }
- X }
- X if (u.dx && u.dy && bad_rock(u.ux,y) && bad_rock(x,u.uy)) {
- X /* Move at a diagonal. */
- X#ifdef POLYSELF
- X if (bigmonst(uasmon)) {
- X Your("body is too large to fit through.");
- X nomul(0);
- X return;
- X }
- X#endif
- X if (invent && inv_weight() > -400) {
- X You("are carrying too much to get through.");
- X nomul(0);
- X return;
- X }
- X }
- X
- X ust = &levl[u.ux][u.uy];
- X
- X /* Now see if other things block our way . . */
- X if (u.dx && u.dy
- X#ifdef POLYSELF
- X && !passes_walls(uasmon)
- X#endif
- X && (IS_DOOR(ust->typ) && ((ust->doormask & ~D_BROKEN)
- X#ifdef REINCARNATION
- X || Is_rogue_level(&u.uz)
- X#endif
- X || block_entry(x, y))
- X )) {
- X /* Can't move at a diagonal out of a doorway with door. */
- X flags.move = 0;
- X nomul(0);
- X return;
- X }
- X
- X if (sobj_at(BOULDER,x,y)
- X#ifdef POLYSELF
- X && !passes_walls(uasmon)
- X#endif
- X ) {
- X if (!(Blind || Hallucination) && (flags.run >= 2)) {
- X nomul(0);
- X flags.move = 0;
- X return;
- X }
- X#ifdef POLYSELF
- X /* tunneling monsters will chew before pushing */
- X if (tunnels(uasmon) && !needspick(uasmon)) {
- X if (still_chewing(x,y)) return;
- X } else
- X#endif
- X if (moverock() < 0) return;
- X }
- X
- X /* OK, it is a legal place to move. */
- X
- X /* Move ball and chain. */
- X if (Punished)
- X if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy))
- X return;
- X
- X /* now move the hero */
- X mtmp = m_at(x, y);
- X if (u.uinwater) water_friction();
- X u.ux += u.dx;
- X u.uy += u.dy;
- X /* if safepet at destination then move the pet to the hero's
- X * previous location using the same conditions as in attack().
- X * there are special extenuating circumstances:
- X * (1) if the pet dies then your god angers,
- X * (2) if the pet gets trapped then your god may disapprove,
- X * (3) if the pet was already trapped and you attempt to free it
- X * not only do you encounter the trap but you may frighten your
- X * pet causing it to go wild! moral: don't abuse this privilege.
- X */
- X /* Ceiling-hiding pets are skipped by this section of code, to
- X * be caught by the normal falling-monster code.
- X */
- X if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
- X int swap_result;
- X
- X /* if trapped, there's a chance the pet goes wild */
- X if (mtmp->mtrapped && !rn2(4)) {
- X pline ("%s suddenly goes wild!",
- X mtmp->mnamelth ? NAME(mtmp) : Monnam(mtmp));
- X mtmp->mtame = mtmp->mpeaceful = mtmp->msleep = 0;
- X }
- X
- X mtmp->mtrapped = 0;
- X mtmp->mundetected = 0;
- X remove_monster(x, y);
- X place_monster(mtmp, u.ux0, u.uy0);
- X
- X /* check first to see if monster drowned.
- X * then check for traps.
- X */
- X if (minwater(mtmp)) {
- X swap_result = 2;
- X } else swap_result = mintrap(mtmp);
- X
- X switch (swap_result) {
- X case 0:
- X You("%s %s.", mtmp->mtame ? "displaced" : "frightened",
- X mtmp->mnamelth ? NAME(mtmp) : mon_nam(mtmp));
- X break;
- X case 1: /* trapped */
- X case 3: /* changed levels */
- X /* there's already been a trap message, reinforce it */
- X pline("Trapping your pet was a selfish move.");
- X if (!rn2(4)) {
- X pline("You'll pay!");
- X adjalign(-5);
- X }
- X break;
- X case 2:
- X /* it may have drowned or died. that's no way to
- X * treat a pet! your god gets angry and complains.
- X */
- X if (rn2(4)) {
- X pline ("%s complains in a booming voice:", u_gname());
- X verbalize("Losing your pet like this was a mistake!");
- X u.ugangr++ ;
- X adjalign(-15);
- X }
- X break;
- X default:
- X pline("that's strange, unknown mintrap result!");
- X break;
- X }
- X }
- X
- X reset_occupations();
- X if(flags.run) {
- X if(IS_DOOR(tmpr->typ) ||
- X#ifdef POLYSELF
- X (IS_ROCK(tmpr->typ)) ||
- X#endif
- X (xupstair == u.ux && yupstair == u.uy) ||
- X (xdnstair == u.ux && ydnstair == u.uy)
- X || (sstairs.sx == u.ux && sstairs.sy == u.uy)
- X || (xupladder == u.ux && yupladder == u.uy)
- X || (xdnladder == u.ux && ydnladder == u.uy)
- X || IS_FOUNTAIN(tmpr->typ)
- X || IS_THRONE(tmpr->typ)
- X#ifdef SINKS
- X || IS_SINK(tmpr->typ)
- X#endif
- X || IS_ALTAR(tmpr->typ)
- X )
- X nomul(0);
- X }
- X#ifdef POLYSELF
- X if (hides_under(uasmon))
- X u.uundetected = OBJ_AT(u.ux, u.uy);
- X else if (u.dx || u.dy) { /* piercer */
- X if (u.usym == S_MIMIC_DEF)
- X u.usym = S_MIMIC;
- X u.uundetected = 0;
- X }
- X#endif
- X
- X#ifdef WALKIES
- X check_leash(u.ux0,u.uy0);
- X#endif
- X if(u.ux0 != u.ux || u.uy0 != u.uy) {
- X u.umoved = TRUE;
- X /* Clean old position -- vision_recalc() will print our new one. */
- X newsym(u.ux0,u.uy0);
- X /* Since the hero has moved, adjust what can be seen/unseen. */
- X vision_recalc(1); /* Do the work now in the recover time. */
- X
- X /* a special clue-msg when on the Invocation position */
- X if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
- X register struct obj *otmp;
- X
- X You("feel a strange vibration under your %s.",
- X makeplural(body_part(FOOT)));
- X
- X for(otmp = invent; otmp; otmp = otmp->nobj) {
- X if(otmp->otyp == CANDELABRUM_OF_INVOCATION &&
- X otmp->spe == 7 && otmp->lamplit) {
- X pline("%s glows with a strange light!",
- X The(xname(otmp)));
- X break;
- X }
- X }
- X
- X }
- X }
- X
- X if (Punished) /* put back ball and chain */
- X move_bc(0,bc_control,ballx,bally,chainx,chainy);
- X
- X spoteffects();
- X}
- X
- X#endif /* OVL3 */
- X#ifdef OVL2
- X
- Xvoid
- Xspoteffects()
- X{
- X register struct trap *trap;
- X register struct monst *mtmp;
- X
- X if(u.uinwater) {
- X int was_underwater;
- X
- X if (!is_pool(u.ux,u.uy)) {
- X if (Is_waterlevel(&u.uz))
- X You("pop into an air bubble.");
- X else
- X You("are on solid ground again.");
- X }
- X else if (Is_waterlevel(&u.uz))
- X goto stillinwater;
- X else if (Levitation || is_floater(uasmon))
- X You("pop out of the water like a cork!");
- X else if (is_flyer(uasmon))
- X You("fly out of the water.");
- X else if (Wwalking)
- X You("slowly rise above the surface.");
- X else
- X goto stillinwater;
- X was_underwater = Underwater && !Is_waterlevel(&u.uz);
- X u.uinwater = 0; /* leave the water */
- X if (was_underwater) { /* restore vision */
- X docrt();
- X vision_full_recalc = 1;
- X }
- X }
- Xstillinwater:;
- X if(!Levitation && !u.ustuck
- X#ifdef POLYSELF
- X && !is_flyer(uasmon)
- X#endif
- X ) {
- X /* limit recursive calls through teleds() */
- X if(is_lava(u.ux,u.uy) && lava_effects())
- X return;
- X if(is_pool(u.ux,u.uy) && !Wwalking && drown())
- X return;
- X }
- X check_special_room(FALSE);
- X#ifdef SINKS
- X if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
- X dosinkfall();
- X#endif
- X if(!flags.nopick && OBJ_AT(u.ux, u.uy) &&
- X (!is_pool(u.ux,u.uy) || Underwater))
- X pickup(1);
- X else read_engr_at(u.ux,u.uy);
- X if(trap = t_at(u.ux,u.uy))
- X dotrap(trap); /* fall into pit, arrow trap, etc. */
- X if((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) {
- X mtmp->mundetected = 0;
- X switch(mtmp->data->mlet) {
- X case S_PIERCER:
- X pline("%s suddenly drops from the ceiling!",
- X Amonnam(mtmp));
- X if(mtmp->mtame) /* jumps to greet you, not attack */
- X ;
- X else if(uarmh)
- X pline("Its blow glances off your helmet.");
- X else if (u.uac + 3 <= rnd(20))
- X You("are almost hit by %s!",
- X x_monnam(mtmp, 2, "falling", 1));
- X else {
- X int dmg;
- X You("are hit by %s!",
- X x_monnam(mtmp, 2, "falling", 1));
- X dmg = d(4,6);
- X if(Half_physical_damage) dmg = (dmg+1) / 2;
- X mdamageu(mtmp, dmg);
- X }
- X break;
- X default: /* monster surprises you. */
- X if(mtmp->mtame)
- X pline("%s jumps near you from the ceiling.",
- X Amonnam(mtmp));
- X else if(mtmp->mpeaceful) {
- X You("surprise %s!",
- X Blind && !sensemon(mtmp) ?
- X "something" : a_monnam(mtmp));
- X mtmp->mpeaceful = 0;
- X } else
- X pline("%s attacks you by surprise!",
- X Amonnam(mtmp));
- X break;
- X }
- X mnexto(mtmp); /* have to move the monster */
- X }
- X}
- X
- XSTATIC_OVL boolean
- Xmonstinroom(mdat,roomno)
- Xstruct permonst *mdat;
- Xint roomno;
- X{
- X register struct monst *mtmp;
- X
- X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- X if(mtmp->data == mdat &&
- X index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET))
- X return(TRUE);
- X return(FALSE);
- X}
- X
- Xchar *
- Xin_rooms(x, y, typewanted)
- Xregister xchar x, y;
- Xregister int typewanted;
- X{
- X static char buf[5];
- X char rno, *ptr = &buf[4];
- X int typefound, min_x, min_y, max_x, max_y_offset, step;
- X register struct rm *lev;
- X
- X#define goodtype(rno) (!typewanted || \
- X ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \
- X ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \
- X
- X switch (rno = levl[x][y].roomno) {
- X case NO_ROOM:
- X return(ptr);
- X case SHARED:
- X step = 2;
- X break;
- X case SHARED_PLUS:
- X step = 1;
- X break;
- X default: /* i.e. a regular room # */
- X if (goodtype(rno))
- X *(--ptr) = rno;
- X return(ptr);
- X }
- X
- X min_x = x - 1;
- X max_x = x + 1;
- X if (x < 0)
- X min_x += step;
- X else
- X if (x >= COLNO)
- X max_x -= step;
- X
- X min_y = y - 1;
- X max_y_offset = 2;
- X if (min_y < 0) {
- X min_y += step;
- X max_y_offset -= step;
- X } else
- X if ((min_y + max_y_offset) >= ROWNO)
- X max_y_offset -= step;
- X
- X for (x = min_x; x <= max_x; x += step) {
- X lev = &levl[x][min_y];
- X y = 0;
- X if (((rno = lev[y].roomno) >= ROOMOFFSET) &&
- X !index(ptr, rno) && goodtype(rno))
- X *(--ptr) = rno;
- X y += step;
- X if (y > max_y_offset)
- X continue;
- X if (((rno = lev[y].roomno) >= ROOMOFFSET) &&
- X !index(ptr, rno) && goodtype(rno))
- X *(--ptr) = rno;
- X y += step;
- X if (y > max_y_offset)
- X continue;
- X if (((rno = lev[y].roomno) >= ROOMOFFSET) &&
- X !index(ptr, rno) && goodtype(rno))
- X *(--ptr) = rno;
- X }
- X return(ptr);
- X}
- X
- Xstatic void
- Xmove_update(newlev)
- Xregister boolean newlev;
- X{
- X char *ptr1, *ptr2, *ptr3, *ptr4;
- X
- X Strcpy(u.urooms0, u.urooms);
- X Strcpy(u.ushops0, u.ushops);
- X if (newlev) {
- X u.urooms[0] = '\0';
- X u.uentered[0] = '\0';
- X u.ushops[0] = '\0';
- X u.ushops_entered[0] = '\0';
- X Strcpy(u.ushops_left, u.ushops0);
- X return;
- X }
- X Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0));
- X
- X for (ptr1 = &u.urooms[0],
- X ptr2 = &u.uentered[0],
- X ptr3 = &u.ushops[0],
- X ptr4 = &u.ushops_entered[0];
- X *ptr1; ptr1++) {
- X if (!index(u.urooms0, *ptr1))
- X *(ptr2++) = *ptr1;
- X if (IS_SHOP(*ptr1 - ROOMOFFSET)) {
- X *(ptr3++) = *ptr1;
- X if (!index(u.ushops0, *ptr1))
- X *(ptr4++) = *ptr1;
- X }
- X }
- X *ptr2 = '\0';
- X *ptr3 = '\0';
- X *ptr4 = '\0';
- X
- X /* filter u.ushops0 -> u.ushops_left */
- X for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++)
- X if (!index(u.ushops, *ptr1))
- X *(ptr2++) = *ptr1;
- X *ptr2 = '\0';
- X}
- X
- Xvoid
- Xcheck_special_room(newlev)
- Xregister boolean newlev;
- X{
- X register struct monst *mtmp;
- X char *ptr;
- X
- X move_update(newlev);
- X
- X if (*u.ushops0)
- X u_left_shop(u.ushops_left, newlev);
- X
- X if (!*u.uentered && !*u.ushops_entered)
- X return; /* no entrance messages necessary */
- X
- X /* Did we just enter a shop? */
- X if (*u.ushops_entered)
- X u_entered_shop(u.ushops_entered);
- X
- X for (ptr = &u.uentered[0]; *ptr; ptr++) {
- X register int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype;
- X
- X /* Did we just enter some other special room? */
- X /* vault.c insists that a vault remain a VAULT,
- X * and temples should remain TEMPLEs,
- X * but everything else gives a message only the first time */
- X if(!newlev)
- X switch (rt) {
- X case ZOO:
- X pline("Welcome to David's treasure zoo!");
- X break;
- X case SWAMP:
- X pline("It %s rather %s down here.",
- X Blind ? "feels" : "looks",
- X Blind ? "humid" : "muddy");
- X break;
- X case COURT:
- X You("enter an opulent throne room!");
- X break;
- X case MORGUE:
- X if(midnight())
- X pline("Run away! Run away!");
- X else
- X You("have an uncanny feeling...");
- X break;
- X case BEEHIVE:
- X You("enter a giant beehive!");
- X break;
- X#ifdef ARMY
- X case BARRACKS:
- X if(monstinroom(&mons[PM_SOLDIER], roomno) ||
- X monstinroom(&mons[PM_SERGEANT], roomno) ||
- X monstinroom(&mons[PM_LIEUTENANT], roomno) ||
- X monstinroom(&mons[PM_CAPTAIN], roomno))
- X You("enter a military barracks!");
- X else
- X You("enter an abandoned barracks.");
- X break;
- X#endif
- X case DELPHI:
- X if(monstinroom(&mons[PM_ORACLE], roomno))
- X verbalize("Hello, %s, welcome to Delphi!", plname);
- X break;
- X case TEMPLE:
- X intemple(roomno + ROOMOFFSET);
- X /* fall through */
- X default:
- X rt = 0;
- X }
- X else
- X rt = 0;
- X
- X if(rt != 0) {
- X rooms[roomno].rtype = OROOM;
- X if (!search_special(rt)) {
- X /* No more room of that type */
- X switch(rt) {
- X case COURT:
- X level.flags.has_court = 0;
- X break;
- X case SWAMP:
- X level.flags.has_swamp = 0;
- X break;
- X case MORGUE:
- X level.flags.has_morgue = 0;
- X break;
- X case ZOO:
- X level.flags.has_zoo = 0;
- X break;
- X#ifdef ARMY
- X case BARRACKS:
- X level.flags.has_barracks = 0;
- X break;
- X#endif
- X case TEMPLE:
- X level.flags.has_temple = 0;
- X break;
- X case BEEHIVE:
- X level.flags.has_beehive = 0;
- X break;
- X }
- X }
- X if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO)
- X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- X if(!Stealth && !rn2(3))
- X mtmp->msleep = 0;
- X }
- X }
- X
- X return;
- X}
- X
- X#endif /* OVL2 */
- X#ifdef OVLB
- X
- Xint
- Xdopickup()
- X{
- X int count;
- X /* awful kludge to work around parse()'s pre-decrement */
- X count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0;
- X multi = 0; /* always reset */
- X /* uswallow case added by GAN 01/29/87 */
- X if(u.uswallow) {
- X if (is_animal(u.ustuck->data)) {
- X You("pick up %s tongue.",
- X s_suffix(mon_nam(u.ustuck)));
- X pline("But it's kind of slimy, so you drop it.");
- X } else
- X You("don't %s anything in here to pick up.",
- X Blind ? "feel" : "see");
- X return(1);
- X }
- X if(!OBJ_AT(u.ux, u.uy)) {
- X pline("There is nothing here to pick up.");
- X return(0);
- X }
- X if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
- X You("cannot reach the floor.");
- X return(1);
- X }
- X if(is_pool(u.ux, u.uy)) {
- X if(Wwalking
- X#ifdef POLYSELF
- X || is_flyer(uasmon) || is_clinger(uasmon)
- X#endif
- X ) {
- X You("cannot dive into the water to pick things up.");
- X return(1);
- X }
- X else if(!Underwater) {
- X You("can't even see the bottom, let alone pick up something.");
- X return(1);
- X }
- X }
- X pickup(-count);
- X return(1);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL2
- X
- X/* stop running if we see something interesting */
- X/* turn around a corner if that is the only way we can proceed */
- X/* do not turn left or right twice */
- Xvoid
- Xlookaround()
- X{
- X register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9;
- X register int corrct = 0, noturn = 0;
- X register struct monst *mtmp;
- X register struct trap *trap;
- X
- X#ifdef POLYSELF
- X /* Grid bugs stop if trying to move diagonal, even if blind. Maybe */
- X /* they polymorphed while in the middle of a long move. */
- X if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) {
- X nomul(0);
- X return;
- X }
- X#endif
- X if(Blind || flags.run == 0) return;
- X for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) {
- X if(!isok(x,y)) continue;
- X#ifdef POLYSELF
- X if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue;
- X#endif
- X if(x == u.ux && y == u.uy) continue;
- X
- X if((mtmp = m_at(x,y)) &&
- X mtmp->m_ap_type != M_AP_FURNITURE &&
- X mtmp->m_ap_type != M_AP_OBJECT &&
- X (!mtmp->minvis || See_invisible) && !mtmp->mundetected) {
- X if((flags.run != 1 && !mtmp->mtame)
- X || (x == u.ux+u.dx && y == u.uy+u.dy))
- X goto stop;
- X }
- X
- X if (levl[x][y].typ == STONE) continue;
- X if (x == u.ux-u.dx && y == u.uy-u.dy) continue;
- X
- X if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM) ||
- X IS_AIR(levl[x][y].typ))
- X continue;
- X else if (closed_door(x,y)) {
- X if(x != u.ux && y != u.uy) continue;
- X if(flags.run != 1) goto stop;
- X goto bcorr;
- X } else if (levl[x][y].typ == CORR) {
- Xbcorr:
- X if(levl[u.ux][u.uy].typ != ROOM) {
- X if(flags.run == 1 || flags.run == 3) {
- X i = dist2(x,y,u.ux+u.dx,u.uy+u.dy);
- X if(i > 2) continue;
- X if(corrct == 1 && dist2(x,y,x0,y0) != 1)
- X noturn = 1;
- X if(i < i0) {
- X i0 = i;
- X x0 = x;
- X y0 = y;
- X m0 = mtmp ? 1 : 0;
- X }
- X }
- X corrct++;
- X }
- X continue;
- X } else if ((trap = t_at(x,y)) && trap->tseen) {
- X if(flags.run == 1) goto bcorr; /* if you must */
- X if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
- X continue;
- X } else if (is_pool(x,y) || is_lava(x,y)) {
- X /* water and lava only stop you if directly in front, and stop
- X * you even if you are running
- X */
- X if(!Levitation &&
- X#ifdef POLYSELF
- X !is_flyer(uasmon) && !is_clinger(uasmon) &&
- X#endif
- X /* No Wwalking check; otherwise they'd be able
- X * to test boots by trying to SHIFT-direction
- X * into a pool and seeing if the game allowed it
- X */
- X x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
- X continue;
- X } else { /* e.g. objects or trap or stairs */
- X if(flags.run == 1) goto bcorr;
- X if(mtmp) continue; /* d */
- X if(((x == u.ux - u.dx) && (y != u.uy + u.dy)) ||
- X ((y == u.uy - u.dy) && (x != u.ux + u.dx)))
- X continue;
- X }
- Xstop:
- X nomul(0);
- X return;
- X } /* end for loops */
- X
- X if(corrct > 1 && flags.run == 2) goto stop;
- X if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
- X (corrct == 1 || (corrct == 2 && i0 == 1))) {
- X /* make sure that we do not turn too far */
- X if(i0 == 2) {
- X if(u.dx == y0-u.uy && u.dy == u.ux-x0)
- X i = 2; /* straight turn right */
- X else
- X i = -2; /* straight turn left */
- X } else if(u.dx && u.dy) {
- X if((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy))
- X i = -1; /* half turn left */
- X else
- X i = 1; /* half turn right */
- X } else {
- X if((x0-u.ux == y0-u.uy && !u.dy) || (x0-u.ux != y0-u.uy && u.dy))
- X i = 1; /* half turn right */
- X else
- X i = -1; /* half turn left */
- X }
- X
- X i += u.last_str_turn;
- X if(i <= 2 && i >= -2) {
- X u.last_str_turn = i;
- X u.dx = x0-u.ux;
- X u.dy = y0-u.uy;
- X }
- X }
- X}
- X
- X/* something like lookaround, but we are not running */
- X/* react only to monsters that might hit us */
- Xint
- Xmonster_nearby()
- X{
- X register int x,y;
- X register struct monst *mtmp;
- X
- X if(!Blind)
- X for(x = u.ux-1; x <= u.ux+1; x++)
- X for(y = u.uy-1; y <= u.uy+1; y++) {
- X if(!isok(x,y)) continue;
- X if(x == u.ux && y == u.uy) continue;
- X if((mtmp = m_at(x,y)) &&
- X mtmp->m_ap_type != M_AP_FURNITURE &&
- X mtmp->m_ap_type != M_AP_OBJECT &&
- X !mtmp->mpeaceful &&
- X (!is_hider(mtmp->data) || !mtmp->mundetected) &&
- X !noattacks(mtmp->data) &&
- X mtmp->mcanmove && !mtmp->msleep && /* aplvax!jcn */
- X (!mtmp->minvis || See_invisible) &&
- X !onscary(u.ux, u.uy, mtmp))
- X return(1);
- X }
- X return(0);
- X}
- X
- Xvoid
- Xnomul(nval)
- X register int nval;
- X{
- X if(multi < nval) return; /* This is a bug fix by ab@unido */
- X u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
- X u.usleep = 0;
- X multi = nval;
- X flags.mv = flags.run = 0;
- X}
- X
- X#endif /* OVL2 */
- X#ifdef OVL1
- X
- Xvoid
- Xlosehp(n, knam, k_format)
- Xregister int n;
- Xregister const char *knam;
- Xboolean k_format;
- X{
- X#ifdef POLYSELF
- X if (u.mtimedone) {
- X u.mh -= n;
- X if (u.mhmax < u.mh) u.mhmax = u.mh;
- X flags.botl = 1;
- X if (u.mh < 1) rehumanize();
- X return;
- X }
- X#endif
- X u.uhp -= n;
- X if(u.uhp > u.uhpmax)
- X u.uhpmax = u.uhp; /* perhaps n was negative */
- X flags.botl = 1;
- X if(u.uhp < 1) {
- X killer_format = k_format;
- X killer = knam; /* the thing that killed you */
- X You("die...");
- X done(DIED);
- X } else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){
- X wailmsg = moves;
- X if(index("WEV", pl_character[0])) {
- X if (u.uhp == 1)
- X pline("%s is about to die.", pl_character);
- X else if (4 <= (!!(HTeleportation & INTRINSIC)) +
- X (!!(HSee_invisible & INTRINSIC)) +
- X (!!(HPoison_resistance & INTRINSIC)) +
- X (!!(HCold_resistance & INTRINSIC)) +
- X (!!(HShock_resistance & INTRINSIC)) +
- X (!!(HFire_resistance & INTRINSIC)) +
- X (!!(HSleep_resistance & INTRINSIC)) +
- X (!!(HDisint_resistance & INTRINSIC)) +
- X (!!(HTeleport_control & INTRINSIC)) +
- X (!!(Stealth & INTRINSIC)) +
- X (!!(Fast & INTRINSIC)) +
- X (!!(HInvis & INTRINSIC)))
- X pline("%s, all your powers will be lost...",
- X pl_character);
- X else
- X pline("%s, your life force is running out.",
- X pl_character);
- X } else {
- X if(u.uhp == 1)
- X You("hear the wailing of the Banshee...");
- X else
- X You("hear the howling of the CwnAnnwn...");
- X }
- X }
- X}
- X
- Xint
- Xweight_cap()
- X{
- X register long carrcap;
- X
- X carrcap = (((ACURRSTR + ACURR(A_CON))/2)+1)*50;
- X#ifdef POLYSELF
- X if (u.mtimedone) {
- X /* consistent with can_carry() in mon.c */
- X if (u.usym == S_NYMPH)
- X carrcap = MAX_CARR_CAP;
- X else if (!uasmon->cwt)
- X carrcap = (carrcap * (long)uasmon->msize) / MZ_HUMAN;
- X else if (!strongmonst(uasmon)
- X || (strongmonst(uasmon) && (uasmon->cwt > WT_HUMAN)))
- X carrcap = (carrcap * (long)uasmon->cwt / WT_HUMAN);
- X }
- X#endif
- X if(Levitation || Is_airlevel(&u.uz)) /* pugh@cornell */
- X carrcap = MAX_CARR_CAP;
- X else {
- X if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
- X if(Wounded_legs & LEFT_SIDE) carrcap -= 100;
- X if(Wounded_legs & RIGHT_SIDE) carrcap -= 100;
- X }
- X return((int) carrcap);
- X}
- X
- X/* returns how far beyond the normal capacity the player is currently. */
- X/* inv_weight() is negative if the player is below normal capacity. */
- Xint
- Xinv_weight()
- X{
- X register struct obj *otmp = invent;
- X#ifdef LINT /* long to int conversion */
- X register int wt = 0;
- X#else
- X register int wt = (int)((u.ugold + 50L)/100L);
- X#endif /* LINT */
- X while(otmp){
- X#ifdef POLYSELF
- X if (otmp->otyp != BOULDER || !throws_rocks(uasmon))
- X#endif
- X wt += otmp->owt;
- X otmp = otmp->nobj;
- X }
- X return(wt - weight_cap());
- X}
- X
- X/*
- X * Returns 0 if below normal capacity, or the number of "capacity units"
- X * over the normal capacity the player is loaded. Max is 5.
- X */
- Xint
- Xnear_capacity()
- X{
- X int cap, wt = inv_weight();
- X
- X if (wt < 0) return UNENCUMBERED;
- X cap = (wt / (weight_cap()/2)) + 1;
- X return min(cap, OVERLOADED);
- X}
- X
- Xint
- Xmax_capacity()
- X{
- X return(inv_weight() - (2 * weight_cap()));
- X}
- X
- Xboolean
- Xcheck_capacity(str)
- Xconst char *str;
- X{
- X if(near_capacity() >= EXT_ENCUMBER) {
- X if(str)
- X pline(str);
- X else
- X You("can't do that while carrying so much stuff.");
- X return 1;
- X }
- X return 0;
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVLB
- X
- Xint
- Xinv_cnt()
- X{
- X register struct obj *otmp = invent;
- X register int ct = 0;
- X
- X while(otmp){
- X ct++;
- X otmp = otmp->nobj;
- X }
- X return(ct);
- X}
- X
- Xint
- Xidentify(otmp) /* also called by newmail() */
- X register struct obj *otmp;
- X{
- X makeknown(otmp->otyp);
- X otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
- X prinv(NULL, otmp, 0L);
- X return(1);
- X}
- X
- X#endif /* OVLB */
- X
- X/*hack.c*/
- END_OF_FILE
- if test 39188 -ne `wc -c <'src/hack.c'`; then
- echo shar: \"'src/hack.c'\" unpacked with wrong size!
- fi
- # end of 'src/hack.c'
- fi
- if test -f 'sys/os2/Install.os2' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sys/os2/Install.os2'\"
- else
- echo shar: Extracting \"'sys/os2/Install.os2'\" \(14816 characters\)
- sed "s/^X//" >'sys/os2/Install.os2' <<'END_OF_FILE'
- X Instructions for compiling and installing NetHack 3.1
- X on an OS/2 system
- X =====================================================
- X Timo Hakulinen
- X Last revision: 24 Jan 1993
- X
- X0. Read this entire file before starting, and come back to the Notes below if
- X you have any problems.
- X
- X1. Make sure all the NetHack files are in the appropriate directory
- X structure. You should have a top directory (e.g. nh31, or whatever you
- X like) with subdirectories dat, doc, include, src, util, sys\share,
- X sys\os2, and win\tty. You may have other subdirectories under sys and
- X win, but they will not affect compilation for an OS/2 system. If you do
- X not follow this structure, the makefile will not function properly. The
- X .c files for the main program belong in src, those for utility programs in
- X util, and OS/2-specific ones in sys\os2. All the .h files belong in
- X include, the documentation in doc, and assorted data files in dat. There
- X are also some necessary files in sys\share (pc*.c, random.c, dgn_*.*,
- X lev_*.*). A more detailed explanation of the directory structure is found
- X in file Files, which should be in the top directory.
- X
- X If you downloaded or ftp'd the sources from a UNIX system, the lines may
- X end in UNIX-style newlines, instead of the carriage return and line feed
- X pairs used by DOS and OS/2. You'll have to convert them (with a utility
- X like Rahul Dhesi's "flip"). Also, every file should end with a carriage
- X return / line feed pair, because Microsoft C has had a habit of ignoring
- X the last line of each file otherwise. Besides, even editing UNIX-style
- X files with DOS editors is often a royal pain.
- X
- X2. The makefile for OS/2, Makefile.os2, is found in directory sys\os2. Copy
- X it to directory src and rename it Makefile. From now on, Makefile.os2
- X will be referred to as "Makefile" in this document.
- X
- X The Makefile supports the following make utilities:
- X
- X NDMAKE a public domain make utility for DOS by Don Kneller
- X NMAKE make shipped with Microsoft languages and IBM C Set/2
- X DMAKE a public domain make for DOS and OS/2 by Dennis Vadura
- X
- X Both NDMAKE and DMAKE are available at major archive sites. The
- X following compilers are supported:
- X
- X compiler: runs in: compiles for:
- X
- X Microsoft C 5.1 DOS / OS/2 1.0-2.x OS/2 1.x
- X Microsoft 6.0A (see note 5) - " - - " -
- X IBM C Set/2 1.00, Toolkit/2 2.00 OS/2 2.x OS/2 2.x
- X GCC emx 0.8f (see note 6) OS/2 2.x OS/2 2.x
- X
- X Note that code compiled for OS/2 versions 1.0-1.3 runs unmodified in OS/2
- X versions 2.0 and up. It should in principle be possible to cross compile
- X NetHack 3.1 for OS/2 in DOS using NDMAKE and MSC, but this is not
- X recommended (see note 3).
- X
- X If you're using some other compiler than one listed above, you will have
- X to adapt Makefile to your needs. In particular, change the CC, CFLAGS,
- X LINK, and LFLAGS macros to your C compiler's and linker's liking. See
- X Makefile for more information.
- X
- X If you are going to be constructing the Fred Fish termlib library you will
- X need Makefile.lib in sys\share (see note 4).
- X
- X3. Go to the include subdirectory. First edit config.h according to the
- X comments to match your system and desired set of features. In particular,
- X make sure that OS2 is defined, and that UNIX, HACKDIR, and COMPRESS are
- X *not* defined. If your compiler is ANSI compliant (like practically all
- X OS/2 compilers are), it's probable that nothing else needs to be
- X configured in config.h. However, if you have VISION_TABLES defined and
- X get a compilation error while processing vis_tab.c, you may have to
- X uncomment BRACES too.
- X
- X Next look at os2conf.h. This file shouldn't need much changing. If you
- X want to use the hardcoded OS/2 system definitions in def_os2.h instead of
- X the compiler's standard headers, comment out OS2_USESYSHEADERS. This may
- X become necessary if you are using a compiler which doesn't come with
- X proper system headers by default. In this case you may have to edit the
- X definitions there, because every compiler has its own way of declaring
- X the necessary system functions and data structures. In general you
- X should prefer the compiler's offerings, if possible.
- X
- X If you are using a 32 bit compiler other than GCC emx 0.8f or C Set/2 in
- X OS/2 2.x, force OS2_32BITAPI to be defined. Otherwise it is defined only
- X for the above mentioned compilers.
- X
- X If you are not going to include random.c, because you are using the
- X random number generator provided by your compiler, you will need to
- X comment out RANDOM.
- X
- X If you want to muck with different termcap settings, uncomment TERMLIB to
- X enable use of termcap routines (see note 4). This is not necessary to
- X create a fully functional game, however.
- X
- X4. If you are using another compiler than MSC, GCC, or IBM C Set/2, you may
- X want to look through system.h in the include directory. This file matches
- X the return and parameter types for system calls and library routines with
- X various flavors of compilers and operating systems. Leaving this file
- X alone is unlikely to cause problems, but if you get compile errors with
- X any functions in the standard library, it's worth checking the
- X declarations there.
- X
- X5. If you want to change the high score list behavior, examine the top of
- X topten.c, in the src directory. You may want to change the definitions of
- X PERSMAX, POINTSMIN, and ENTRYMAX.
- X
- X6. Go to the src directory and edit the top of Makefile. Be sure the
- X directory you want the game installed in actually exists.
- X
- X You'll need nroff and/or TeX to do the files in doc. If you don't have
- X either of these, you can skip it.
- X
- X If you elected not to use the high-quality BSD random number routines by
- X commenting out RANDOM in os2conf.h, comment out (or set equal to nothing)
- X the RANDOM macro in Makefile.
- X
- X If you elected to use Fred Fish's termcap library (bundled in as
- X termcap.uu in directory sys\share), you will have to generate termlib.lib
- X from those sources by typing "make -f makefile.lib termlib.lib". You must
- X set the TERMLIB option in Makefile to link in the resulting termlib.lib.
- X
- X If you are recompiling after patching your sources, or if you got your
- X files from somewhere other than the official distribution, "touch
- X makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
- X lest potentially troublesome timestamps fool make.
- X
- X If you have lex and yacc programs, or the equivalent flex and bison
- X programs, you can set up Makefile to generate the appropriate .h and .c
- X files from their .l and .y counterparts whenever you recompile. This is
- X done by changing the do_yacc and do_lex targets in Makefile to depend on
- X targets yacc_act and lex_act instead of yacc_cpy and lex_cpy. Otherwise
- X Makefile will copy pre-generated yacc and lex output files dgn_*.* and
- X lev_*.* from directory sys\share to util and include.
- X
- X Now, enter "make all", and take a siesta; your computer will be occupied
- X for a fair amount of time. If all goes well, you will get an executable.
- X
- X7. All the support data files should have been copied to the game directory
- X by the make process. Here is the complete list in alphabetical order of
- X all the files that should have gotten there during a full build:
- X
- X A-filla.lev A-fillb.lev A-goal.lev A-locate.lev A-start.lev
- X B-filla.lev B-fillb.lev B-goal.lev B-locate.lev B-start.lev
- X C-filla.lev C-fillb.lev C-goal.lev C-locate.lev C-start.lev
- X E-filla.lev E-fillb.lev E-goal.lev E-locate.lev E-start.lev
- X H-filla.lev H-fillb.lev H-goal.lev H-locate.lev H-start.lev
- X K-filla.lev K-fillb.lev K-goal.lev K-locate.lev K-start.lev
- X P-filla.lev P-fillb.lev P-goal.lev P-locate.lev P-start.lev
- X R-filla.lev R-fillb.lev R-goal.lev R-locate.lev R-start.lev
- X S-filla.lev S-fillb.lev S-goal.lev S-locate.lev S-start.lev
- X T-filla.lev T-fillb.lev T-goal.lev T-locate.lev T-start.lev
- X V-filla.lev V-fillb.lev V-goal.lev V-locate.lev V-start.lev
- X W-filla.lev W-fillb.lev W-goal.lev W-locate.lev W-start.lev
- X air.lev asmodeus.lev astral.lev baalz.lev bigroom.lev
- X castle.lev cmdhelp data dungeon earth.lev
- X fakewiz1.lev fakewiz2.lev fire.lev help hh
- X history juiblex.lev knox.lev license medusa-1.lev
- X medusa-2.lev mine_end.lev minefill.lev minetown.lev nethack.cmd
- X nethack.cnf nethack.exe nethack.ico opthelp options
- X oracle.lev oracles orcus.lev quest.dat recover.exe
- X rumors sanctum.lev tower1.lev tower2.lev tower3.lev
- X valley.lev water.lev wizard1.lev wizard2.lev wizard3.lev
- X wizhelp
- X
- X Yes. It's 106 files for a full featured NetHack 3.1. If any of the files
- X are missing, try to rerun make. If that doesn't help, you'll have to try
- X to decipher Makefile to find out how to manually create the missing
- X files. These kinds of troubles shouldn't happen except for two reasons:
- X You've run out of disk space while compiling or your make utility doesn't
- X understand Makefile properly for some reason. In either case, you should
- X get some warnings from the make, though.
- X
- X If you have old record, logfile, or news files in the game directory, they
- X are not overwritten. Of course, old records from NetHack 3.0 are not
- X worth keeping with 3.1, since these games are really quite different.
- X
- X Edit file nethack.cnf in the game directory to reflect your particular
- X setup and personal preferences, following the comments there. More info
- X about settable options can be found in the file opthelp and the Guidebook.
- X
- X If you compiled in the TERMLIB feature, also move the sys\share\termcap
- X file to your game directory.
- X
- X8. If you'll be running NetHack from a different subdirectory, you will want
- X to "set HACKDIR=c:\games\nh31" (or whatever directory you want to use).
- X Add it to your config.sys, if you'll be playing often.
- X
- X You can also create a special NetHack entry in your Presentation Manager /
- X Workplace Shell desktop. This will use the included NetHack icon.
- X The following is a sample program description for OS/2 1.3 desktop, but
- X it's similar for OS/2 2.0:
- X
- X Program title: NetHack 3.1
- X Path and file name: c:\games\nh31\nethack.cmd
- X Parameters:
- X Working directory: c:\games\nh31
- X Program type: OS/2 Full screen
- X
- X Naturally you must fill in your own game directory and parameters if you
- X want to set any. The program type can be either OS/2 Full screen or OS/2
- X Windowed. Note that you should set the executable path to use the .cmd
- X file generated by Makefile. This file generates an extra pause after the
- X program exit, because otherwise you wouldn't get to see the high score
- X list upon quitting due to PM/WPS automatically closing the program window.
- X When starting NetHack normally from OS/2 command prompt, the command
- X processor starts nethack.exe instead, so no extra pause is generated.
- X
- X9. If you want to clear up the temporary files and objects created by the
- X compilation process, you may issue "make spotless". This will return your
- X source tree to near-distribution condition. Naturally, it will not touch
- X your newly built game files in any way.
- X
- X10. Play NetHack. If it works, you're done!
- X
- X
- XNotes
- X-----
- X
- X1) Save files and bones files from previous versions will not work with
- X NetHack 3.1. Don't bother trying to keep them.
- X
- X2) To install an update of NetHack after changing something, enter "make"
- X from the src directory. If you add, delete, or reorder monsters or
- X objects, or you change the format of saved level files, delete any save
- X and bones files. (Trying to use such files sometimes produces amusing
- X confusions on the game's part, but usually crashes.)
- X
- X3) When cross-compiling for OS/2 in DOS, NDMAKE is the best choice because it
- X requires the least RAM for itself. Note however, that cross-compilation
- X in DOS is discouraged, because it is considered obsolete (OS/2 is really
- X a much better place to compile). If you still want to try, here are some
- X suggestions:
- X
- X During linking, the Microsoft linker will need temporary storage space.
- X Make sure you have about a meg of free disk where-ever you have defined
- X your temporary storage. It is also a good idea to compile with as much
- X free RAM as possible. It may otherwise get crowded with the bigger, more
- X complex source files (compiler bombs with "out of heap space" or similar).
- X If this happens, strip your configuration, zap TSR's, get a better memory
- X manager etc.
- X
- X4) The file sys\share\termcap.uu is the fixed version of the Fred Fish
- X termcap library. You will need to run a uudecode utility on it to
- X generate the file termcap.zip. termcap.zip contains several files of
- X termcap routines. Using them with NetHack involves very little knowledge
- X of the UNIX concept of a termcap database; mostly you need to know enough
- X to set a TERM environment variable. You can unzip termcap.zip in the
- X sys\share directory, but if you are going to use it, it is probably best
- X to unzip a copy in the src directory. That way you will not miss copying
- X any files over. Wherever you unzip it, get rid of the included makefile
- X since a better version has been provided as Makefile.lib. After creating
- X the termcap library file termlib.lib, copy it to src before compiling the
- X game main source.
- X
- X5) When compiling with MSC 6.0, the maintenance version 6.0A should be used
- X instead of the original 6.0, which was all too buggy to successfully build
- X NetHack 3.1.
- X
- X6) Note that emx 0.8f is the first version of GCC for OS/2 that can properly
- X compile NetHack. Earlier versions do not work, because they don't support
- X the 16 bit API calls of OS/2.
- X
- X GCC emx 0.8f does not currently work properly when fseek() function is
- X used with text files. This is well documented in the compiler's
- X documentation. Unfortunately NetHack uses fseek() in several places in
- X connection with text data. This means that some help texts may not come
- X out right, but no serious problems should emerge.
- END_OF_FILE
- if test 14816 -ne `wc -c <'sys/os2/Install.os2'`; then
- echo shar: \"'sys/os2/Install.os2'\" unpacked with wrong size!
- fi
- # end of 'sys/os2/Install.os2'
- fi
- echo shar: End of archive 34 \(of 108\).
- cp /dev/null ark34isdone
- 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
-