home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume10
/
nethack3p9
/
part34
< prev
next >
Wrap
Internet Message Format
|
1990-07-27
|
61KB
Path: uunet!lll-winken!sun-barr!cs.utexas.edu!rice!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v10i079: nethack3p9 - display oriented dungeons & dragons (Ver. 3.0i), Part34/56
Message-ID: <5937@tekred.CNA.TEK.COM>
Date: 12 Jul 90 16:07:40 GMT
Sender: news@tekred.CNA.TEK.COM
Lines: 2504
Approved: billr@saab.CNA.TEK.COM
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 79
Archive-name: nethack3p9/Part34
Supersedes: NetHack3: Volume 7, Issue 56-93
#! /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 56)."
# Contents: src/dbridge.c src/pager.c src/sit.c
# Wrapped by billr@saab on Wed Jul 11 17:11:42 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/dbridge.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/dbridge.c'\"
else
echo shar: Extracting \"'src/dbridge.c'\" \(20980 characters\)
sed "s/^X//" >'src/dbridge.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)dbridge.c 3.0 88/18/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 drawbridge manipulation (create, open, close,
X * destroy).
X *
X * Added comprehensive monster-handling, and the "entity" structure to
X * deal with players as well. - 11/89
X */
X
X#include "hack.h"
X
X#ifdef STRONGHOLD
X# ifdef OVLB
Xstatic void FDECL(redosym, (int, int));
Xstatic void FDECL(get_wall_for_db, (int *, int *));
Xstatic struct entity *FDECL(e_at, (int, int));
Xstatic void FDECL(m_to_e, (struct monst *, struct entity *));
Xstatic void FDECL(u_to_e, (struct entity *));
Xstatic void FDECL(set_entity, (int, int, struct entity *));
Xstatic char *FDECL(e_nam, (struct entity *));
X/* static char *FDECL(Enam, (struct entity *)); */ /* unused */
Xstatic char *FDECL(E_phrase, (struct entity *, const char *));
Xstatic boolean FDECL(e_survives_at, (struct entity *, int, int));
Xstatic void FDECL(e_died, (struct entity *, int, int));
Xstatic boolean FDECL(automiss, (struct entity *));
Xstatic boolean FDECL(e_missed, (struct entity *, BOOLEAN_P));
Xstatic boolean FDECL(e_jumps, (struct entity *));
Xstatic void FDECL(do_entity, (struct entity *));
X# endif /* OVLB */
X#endif /* STRONGHOLD */
X
X#ifdef OVL0
X
Xboolean
Xis_pool(x,y)
Xint x,y;
X{
X if(levl[x][y].typ == POOL || levl[x][y].typ == MOAT) return TRUE;
X#ifdef STRONGHOLD
X if(levl[x][y].typ == DRAWBRIDGE_UP &&
X (levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE;
X#endif
X return FALSE;
X}
X
X#endif /* OVL0 */
X
X#ifdef STRONGHOLD
X
X#ifdef OVL1
X
Xvoid
Xinitsym(x,y)
Xint x,y;
X{
X char oldseen;
X struct rm *crm = &levl[x][y];
X
X oldseen = crm->seen;
X crm->seen = 1;
X crm->scrsym = news0(x,y);
X crm->seen = oldseen;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xstatic void
Xredosym(x,y)
Xint x,y;
X{
X if(cansee(x,y)) {
X levl[x][y].seen = 0; /* force prl */
X prl(x, y);
X } else {
X initsym(x,y);
X levl[x][y].seen = 0;
X }
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
X/*
X * We want to know whether a wall (or a door) is the portcullis (passageway)
X * of an eventual drawbridge.
X *
X * Return value: the direction of the drawbridge.
X */
X
Xint
Xis_drawbridge_wall(x,y)
Xint x,y;
X{
X struct rm *lev;
X
X lev = &levl[x][y];
X if (lev->typ != DOOR && !(lev->diggable & W_GATEWAY))
X return (-1);
X switch (lev->typ) {
X case DOOR:
X case VWALL:
X if (IS_DRAWBRIDGE(levl[x+1][y].typ) &&
X (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST)
X return (DB_WEST);
X if (IS_DRAWBRIDGE(levl[x-1][y].typ) &&
X (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST)
X return (DB_EAST);
X if (lev->typ == VWALL) break;
X case HWALL:
X if (IS_DRAWBRIDGE(levl[x][y-1].typ) &&
X (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH)
X return (DB_SOUTH);
X if (IS_DRAWBRIDGE(levl[x][y+1].typ) &&
X (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH)
X return (DB_NORTH);
X }
X return (-1);
X}
X
X/*
X * Use is_db_wall where you want to verify that a
X * drawbridge "wall" is UP in the location x, y
X * (instead of UP or DOWN, as with is_drawbridge_wall).
X */
Xboolean
Xis_db_wall(x,y)
Xint x,y;
X{
X return( (levl[x][y].typ == VWALL || levl[x][y].typ == HWALL) &&
X levl[x][y].diggable & W_GATEWAY);
X}
X
X
X/*
X * Return true with x,y pointing to the drawbridge if x,y initially indicate
X * a drawbridge or drawbridge wall.
X */
Xboolean
Xfind_drawbridge(x,y)
Xint *x,*y;
X{
X int dir;
X
X if (IS_DRAWBRIDGE(levl[*x][*y].typ))
X return TRUE;
X dir = is_drawbridge_wall(*x,*y);
X if (dir >= 0) {
X switch(dir) {
X case DB_NORTH: (*y)++; break;
X case DB_SOUTH: (*y)--; break;
X case DB_EAST: (*x)--; break;
X case DB_WEST: (*x)++; break;
X }
X return TRUE;
X }
X return FALSE;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
X/*
X * Find the drawbridge wall associated with a drawbridge.
X */
Xstatic void
Xget_wall_for_db(x,y)
Xint *x,*y;
X{
X switch (levl[*x][*y].drawbridgemask & DB_DIR) {
X case DB_NORTH: (*y)--; break;
X case DB_SOUTH: (*y)++; break;
X case DB_EAST: (*x)++; break;
X case DB_WEST: (*x)--; break;
X }
X}
X
X/*
X * Creation of a drawbridge at pos x,y.
X * dir is the direction.
X * flag must be put to TRUE if we want the drawbridge to be opened.
X */
X
Xboolean
Xcreate_drawbridge(x,y,dir,flag)
Xint x,y,dir;
Xboolean flag;
X{
X int x2,y2;
X uchar wall;
X
X x2 = x; y2 = y;
X switch(dir) {
X case DB_NORTH:
X wall = HWALL;
X y2--;
X break;
X case DB_SOUTH:
X wall = HWALL;
X y2++;
X break;
X case DB_EAST:
X wall = VWALL;
X x2++;
X break;
X default:
X impossible("bad direction in create_drawbridge");
X /* fall through */
X case DB_WEST:
X wall = VWALL;
X x2--;
X break;
X }
X if (!IS_WALL(levl[x2][y2].typ))
X return(FALSE);
X if (flag) { /* We want the bridge open */
X levl[x][y].typ = DRAWBRIDGE_DOWN;
X levl[x2][y2].typ = DOOR;
X levl[x2][y2].doormask = D_NODOOR;
X } else {
X levl[x][y].typ = DRAWBRIDGE_UP;
X levl[x2][y2].typ = wall;
X /* Beware, drawbridges are non-diggable. */
X levl[x2][y2].diggable = (W_NONDIGGABLE | W_GATEWAY);
X }
X levl[x][y].drawbridgemask = dir; /* always have DB_MOAT */
X initsym(x,y);
X initsym(x2,y2);
X return(TRUE);
X}
X
Xstruct entity {
X struct monst *emon; /* youmonst for the player */
X struct permonst *edata; /* must be non-zero for record to be valid */
X int ex, ey;
X};
X
X#define ENTITIES 2
X
Xstatic struct entity NEARDATA occupants[ENTITIES];
X
Xstatic
Xstruct entity *
Xe_at(x, y)
Xint x, y;
X{
X int entitycnt;
X
X for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++)
X if ((occupants[entitycnt].edata) &&
X (occupants[entitycnt].ex == x) &&
X (occupants[entitycnt].ey == y))
X break;
X#ifdef D_DEBUG
X pline("entitycnt = %d", entitycnt);
X fflush(stdout);
X#endif
X return((entitycnt == ENTITIES)?
X (struct entity *)0 : &(occupants[entitycnt]));
X}
X
Xstatic void
Xm_to_e(mtmp, etmp)
Xstruct monst *mtmp;
Xstruct entity *etmp;
X{
X etmp->emon = mtmp;
X if (mtmp) {
X etmp->ex = mtmp->mx;
X etmp->ey = mtmp->my;
X etmp->edata = mtmp->data;
X } else
X etmp->edata = (struct permonst *)0;
X}
X
Xstatic void
Xu_to_e(etmp)
Xstruct entity *etmp;
X{
X etmp->emon = &youmonst;
X etmp->ex = u.ux;
X etmp->ey = u.uy;
X etmp->edata = uasmon;
X}
X
Xstatic void
Xset_entity(x, y, etmp)
Xint x, y;
Xstruct entity *etmp;
X{
X if ((x == u.ux) && (y == u.uy))
X u_to_e(etmp);
X else
X if (MON_AT(x, y))
X m_to_e(m_at(x, y), etmp);
X else
X etmp->edata = (struct permonst *)0;
X}
X
X#ifdef POLYSELF
X#define is_u(etmp) (etmp->emon == &youmonst)
X#else
X#define is_u(x) FALSE
X#endif
X
X/*
X * WARNING! THE FOLLOWING IS ONLY USEFUL FOR CANSEEMON, OR OTHER FUNCS WHICH
X * ALWAYS RETURN TRUE FOR U.
X */
X
X#define e_boolean(etmp, func) (is_u(etmp)? (boolean)TRUE : func(etmp->emon))
X
X/*
X * e_strg is a utility routine which is not actually in use anywhere, since
X * the specialized routines below suffice for all current purposes.
X */
X
X/* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */
X
Xstatic char *
Xe_nam(etmp)
Xstruct entity *etmp;
X{
X return(is_u(etmp)? "you" : mon_nam(etmp->emon));
X}
X
X/*
X * Enam is another unused utility routine: E_phrase is preferable.
X */
X
X/*
Xstatic char *
XEnam(etmp)
Xstruct entity *etmp;
X{
X return(is_u(etmp)? "You" : Monnam(etmp->emon));
X}
X*/
X
X/*
X * Generates capitalized entity name, makes 2nd -> 3rd person conversion on
X * verb, where necessary.
X */
X
Xstatic char *
XE_phrase(etmp, verb)
Xstruct entity *etmp;
Xconst char *verb;
X{
X char wholebuf[80], verbbuf[30];
X
X if (is_u(etmp))
X Strcpy(wholebuf, "You");
X else
X Strcpy(wholebuf, Monnam(etmp->emon));
X if (!*verb)
X return(wholebuf);
X Strcat(wholebuf, " ");
X verbbuf[0] = '\0';
X if (is_u(etmp))
X Strcpy(verbbuf, verb);
X else {
X if (!strcmp(verb, "are"))
X Strcpy(verbbuf, "is");
X if (!strcmp(verb, "have"))
X Strcpy(verbbuf, "has");
X if (!verbbuf[0]) {
X Strcpy(verbbuf, verb);
X switch (verbbuf[strlen(verbbuf) - 1]) {
X case 'y':
X verbbuf[strlen(verbbuf) - 1] = '\0';
X Strcat(verbbuf, "ies");
X break;
X case 'h':
X case 'o':
X case 's':
X Strcat(verbbuf, "es");
X break;
X default:
X Strcat(verbbuf, "s");
X break;
X }
X }
X }
X Strcat(wholebuf, verbbuf);
X return(wholebuf);
X}
X
X/*
X * Simple-minded "can it be here?" routine
X */
X
Xstatic boolean
Xe_survives_at(etmp, x, y)
Xstruct entity *etmp;
Xint x, y;
X{
X if (noncorporeal(etmp->edata))
X return(TRUE);
X if (is_pool(x, y))
X return((is_u(etmp) && (Wwalking || Levitation)) ||
X is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||
X is_floater(etmp->edata));
X if (is_db_wall(x, y))
X return(passes_walls(etmp->edata));
X return(TRUE);
X}
X
Xstatic void
Xe_died(etmp, dest, how)
Xstruct entity *etmp;
Xint dest, how;
X{
X if (is_u(etmp)) {
X if (how == DROWNING)
X drown();
X else {
X coord xy;
X
X killer_format = KILLED_BY_AN;
X killer = "falling drawbridge";
X done(how);
X /* So, you didn't die */
X if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
X pline("A %s force teleports you away...",
X Hallucination ? "normal" : "strange");
X (void) enexto(&xy, etmp->ex, etmp->ey,
X etmp->edata);
X teleds(xy.x, xy.y);
X }
X }
X } else {
X xkilled(etmp->emon, dest);
X etmp->edata = (struct permonst *)0;
X }
X}
X
X
X/*
X * These are never directly affected by a bridge or portcullis.
X */
X
Xstatic boolean
Xautomiss(etmp)
Xstruct entity *etmp;
X{
X return(passes_walls(etmp->edata) || noncorporeal(etmp->edata));
X}
X
X/*
X * Does falling drawbridge or portcullis miss etmp?
X */
X
Xstatic boolean
Xe_missed(etmp, chunks)
Xstruct entity *etmp;
Xboolean chunks;
X{
X int misses;
X
X#ifdef D_DEBUG
X if (chunks)
X pline("Do chunks miss?");
X#endif
X if (automiss(etmp))
X return(TRUE);
X
X if (is_flyer(etmp->edata) &&
X (is_u(etmp)? !Sleeping :
X (etmp->emon->mcanmove && !etmp->emon->msleep)))
X /* flying requires mobility */
X misses = 5; /* out of 8 */
X else
X if (is_floater(etmp->edata) ||
X (is_u(etmp) && Levitation)) /* doesn't require mobility */
X misses = 3;
X else
X if (chunks && is_pool(etmp->ex, etmp->ey))
X misses = 2; /* sitting ducks */
X else
X misses = 0;
X
X if (is_db_wall(etmp->ex, etmp->ey))
X misses -= 3; /* less airspace */
X
X#ifdef D_DEBUG
X pline("Miss chance = %d (out of 8)", misses);
X#endif
X
X return((misses >= rnd(8))? TRUE : FALSE);
X}
X
X/*
X * Can etmp jump from death?
X */
X
Xstatic boolean
Xe_jumps(etmp)
Xstruct entity *etmp;
X{
X int tmp = 4; /* out of 10 */
X
X if (is_u(etmp)? (Sleeping || Fumbling) :
X (!etmp->emon->mcanmove || etmp->emon->msleep ||
X !etmp->edata->mmove))
X return(FALSE);
X
X if (is_u(etmp)? Confusion : etmp->emon->mconf)
X tmp -= 2;
X
X if (is_u(etmp)? Stunned : etmp->emon->mstun)
X tmp -= 3;
X
X if (is_db_wall(etmp->ex, etmp->ey))
X tmp -= 2; /* less room to maneuver */
X
X#ifdef D_DEBUG
X pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp);
X#endif
X return((tmp >= rnd(10))? TRUE : FALSE);
X}
X
Xstatic void
Xdo_entity(etmp)
Xstruct entity *etmp;
X{
X int newx, newy, at_portcullis, oldx, oldy;
X boolean must_jump = FALSE, relocates = FALSE, e_inview;
X struct rm *crm;
X
X if (!etmp->edata)
X return;
X
X e_inview = e_boolean(etmp, canseemon);
X
X oldx = etmp->ex;
X oldy = etmp->ey;
X
X at_portcullis = is_db_wall(oldx, oldy);
X
X crm = &levl[oldx][oldy];
X
X if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
X char edifice[20];
X
X if (e_inview) {
X *edifice = '\0';
X if ((crm->typ == DRAWBRIDGE_DOWN) ||
X (crm->typ == DRAWBRIDGE_UP))
X Strcpy(edifice, "drawbridge");
X else
X if (at_portcullis)
X Strcpy(edifice, "portcullis");
X if (*edifice)
X pline("The %s passes through %s!", edifice,
X e_nam(etmp));
X }
X return;
X }
X if (e_missed(etmp, FALSE)) {
X if (at_portcullis)
X pline("The portcullis misses %s!",
X e_nam(etmp));
X#ifdef D_DEBUG
X else
X pline("The drawbridge misses %s!",
X e_nam(etmp));
X#endif
X if (e_survives_at(etmp, oldx, oldy))
X return;
X else {
X#ifdef D_DEBUG
X pline("Mon can't survive here");
X#endif
X if (at_portcullis)
X must_jump = TRUE;
X else
X relocates = TRUE; /* just ride drawbridge in */
X }
X } else {
X if (crm->typ == DRAWBRIDGE_DOWN) {
X pline("%s crushed underneath the drawbridge.",
X E_phrase(etmp, "are")); /* no jump */
X e_died(etmp, e_inview? 2 : 3, CRUSHING); /* no corpse */
X return; /* Note: Beyond this point, we know we're */
X } /* not at an opened drawbridge, since all */
X must_jump = TRUE; /* *missable* creatures survive on the */
X } /* square, and all the unmissed ones die. */
X if (must_jump)
X if (at_portcullis) {
X if (e_jumps(etmp)) {
X relocates = TRUE;
X#ifdef D_DEBUG
X pline("Jump succeeds!");
X#endif
X } else {
X if (e_inview)
X pline("%s crushed by the falling portcullis!",
X E_phrase(etmp, "are"));
X else
X if (flags.soundok)
X You("hear a crushing sound.");
X e_died(etmp, e_inview? 1 : 0, CRUSHING);
X /* corpse */
X return;
X }
X } else { /* tries to jump off bridge to original square */
X relocates = !e_jumps(etmp);
X#ifdef D_DEBUG
X pline("Jump %s!", (relocates)? "fails" : "succeeds");
X#endif
X }
X
X/*
X * Here's where we try to do relocation. Assumes that etmp is not arriving
X * at the portcullis square while the drawbridge is falling, since this square
X * would be inaccessible (i.e. etmp started on drawbridge square) or
X * unnecessary (i.e. etmp started here) in such a situation.
X */
X#ifdef D_DEBUG
X pline("Doing relocation");
X#endif
X newx = oldx;
X newy = oldy;
X (void)find_drawbridge(&newx, &newy);
X if ((newx == oldx) && (newy == oldy))
X get_wall_for_db(&newx, &newy);
X#ifdef D_DEBUG
X pline("Checking new square for occupancy");
X#endif
X if (relocates && (e_at(newx, newy))) {
X
X/*
X * Standoff problem: one or both entities must die, and/or both switch
X * places. Avoid infinite recursion by checking first whether the other
X * entity is staying put. Clean up if we happen to move/die in recursion.
X */
X struct entity *other;
X
X other = e_at(newx, newy);
X#ifdef D_DEBUG
X pline("New square is occupied by %s", e_nam(other));
X#endif
X if (e_survives_at(other, newx, newy) && automiss(other)) {
X relocates = FALSE; /* "other" won't budge */
X#ifdef D_DEBUG
X pline("%s suicide.", E_phrase(etmp, "commit"));
X#endif
X } else {
X
X#ifdef D_DEBUG
X pline("Handling %s", e_nam(other));
X#endif
X while ((e_at(newx, newy)) &&
X (e_at(newx, newy) != etmp))
X do_entity(other);
X#ifdef D_DEBUG
X pline("Checking existence of %s",
X e_nam(etmp));
X fflush(stdout);
X#endif
X if (e_at(oldx, oldy) != etmp) {
X#ifdef D_DEBUG
X pline("%s moved or died in recursion somewhere",
X E_phrase(etmp, "have"));
X fflush(stdout);
X#endif
X return;
X }
X }
X }
X if (relocates) {
X#ifdef D_DEBUG
X pline("Moving %s", e_nam(etmp));
X#endif
X if (!is_u(etmp)) {
X remove_monster(etmp->ex, etmp->ey);
X place_monster(etmp->emon, newx, newy);
X } else {
X u.ux = newx;
X u.uy = newy;
X }
X etmp->ex = newx;
X etmp->ey = newy;
X e_inview = e_boolean(etmp, canseemon);
X }
X#ifdef D_DEBUG
X pline("Final disposition of %s", e_nam(etmp));
X fflush(stdout);
X#endif
X if (is_db_wall(etmp->ex, etmp->ey)) {
X#ifdef D_DEBUG
X pline("%s in portcullis chamber", E_phrase(etmp, "are"));
X fflush(stdout);
X#endif
X if (e_inview)
X if (is_u(etmp)) {
X You("tumble towards the closed portcullis!");
X if (automiss(etmp))
X You("pass through it!");
X else
X pline("The drawbridge closes in...");
X } else
X pline("%s behind the drawbridge.",
X E_phrase(etmp, "disappear"));
X if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
X killer_format = KILLED_BY_AN;
X killer = "closing drawbridge";
X e_died(etmp, 0, CRUSHING); /* no message */
X return;
X }
X#ifdef D_DEBUG
X pline("%s in here", E_phrase(etmp, "survive"));
X#endif
X } else {
X#ifdef D_DEBUG
X pline("%s on drawbridge square", E_phrase(etmp, "are"));
X#endif
X if (is_pool(etmp->ex, etmp->ey) && !e_inview)
X if (flags.soundok)
X You("hear a splash.");
X if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
X if (e_inview && !is_flyer(etmp->edata) &&
X !is_floater(etmp->edata))
X pline("%s from the bridge.",
X E_phrase(etmp, "fall"));
X return;
X }
X#ifdef D_DEBUG
X pline("%s cannot survive on the drawbridge square", Enam(etmp));
X#endif
X if (is_pool(etmp->ex, etmp->ey))
X if (e_inview &&
X !is_u(etmp)) /* drown() will supply msgs if nec. */
X if (Hallucination)
X pline("%s the moat and disappears.",
X E_phrase(etmp, "drink"));
X else
X pline("%s into the moat.",
X E_phrase(etmp, "fall"));
X killer_format = NO_KILLER_PREFIX;
X killer = "fell from a drawbridge";
X e_died(etmp, e_inview? 1 : 0, /* CRUSHING is arbitrary */
X (is_pool(etmp->ex, etmp->ey))? DROWNING : CRUSHING);
X /* corpse */
X return;
X }
X}
X
X/*
X * Close the drawbridge located at x,y
X */
X
Xvoid
Xclose_drawbridge(x,y)
Xint x,y;
X{
X register struct rm *lev1, *lev2;
X struct obj *otmp, *otmp2;
X int x2, y2;
X
X lev1 = &levl[x][y];
X if (lev1->typ != DRAWBRIDGE_DOWN) return;
X x2 = x; y2 = y;
X get_wall_for_db(&x2,&y2);
X if (cansee(x,y)) /* change msgs if you are a w-walker at portcullis */
X You("see a drawbridge %s up!",
X ((u.ux == x2) && (u.uy == y2))? "coming" : "going");
X lev1->typ = DRAWBRIDGE_UP;
X lev2 = &levl[x2][y2];
X switch (lev1->drawbridgemask & DB_DIR) {
X case DB_NORTH:
X case DB_SOUTH:
X lev2->typ = HWALL;
X break;
X case DB_WEST:
X case DB_EAST:
X lev2->typ = VWALL;
X break;
X }
X lev2->diggable = (W_NONDIGGABLE | W_GATEWAY);
X set_entity(x, y, &(occupants[0]));
X set_entity(x2, y2, &(occupants[1]));
X do_entity(&(occupants[0]));
X do_entity(&(occupants[1]));
X redosym(x, y);
X for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
X otmp2 = otmp->nexthere;
X delobj(otmp);
X }
X for (otmp = level.objects[x2][y2]; otmp; otmp = otmp2) {
X otmp2 = otmp->nexthere;
X delobj(otmp);
X }
X redosym(x2, y2);
X}
X
X/*
X * Open the drawbridge located at x,y
X */
X
Xvoid
Xopen_drawbridge(x,y)
Xint x,y;
X{
X register struct rm *lev1, *lev2;
X int x2, y2;
X
X lev1 = &levl[x][y];
X if (lev1->typ != DRAWBRIDGE_UP) return;
X x2 = x; y2 = y;
X get_wall_for_db(&x2,&y2);
X if (cansee(x,y)) /* change msgs if you are a w-walker at portcullis */
X You("see a drawbridge %s down!",
X ((x2 == u.ux) && (y2 == u.uy))? "going" : "coming");
X lev1->typ = DRAWBRIDGE_DOWN;
X lev2 = &levl[x2][y2];
X lev2->typ = DOOR;
X lev2->doormask = D_NODOOR;
X set_entity(x, y, &(occupants[0]));
X set_entity(x2, y2, &(occupants[1]));
X do_entity(&(occupants[0]));
X do_entity(&(occupants[1]));
X redosym(x, y);
X redosym(x2, y2);
X}
X
X/*
X * Let's destroy the drawbridge located at x,y
X */
X
Xvoid
Xdestroy_drawbridge(x,y)
Xint x,y;
X{
X register struct rm *lev1, *lev2;
X int x2, y2;
X boolean e_inview;
X struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);
X
X lev1 = &levl[x][y];
X if (!IS_DRAWBRIDGE(lev1->typ))
X return;
X x2 = x; y2 = y;
X get_wall_for_db(&x2,&y2);
X lev2 = &levl[x2][y2];
X if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) {
X if (lev1->typ == DRAWBRIDGE_UP) {
X if (cansee(x2,y2))
X pline("The portcullis of the drawbridge falls into the moat!");
X else if (flags.soundok)
X You("hear a loud *SPLASH*!");
X } else {
X if (cansee(x,y))
X pline("The drawbridge collapses into the moat!");
X else if (flags.soundok)
X You("hear a loud *SPLASH*!");
X }
X lev1->typ = MOAT;
X lev1->drawbridgemask = 0;
X } else {
X if (cansee(x,y))
X pline("The drawbridge disintegrates!");
X else
X You("hear a loud *CRASH*!");
X lev1->typ = ROOM;
X lev1->icedpool =
X ((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
X }
X set_entity(x2, y2, etmp2); /* currently, only automissers can be here */
X if (etmp2->edata) {
X e_inview = e_boolean(etmp2, canseemon);
X if (!automiss(etmp2)) { /* i.e. no-one yet */
X if (e_inview)
X pline("%s blown apart by flying debris",
X E_phrase(etmp2, "are"));
X killer_format = KILLED_BY_AN;
X killer = "exploding drawbridge";
X e_died(etmp2, e_inview? 2 : 3, CRUSHING);/* no corpse */
X } /* nothing which is vulnerable can survive this */
X }
X lev2->typ = DOOR;
X lev2->doormask = D_NODOOR;
X set_entity(x, y, etmp1);
X if (etmp1->edata) {
X e_inview = e_boolean(etmp1, canseemon);
X if (e_missed(etmp1, TRUE)) {
X#ifdef D_DEBUG
X pline("%s spared!", E_phrase(etmp1, "are"));
X#endif
X } else {
X if (e_inview)
X if (!is_u(etmp1) && Hallucination)
X pline("%s into some heavy metal",
X E_phrase(etmp1, "get"));
X else
X pline("%s hit by a huge chunk of metal!",
X E_phrase(etmp1, "are"));
X else
X if (flags.soundok && !is_u(etmp1) &&
X !is_pool(x, y))
X You("hear a crushing sound");
X#ifdef D_DEBUG
X else
X pline("%s from shrapnel",
X E_phrase(etmp1, "die"));
X#endif
X killer_format = KILLED_BY_AN;
X killer = "collapsing drawbridge";
X e_died(etmp1, e_inview? 0 : 1, CRUSHING); /* corpse */
X }
X }
X redosym(x,y);
X redosym(x2,y2);
X}
X
X
X#endif /* OVLB */
X
X#endif /* STRONGHOLD /**/
END_OF_FILE
if test 20980 -ne `wc -c <'src/dbridge.c'`; then
echo shar: \"'src/dbridge.c'\" unpacked with wrong size!
fi
# end of 'src/dbridge.c'
fi
if test -f 'src/pager.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/pager.c'\"
else
echo shar: Extracting \"'src/pager.c'\" \(28788 characters\)
sed "s/^X//" >'src/pager.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)pager.c 3.0 89/11/19
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X/* This file contains the command routine dowhatis() and a pager. */
X/* Also readmail() and doshell(), and generally the things that
X contact the outside world. */
X
X#define MONATTK_H /* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include "hack.h"
X
X#include <ctype.h>
X#ifndef NO_SIGNAL
X#include <signal.h>
X#endif
X#if defined(BSD) || defined(ULTRIX)
X#include <sys/wait.h>
X#endif
X#ifdef MACOS
Xextern WindowPtr HackWindow;
Xextern short macflags;
X#endif
X
X#ifndef SEEK_SET
X#define SEEK_SET 0
X#endif
X
XSTATIC_DCL boolean FDECL(clear_help, (CHAR_P));
XSTATIC_DCL boolean FDECL(valid_help, (CHAR_P));
X
X#ifndef OVLB
XSTATIC_DCL char hc;
X#else /* OVLB */
XSTATIC_OVL char NEARDATA hc = 0;
X
Xstatic void FDECL(page_more, (FILE *,int));
Xstatic boolean FDECL(is_swallow_sym, (UCHAR_P));
Xstatic boolean FDECL(pmatch,(const char *,const char *));
Xstatic boolean FDECL(outspec,(const char *,int));
Xstatic const char *FDECL(lookat,(int,int,UCHAR_P));
X#ifdef WIZARD
Xstatic void NDECL(wiz_help);
X#endif
Xstatic void NDECL(help_menu);
X
X/*
X * simple pattern matcher: '*' matches 0 or more characters
X * returns TRUE if strng matches patrn
X */
X
Xstatic boolean
Xpmatch(patrn, strng)
X const char *patrn, *strng;
X{
X char s, p;
X
X s = *strng;
X p = *patrn;
X
X if (!p) {
X return (s == 0);
X }
X
X if (p == '*') {
X if (!patrn[1] || pmatch(patrn+1, strng)) {
X return TRUE;
X }
X return (s ? pmatch(patrn, strng+1) : FALSE);
X }
X
X return (p == s) ? pmatch(patrn+1, strng+1) : FALSE;
X}
X
X/*
X * returns "true" for characters that could represent a monster's stomach
X */
X
Xstatic boolean
Xis_swallow_sym(c)
Xuchar c;
X{
X return (index(" /-\\|", (char)c) != 0);
X}
X
X/*
X * print out another possibility for dowhatis. "new" is the possible new
X * string; "out_flag" indicates whether we really want output, and if
X * so what kind of output: 0 == no output, 1 == "(or %s)" output.
X * Returns TRUE if this new string wasn't the last string printed.
X */
X
Xstatic boolean
Xoutspec(new, out_flag)
Xconst char *new;
Xint out_flag;
X{
X static char NEARDATA old[50];
X
X if (!strcmp(old, new))
X return FALSE; /* don't print the same thing twice */
X
X if (out_flag)
X pline("(or %s)", an(new));
X
X Strcpy(old, new);
X return 1;
X}
X
X/*
X * return the name of the character ch found at (x,y)
X */
X
Xstatic
Xconst char *
Xlookat(x, y, ch)
Xint x,y;
Xuchar ch;
X{
X register struct monst *mtmp;
X register struct obj *otmp;
X struct trap *trap;
X static char NEARDATA answer[50];
X register char *s, *t;
X uchar typ;
X
X answer[0] = 0;
X
X if(MON_AT(x,y)) {
X mtmp = m_at(x,y);
X if (!showmon(mtmp) || Hallucination)
X mtmp = (struct monst *)0;
X } else
X mtmp = (struct monst *) 0;
X typ = levl[x][y].typ;
X if (!Invisible
X#ifdef POLYSELF
X && !u.uundetected
X#endif
X && u.ux==x && u.uy==y) {
X Sprintf(answer, "%s named %s",
X#ifdef POLYSELF
X u.mtimedone ? mons[u.umonnum].mname :
X#endif
X pl_character, plname);
X } else if (u.uswallow && is_swallow_sym(ch)) {
X Sprintf(answer, "interior of %s", defmonnam(u.ustuck));
X } else if (mtmp && !mtmp->mimic)
X Sprintf(answer, "%s%s",
X mtmp->mtame ? "tame " :
X mtmp->mpeaceful ? "peaceful " : "",
X strncmp(lmonnam(mtmp), "the ", 4)
X ? lmonnam(mtmp) : lmonnam(mtmp)+4);
X else if (!levl[x][y].seen)
X Strcpy(answer,"dark part of a room");
X else if (mtmp && mtmp->mimic) {
X if (mtmp->m_ap_type == M_AP_FURNITURE) {
X if (mtmp->mappearance == S_altar)
X Strcpy(answer, "neutral altar");
X else
X Strcpy(answer, explainsyms[mtmp->mappearance]);
X }
X else if (mtmp->m_ap_type == M_AP_OBJECT) {
X if (mtmp->mappearance == STRANGE_OBJECT)
X Strcpy(answer, "strange object");
X else {
X int oindx = mtmp->mappearance;
X otmp = mksobj(oindx,FALSE );
X if(oindx == STATUE || oindx == FIGURINE)
X otmp->corpsenm = PM_KOBOLD;
X else if (oindx == DRAGON_SCALE_MAIL)
X otmp->corpsenm = PM_RED_DRAGON;
X Strcpy(answer, distant_name(otmp, xname));
X free((genericptr_t) otmp);
X }
X }
X else if (mtmp->m_ap_type == M_AP_GOLD)
X Strcpy(answer, "pile of gold");
X }
X else if (OBJ_AT(x, y)) {
X otmp = level.objects[x][y];
X Strcpy(answer, distant_name(otmp, xname));
X }
X else if (ch == GOLD_SYM) {
X Strcpy(answer, "pile of gold");
X }
X#ifdef ALTARS
X else if (ch == ALTAR_SYM && IS_ALTAR(typ)) {
X int kind = levl[x][y].altarmask & ~A_SHRINE;
X Sprintf( answer, "%s altar",
X (kind == A_CHAOS) ? "chaotic" :
X (kind == A_NEUTRAL) ? "neutral" :
X "lawful" );
X }
X#endif
X#ifdef STRONGHOLD
X else if ((ch == DB_VWALL_SYM || ch == DB_HWALL_SYM) && is_db_wall(x,y))
X Strcpy(answer,"raised drawbridge");
X#endif
X#ifdef THRONES
X else if ((ch == THRONE_SYM) && IS_THRONE(typ))
X Strcpy(answer, "throne");
X#endif
X else if ( (ch==H_OPEN_DOOR_SYM ||
X ch==V_OPEN_DOOR_SYM ||
X ch==CLOSED_DOOR_SYM ||
X ch==NO_DOOR_SYM) &&
X IS_DOOR(typ) ) {
X switch(levl[x][y].doormask & ~D_TRAPPED) {
X case D_NODOOR: Strcpy(answer,"doorway"); break;
X case D_BROKEN: Strcpy(answer,"broken door"); break;
X case D_ISOPEN: Strcpy(answer,"open door"); break;
X default: Strcpy(answer,"closed door"); break;
X /* locked or not */
X }
X }
X#ifdef SINKS
X else if (ch == SINK_SYM && IS_SINK(levl[x][y].typ))
X Strcpy(answer,"sink");
X#endif
X else if ((ch == TRAP_SYM || ch == WEB_SYM) && (trap = t_at(x, y))) {
X if (trap->ttyp == WEB && ch == WEB_SYM)
X Strcpy(answer, "web");
X else if (trap->ttyp != MONST_TRAP && ch == TRAP_SYM) {
X Strcpy(answer, traps[ Hallucination ?
X rn2(TRAPNUM-3)+3 : trap->ttyp]);
X /* strip leading garbage */
X for (s = answer; *s && *s != ' '; s++) ;
X if (*s) ++s;
X for (t = answer; *t++ = *s++; ) ;
X }
X }
X else if (ch == UP_SYM && x == xupstair && y == yupstair)
X Strcpy(answer, "staircase up");
X else if (ch == DN_SYM && x == xdnstair && y == ydnstair)
X Strcpy(answer, "staircase down");
X#ifdef STRONGHOLD
X else if (ch == UPLADDER_SYM && x && x == xupladder && y == ydnladder)
X Strcpy(answer, "ladder up");
X else if (ch == DNLADDER_SYM && x && x == xdnladder && y == ydnladder)
X Strcpy(answer, "ladder down");
X#endif
X else if (IS_ROOM(typ)) {
X if (ch == ROOM_SYM) {
X if (levl[x][y].icedpool)
X Strcpy(answer,"iced pool");
X else
X Strcpy(answer,"floor of a room");
X }
X else if (ch == STONE_SYM || ch == ' ')
X Strcpy(answer,"dark part of a room");
X }
X else if (ch == CORR_SYM && SPACE_POS(typ))
X Strcpy(answer,"corridor");
X else if (!ACCESSIBLE(typ)) {
X if (ch == STONE_SYM || ch == ' ')
X Strcpy(answer,"dark part of a room");
X else
X Strcpy(answer,"wall");
X }
X return answer;
X}
X
X
Xint
Xdowhatis()
X{
X FILE *fp;
X char buf[BUFSZ], inpbuf[BUFSZ];
X register char *ep, *inp = inpbuf;
X char *alt = 0; /* alternate description */
X#ifdef __GNULINT__
X const char *firstmatch = 0;
X#else
X const char *firstmatch;
X#endif
X uchar q;
X register int i;
X coord cc;
X boolean oldverb = flags.verbose;
X boolean found_in_file = FALSE, need_to_print = FALSE;
X int found = 0;
X static const char *mon_interior = "the interior of a monster";
X
X#ifdef OS2_CODEVIEW
X char tmp[PATHLEN];
X
X Strcpy(tmp,hackdir);
X append_slash(tmp);
X Strcat(tmp,DATAFILE);
X fp = fopen(tmp,"r"));
X#else
X fp = fopen(DATAFILE, "r");
X#endif
X if(!fp) {
X#ifdef MACOS
X fp = openFile(DATAFILE, "r");
X }
X if (!fp) {
X#endif
X pline("Cannot open data file!");
X return 0;
X }
X
X pline ("Specify unknown object by cursor? ");
X q = ynq();
X if (q == 'q') {
X (void) fclose(fp);
X return 0;
X } else if (q == 'n') {
X cc.x = cc.y = -1;
X pline("Specify what? (type the word) ");
X getlin(inp);
X if (inp[0] == '\033' || !inp[0]) {
X (void)fclose(fp);
X return 0;
X }
X if (!inp[1])
X q = inp[0];
X else
X q = 0;
X } else {
X cc.x = u.ux;
X cc.y = u.uy;
Xselobj:
X need_to_print = found_in_file = FALSE;
X found = 0;
X inp = inpbuf;
X alt = 0;
X (void) outspec("", 0); /* reset output */
X if(flags.verbose)
X pline("Please move the cursor to an unknown object.");
X else
X pline("Pick an object.");
X getpos(&cc, FALSE, "an unknown object");
X if (cc.x < 0) {
X (void) fclose(fp); /* sweet@scubed */
X flags.verbose = oldverb;
X return 0;
X }
X flags.verbose = FALSE;
X if (!u.uswallow) {
X q = levl[cc.x][cc.y].scrsym;
X if (!q || (!levl[cc.x][cc.y].seen && !MON_AT(cc.x,cc.y)))
X q = ' ';
X }
X else if (cc.x == u.ux && cc.y == u.uy)
X q = u.usym;
X else {
X i = (u.uy - cc.y)+1;
X if (i < 0 || i > 2)
X q = ' ';
X else {
X firstmatch = (i == 0) ? "/-\\" :
X (i == 1) ? "| |" : "\\-/";
X i = (u.ux - cc.x)+1;
X if (i < 0 || i > 2)
X q = ' ';
X else
X q = firstmatch[i];
X }
X }
X }
X
X if (!q)
X goto checkfile; /* user typed in a complete string */
X
X if (q != ' ' && index(quitchars, (char)q)) {
X (void) fclose(fp); /* sweet@scubed */
X flags.verbose = oldverb;
X return 0;
X }
X/*
X * if the user just typed one letter, or we're identifying from the
X * screen, then we have to check all the possibilities and print them
X * out for him/her.
X */
X
X/* Check for monsters */
X for (i = 0; monsyms[i]; i++) {
X if (q == monsyms[i]) {
X need_to_print = TRUE;
X pline("%c %s",q,an(monexplain[i]));
X (void) outspec(firstmatch = monexplain[i], 0);
X found++;
X break;
X }
X }
X
X/* Special case: if identifying from the screen, and
X * we're swallowed, and looking at something other than our own symbol,
X * then just say "the interior of a monster".
X */
X if (u.uswallow && is_swallow_sym(q)) {
X if (!found) {
X pline("%c %s", q, mon_interior);
X (void)outspec(firstmatch=mon_interior, 0);
X }
X else
X (void)outspec(mon_interior, 1);
X found++; need_to_print = TRUE;
X }
X
X/* Now check for objects */
X for (i = 0; objsyms[i]; i++) {
X if (q == objsyms[i]) {
X need_to_print = TRUE;
X if (!found) {
X pline("%c %s",q,an(objexplain[i]));
X (void)outspec(firstmatch = objexplain[i], 0);
X found++;
X }
X else if (outspec(objexplain[i], 1))
X found++;
X }
X }
X
X/* Now check for graphics symbols */
X for (i = 0; i < MAXPCHARS; i++) {
X if ( q == showsyms[i] && (*explainsyms[i])) {
X if (!found) {
X pline("%c %s",q,an(explainsyms[i]));
X (void)outspec(firstmatch = explainsyms[i], 0);
X found++;
X }
X else if (outspec(explainsyms[i], 1))
X found++;
X if (i == S_altar || i == S_trap || i == S_web)
X need_to_print = TRUE;
X }
X }
X
X if (!found)
X pline("I've never heard of such things.");
X else if (cc.x != -1) { /* a specific object on screen */
X if (found > 1 || need_to_print) {
X Strcpy(inp, lookat(cc.x, cc.y, q));
X if (*inp)
X pline("(%s)", inp);
X }
X else {
X Strcpy(inp, firstmatch);
X }
X }
X else if (found == 1) {
X Strcpy(inp, firstmatch);
X }
X else
X found = FALSE; /* abort the 'More info?' stuff */
X
X/* check the data file for information about this thing */
X
Xcheckfile:
X
X if (!strncmp(inp, "interior of ", 12))
X inp += 12;
X if (!strncmp(inp, "a ", 2))
X inp += 2;
X else if (!strncmp(inp, "an ", 3))
X inp += 3;
X else if (!strncmp(inp, "the ", 4))
X inp += 4;
X if (!strncmp(inp, "tame ", 5))
X inp += 5;
X else if (!strncmp(inp, "peaceful ", 9))
X inp += 9;
X if (!strncmp(inp, "invisible ", 10))
X inp += 10;
X
X/*
X * look in the file for more info if:
X * the user typed in the whole name (!q)
X * OR we've found a possible match with the character q (found) and
X * flags.help is TRUE
X * and, of course, the name to look for must be non-empty.
X */
X if ((!q || (found && flags.help)) && *inp) {
X/* adjust the input to remove "named " and convert to lower case */
X for (ep = inp; *ep; ) {
X if ((!strncmp(ep, " named ", 7) && (alt = ep + 7)) ||
X !strncmp(ep, " called ", 8))
X *ep = 0;
X else {
X if(isupper(*ep)) *ep = tolower(*ep);
X ep++;
X }
X }
X
X/*
X * If the object is named, then the name is the alternate search string;
X * otherwise, the result of makesingular() applied to the name is. This
X * isn't strictly optimal, but named objects of interest to the user
X * will usually be found under their name, rather than under their
X * object type, so looking for a singular form is pointless.
X */
X
X if (!alt)
X alt = makesingular(inp);
X else
X for (ep = alt; *ep; ep++)
X if(isupper(*ep)) *ep = tolower(*ep);
X
X while(fgets(buf,BUFSZ,fp)) {
X if(*buf != '\t') {
X ep = index(buf, '\n');
X if(ep) *ep = 0;
X else impossible("bad data file");
X if (pmatch(buf, inp)||(alt && pmatch(buf, alt))) {
X found_in_file = TRUE;
X break;
X }
X }
X }
X }
X
X if(found_in_file) {
X/* skip over other possible matches for the info */
X for(;;) {
X if ( (i = getc(fp)) == '\t' ) {
X (void) ungetc(i, fp);
X break;
X }
X if (!fgets(buf, BUFSZ, fp)) {
X break;
X }
X }
X if (q) {
X pline("More info? ");
X if(yn() == 'y') {
X page_more(fp,1); /* does fclose() */
X flags.verbose = oldverb;
X return 0;
X }
X }
X else {
X page_more(fp, 1);
X flags.verbose = oldverb;
X return 0;
X }
X }
X else if (!q)
X pline("I don't have any information on those things.");
X
X/* if specified by cursor, keep going */
X if(cc.x != -1) {
X more();
X rewind(fp);
X goto selobj;
X }
X (void) fclose(fp); /* kopper@psuvax1 */
X flags.verbose = oldverb;
X return 0;
X}
X
Xint
Xdowhatdoes()
X{
X FILE *fp;
X char bufr[BUFSZ+6];
X register char *buf = &bufr[6], *ep, q, ctrl, meta;
X#ifdef OS2_CODEVIEW
X char tmp[PATHLEN];
X
X Strcpy(tmp,hackdir);
X append_slash(tmp);
X Strcat(tmp,CMDHELPFILE);
X if(!(fp = fopen(tmp,"r"))) {
X#else
X# ifdef MACOS
X if(!(fp = fopen(CMDHELPFILE, "r")))
X fp = openFile(CMDHELPFILE, "r");
X if (!fp) {
X# else
X if(!(fp = fopen(CMDHELPFILE, "r"))) {
X# endif
X#endif
X pline("Cannot open data file!");
X return 0;
X }
X
X pline("What command? ");
X#if defined(UNIX) || defined(VMS)
X introff();
X#endif
X q = readchar();
X#if defined(UNIX) || defined(VMS)
X intron();
X#endif
X ctrl = ((q <= '\033') ? (q - 1 + 'A') : 0);
X meta = ((0x80 & q) ? (0x7f & q) : 0);
X while(fgets(buf,BUFSZ,fp))
X if ((ctrl && *buf=='^' && *(buf+1)==ctrl) ||
X (meta && *buf=='M' && *(buf+1)=='-' && *(buf+2)==meta) ||
X *buf==q) {
X ep = index(buf, '\n');
X if(ep) *ep = 0;
X if (ctrl && buf[2] == '\t'){
X buf = bufr + 1;
X (void) strncpy(buf, "^? ", 8);
X buf[1] = ctrl;
X } else if (meta && buf[3] == '\t'){
X buf = bufr + 2;
X (void) strncpy(buf, "M-? ", 8);
X buf[2] = meta;
X } else if(buf[1] == '\t'){
X buf = bufr;
X buf[0] = q;
X (void) strncpy(buf+1, " ", 7);
X }
X pline("%s", buf);
X (void) fclose(fp);
X return 0;
X }
X pline("I've never heard of such commands.");
X (void) fclose(fp);
X return 0;
X}
X
X/* make the paging of a file interruptible */
Xstatic volatile int NEARDATA got_intrup;
X
X#if !defined(MSDOS) && !defined(TOS) && !defined(MACOS)
Xstatic int
Xintruph(){
X (void) signal(SIGINT, (SIG_RET_TYPE) intruph);
X got_intrup++;
X return 0;
X}
X#endif
X
X/* simple pager, also used from dohelp() */
Xstatic void
Xpage_more(fp,strip)
XFILE *fp;
Xint strip; /* nr of chars to be stripped from each line (0 or 1) */
X{
X#ifdef MACOS
X short tmpflags;
X
X tmpflags = macflags;
X macflags &= ~fDoUpdate;
X if(!mac_more(fp, strip)) {
X macflags |= (tmpflags & fDoUpdate);
X return;
X }
X macflags |= (tmpflags & fDoUpdate);
X#else
X register char *bufr;
X#if !defined(MSDOS) && !defined(MINIMAL_TERM)
X register char *ep;
X#endif
X#if !defined(MSDOS) && !defined(TOS)
X int (*prevsig)() = (int (*)())signal(SIGINT, (SIG_RET_TYPE) intruph);
X#endif
X#if defined(MSDOS) || defined(MINIMAL_TERM)
X /* There seems to be a bug in ANSI.SYS The first tab character
X * after a clear screen sequence is not expanded correctly. Thus
X * expand the tabs by hand -dgk
X */
X int tabstop = 8, spaces;
X char buf[BUFSIZ], *bufp, *bufrp;
X
X set_pager(0);
X bufr = (char *) alloc((unsigned) COLNO);
X while (fgets(buf, BUFSIZ, fp) && (!strip || *buf == '\t')){
X bufp = buf;
X bufrp = bufr;
X if (strip && *bufp && *bufp != '\n')
X *bufrp++ = *bufp++;
X while (*bufp && *bufp != '\n') {
X if (*bufp == '\t') {
X spaces = tabstop - (bufrp - bufr) % tabstop;
X while (spaces--)
X *bufrp++ = ' ';
X bufp++;
X } else
X *bufrp++ = *bufp++;
X }
X *bufrp = '\0';
X#else /* MSDOS /**/
X set_pager(0);
X bufr = (char *) alloc((unsigned) COLNO);
X bufr[COLNO-1] = 0;
X while(fgets(bufr,COLNO-1,fp) && (!strip || *bufr == '\t')){
X ep = index(bufr, '\n');
X if(ep)
X *ep = 0;
X#endif /* MSDOS /**/
X if(got_intrup || page_line(bufr+strip)) {
X set_pager(2);
X goto ret;
X }
X }
X set_pager(1);
Xret:
X free((genericptr_t) bufr);
X (void) fclose(fp);
X#if !defined(MSDOS) && !defined(TOS)
X (void) signal(SIGINT, (SIG_RET_TYPE) prevsig);
X got_intrup = 0;
X#endif
X#endif /* MACOS */
X}
X
X#endif /* OVLB */
X
X#define PAGMIN 12 /* minimum # of lines for page below level map */
X
X#ifndef OVLB
X
XSTATIC_DCL boolean whole_screen;
X
X#else /* OVLB */
X
XSTATIC_OVL boolean NEARDATA whole_screen = TRUE;
X
Xvoid
Xset_whole_screen() { /* called in termcap as soon as LI is known */
X whole_screen = (LI-ROWNO-2 <= PAGMIN || !CD);
X}
X
X#ifdef NEWS
Xint
Xreadnews() {
X register int ret;
X
X whole_screen = TRUE; /* force a docrt(), our first */
X ret = page_file(NEWS, TRUE);
X set_whole_screen();
X return(ret); /* report whether we did docrt() */
X}
X#endif
X
Xvoid
Xset_pager(mode)
Xregister int mode; /* 0: open 1: wait+close 2: close */
X{
X#ifdef LINT /* lint may handle static decl poorly -- static boolean so; */
X boolean so;
X#else
X static boolean NEARDATA so;
X#endif
X if(mode == 0) {
X if(!whole_screen) {
X /* clear topline */
X clrlin();
X /* use part of screen below level map */
X curs(1, ROWNO+4);
X } else {
X cls();
X }
X so = flags.standout;
X flags.standout = 1;
X } else {
X if(mode == 1) {
X curs(1, LI);
X more();
X }
X flags.standout = so;
X if(whole_screen)
X docrt();
X else {
X curs(1, ROWNO+4);
X cl_eos();
X }
X }
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xint
Xpage_line(s) /* returns 1 if we should quit */
Xregister const char *s;
X{
X#ifdef CLIPPING
X/* we assume here that no data files have more than 80 chars/line */
X static char tmp[81], *t;
X#endif
X if(cury == LI-1) {
X if(!*s)
X return(0); /* suppress blank lines at top */
X (void) putchar('\n');
X cury++;
X cmore("q\033");
X if(morc) {
X morc = 0;
X return(1);
X }
X if(whole_screen)
X cls();
X else {
X curs(1, ROWNO+4);
X cl_eos();
X }
X }
X#ifdef CLIPPING
X/* if lines are too long for the screen, first try stripping leading blanks */
X if (strlen(s) >= CO) {
X while (*s == ' ' || *s == '\t') s++;
X }
X
X/* if it's still too long, try compressing blanks */
X if (strlen(s) >= CO) {
X t = tmp;
X while ( (*t = *s) != 0) {
X if (*t == ' ') {
X while (*s == ' ')
X s++;
X }
X else
X s++;
X t++;
X }
X s = tmp;
X }
X#endif /* CLIPPING */
X
X#ifdef TERMINFO
X xputs(s); xputc('\n');
X#else
X (void) puts(s);
X# ifdef MACOS
X (void) putchar('\n');
X# endif
X#endif
X cury++;
X return(0);
X}
X
X/*
X * Flexible pager: feed it with a number of lines and it will decide
X * whether these should be fed to the pager above, or displayed in a
X * corner.
X * Call:
X * cornline(0, title or 0) : initialize
X * cornline(1, text) : add text to the chain of texts
X * cornline(2, morcs) : output everything and cleanup
X * cornline(3, 0) : cleanup
X * cornline(-1,"") : special, for help menu mode only
X */
X
Xvoid
Xcornline(mode, text)
Xint mode;
Xconst char *text;
X{
X static struct line {
X struct line *next_line;
X char *line_text;
X } NEARDATA *texthead, NEARDATA *texttail;
X static int NEARDATA maxlen;
X static int NEARDATA linect;
X register struct line *tl;
X register boolean hmenu = FALSE;
X
X if(mode == -1) { /* help menu display only */
X mode = 2;
X hmenu = TRUE;
X }
X if(mode == 0) {
X texthead = 0;
X maxlen = 0;
X linect = 0;
X if(text) {
X cornline(1, text); /* title */
X cornline(1, ""); /* blank line */
X }
X return;
X }
X
X if(mode == 1) {
X register int len;
X
X if(!text) return; /* superfluous, just to be sure */
X linect++;
X len = strlen(text) + 1; /* allow for an extra leading space */
X if(len > maxlen)
X maxlen = len;
X tl = (struct line *)
X alloc((unsigned)(len + sizeof(struct line) + 1));
X tl->next_line = 0;
X tl->line_text = (char *)(tl + 1);
X tl->line_text[0] = ' ';
X tl->line_text[1] = '\0';
X Strcat(tl->line_text, text);
X if(!texthead)
X texthead = tl;
X else
X texttail->next_line = tl;
X texttail = tl;
X return;
X }
X
X /* --- now we really do it --- */
X if(mode == 2 && linect == 1) /* topline only */
X pline("%s", texthead->line_text);
X else
X if(mode == 2) {
X register int curline, lth;
X
X if(flags.toplin == 1) more(); /* ab@unido */
X remember_topl();
X
X lth = CO - maxlen - 2; /* Use full screen width */
X if (linect < LI && lth >= 10) { /* in a corner */
X home ();
X cl_end ();
X flags.toplin = 0;
X curline = 1;
X for (tl = texthead; tl; tl = tl->next_line) {
X#if defined(MSDOS) && !defined(AMIGA)
X cmov (lth, curline);
X#else
X curs (lth, curline);
X#endif
X if(curline > 1)
X cl_end ();
X xputs(tl->line_text);
X curx = curx + strlen(tl->line_text);
X curline++;
X }
X if(hmenu) { /* help menu display */
X do
X hc = lowc(readchar());
X while (!valid_help(hc));
X }
X#if defined(MSDOS) && !defined(AMIGA)
X cmov (lth, curline);
X#else
X curs (lth, curline);
X#endif
X cl_end ();
X if (!hmenu) {
X cmore (text);
X }
X if (!hmenu || clear_help(hc)) {
X home ();
X cl_end ();
X docorner (lth, curline-1);
X }
X } else { /* feed to pager */
X#ifdef MACOS
X short tmpflags;
X
X tmpflags = macflags;
X macflags &= ~fDoNonKeyEvt;
X#endif
X set_pager(0);
X for (tl = texthead; tl; tl = tl->next_line) {
X if (page_line (tl->line_text)) {
X set_pager(2);
X#ifdef MACOS
X macflags = tmpflags;
X#endif
X while(tl = texthead) {
X texthead = tl->next_line;
X free((genericptr_t) tl);
X }
X return;
X }
X }
X if(text) {
X cgetret(text);
X set_pager(2);
X } else
X set_pager(1);
X#ifdef MACOS
X macflags = tmpflags;
X#endif
X }
X }
X
X while(tl = texthead) {
X texthead = tl->next_line;
X free((genericptr_t) tl);
X }
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X#ifdef WIZARD
Xstatic
Xvoid
Xwiz_help()
X{
X cornline(0, "Wizard-Mode Quick Reference:");
X cornline(1, "^E == detect secret doors and traps.");
X cornline(1, "^F == do magic mapping.");
X cornline(1, "^G == create monster.");
X cornline(1, "^I == identify items in pack.");
X cornline(1, "^O == tell locations of special levels.");
X cornline(1, "^T == do intra-level teleport.");
X cornline(1, "^V == do trans-level teleport.");
X cornline(1, "^W == make wish.");
X cornline(1, "^X == show intrinsic attributes.");
X cornline(1, "");
X cornline(2, "");
X}
X#endif
X
Xstatic void
Xhelp_menu() {
X cornline(0, "Information available:");
X cornline(1, "a. Long description of the game and commands.");
X cornline(1, "b. List of game commands.");
X cornline(1, "c. Concise history of NetHack.");
X cornline(1, "d. Info on a character in the game display.");
X cornline(1, "e. Info on what a given key does.");
X cornline(1, "f. List of game options.");
X cornline(1, "g. Longer explanation of game options.");
X cornline(1, "h. List of extended commands.");
X cornline(1, "i. The NetHack license.");
X#ifdef MACOS
X cornline(1, "j. Macintosh primer.");
X#endif
X#ifdef WIZARD
X if (wizard)
X# ifdef MACOS
X cornline(1, "k. List of wizard-mode commands.");
X# else
X cornline(1, "j. List of wizard-mode commands.");
X# endif
X#endif
X cornline(1, "");
X#ifdef WIZARD
X if (wizard)
X# ifdef MACOS
X cornline(1, "Select one of a,b,c,d,e,f,g,h,i,j,k or ESC: ");
X# else
X cornline(1, "Select one of a,b,c,d,e,f,g,h,i,j or ESC: ");
X# endif
X else
X#endif
X#ifdef MACOS
X cornline(1, "Select one of a,b,c,d,e,f,g,h,i,j or ESC: ");
X#else
X cornline(1, "Select one of a,b,c,d,e,f,g,h,i or ESC: ");
X#endif
X cornline(-1,"");
X}
X
XSTATIC_OVL boolean
Xclear_help(c)
Xchar c;
X{
X /* those valid_help characters which do not correspond to help routines
X * that redraw the whole screen on their own. if we always clear the
X * help menu, we end up restoring the part of the maze underneath the
X * help menu when the last page of a long help file is displayed with
X * an external pager.
X *
X * When whole_screen is FALSE and the internal pager is used, the
X * screen is big enough so that the maze is left in place during paging
X * and the paging occurs in the lower part of the screen. In this case
X * the pager clears out the part it wrote over when it exits but it
X * doesn't redraw the whole screen. So all characters require that
X * the help menu be cleared.
X *
X * When an external pager is used, the screen is always cleared.
X * However, the "f" and "h" help options always use the internal
X * pager even if DEF_PAGER is defined.
X * - Bob Wilber wilber@homxb.att.com 10/20/89
X */
X return(index(quitchars,c) || c == 'd' || c == 'e'
X#ifdef DEF_PAGER
X || (!whole_screen && (c == 'f' || c == 'h'))
X#else
X || !whole_screen
X#endif
X#ifdef WIZARD
X# ifdef MACOS
X || c == 'k'
X# else
X || c == 'j'
X# endif
X#endif
X );
X}
X
XSTATIC_OVL boolean
Xvalid_help(c)
Xchar c;
X{
X#ifdef WIZARD
X# ifdef MACOS
X return ((c >= 'a' && c <= (wizard ? 'k' : 'j')) || index(quitchars,c));
X# else
X return ((c >= 'a' && c <= (wizard ? 'j' : 'i')) || index(quitchars,c));
X# endif
X#else
X# ifdef MACOS
X return ((c >= 'a' && c <= 'j') || index(quitchars,c));
X# else
X return ((c >= 'a' && c <= 'i') || index(quitchars,c));
X# endif
X#endif
X}
X
Xint
Xdohelp()
X{
X#ifdef MACOS
X term_info *t;
X
X macflags &= ~fDoNonKeyEvt;
X t = (term_info *)GetWRefCon(HackWindow);
X SetVol((StringPtr)NULL,
X (t->auxFileVRefNum) ? t->auxFileVRefNum : t->recordVRefNum);
X#endif
X help_menu();
X if (!index(quitchars, hc)) {
X switch(hc) {
X case 'a': (void) page_file(HELP, FALSE); break;
X case 'b': (void) page_file(SHELP, FALSE); break;
X case 'c': (void) dohistory(); break;
X case 'd': (void) dowhatis(); break;
X case 'e': (void) dowhatdoes(); break;
X case 'f': option_help(); break;
X case 'g': (void) page_file(OPTIONFILE, FALSE); break;
X case 'h': (void) doextlist(); break;
X case 'i': (void) page_file(LICENSE, FALSE); break;
X#ifdef WIZARD
X# ifdef MACOS
X case 'j': (void) page_file(MACHELP, FALSE); break;
X case 'k': wiz_help(); break;
X# else
X case 'j': wiz_help(); break;
X# endif
X#endif
X }
X }
X#ifdef MACOS
X SetVol((StringPtr)NULL, t->recordVRefNum);
X macflags |= fDoNonKeyEvt;
X#endif
X return 0;
X}
X
Xint
Xdohistory()
X{
X (void) page_file(HISTORY, FALSE);
X return 0;
X}
X
Xint
Xpage_file(fnam, silent) /* return: 0 - cannot open fnam; 1 - otherwise */
Xregister const char *fnam;
Xboolean silent;
X{
X#ifdef DEF_PAGER /* this implies that UNIX is defined */
X {
X /* use external pager; this may give security problems */
X
X register int fd = open(fnam, 0);
X
X if(fd < 0) {
X if(!silent) pline("Cannot open %s.", fnam);
X return(0);
X }
X if(child(1)){
X /* Now that child() does a setuid(getuid()) and a chdir(),
X we may not be able to open file fnam anymore, so make
X it stdin. */
X (void) close(0);
X if(dup(fd)) {
X if(!silent) Printf("Cannot open %s as stdin.\n", fnam);
X } else {
X (void) execl(catmore, "page", NULL);
X if(!silent) Printf("Cannot exec %s.\n", catmore);
X }
X exit(1);
X }
X (void) close(fd);
X }
X#else
X {
X FILE *f; /* free after Robert Viduya */
X#ifdef OS2_CODEVIEW
X char tmp[PATHLEN];
X
X Strcpy(tmp,hackdir);
X append_slash(tmp);
X Strcat(tmp,fnam);
X if ((f = fopen (tmp, "r")) == (FILE *) 0) {
X#else
X# ifdef MACOS
X if ((f = fopen (fnam, "r")) == (FILE *) 0)
X f = openFile(fnam, "r");
X if (!f) {
X# else
X if ((f = fopen (fnam, "r")) == (FILE *) 0) {
X# endif
X#endif
X if(!silent) {
X home(); perror (fnam); flags.toplin = 1;
X pline ("Cannot open %s.", fnam);
X }
X return(0);
X }
X page_more(f, 0);
X }
X#endif /* DEF_PAGER /**/
X
X return(1);
X}
X
X#ifdef UNIX
X#ifdef SHELL
Xint
Xdosh(){
Xregister char *str;
X if(child(0)) {
X if(str = getenv("SHELL"))
X (void) execl(str, str, NULL);
X else
X (void) execl("/bin/sh", "sh", NULL);
X pline("sh: cannot execute.");
X exit(1);
X }
X return 0;
X}
X#endif /* SHELL /**/
X
X#if defined(SHELL) || defined(DEF_PAGER) || defined(DEF_MAILREADER)
Xint
Xchild(wt)
Xint wt;
X{
Xregister int f = fork();
X if(f == 0){ /* child */
X settty(NULL); /* also calls end_screen() */
X (void) setgid(getgid());
X (void) setuid(getuid());
X#ifdef CHDIR
X (void) chdir(getenv("HOME"));
X#endif
X return(1);
X }
X if(f == -1) { /* cannot fork */
X pline("Fork failed. Try again.");
X return(0);
X }
X /* fork succeeded; wait for child to exit */
X (void) signal(SIGINT,SIG_IGN);
X (void) signal(SIGQUIT,SIG_IGN);
X (void) wait(
X#if defined(BSD) || defined(ULTRIX)
X (union wait *)
X#else
X (int *)
X#endif
X 0);
X gettty();
X setftty();
X (void) signal(SIGINT, (SIG_RET_TYPE) done1);
X#ifdef WIZARD
X if(wizard) (void) signal(SIGQUIT,SIG_DFL);
X#endif
X if(wt) {
X boolean so;
X
X cmov(1, LI); /* get prompt in reasonable place */
X so = flags.standout;
X flags.standout = 1;
X more();
X flags.standout = so;
X }
X docrt();
X return(0);
X}
X#endif
X#endif /* UNIX /**/
X
X#endif /* OVLB */
END_OF_FILE
if test 28788 -ne `wc -c <'src/pager.c'`; then
echo shar: \"'src/pager.c'\" unpacked with wrong size!
fi
# end of 'src/pager.c'
fi
if test -f 'src/sit.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/sit.c'\"
else
echo shar: Extracting \"'src/sit.c'\" \(5549 characters\)
sed "s/^X//" >'src/sit.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)sit.c 3.0 89/06/12
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#if defined(THRONES) || defined(SPELLS)
Xvoid
Xtake_gold()
X{
X if (u.ugold <= 0) {
X You("feel a strange sensation.");
X } else {
X You("notice you have no gold!");
X u.ugold = 0;
X flags.botl = 1;
X }
X}
X#endif
X
Xint
Xdosit() {
X#ifdef THRONES
X register int cnt;
X#endif
X
X if(Levitation) {
X pline("There's nothing to sit on up here.");
X#ifdef THRONES
X } else if(IS_THRONE(levl[u.ux][u.uy].typ)) {
X
X if (rnd(6) > 4) {
X switch (rnd(13)) {
X case 1:
X adjattrib(rn2(A_MAX), -rn1(4,3), FALSE);
X losehp(rnd(10), "cursed throne", KILLED_BY_AN);
X break;
X case 2:
X adjattrib(rn2(A_MAX), 1, FALSE);
X break;
X case 3:
X pline("A%s charge of electricity shoots through your body!",
X (Shock_resistance) ? "" : " massive");
X if(Shock_resistance)
X losehp(rnd(6), "electric chair", KILLED_BY_AN);
X else losehp(rnd(30), "electric chair", KILLED_BY_AN);
X break;
X case 4:
X You("feel much, much better!");
X if(u.uhp >= (u.uhpmax - 5)) u.uhpmax += 4;
X u.uhp = u.uhpmax;
X make_blinded(0L,TRUE);
X make_sick(0L,FALSE);
X heal_legs();
X flags.botl = 1;
X break;
X case 5:
X take_gold();
X break;
X case 6:
X if(u.uluck + rn2(5) < 0) {
X You("feel your luck is changing.");
X change_luck(1);
X } else makewish();
X break;
X case 7:
X cnt = rnd(10);
X You("hear a voice echo:");
X pline("\"Thy audience hath been summoned, Sire!\"");
X while(cnt--)
X (void) makemon(courtmon(), u.ux, u.uy);
X break;
X case 8:
X You("hear a voice echo:");
X pline("\"By thy Imperious order, Sire...\"");
X do_genocide(1);
X break;
X case 9:
X You("hear a voice echo:");
X pline("\"A curse upon thee for sitting upon this most holy throne!\"");
X if (Luck > 0) {
X make_blinded(Blinded + rn1(100,250),TRUE);
X } else rndcurse();
X break;
X case 10:
X if (Luck < 0 || (HSee_invisible & INTRINSIC)) {
X pline("An image forms in your mind.");
X do_mapping();
X } else {
X Your("vision clarifies.");
X HSee_invisible |= INTRINSIC;
X }
X break;
X case 11:
X if (Luck < 0) {
X You("feel threatened.");
X aggravate();
X } else {
X
X You("feel a wrenching sensation.");
X tele(); /* teleport him */
X }
X break;
X case 12:
X You("are granted a gift of insight!");
X while (!ggetobj("identify", identify, rn2(5))
X && invent);
X break;
X case 13:
X Your("mind turns into a pretzel!");
X make_confused(HConfusion + rn1(7,16),FALSE);
X break;
X default: impossible("throne effect");
X break;
X }
X } else You("feel somehow out of place...");
X
X if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
X pline("The throne vanishes in a puff of logic.");
X/* levl[u.ux][u.uy].scrsym = ROOM_SYM; */
X levl[u.ux][u.uy].typ = ROOM;
X if(Invisible) newsym(u.ux,u.uy);
X }
X#endif
X#ifdef POLYSELF
X } else if (lays_eggs(uasmon) || u.umonnum == PM_QUEEN_BEE) {
X struct obj *uegg;
X
X if (u.uhunger < objects[EGG].nutrition) {
X You("are too weak to lay an egg.");
X return 0;
X }
X
X uegg = mksobj(EGG, 0);
X uegg->spe = 1;
X uegg->quan = 1;
X uegg->owt = weight(uegg);
X uegg->corpsenm =
X (u.umonnum==PM_QUEEN_BEE ? PM_KILLER_BEE : monsndx(uasmon));
X uegg->known = uegg->dknown = 1;
X You("lay an egg.");
X dropy(uegg);
X stackobj(uegg);
X morehungry(objects[EGG].nutrition);
X#endif
X } else
X pline("Having fun sitting on the floor?");
X return(1);
X}
X
Xvoid
Xrndcurse() { /* curse a few inventory items at random! */
X
X int nobj = 0;
X int cnt, onum;
X struct obj *otmp;
X
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X You("feel a malignant aura surround you.");
X }
X
X for (otmp = invent; otmp; otmp = otmp->nobj) nobj++;
X
X if (nobj)
X for (cnt = rnd(6/((!!Antimagic) + 1)); cnt > 0; cnt--) {
X onum = rn2(nobj);
X for(otmp = invent; onum != 0; onum--)
X otmp = otmp->nobj;
X if(otmp->blessed)
X otmp->blessed = 0;
X else
X otmp->cursed++;
X }
X}
X
Xvoid
Xattrcurse() { /* remove a random INTRINSIC ability */
X switch(rnd(10)) {
X case 1 : if (HFire_resistance & INTRINSIC) {
X HFire_resistance &= ~INTRINSIC;
X if (Inhell && !Fire_resistance) {
X You("burn to a crisp.");
X killer_format = NO_KILLER_PREFIX;
X killer = self_pronoun("a gremlin stole %s fire resistance in hell", "his");
X done(BURNING);
X } else You("feel warmer.");
X break;
X }
X case 2 : if (HTeleportation & INTRINSIC) {
X HTeleportation &= ~INTRINSIC;
X You("feel less jumpy.");
X break;
X }
X case 3 : if (HPoison_resistance & INTRINSIC) {
X HPoison_resistance &= ~INTRINSIC;
X You("feel a little sick!");
X break;
X }
X case 4 : if (HTelepat & INTRINSIC) {
X HTelepat &= ~INTRINSIC;
X Your("senses fail!");
X break;
X }
X case 5 : if (HCold_resistance & INTRINSIC) {
X HCold_resistance &= ~INTRINSIC;
X You("feel cooler.");
X break;
X }
X case 6 : if (HInvis & INTRINSIC) {
X HInvis &= ~INTRINSIC;
X You("feel paranoid.");
X break;
X }
X case 7 : if (HSee_invisible & INTRINSIC) {
X HSee_invisible &= ~INTRINSIC;
X You("thought you saw something!");
X break;
X }
X case 8 : if (Fast & INTRINSIC) {
X Fast &= ~INTRINSIC;
X You("feel slower.");
X break;
X }
X case 9 : if (Stealth & INTRINSIC) {
X Stealth &= ~INTRINSIC;
X You("feel clumsy.");
X break;
X }
X case 10: if (Protection & INTRINSIC) {
X Protection &= ~INTRINSIC;
X You("feel vulnerable.");
X break;
X }
X default: break;
X }
X}
END_OF_FILE
if test 5549 -ne `wc -c <'src/sit.c'`; then
echo shar: \"'src/sit.c'\" unpacked with wrong size!
fi
# end of 'src/sit.c'
fi
echo shar: End of archive 34 \(of 56\).
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 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 56 archives.
rm -f 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