[comp.sources.games] v11i087: larn - dungeon type adventure game, Part04/11

billr@saab.CNA.TEK.COM (Bill Randle) (12/19/90)

Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 11, Issue 87
Archive-name: larn/Part04
Environment: Unix, VMS, MS-DOS, termcap



#! /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 4 (of 11)."
# Contents:  monster.c object.c termcap.pc
# Wrapped by billr@saab on Tue Dec 18 10:14:18 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'monster.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'monster.c'\"
else
echo shar: Extracting \"'monster.c'\" \(21846 characters\)
sed "s/^X//" >'monster.c' <<'END_OF_FILE'
X/*
X *  monster.c       Larn is copyrighted 1986 by Noah Morgan.
X *
X *  This file contains the following functions:
X *  ----------------------------------------------------------------------------
X *
X *  createmonster(monstno)      Function to create a monster next to the player
X *      int monstno;
X *
X *  int cgood(x,y,itm,monst)    Function to check location for emptiness
X *      int x,y,itm,monst;
X *
X *  createitem(it,arg)          Routine to place an item next to the player
X *      int it,arg;
X *
X *  vxy(x,y)            Routine to verify/fix (*x,*y) for being within bounds
X *      int *x,*y;
X *
X *  hitmonster(x,y)     Function to hit a monster at the designated coordinates
X *      int x,y;
X *
X *  hitm(x,y,amt)       Function to just hit a monster at a given coordinates
X *      int x,y,amt;
X *
X *  hitplayer(x,y)      Function for the monster to hit the player from (x,y)
X *      int x,y;
X *
X *  dropsomething(monst)    Function to create an object when a monster dies
X *      int monst;
X *
X *  dropgold(amount)        Function to drop some gold around player
X *      int amount;
X *
X *  something(level)        Function to create a random item around player
X *      int level;
X *
X *  newobject(lev,i)        Routine to return a randomly selected new object
X *      int lev,*i;
X *
X *  spattack(atckno,xx,yy)  Function to process special attacks from monsters
X *      int atckno,xx,yy;
X *
X *  checkloss(x)    Routine to subtract hp from user and flag bottomline display
X *      int x;
X *
X */
X#include "header.h"
X#include <ctype.h>
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
Xextern fullhit(), ifblind();
X
X/*
X *  createmonster(monstno)      Function to create a monster next to the player
X *      int monstno;
X *
X *  Enter with the monster number (1 to MAXMONST+8)
X *  Returns no value.
X */
Xcreatemonster(mon)
X    int mon;
X    {
X    register int x,y,k,i;
X    if (mon<1 || mon>MAXMONST+8)    /* check for monster number out of bounds */
X        {
X        beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;
X        }
X    while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */
X    for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
X        {
X        if (k>8) k=1;   /* wraparound the diroff arrays */
X        x = playerx + diroffx[k];       y = playery + diroffy[k];
X        if (cgood(x,y,0,1)) /* if we can create here */
X            {
X            mitem[x][y] = mon;
X            hitp[x][y] = monster[mon].hitpoints;
X# ifdef DGK
X            stealth[x][y]=0;
X            know[x][y] &= ~KNOWHERE;
X# else
X            stealth[x][y]=know[x][y]=0;
X# endif
X            switch(mon)
X                {
X                case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;
X                };
X            return;
X            }
X        }
X    }
X
X/*
X *  int cgood(x,y,itm,monst)      Function to check location for emptiness
X *      int x,y,itm,monst;
X *
X *  Routine to return TRUE if a location does not have itm or monst there
X *  returns FALSE (0) otherwise
X *  Enter with itm or monst TRUE or FALSE if checking it
X *  Example:  if itm==TRUE check for no item at this location
X *            if monst==TRUE check for no monster at this location
X *  This routine will return FALSE if at a wall,door or the dungeon exit
X *  on level 1
X */
Xstatic int cgood(x,y,itm,monst)
X    register int x,y;
X    int itm,monst;
X    {
X    /* cannot create either monster or item if:
X       - out of bounds
X       - wall
X       - closed door
X       - dungeon entrance
X    */
X    if (((y < 0) || (y > MAXY-1) || (x < 0) || (x > MAXX-1)) ||
X         (item[x][y] == OWALL) ||
X         (item[x][y] == OCLOSEDDOOR) ||
X         ((level == 1) && (x == 33) && (y == MAXY-1)))
X        return( FALSE );
X
X    /* if checking for an item, return False if one there already
X    */
X    if ( itm && item[x][y])
X        return( FALSE );
X
X    /* if checking for a monster, return False if one there already _or_
X       there is a pit/trap there.
X    */
X    if (monst)
X        {
X        if (mitem[x][y])
X            return (FALSE);
X        switch(item[x][y])
X            {
X            /* note: not invisible traps, since monsters are not affected
X               by them.
X            */
X            case OPIT:         case OANNIHILATION:
X            case OTELEPORTER:  case OTRAPARROW:
X            case ODARTRAP:    case OTRAPDOOR:
X                return(FALSE);
X                break;
X            default:
X                break;
X            }
X        }
X    return(TRUE);
X    }
X
X/*
X *  createitem(it,arg)      Routine to place an item next to the player
X *      int it,arg;
X *
X *  Enter with the item number and its argument (iven[], ivenarg[])
X *  Returns no value, thus we don't know about createitem() failures.
X */
Xcreateitem(it,arg)
X    int it,arg;
X    {
X    register int x,y,k,i;
X    if (it >= MAXOBJ) return;   /* no such object */
X    for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
X        {
X        if (k>8) k=1;   /* wraparound the diroff arrays */
X        x = playerx + diroffx[k];       y = playery + diroffy[k];
X        if (cgood(x,y,1,0)) /* if we can create here */
X            {
X            item[x][y] = it;  know[x][y]=0;  iarg[x][y]=arg;  return;
X            }
X        }
X    }
X
X
X/*
X *  vxy(x,y)       Routine to verify/fix coordinates for being within bounds
X *      int *x,*y;
X *
X *  Function to verify x & y are within the bounds for a level
X *  If *x or *y is not within the absolute bounds for a level, fix them so that
X *    they are on the level.
X *  Returns TRUE if it was out of bounds, and the *x & *y in the calling
X *  routine are affected.
X */
Xvxy(x,y)
X    int *x,*y;
X    {
X    int flag=0;
X    if (*x<0) { *x=0; flag++; }
X    if (*y<0) { *y=0; flag++; }
X    if (*x>=MAXX) { *x=MAXX-1; flag++; }
X    if (*y>=MAXY) { *y=MAXY-1; flag++; }
X    return(flag);
X    }
X
X/*
X *  hitmonster(x,y)     Function to hit a monster at the designated coordinates
X *      int x,y;
X *
X *  This routine is used for a bash & slash type attack on a monster
X *  Enter with the coordinates of the monster in (x,y).
X *  Returns no value.
X */
Xhitmonster(x,y)
X    int x,y;
X    {
X    extern char lastmonst[] ;
X    register int tmp,monst,damag,flag;
X    if (c[TIMESTOP])  return;  /* not if time stopped */
X    vxy(&x,&y); /* verify coordinates are within range */
X    if ((monst = mitem[x][y]) == 0) return;
X    hit3flag=1;  ifblind(x,y);
X    tmp = monster[monst].armorclass + c[LEVEL] + c[DEXTERITY] + c[WCLASS]/4 - 12;
X    cursors();
X    if ((rnd(20) < tmp-c[HARDGAME]) || (rnd(71) < 5)) /* need at least random chance to hit */
X        {
X        lprcat("\nYou hit");  flag=1;
X        damag = fullhit(1);
X        if (damag<9999) damag=rnd(damag)+1;
X        }
X    else
X        {
X        lprcat("\nYou missed");  flag=0;
X        }
X    lprcat(" the "); lprcat(lastmonst);
X    if (flag)   /* if the monster was hit */
X      if ((monst==RUSTMONSTER) || (monst==DISENCHANTRESS) || (monst==CUBE))
X        if (c[WIELD]>0)
X          if (ivenarg[c[WIELD]] > -10)
X            {
X            lprintf("\nYour weapon is dulled by the %s",lastmonst); beep();
X            --ivenarg[c[WIELD]];
X
X            /* fix for dulled rings of strength,cleverness, and dexterity
X               bug.
X            */
X            switch (iven[c[WIELD]])
X                {
X                case ODEXRING :
X                    c[DEXTERITY]--;
X                    break;
X                case OSTRRING :
X                    c[STREXTRA]--;
X                    break;
X                case OCLEVERRING :
X                    c[INTELLIGENCE]--;
X                    break;
X                }
X            }
X    if (flag)  hitm(x,y,damag);
X    if (monst == VAMPIRE) if (hitp[x][y]<25)  { mitem[x][y]=BAT; know[x][y]=0; }
X    }
X
X/*
X *  hitm(x,y,amt)       Function to just hit a monster at a given coordinates
X *      int x,y,amt;
X *
X *  Returns the number of hitpoints the monster absorbed
X *  This routine is used to specifically damage a monster at a location (x,y)
X *  Called by hitmonster(x,y)
X */
Xhitm(x,y,amt)
X    int x,y;
X    register amt;
X    {
X    extern char lastmonst[] ;
X    register int monst;
X    int hpoints,amt2;
X    vxy(&x,&y); /* verify coordinates are within range */
X    amt2 = amt;     /* save initial damage so we can return it */
X    monst = mitem[x][y];
X    if (c[HALFDAM]) amt >>= 1;  /* if half damage curse adjust damage points */
X    if (amt<=0) amt2 = amt = 1;
X    lasthx=x;  lasthy=y;
X    stealth[x][y]=1;    /* make sure hitting monst breaks stealth condition */
X    c[HOLDMONST]=0; /* hit a monster breaks hold monster spell  */
X    switch(monst) /* if a dragon and orb(s) of dragon slaying   */
X        {
X        case WHITEDRAGON:       case REDDRAGON:         case GREENDRAGON:
X        case BRONZEDRAGON:      case PLATINUMDRAGON:    case SILVERDRAGON:
X            amt *= 1+(c[SLAYING]<<1);   break;
X        }
X/* invincible monster fix is here */
X    if (hitp[x][y] > monster[monst].hitpoints)
X        hitp[x][y] = monster[monst].hitpoints;
X    if ((hpoints = hitp[x][y]) <= amt)
X        {
X#ifdef EXTRA
X        c[MONSTKILLED]++;
X#endif
X        lprintf("\nThe %s died!",lastmonst);
X        raiseexperience((long)monster[monst].experience);
X        amt = monster[monst].gold;  if (amt>0) dropgold(rnd(amt)+amt);
X        dropsomething(monst);   disappear(x,y); bottomline();
X        return(hpoints);
X        }
X    hitp[x][y] = hpoints-amt;   return(amt2);
X    }
X
X/*
X *  hitplayer(x,y)      Function for the monster to hit the player from (x,y)
X *      int x,y;
X *
X *  Function for the monster to hit the player with monster at location x,y
X *  Returns nothing of value.
X */
Xhitplayer(x,y)
X    int x,y;
X    {
X    extern char lastmonst[] ;
X    register int dam,tmp,mster,bias;
X    vxy(&x,&y); /* verify coordinates are within range */
X    lastnum = mster = mitem[x][y];
X/*  spirit naga's and poltergeist's do nothing if scarab of negate spirit   */
X    if (c[NEGATESPIRIT] || c[SPIRITPRO])  if ((mster ==POLTERGEIST) || (mster ==SPIRITNAGA))  return;
X/*  if undead and cube of undead control    */
X    if (c[CUBEofUNDEAD] || c[UNDEADPRO]) if ((mster ==VAMPIRE) || (mster ==WRAITH) || (mster ==ZOMBIE)) return;
X# ifdef DGK
X    if ((know[x][y] & KNOWHERE) == 0)
X        show1cell(x,y);
X# else
X    if ((know[x][y]&1) == 0)
X        {
X        know[x][y]=1; show1cell(x,y);
X        }
X# endif
X    bias = (c[HARDGAME]) + 1;
X    hitflag = hit2flag = hit3flag = 1;
X    yrepcount=0;
X    cursors();  ifblind(x,y);
X    if (c[INVISIBILITY]) if (rnd(33)<20) 
X        {
X        lprintf("\nThe %s misses wildly",lastmonst);    return;
X        }
X    if (c[CHARMCOUNT]) if (rnd(30)+5*monster[mster].level-c[CHARISMA]<30)
X        {
X        lprintf("\nThe %s is awestruck at your magnificence!",lastmonst);
X        return;
X        }
X    if (mster==BAT) dam=1;
X    else
X        {
X        dam = monster[mster].damage;
X        dam += rnd((int)((dam<1)?1:dam)) + monster[mster].level;
X        }
X    tmp = 0;
X    if (monster[mster].attack>0)
X      if (((dam + bias + 8) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
X        { if (spattack(monster[mster].attack,x,y)) { flushall(); return; }
X          tmp = 1;  bias -= 2; cursors(); }
X    if (((dam + bias) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
X        {
X        lprintf("\n  The %s hit you ",lastmonst);   tmp = 1;
X        if ((dam -= c[AC]) < 0) dam=0;
X        if (dam > 0) { losehp(dam); bottomhp(); flushall(); }
X        }
X    if (tmp == 0)  lprintf("\n  The %s missed ",lastmonst);
X    }
X
X/*
X *  dropsomething(monst)    Function to create an object when a monster dies
X *      int monst;
X *
X *  Function to create an object near the player when certain monsters are killed
X *  Enter with the monster number
X *  Returns nothing of value.
X */
Xstatic dropsomething(monst)
X    int monst;
X    {
X    switch(monst)
X        {
X        case ORC:             case NYMPH:      case ELF:      case TROGLODYTE:
X        case TROLL:           case ROTHE:      case VIOLETFUNGI:
X        case PLATINUMDRAGON:  case GNOMEKING:  case REDDRAGON:
X            something(level); return;
X
X        case LEPRECHAUN: if (rnd(101)>=75) creategem();
X                         if (rnd(5)==1) dropsomething(LEPRECHAUN);   return;
X        }
X    }
X
X/*
X *  dropgold(amount)    Function to drop some gold around player
X *      int amount;
X *
X *  Enter with the number of gold pieces to drop
X *  Returns nothing of value.
X */
Xdropgold(amount)
X    register int amount;
X    {
X    if (amount > 250) createitem(OMAXGOLD,amount/100);  else  createitem(OGOLDPILE,amount);
X    }
X
X/*
X *  something(level)    Function to create a random item around player
X *      int level;
X *
X *  Function to create an item from a designed probability around player
X *  Enter with the cave level on which something is to be dropped
X *  Returns nothing of value.
X */
Xsomething(level)
X    int level;
X    {
X    register int j;
X    int i;
X    if (level<0 || level>MAXLEVEL+MAXVLEVEL) return;    /* correct level? */
X    if (rnd(101)<8) something(level); /* possibly more than one item */
X    j = newobject(level,&i);        createitem(j,i);
X    }
X
X/*
X *  newobject(lev,i)    Routine to return a randomly selected new object
X *      int lev,*i;
X *
X *  Routine to return a randomly selected object to be created
X *  Returns the object number created, and sets *i for its argument
X *  Enter with the cave level and a pointer to the items arg
X */
Xstatic char nobjtab[] = { 0, OSCROLL,  OSCROLL,  OSCROLL,  OSCROLL, OPOTION,
X    OPOTION, OPOTION, OPOTION, OGOLDPILE, OGOLDPILE, OGOLDPILE, OGOLDPILE, 
X    OBOOK, OBOOK, OBOOK, OBOOK, ODAGGER, ODAGGER, ODAGGER, OLEATHER, OLEATHER,
X    OLEATHER, OREGENRING, OPROTRING, OENERGYRING, ODEXRING, OSTRRING, OSPEAR,
X    OBELT, ORING, OSTUDLEATHER, OSHIELD, OFLAIL, OCHAIN, O2SWORD, OPLATE,
X    OLONGSWORD };
X
Xnewobject(lev,i)
X    register int lev,*i;
X    {
X    register int tmp=32,j;
X    if (level<0 || level>MAXLEVEL+MAXVLEVEL) return(0); /* correct level? */
X    if (lev>6) tmp=37; else if (lev>4) tmp=35; 
X    j = nobjtab[tmp=rnd(tmp)];  /* the object type */
X    switch(tmp)
X        {
X        case 1: case 2: case 3: case 4: *i=newscroll(); break;
X        case 5: case 6: case 7: case 8: *i=newpotion(); break;
X        case 9: case 10: case 11: case 12: *i=rnd((lev+1)*10)+lev*10+10; break;
X        case 13: case 14: case 15: case 16: *i=lev; break;
X        case 17: case 18: case 19: if (!(*i=newdagger()))  return(0);  break;
X        case 20: case 21: case 22: if (!(*i=newleather()))  return(0);  break;
X        case 23: case 32: case 35: *i=rund(lev/3+1); break;
X        case 24: case 26: *i=rnd(lev/4+1);   break;
X        case 25: *i=rund(lev/4+1); break;
X        case 27: *i=rnd(lev/2+1);   break;
X        case 30: case 33: *i=rund(lev/2+1);   break;
X        case 28: *i=rund(lev/3+1); if (*i==0) return(0); break;
X        case 29: case 31: *i=rund(lev/2+1); if (*i==0) return(0); break;
X        case 34: *i=newchain();     break;
X        case 36: *i=newplate();     break;
X        case 37: *i=newsword();     break; 
X        }
X    return(j);
X    }
X
X/*
X *  spattack(atckno,xx,yy)  Function to process special attacks from monsters
X *      int atckno,xx,yy;
X *
X *  Enter with the special attack number, and the coordinates (xx,yy)
X *      of the monster that is special attacking
X *  Returns 1 if must do a show1cell(xx,yy) upon return, 0 otherwise
X *
X * atckno   monster     effect
X * ---------------------------------------------------
X *  0   none
X *  1   rust monster    eat armor
X *  2   hell hound      breathe light fire
X *  3   dragon          breathe fire
X *  4   giant centipede weakening sing
X *  5   white dragon    cold breath
X *  6   wraith          drain level
X *  7   waterlord       water gusher
X *  8   leprechaun      steal gold
X *  9   disenchantress  disenchant weapon or armor
X *  10  ice lizard      hits with barbed tail
X *  11  umber hulk      confusion
X *  12  spirit naga     cast spells taken from special attacks
X *  13  platinum dragon psionics
X *  14  nymph           steal objects
X *  15  bugbear         bite
X *  16  osequip         bite
X *
X *  char rustarm[ARMORTYPES][2];
X *  special array for maximum rust damage to armor from rustmonster
X *  format is: { armor type , minimum attribute 
X */
X#define ARMORTYPES 6
Xstatic char rustarm[ARMORTYPES][2] = { OSTUDLEATHER,-2, ORING,-4, OCHAIN,-5,
X    OSPLINT,-6,     OPLATE,-8,      OPLATEARMOR,-9  };
Xstatic char spsel[] = { 1, 2, 3, 5, 6, 8, 9, 11, 13, 14 };
Xstatic spattack(x,xx,yy)
X    int x,xx,yy;
X    {
X    extern char lastmonst[] ;
X    register int i,j=0,k,m;
X    register char *p=0;
X    if (c[CANCELLATION]) return(0);
X    vxy(&xx,&yy);   /* verify x & y coordinates */
X    switch(x)
X        {
X        case 1: /* rust your armor, j=1 when rusting has occurred */
X                m = k = c[WEAR];
X                if ((i=c[SHIELD]) != -1)
X                    if (--ivenarg[i] < -1) ivenarg[i]= -1; else j=1;
X                if ((j==0) && (k != -1))
X                  {
X                  m = iven[k];
X                  for (i=0; i<ARMORTYPES; i++)
X                    if (m == rustarm[i][0]) /* find his armor in table */
X                        {
X                        if (--ivenarg[k]< rustarm[i][1])
X                            ivenarg[k]= rustarm[i][1]; else j=1; 
X                        break;
X                        }
X                  }
X                if (j==0)   /* if rusting did not occur */
X                  switch(m)
X                    {
X                    case OLEATHER:  p = "\nThe %s hit you -- Your lucky you have leather on";
X                                    break;
X                    case OSSPLATE:  p = "\nThe %s hit you -- Your fortunate to have stainless steel armor!";
X                                    break;
X                    }
X                else  { beep(); p = "\nThe %s hit you -- your armor feels weaker"; }
X                break;
X
X        case 2:     i = rnd(15)+8-c[AC];
X            spout:  p="\nThe %s breathes fire at you!";
X                    if (c[FIRERESISTANCE])
X                      p="\nThe %s's flame doesn't phase you!";
X                    else
X            spout2: if (p) { lprintf(p,lastmonst); beep(); }
X                    checkloss(i);
X                    return(0);
X
X        case 3:     i = rnd(20)+25-c[AC];  goto spout;
X
X        case 4: if (c[STRENGTH]>3)
X                    {
X                    p="\nThe %s stung you!  You feel weaker"; beep();
X                    --c[STRENGTH];
X                    }
X                else p="\nThe %s stung you!";
X                break;
X
X        case 5:     p="\nThe %s blasts you with his cold breath";
X                    i = rnd(15)+18-c[AC];  goto spout2;
X
X        case 6:     lprintf("\nThe %s drains you of your life energy!",lastmonst);
X                    loselevel();  beep();  return(0);
X
X        case 7:     p="\nThe %s got you with a gusher!";
X                    i = rnd(15)+25-c[AC];  goto spout2;
X
X        case 8:     if (c[NOTHEFT]) return(0); /* he has a device of no theft */
X                    if (c[GOLD])
X                        {
X                        p="\nThe %s hit you -- Your purse feels lighter";
X                        if (c[GOLD]>32767)  c[GOLD]>>=1;
X                            else c[GOLD] -= rnd((int)(1+(c[GOLD]>>1)));
X                        if (c[GOLD] < 0) c[GOLD]=0;
X                        }
X                    else  p="\nThe %s couldn't find any gold to steal";
X                    lprintf(p,lastmonst); disappear(xx,yy); beep();
X                    bottomgold();  return(1);
X
X        case 9: for(j=50; ; )   /* disenchant */
X                    {
X                    i=rund(26);  m=iven[i]; /* randomly select item */
X                    if (m>0 && ivenarg[i]>0 && m!=OSCROLL && m!=OPOTION)
X                        {
X                        if ((ivenarg[i] -= 3)<0) ivenarg[i]=0;
X                        lprintf("\nThe %s hits you -- you feel a sense of loss",lastmonst);
X                        srcount=0; beep(); show3(i);  bottomline();  return(0);
X                        }
X                    if (--j<=0)
X                        {
X                        p="\nThe %s nearly misses"; break;
X                        }
X                    break;
X                    }       
X                break;
X
X        case 10:   p="\nThe %s hit you with his barbed tail";
X                   i = rnd(25)-c[AC];  goto spout2;
X
X        case 11:    p="\nThe %s has confused you"; beep();
X                    c[CONFUSE]+= 10+rnd(10);        break;
X
X        case 12:    /*  performs any number of other special attacks    */
X                    return(spattack(spsel[rund(10)],xx,yy));
X
X        case 13:    p="\nThe %s flattens you with his psionics!";
X                    i = rnd(15)+30-c[AC];  goto spout2;
X
X        case 14:    if (c[NOTHEFT]) return(0); /* he has device of no theft */
X                    if (emptyhanded()==1)
X                      {
X                      p="\nThe %s couldn't find anything to steal";
X                      break;
X                      }
X                    lprintf("\nThe %s picks your pocket and takes:",lastmonst);
X                    beep();
X                    if (stealsomething()==0) lprcat("  nothing"); disappear(xx,yy);
X                    bottomline();  return(1);
X
X        case 15:    i= rnd(10)+ 5-c[AC];
X            spout3: p="\nThe %s bit you!";
X                    goto spout2;
X
X        case 16:    i= rnd(15)+10-c[AC];  goto spout3;
X        };
X    if (p) { lprintf(p,lastmonst); bottomline(); }
X    return(0);
X    }
X
X/*
X *  checkloss(x)    Routine to subtract hp from user and flag bottomline display
X *      int x;
X *
X *  Routine to subtract hitpoints from the user and flag the bottomline display
X *  Enter with the number of hit points to lose
X *  Note: if x > c[HP] this routine could kill the player!
X */
Xcheckloss(x)
X    int x;
X    {
X    if (x>0) { losehp(x);  bottomhp(); }
X    }
END_OF_FILE
if test 21846 -ne `wc -c <'monster.c'`; then
    echo shar: \"'monster.c'\" unpacked with wrong size!
fi
# end of 'monster.c'
fi
if test -f 'object.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'object.c'\"
else
echo shar: Extracting \"'object.c'\" \(28660 characters\)
sed "s/^X//" >'object.c' <<'END_OF_FILE'
X/*  object.c        Larn is copyrighted 1986 by Noah Morgan. */
X#include "header.h"
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
X/*
X    ***************
X    LOOK_FOR_OBJECT
X    ***************
X
X    subroutine to look for an object and give the player his options
X    if an object was found.
X */
Xlookforobject(do_ident, do_pickup, do_action)
X    char do_ident;   /* identify item: T/F */
X    char do_pickup;  /* pickup item:   T/F */
X    char do_action;  /* prompt for actions on object: T/F */
X    {
X    register int i,j;
X
X    /* can't find objects if time is stopped    */
X    if (c[TIMESTOP])  
X        return;
X    i=item[playerx][playery];   if (i==0) return;
X    j=iarg[playerx][playery];
X    showcell(playerx,playery);  cursors();  yrepcount=0;
X    switch(i)
X	{
X	case OGOLDPILE: case OMAXGOLD:
X	case OKGOLD:    case ODGOLD:    
X	    lprcat("\n\nYou have found some gold!");    
X	    ogold(i);   
X	    break;
X
X	case OPOTION:   
X	    if (do_ident)
X		{
X		lprcat("\n\nYou have found a magic potion");
X		if (potionname[j][0]) 
X		    lprintf(" of %s",&potionname[j][1]);  
X		}
X	    if (do_pickup)
X		if (take(OPOTION, j) == 0)
X		    forget();
X	    if (do_action)
X		opotion(j);  
X	    break;
X
X	case OSCROLL:   
X	    if (do_ident)
X		{
X		lprcat("\n\nYou have found a magic scroll");
X		if (scrollname[j][0])   
X		    lprintf(" of %s",&scrollname[j][1]);
X		}
X	    if (do_pickup)
X		if (take(OSCROLL, j) == 0)
X		    forget();
X	    if (do_action)
X		oscroll(j);  
X	    break;
X
X	case OALTAR:    
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nThere is a Holy Altar here!"); 
X	    if (do_action)
X		oaltar(); 
X	    break;
X
X	case OBOOK: 
X	    if (do_ident)
X		lprcat("\n\nYou have found a book."); 
X	    if (do_pickup)
X		if (take(OBOOK, j) == 0)
X		    forget();
X	    if (do_action)
X		obook(); 
X	    break;
X
X	case OCOOKIE:   
X	    if (do_ident)
X		lprcat("\n\nYou have found a fortune cookie."); 
X	    if (do_pickup)
X		if (take(OCOOKIE, 0)==0)
X		    forget();
X	    if (do_action)
X		ocookie(); 
X	    break;
X
X	case OTHRONE:   
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprintf("\n\nThere is %s here!",objectname[i]); 
X	    if (do_action)
X		othrone(0); 
X	    break;
X
X	case OTHRONE2:  
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprintf("\n\nThere is %s here!",objectname[i]); 
X	    if (do_action)
X		othrone(1); 
X	    break;
X
X	case ODEADTHRONE: 
X	    if (do_ident)
X		lprintf("\n\nThere is %s here!",objectname[i]); 
X	    if (do_action)
X		odeadthrone(); 
X	    break;
X
X	case OORB:      
X	    lprcat("\n\nYou have found the Orb!!!!!"); 
X	    oorb(); 
X	    break;
X
X	case OPIT:
X	    /* always perform these actions. */
X	    lprcat("\n\nYou're standing at the top of a pit.");
X	    opit();
X	    break;
X
X	case OSTAIRSUP:                                   /* up */
X	    if (do_ident)
X		lprcat("\n\nThere is a circular staircase here");
X	    if (do_action)
X		ostairs(1);
X	    break;
X
X	case OELEVATORUP:   
X	    lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
X	    oelevator(1);  /*  up  */  
X	    break;
X
X	case OFOUNTAIN: 
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nThere is a fountain here"); 
X	    if (do_action)
X		ofountain(); 
X	    break;
X
X	case OSTATUE:   
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nYou are standing in front of a statue"); 
X	    if (do_action)
X		ostatue();
X	    break;
X
X	case OCHEST:    
X	    if (do_ident)
X		lprcat("\n\nThere is a chest here");  
X	    if (do_pickup)
X		if (take(OCHEST,j)==0)
X		    forget();
X	    if (do_action)
X		ochest();  
X	    break;
X
X	case OSCHOOL:
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nYou have found the College of Larn.");
X	    if (do_action)
X		prompt_enter();
X	    break;
X
X	case OMIRROR:   
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nThere is a mirror here");
X	    if (do_action)
X		omirror();  
X	    break;
X
X	case OBANK2:
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nYou have found a branch office of the bank of Larn.");
X	    if (do_action)
X		prompt_enter();
X	    break ;
X
X	case OBANK: 
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nYou have found the bank of Larn.");
X	    if (do_action)
X		prompt_enter();
X	    break;
X
X	case ODEADFOUNTAIN: 
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nThere is a dead fountain here");
X	    break;
X
X	case ODNDSTORE: 
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nThere is a DND store here.");
X	    if (do_action)
X		prompt_enter();
X	    break;
X
X	case OSTAIRSDOWN:                    /* down */
X	    if (do_ident)
X		lprcat("\n\nThere is a circular staircase here");
X	    if (do_action)
X		 ostairs(-1);
X	    break;
X
X	case OELEVATORDOWN: 
X	    lprcat("\n\nYou feel light for a moment, but the feeling disappears");
X	    oelevator(-1);  /*  down    */
X	    break;
X
X	case OOPENDOOR:
X	    if (do_ident)
X		lprintf("\n\nYou have found %s",objectname[i]);
X	    if (do_action)
X		o_open_door();
X	    break;
X
X	case OCLOSEDDOOR:   
X	    if (do_ident)
X		lprintf("\n\nYou have found %s",objectname[i]);
X	    if (do_action)
X		o_closed_door();
X	    break;
X
X	case OENTRANCE: 
X	    if (do_ident)
X		lprcat("\nYou have found "); lprcat(objectname[i]);
X	    if (do_action)
X		prompt_enter();
X	    break;
X
X	case OVOLDOWN:  
X	    if (do_ident)
X		lprcat("\nYou have found "); lprcat(objectname[i]);
X	    if (do_action)
X		prompt_volshaft(-1);
X	    break;
X
X	case OVOLUP:    
X	    if (do_ident)
X		lprcat("\nYou have found "); lprcat(objectname[i]);
X	    if (do_action)
X		prompt_volshaft(1);
X	    break;
X
X	case OIVTELETRAP:   
X	    if (rnd(11)<6) 
X		return;
X	    item[playerx][playery] = OTELEPORTER;
X	    know[playerx][playery] = KNOWALL;
X	    /* fall through to OTELEPORTER case below!!!*/
X
X	case OTELEPORTER:   
X	    lprcat("\nZaaaappp!  You've been teleported!\n");
X	    beep(); nap(3000); oteleport(0);
X	    break; 
X
X	case OTRAPARROWIV:     /* for an arrow trap */  
X	    if (rnd(17)<13) 
X		return; 
X	    item[playerx][playery] = OTRAPARROW;
X	    know[playerx][playery] = 0;
X	    /* fall through to OTRAPARROW case below!!!*/
X
X	case OTRAPARROW:    
X	    lprcat("\nYou are hit by an arrow"); beep();
X	    lastnum=259;    losehp(rnd(10)+level);
X	    bottomhp(); return;
X
X	case OIVDARTRAP:         /* for a dart trap */
X	    if (rnd(17)<13) 
X		return;
X	    item[playerx][playery] = ODARTRAP;
X	    know[playerx][playery] = 0;
X	    /* fall through to ODARTTRAP case below!!!*/
X
X	case ODARTRAP:      
X	    lprcat("\nYou are hit by a dart"); beep();  /* for a dart trap */
X	    lastnum=260;    losehp(rnd(5));
X	    if ((--c[STRENGTH]) < 3) c[STRENGTH] = 3;
X	    bottomline();   return;
X
X	case OIVTRAPDOOR:        /* for a trap door */
X	    if (rnd(17)<13) 
X		return;
X	    item[playerx][playery] = OTRAPDOOR;
X	    know[playerx][playery] = KNOWALL;
X	    /* fall through to OTRAPDOOR case below!!!*/
X
X	case OTRAPDOOR:     
X	    lastnum = 272; /* a trap door */
X	    if ((level==MAXLEVEL-1) || (level==MAXLEVEL+MAXVLEVEL-1))
X		{
X		lprcat("\nYou fell through a bottomless trap door!");
X		beep();
X		nap(3000);
X		died(271);
X		}
X	    i = rnd( 5 + level );
X	    lprintf("\nYou fall through a trap door!  You lose %d hit points.", (long)i);
X	    beep();  losehp(i);  nap(2000);
X	    newcavelevel(level+1);  draws(0,MAXX,0,MAXY);  bot_linex();
X	    return;
X
X	case OTRADEPOST:
X	    if (nearbymonst())
X		return;
X	    if (do_ident)
X		lprcat("\nYou have found the Larn trading Post.");
X	    if (do_action)
X		prompt_enter();
X	    return;
X
X	case OHOME: 
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\nYou have found your way home.");
X	    if (do_action)
X		prompt_enter();
X	    return;
X
X	case OWALL:
X	    break;
X
X	case OANNIHILATION: 
X	    died(283);   /* annihilated by sphere of annihilation */
X	    return;
X
X	case OLRS:  
X	    if (nearbymonst()) 
X		return;
X	    if (do_ident)
X		lprcat("\n\nThere is an LRS office here.");
X	    if (do_action)
X		prompt_enter();
X	    break;
X
X	default:
X	    if (do_ident)
X		{
X		lprintf("\n\nYou have found %s ",objectname[i]);
X		switch(i)
X		    {
X		    case ODIAMOND:      case ORUBY:         case OEMERALD:
X		    case OSAPPHIRE:     case OSPIRITSCARAB: case OORBOFDRAGON:
X		    case OCUBEofUNDEAD: case ONOTHEFT:  
X			break;
X
X		    default:
X			if (j>0) 
X			    lprintf("+ %d",(long)j); 
X			else if (j<0) 
X			    lprintf(" %d",(long)j);
X			break;
X		    }
X		}
X	    if (do_pickup)
X		if (take(i,j) == 0)
X                    forget();
X            if (do_action)
X	        {
X		char tempc = 0;
X
X		lprcat("\nDo you want to (t) take it"); iopts();
X		while (tempc!='t' && tempc!='i' && tempc!='\33') 
X                    tempc=ttgetch();
X		if (tempc == 't')
X		    {   
X		    lprcat("take");  if (take(i,j)==0) forget();   
X		    return; 
X		    }
X		ignore();
X		}
X	    break;
X	};
X    }
X
X/*
X    subroutine to process the stair cases
X    if dir > 0 the up else down
X*/
Xostairs(dir)
X    int dir;
X    {
X    register int k;
X    lprcat("\nDo you (s) stay here  ");
X    if (dir > 0)    lprcat("(u) go up  ");  else    lprcat("(d) go down  ");
X    lprcat("or (f) kick stairs? ");
X
X    while (1) switch(ttgetch())
X        {
X        case '\33':
X        case 's':   case 'i':   lprcat("stay here");    return;
X
X        case 'f':   
X            lprcat("kick stairs");
X            act_kick_stairs();
X            return;
X
X        case 'u':   
X            lprcat("go up");
X            act_up_stairs();
X            return;
X
X        case 'd':   
X            lprcat("go down");
X            act_down_stairs();
X            return;
X        };
X    }
X
X
X/*
X    subroutine to handle a teleport trap +/- 1 level maximum
X*/
Xoteleport(err)
X    int err;
X    {
X    register int tmp;
X    if (err) if (rnd(151)<3)  died(264);  /*    stuck in a rock */
X    c[TELEFLAG]=1;  /*  show ?? on bottomline if been teleported    */
X    if (level==0) tmp=0;
X    else if (level < MAXLEVEL)
X        { tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
X            if (tmp<1) tmp=1; }
X    else
X        { tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
X            if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
X    playerx = rnd(MAXX-2);  playery = rnd(MAXY-2);
X    if (level != tmp)   newcavelevel(tmp);  positionplayer();
X    draws(0,MAXX,0,MAXY); bot_linex();
X    }
X
X/*
X    function to process a potion
X*/
Xopotion(pot)
X    int pot;
X    {
X    lprcat("\nDo you (d) drink it, (t) take it"); iopts();
X    while (1) switch(ttgetch())
X        {
X        case '\33':
X        case 'i':   ignore();  return;
X
X        case 'd':   lprcat("drink\n");  forget();   /*  destroy potion  */
X                    quaffpotion(pot,TRUE);       return;
X
X        case 't':   lprcat("take\n");   if (take(OPOTION,pot)==0)  forget();
X                    return;
X        };
X    }
X        
X/*
X    function to drink a potion
X
X    Also used to perform the action of a potion without quaffing a potion
X    (see invisible capability when drinking from a fountain).
X*/
Xquaffpotion(pot,set_known)
X    int pot;
X    int set_known;
X    {
X    register int i,j,k;
X
X    /* check for within bounds */
X    if (pot<0 || pot>=MAXPOTION)
X        return; 
X
X    /* if player is to know this potion (really quaffing one), make it known */
X    if (set_known)
X        potionname[pot][0] = ' ';
X
X    switch(pot)
X        {
X	case 9: lprcat("\nYou feel greedy . . .");   nap(1000);
X		if (c[BLINDCOUNT])
X		    return;
X                for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
X                  if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
X                    {
X                    know[j][i]=1; show1cell(j,i);
X                    }
X                showplayer();  return;
X
X	case 19: lprcat("\nYou feel greedy . . .");   nap(1000);
X		if (c[BLINDCOUNT])
X		    return;
X                for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
X                    {
X                    k=item[j][i];
X                    if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD)
X                         || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE))
X                         {
X                         know[j][i]=1; show1cell(j,i);
X                         }
X                    }
X                showplayer();  return;
X
X        case 20: c[HP] = c[HPMAX]; break;   /* instant healing */
X
X        case 1: lprcat("\nYou feel better");
X                if (c[HP] == c[HPMAX])  raisemhp(1);
X                else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX];  break;
X
X        case 2: lprcat("\nSuddenly, you feel much more skillful!");
X                raiselevel();  raisemhp(1); return;
X
X        case 3: lprcat("\nYou feel strange for a moment"); 
X                c[rund(6)]++;  break;
X
X        case 4: lprcat("\nYou feel more self confident!");
X                c[WISDOM] += rnd(2);  break;
X
X        case 5: lprcat("\nWow!  You feel great!");
X                if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++;  break;
X
X        case 6: lprcat("\nYour charm went up by one!");  c[CHARISMA]++;  break;
X
X        case 8: lprcat("\nYour intelligence went up by one!");
X                c[INTELLIGENCE]++;  break;
X
X        case 10:                        /* monster detection */
X	    lprcat("\nYou detect the presence of monsters!");
X	    nap(1000);
X	    if (c[BLINDCOUNT])
X		return;
X	    for (i=0; i<MAXY; i++)
X                for (j=0; j<MAXX; j++)
X                   if (mitem[j][i] && (monstnamelist[mitem[j][i]] != floorc))
X                    {
X                    know[j][i]=1; 
X                    show1cell(j,i);
X                    }
X            return;
X
X        case 12: lprcat("\nThis potion has no taste to it");  return;
X
X        case 15: lprcat("\nWOW!!!  You feel Super-fantastic!!!");
X                 if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11;
X                    c[HERO] += 250;  break;
X
X        case 16: lprcat("\nYou have a greater intestinal constitude!");
X                 c[CONSTITUTION]++;  break;
X
X        case 17: lprcat("\nYou now have incredibly bulging muscles!!!");
X                 if (c[GIANTSTR]==0) c[STREXTRA] += 21;
X                 c[GIANTSTR] += 700;  break;
X
X        case 18: lprcat("\nYou feel a chill run up your spine!");
X                 c[FIRERESISTANCE] += 1000;  break;
X
X        case 0: lprcat("\nYou fall asleep. . .");
X                i=rnd(11)-(c[CONSTITUTION]>>2)+2;  while(--i>0) { parse2();  nap(1000); }
X                cursors();  lprcat("\nYou woke up!");  return;
X
X        case 7: lprcat("\nYou become dizzy!");
X                if (--c[STRENGTH] < 3) c[STRENGTH]=3;  break;
X
X        case 11: lprcat("\nYou stagger for a moment . .");
X                 for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
X                    know[j][i]=0;
X                 nap(2000); draws(0,MAXX,0,MAXY); /* potion of forgetfulness */  return;
X
X        case 13: lprcat("\nYou can't see anything!");  /* blindness */
X                 c[BLINDCOUNT]+=500;  return;
X
X        case 14: lprcat("\nYou feel confused"); c[CONFUSE]+= 20+rnd(9); return;
X
X        case 21: lprcat("\nYou don't seem to be affected");  return; /* cure dianthroritis */
X
X        case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */
X                 c[HALFDAM] += 200 + rnd(200);  return;
X
X        case 23: lprcat("\nYou feel your vision sharpen");  /* see invisible */
X                 c[SEEINVISIBLE] += rnd(1000)+400;
X                 monstnamelist[INVISIBLESTALKER] = 'I';  return;
X        };
X    bottomline();       /*  show new stats      */  return;
X    }
X
X/*
X    function to process a magic scroll
X*/
Xoscroll(typ)
X    int typ;
X    {
X    lprcat("\nDo you ");
X    if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
X    while (1) switch(ttgetch())
X        {
X        case '\33':
X        case 'i':   ignore();  return;
X
X        case 'r':   if (c[BLINDCOUNT]) break;
X                    lprcat("read"); forget();
X                    if (typ==2 || typ==15)  { show1cell(playerx,playery); cursors(); }
X                    /*  destroy it  */  read_scroll(typ);  return;
X
X        case 't':   lprcat("take"); if (take(OSCROLL,typ)==0)   forget();   /*  destroy it  */
X                    return;
X        };
X    }
X
X/*
X    data for the function to read a scroll
X*/
Xstatic int xh,yh,yl,xl;
Xstatic char curse[] = { BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
X    LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM };
Xstatic char exten[] = { PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT,
X    INVISIBILITY, CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP };
Xchar time_change[] = { HASTESELF,HERO,ALTPRO,PROTECTIONTIME,DEXCOUNT,
X    STRCOUNT,GIANTSTR,CHARMCOUNT,INVISIBILITY,CANCELLATION,
X    HASTESELF,AGGRAVATE,SCAREMONST,STEALTH,AWARENESS,HOLDMONST,HASTEMONST,
X    FIRERESISTANCE,GLOBE,SPIRITPRO,UNDEADPRO,HALFDAM,SEEINVISIBLE,
X    ITCHING,CLUMSINESS, WTW };
X/*
X   function to adjust time when time warping and taking courses in school
X*/
Xadjtime(tim)
X    register long tim;
X    {
X    register int j;
X    for (j=0; j<26; j++)    /* adjust time related parameters */
X        if (c[time_change[j]])
X            if ((c[time_change[j]] -= tim) < 1) c[time_change[j]]=1;
X    regen();
X    }
X
X/*
X    function to read a scroll
X*/
Xread_scroll(typ)
X    int typ;
X    {
X    register int i,j;
X    if (typ<0 || typ>=MAXSCROLL) return;  /* be sure we are within bounds */
X    scrollname[typ][0] = ' ';
X    switch(typ)
X      {
X      case 0:   lprcat("\nYour armor glows for a moment");  enchantarmor(); return;
X
X      case 1:   lprcat("\nYour weapon glows for a moment"); enchweapon(); return;  /* enchant weapon */
X
X      case 2:   lprcat("\nYou have been granted enlightenment!");
X                yh = min(playery+7,MAXY);   xh = min(playerx+25,MAXX);
X                yl = max(playery-7,0);      xl = max(playerx-25,0);
X                for (i=yl; i<yh; i++) 
X		    for (j=xl; j<xh; j++)  
X		        know[j][i]=KNOWALL;
X                nap(2000);  draws(xl,xh,yl,yh); return;
X
X      case 3:   lprcat("\nThis scroll seems to be blank");  return;
X
X      case 4:   createmonster(makemonst(level+1));  return;  /*  this one creates a monster  */
X
X      case 5:   something(level);   /*  create artifact     */  return;
X
X      case 6:   c[AGGRAVATE]+=800; return; /* aggravate monsters */
X
X      case 7:   gtime += (i = rnd(1000) - 850); /* time warp */
X                if (i>=0) lprintf("\nYou went forward in time by %d mobuls",(long)((i+99)/100));
X                else lprintf("\nYou went backward in time by %d mobuls",(long)(-(i+99)/100));
X                adjtime((long)i);   /* adjust time for time warping */
X                return;
X
X      case 8:   oteleport(0);     return;   /*  teleportation */
X
X      case 9:   c[AWARENESS] += 1800;  return;  /* expanded awareness   */
X
X      case 10:  c[HASTEMONST] += rnd(55)+12; return;    /* haste monster */
X
X      case 11:  for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
X                    if (mitem[j][i])
X                        hitp[j][i] = monster[mitem[j][i]].hitpoints;
X                return; /* monster healing */
X      case 12:  c[SPIRITPRO] += 300 + rnd(200); bottomline(); return; /* spirit protection */
X
X      case 13:  c[UNDEADPRO] += 300 + rnd(200); bottomline(); return; /* undead protection */
X
X      case 14:  c[STEALTH] += 250 + rnd(250);  bottomline(); return; /* stealth */
X
X      case 15:  lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
X                for (i=0; i<MAXY; i++) 
X		    for (j=0; j<MAXX; j++)  
X			know[j][i]=KNOWALL;
X                nap(2000);  draws(0,MAXX,0,MAXY);   return;
X
X      case 16:  c[HOLDMONST] += 30; bottomline(); return; /* hold monster */
X
X      case 17:  for (i=0; i<26; i++)    /* gem perfection */
X                    switch(iven[i])
X                        {
X                        case ODIAMOND:  case ORUBY:
X                        case OEMERALD:  case OSAPPHIRE:
X                            j = ivenarg[i];  j &= 255;  j <<= 1;
X                            if (j  > 255) j=255; /* double value */
X                            ivenarg[i] = j; break;
X                        }
X                break;
X
X      case 18:  for (i=0; i<11; i++)    c[exten[i]] <<= 1; /* spell extension */
X                break;
X
X      case 19:  for (i=0; i<26; i++)    /* identify */
X                    {
X                    if (iven[i]==OPOTION)  potionname[ivenarg[i]][0] = ' ';
X                    if (iven[i]==OSCROLL)  scrollname[ivenarg[i]][0] = ' ';
X                    }
X                break;
X
X      case 20:  for (i=0; i<10; i++)    /* remove curse */
X                    if (c[curse[i]]) c[curse[i]] = 1;
X                break;
X
X      case 21:  annihilate();   break;  /* scroll of annihilation */
X
X      case 22:  godirect(22,150,"The ray hits the %s",0,' ');   /* pulverization */
X                break;
X      case 23:  c[LIFEPROT]++;  break; /* life protection */
X      };
X    }
X
X
Xoorb()
X    {
X    }
X
Xopit()
X    {
X    register int i;
X    if (rnd(101)<81)
X      if (rnd(70) > 9*c[DEXTERITY]-packweight() || rnd(101)<5)
X        if (level==MAXLEVEL-1) obottomless(); else
X        if (level==MAXLEVEL+MAXVLEVEL-1) obottomless(); else
X            {
X            if (rnd(101)<20)
X                {
X                i=0; lprcat("\nYou fell into a pit!  Your fall is cushioned by an unknown force\n");
X                }
X            else
X                {
X                i = rnd(level*3+3);
X                lprintf("\nYou fell into a pit!  You suffer %d hit points damage",(long)i);
X                lastnum=261;    /*  if he dies scoreboard will say so */
X                }
X            losehp(i); nap(2000);  newcavelevel(level+1);  draws(0,MAXX,0,MAXY);
X            }
X    }
X
Xobottomless()
X    {
X    lprcat("\nYou fell into a bottomless pit!");  beep(); nap(3000);  died(262);
X    }
Xoelevator(dir)
X    int dir;
X    {
X#ifdef lint
X    int x;
X    x=dir;
X    dir=x;
X#endif lint
X    }
X
Xostatue()
X    {
X    }
X
Xomirror()
X    {
X    }
X
Xobook()
X    {
X    lprcat("\nDo you ");
X    if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
X    while (1) switch(ttgetch())
X        {
X        case '\33':
X        case 'i':   ignore();   return;
X
X        case 'r':   if (c[BLINDCOUNT]) break;
X                    lprcat("read");
X                    /* no more book */  readbook(iarg[playerx][playery]);  forget(); return;
X
X        case 't':   lprcat("take");  if (take(OBOOK,iarg[playerx][playery])==0)  forget();  /* no more book */
X                    return;
X        };
X    }
X
X/*
X    function to read a book
X*/
Xreadbook(lev)
X    register int lev;
X    {
X    register int i,tmp;
X    if (lev<=3) i = rund((tmp=splev[lev])?tmp:1); else
X        i = rnd((tmp=splev[lev]-9)?tmp:1) + 9;
X    spelknow[i]=1;
X    lprintf("\nSpell \"%s\":  %s\n%s",spelcode[i],spelname[i],speldescript[i]);
X    if (rnd(10)==4)
X     { lprcat("\nYour int went up by one!"); c[INTELLIGENCE]++; bottomline(); }
X    }
X
Xocookie()
X    {
X    char *p;
X    lprcat("\nDo you (e) eat it, (t) take it"); iopts();
X    while (1) switch(ttgetch())
X        {
X        case '\33':
X        case 'i':   ignore();   return;
X
X        case 'e':   lprcat("eat\nThe cookie tasted good.");
X                    forget(); /* no more cookie */
X                    if (c[BLINDCOUNT]) return;
X# ifdef MSDOS
X                    outfortune();
X# else
X                    if (!(p=fortune(fortfile))) return;
X                    lprcat("  A message inside the cookie reads:\n"); lprcat(p);
X# endif
X                    return;
X
X        case 't':   lprcat("take");  if (take(OCOOKIE,0)==0) forget();  /* no more book */
X                    return;
X        };
X    }
X
X
X/* 
X    routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth 
X    100* the argument 
X*/
Xogold(arg)
X    int arg;
X    {
X    register long i;
X    i = iarg[playerx][playery];
X    if (arg==OMAXGOLD) i *= 100;
X        else if (arg==OKGOLD) i *= 1000;
X            else if (arg==ODGOLD) i *= 10;
X    lprintf("\nIt is worth %d!",(long)i);   c[GOLD] += i;  bottomgold();
X    item[playerx][playery] = know[playerx][playery] = 0; /* destroy gold    */
X    }
X
Xohome()
X    {
X    register int i;
X    nosignal = 1;   /* disable signals */
X    for (i=0; i<26; i++) if (iven[i]==OPOTION) if (ivenarg[i]==21)
X        {
X        iven[i]=0;  /* remove the potion of cure dianthroritis from inventory */
X        clear(); lprcat("Congratulations.  You found a potion of cure dianthroritis.\n");
X        lprcat("\nFrankly, No one thought you could do it.  Boy!  Did you surprise them!\n");
X        if (gtime>TIMELIMIT)
X            {
X# ifdef MSDOS
X    /* The original is a little too morbid for my taste.
X     */
X            lprcat("\nThe doctor has the sad duty to inform you that your daughter died");
X            lprcat("\nbefore your return.  There was nothing he could do without the potion.\n");
X# else
X            lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
X            lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
X# endif
X            nap(5000); died(269);
X            }
X        else
X            {
X            lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
X            lprcat("your daughter should be well on her way to recovery.\n");
X            nap(6000);
X            lprcat("\nThe potion is"); nap(3000); lprcat(" working!  The doctor thinks that\n");
X            lprcat("your daughter will recover in a few days.  Congratulations!\n");
X            beep(); nap(5000); died(263);
X            }
X        }
X
X    while (1)
X        {
X        clear(); lprintf("Welcome home %s.  Latest word from the doctor is not good.\n",logname);
X
X        if (gtime>TIMELIMIT)
X            {
X            lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
X            lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
X            nap(5000); died(269);
X            }
X
X        lprcat("\nThe diagnosis is confirmed as dianthroritis.  He guesses that\n");
X        lprintf("your daughter has only %d mobuls left in this world.  It's up to you,\n",(long)((TIMELIMIT-gtime+99)/100));
X        lprintf("%s, to find the only hope for your daughter, the very rare\n",logname);
X        lprcat("potion of cure dianthroritis.  It is rumored that only deep in the\n");
X        lprcat("depths of the caves can this potion be found.\n\n\n");
X        lprcat("\n     ----- press "); standout("return");
X        lprcat(" to continue, "); standout("escape");
X        lprcat(" to leave ----- ");
X        i=ttgetch();  while (i!='\33' && i!='\n') i=ttgetch();
X        if (i=='\33') { drawscreen(); nosignal = 0; /* enable signals */ return; }
X        }
X    }
X
X/*  routine to save program space   */
Xiopts()
X    {   lprcat(", or (i) ignore it? "); }
Xignore()
X    {   lprcat("ignore\n"); }
X
X/*
X    For prompt mode, prompt for entering a building.
X*/
Xprompt_enter()
X    {
X    char i ;
X
X    lprcat("\nDo you (g) go inside, or (i) stay here? ");
X    i=0;
X    while ((i!='g') && (i!='i') && (i!='\33')) 
X        i=ttgetch();
X    if (i == 'g')
X        enter();
X    else    
X        lprcat(" stay here");
X    }
X
X/*
X    For prompt mode, prompt for climbing up/down the volcanic shaft.
X
X    Takes one parameter: if it is negative, going down the shaft,
X    otherwise, going up the shaft.
X*/
Xprompt_volshaft(dir)
Xint dir;
X    {
X    char i ;
X
X    lprcat("\nDo you (c) climb "); 
X    if (dir > 0)
X        lprcat("up");
X    else
X        lprcat("down");
X    iopts();
X
X    i=0; 
X    while ((i!='c') && (i!='i') && (i!='\33')) 
X        i=ttgetch();
X
X    if ((i=='\33') || (i=='i')) 
X        { 
X        ignore();
X        return; 
X        }
X
X    if (dir > 0)
X        act_up_shaft();
X    else
X        act_down_shaft();
X    }
X
Xo_open_door()
X    {
X    char i;
X    lprcat("\nDo you (c) close it"); iopts();
X    i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=ttgetch();
X    if ((i=='\33') || (i=='i')) 
X        { 
X        ignore();  
X        return; 
X        }
X    lprcat("close");  forget();
X    item[playerx][playery]=OCLOSEDDOOR;
X    iarg[playerx][playery]=0;
X    playerx = lastpx;  playery = lastpy;
X    }
X
Xo_closed_door()
X    {
X    char i;
X    lprcat("\nDo you (o) try to open it"); iopts();
X    i=0; while ((i!='o') && (i!='i') && (i!='\33')) i=ttgetch();
X    if ((i=='\33') || (i=='i'))
X       { ignore();  playerx = lastpx;
X         playery = lastpy; return; }
X    else
X        {
X        lprcat("open");
X        /* if he failed to open the door ... 
X        */
X        if ( !act_open_door( playerx, playery ) )
X            {
X            playerx = lastpx ;
X            playery = lastpy ;
X            }
X        }
X    }
END_OF_FILE
if test 28660 -ne `wc -c <'object.c'`; then
    echo shar: \"'object.c'\" unpacked with wrong size!
fi
# end of 'object.c'
fi
if test -f 'termcap.pc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'termcap.pc'\"
else
echo shar: Extracting \"'termcap.pc'\" \(439 characters\)
sed "s/^X//" >'termcap.pc' <<'END_OF_FILE'
X#
X# Monochrome IBMPC.
X#	This is a termcap for the NANSI.SYS device driver.
X#	It is the same as the ANSI termcap, except NANSI supports
X#	line insert (al) and delete (dl) while ANSI does not.
X#
Xibmpc-mono:\
X	:co#80:\
X	:li#24:\
X	:cl=\E[;H\E[2J:\
X	:bs:\
X	:ho=\E[H:\
X	:cm=\E[%i%2;%2H:\
X	:up=\E[A:\
X	:xd=\E[B:\
X	:nd=\E[C:\
X	:bc=\E[D:\
X	:ce=\E[K:\
X	:ti=\E[m:\
X	:te=\E[m:\
X	:so=\E[1m:\
X	:se=\E[m:\
X	:us=\E[4m:\
X	:ue=\E[m:\
X	:al=\E[L:\
X	:dl=\E[M:
END_OF_FILE
if test 439 -ne `wc -c <'termcap.pc'`; then
    echo shar: \"'termcap.pc'\" unpacked with wrong size!
fi
# end of 'termcap.pc'
fi
echo shar: End of archive 4 \(of 11\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 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