Annotation of 43BSDReno/games/larn/movem.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     movem.c (move monster)          Larn is copyrighted 1986 by Noah Morgan.
                      3:  *
                      4:  *     Here are the functions in this file:
                      5:  *
                      6:  *     movemonst()             Routine to move the monsters toward the player
                      7:  *     movemt(x,y)             Function to move a monster at (x,y) -- must determine where
                      8:  *     mmove(x,y,xd,yd)        Function to actually perform the monster movement
                      9:  *     movsphere()             Function to look for and move spheres of annihilation
                     10:  */
                     11: #include "header.h"
                     12: 
                     13: /*
                     14:  *     movemonst()             Routine to move the monsters toward the player
                     15:  *
                     16:  *     This routine has the responsibility to determine which monsters are to
                     17:  *     move, and call movemt() to do the move.
                     18:  *     Returns no value.
                     19:  */
                     20: static short w1[9],w1x[9],w1y[9];
                     21: static int tmp1,tmp2,tmp3,tmp4,distance;
                     22: movemonst()
                     23:        {
                     24:        register int i,j;
                     25:        if (c[TIMESTOP]) return;        /* no action if time is stopped */
                     26:        if (c[HASTESELF])  if ((c[HASTESELF]&1)==0)  return;
                     27:        if (spheres) movsphere();       /* move the spheres of annihilation if any */
                     28:        if (c[HOLDMONST])  return;      /* no action if monsters are held */
                     29: 
                     30:        if (c[AGGRAVATE])       /* determine window of monsters to move */
                     31:          {
                     32:          tmp1=playery-5; tmp2=playery+6; tmp3=playerx-10; tmp4=playerx+11;
                     33:          distance=40; /* depth of intelligent monster movement */
                     34:          }
                     35:        else
                     36:          {
                     37:          tmp1=playery-3; tmp2=playery+4; tmp3=playerx-5; tmp4=playerx+6;
                     38:          distance=17; /* depth of intelligent monster movement */
                     39:          }
                     40: 
                     41:        if (level == 0) /* if on outside level monsters can move in perimeter */
                     42:                {
                     43:                if (tmp1 < 0) tmp1=0;            if (tmp2 > MAXY) tmp2=MAXY;
                     44:                if (tmp3 < 0) tmp3=0;            if (tmp4 > MAXX) tmp4=MAXX;
                     45:                }
                     46:        else /* if in a dungeon monsters can't be on the perimeter (wall there) */
                     47:                {
                     48:                if (tmp1 < 1) tmp1=1;            if (tmp2 > MAXY-1) tmp2=MAXY-1;
                     49:                if (tmp3 < 1) tmp3=1;            if (tmp4 > MAXX-1) tmp4=MAXX-1;
                     50:                }
                     51: 
                     52:        for (j=tmp1; j<tmp2; j++) /* now reset monster moved flags */
                     53:                for (i=tmp3; i<tmp4; i++)
                     54:                        moved[i][j] = 0;
                     55:     moved[lasthx][lasthy]=0;
                     56: 
                     57:        if (c[AGGRAVATE] || !c[STEALTH]) /* who gets moved? split for efficiency */
                     58:          {
                     59:          for (j=tmp1; j<tmp2; j++) /* look thru all locations in window */
                     60:            for (i=tmp3; i<tmp4; i++)
                     61:                  if (mitem[i][j])      /* if there is a monster to move */
                     62:                    if (moved[i][j]==0) /* if it has not already been moved */
                     63:                          movemt(i,j);  /* go and move the monster */
                     64:          }
                     65:        else /* not aggravated and not stealth */
                     66:          {
                     67:          for (j=tmp1; j<tmp2; j++) /* look thru all locations in window */
                     68:            for (i=tmp3; i<tmp4; i++)
                     69:                  if (mitem[i][j])      /* if there is a monster to move */
                     70:                    if (moved[i][j]==0) /* if it has not already been moved */
                     71:                          if (stealth[i][j])    /* if it is asleep due to stealth */
                     72:                            movemt(i,j);        /* go and move the monster */
                     73:          }
                     74: 
                     75:        if (mitem[lasthx][lasthy]) /* now move monster last hit by player if not already moved */
                     76:                {
                     77:            if (moved[lasthx][lasthy]==0)       /* if it has not already been moved */
                     78:                        {
                     79:                        movemt(lasthx,lasthy);
                     80:                        lasthx = w1x[0];   lasthy = w1y[0];
                     81:                        }
                     82:                }
                     83:        }
                     84: 
                     85: /*
                     86:  *     movemt(x,y)             Function to move a monster at (x,y) -- must determine where
                     87:  *             int x,y;
                     88:  *
                     89:  *     This routine is responsible for determining where one monster at (x,y) will
                     90:  *     move to.  Enter with the monsters coordinates in (x,y).
                     91:  *     Returns no value.
                     92:  */
                     93: static int tmpitem,xl,xh,yl,yh;
                     94: movemt(i,j)
                     95:        int i,j;
                     96:        {
                     97:        register int k,m,z,tmp,xtmp,ytmp,monst;
                     98:        switch(monst=mitem[i][j])  /* for half speed monsters */
                     99:                {
                    100:                case TROGLODYTE:  case HOBGOBLIN:  case METAMORPH:  case XVART:
                    101:                case INVISIBLESTALKER:  case ICELIZARD: if ((gtime & 1) == 1) return;
                    102:                };
                    103: 
                    104:        if (c[SCAREMONST]) /* choose destination randomly if scared */
                    105:                {
                    106:                if ((xl = i+rnd(3)-2) < 0) xl=0;  if (xl >= MAXX) xl=MAXX-1;
                    107:                if ((yl = j+rnd(3)-2) < 0) yl=0;  if (yl >= MAXY) yl=MAXY-1;
                    108:                if ((tmp=item[xl][yl]) != OWALL)
                    109:                  if (mitem[xl][yl] == 0)
                    110:                        if ((mitem[i][j] != VAMPIRE) || (tmpitem != OMIRROR))
                    111:                          if (tmp != OCLOSEDDOOR)               mmove(i,j,xl,yl);
                    112:                return;
                    113:                }
                    114: 
                    115:        if (monster[monst].intelligence > 10-c[HARDGAME]) /* if smart monster */
                    116: /* intelligent movement here -- first setup screen array */
                    117:          {
                    118:          xl=tmp3-2; yl=tmp1-2; xh=tmp4+2;  yh=tmp2+2;
                    119:          vxy(&xl,&yl);  vxy(&xh,&yh);
                    120:          for (k=yl; k<yh; k++)
                    121:            for (m=xl; m<xh; m++)
                    122:                  {
                    123:                  switch(item[m][k])
                    124:                        {
                    125:                        case OWALL: case OPIT: case OTRAPARROW: case ODARTRAP:
                    126:                        case OCLOSEDDOOR: case OTRAPDOOR: case OTELEPORTER:
                    127:                                smm:      screen[m][k]=127;  break;
                    128:                        case OMIRROR: if (mitem[m][k]==VAMPIRE) goto smm;
                    129:                        default:  screen[m][k]=  0;  break;
                    130:                        };
                    131:                  }
                    132:          screen[playerx][playery]=1;
                    133: 
                    134: /* now perform proximity ripple from playerx,playery to monster */
                    135:          xl=tmp3-1; yl=tmp1-1; xh=tmp4+1;  yh=tmp2+1;
                    136:          vxy(&xl,&yl);  vxy(&xh,&yh);
                    137:          for (tmp=1; tmp<distance; tmp++)      /* only up to 20 squares away */
                    138:            for (k=yl; k<yh; k++)
                    139:              for (m=xl; m<xh; m++)
                    140:                    if (screen[m][k]==tmp) /* if find proximity n advance it */
                    141:                          for (z=1; z<9; z++) /* go around in a circle */
                    142:                            {
                    143:                            if (screen[xtmp=m+diroffx[z]][ytmp=k+diroffy[z]]==0)
                    144:                                  screen[xtmp][ytmp]=tmp+1;
                    145:                            if (xtmp==i && ytmp==j) goto out;
                    146:                            }
                    147: 
                    148: out:  if (tmp<distance) /* did find connectivity */
                    149:                /* now select lowest value around playerx,playery */
                    150:                for (z=1; z<9; z++) /* go around in a circle */
                    151:                  if (screen[xl=i+diroffx[z]][yl=j+diroffy[z]]==tmp)
                    152:                        if (!mitem[xl][yl]) { mmove(i,j,w1x[0]=xl,w1y[0]=yl); return; }
                    153:          }
                    154: 
                    155:        /* dumb monsters move here */
                    156:        xl=i-1;  yl=j-1;  xh=i+2;  yh=j+2;
                    157:        if (i<playerx) xl++; else if (i>playerx) --xh;
                    158:        if (j<playery) yl++; else if (j>playery) --yh;
                    159:        for (k=0; k<9; k++) w1[k] = 10000;
                    160: 
                    161:        for (k=xl; k<xh; k++)
                    162:                for (m=yl; m<yh; m++) /* for each square compute distance to player */
                    163:                        {
                    164:                        tmp = k-i+4+3*(m-j);
                    165:                        tmpitem = item[k][m];
                    166:                        if (tmpitem!=OWALL || (k==playerx && m==playery))
                    167:                         if (mitem[k][m]==0)
                    168:                          if ((mitem[i][j] != VAMPIRE) || (tmpitem != OMIRROR))
                    169:                                 if (tmpitem!=OCLOSEDDOOR)
                    170:                                        {
                    171:                                        w1[tmp] = (playerx-k)*(playerx-k)+(playery-m)*(playery-m);
                    172:                                        w1x[tmp] = k;  w1y[tmp] = m;
                    173:                                        }
                    174:                        }
                    175: 
                    176:        tmp = 0;
                    177:        for (k=1; k<9; k++)  if (w1[tmp] > w1[k])  tmp=k;
                    178: 
                    179:        if (w1[tmp] < 10000)
                    180:                if ((i!=w1x[tmp]) || (j!=w1y[tmp]))
                    181:                        mmove(i,j,w1x[tmp],w1y[tmp]);
                    182:        }
                    183: 
                    184: /*
                    185:  *     mmove(x,y,xd,yd)        Function to actually perform the monster movement
                    186:  *             int x,y,xd,yd;
                    187:  *
                    188:  *     Enter with the from coordinates in (x,y) and the destination coordinates
                    189:  *     in (xd,yd).
                    190:  */
                    191: mmove(aa,bb,cc,dd)
                    192:        int aa,bb,cc,dd;
                    193:        {
                    194:        register int tmp,i,flag;
                    195:        char *who,*p;
                    196:        flag=0; /* set to 1 if monster hit by arrow trap */
                    197:        if ((cc==playerx) && (dd==playery))
                    198:                {
                    199:                hitplayer(aa,bb);  moved[aa][bb] = 1;  return;
                    200:                }
                    201:        i=item[cc][dd];
                    202:        if ((i==OPIT) || (i==OTRAPDOOR))
                    203:          switch(mitem[aa][bb])
                    204:                {
                    205:                case SPIRITNAGA:        case PLATINUMDRAGON:    case WRAITH:
                    206:                case VAMPIRE:           case SILVERDRAGON:              case POLTERGEIST:
                    207:                case DEMONLORD:         case DEMONLORD+1:               case DEMONLORD+2:
                    208:                case DEMONLORD+3:       case DEMONLORD+4:               case DEMONLORD+5:
                    209:                case DEMONLORD+6:       case DEMONPRINCE:       break;
                    210: 
                    211:                default:        mitem[aa][bb]=0; /* fell in a pit or trapdoor */
                    212:                };
                    213:        tmp = mitem[cc][dd] = mitem[aa][bb];
                    214:        if (i==OANNIHILATION)
                    215:                {
                    216:                if (tmp>=DEMONLORD+3) /* demons dispel spheres */
                    217:                        {
                    218:                        cursors();
                    219:                        lprintf("\nThe %s dispels the sphere!",monster[tmp].name);
                    220:                        rmsphere(cc,dd);        /* delete the sphere */
                    221:                        }
                    222:                else i=tmp=mitem[cc][dd]=0;
                    223:                }
                    224:        stealth[cc][dd]=1;
                    225:        if ((hitp[cc][dd] = hitp[aa][bb]) < 0) hitp[cc][dd]=1;
                    226:        mitem[aa][bb] = 0;                              moved[cc][dd] = 1;
                    227:        if (tmp == LEPRECHAUN)
                    228:                switch(i)
                    229:                        {
                    230:                        case OGOLDPILE:  case OMAXGOLD:  case OKGOLD:  case ODGOLD:
                    231:                        case ODIAMOND:   case ORUBY:     case OEMERALD: case OSAPPHIRE:
                    232:                                        item[cc][dd] = 0; /* leprechaun takes gold */
                    233:                        };
                    234: 
                    235:        if (tmp == TROLL)  /* if a troll regenerate him */
                    236:                if ((gtime & 1) == 0)
                    237:                        if (monster[tmp].hitpoints > hitp[cc][dd])  hitp[cc][dd]++;
                    238: 
                    239:        if (i==OTRAPARROW)      /* arrow hits monster */
                    240:                { who = "An arrow";  if ((hitp[cc][dd] -= rnd(10)+level) <= 0)
                    241:                        { mitem[cc][dd]=0;  flag=2; } else flag=1; }
                    242:        if (i==ODARTRAP)        /* dart hits monster */
                    243:                { who = "A dart";  if ((hitp[cc][dd] -= rnd(6)) <= 0)
                    244:                        { mitem[cc][dd]=0;  flag=2; } else flag=1; }
                    245:        if (i==OTELEPORTER)     /* monster hits teleport trap */
                    246:                { flag=3; fillmonst(mitem[cc][dd]);  mitem[cc][dd]=0; }
                    247:        if (c[BLINDCOUNT]) return;      /* if blind don't show where monsters are       */
                    248:        if (know[cc][dd] & 1) 
                    249:                {
                    250:                p=0;
                    251:                if (flag) cursors();
                    252:                switch(flag)
                    253:                  {
                    254:                  case 1: p="\n%s hits the %s";  break;
                    255:                  case 2: p="\n%s hits and kills the %s";  break;
                    256:                  case 3: p="\nThe %s%s gets teleported"; who="";  break;
                    257:                  };
                    258:                if (p) { lprintf(p,who,monster[tmp].name); beep(); }
                    259:                }
                    260: /*     if (yrepcount>1) { know[aa][bb] &= 2;  know[cc][dd] &= 2; return; } */
                    261:        if (know[aa][bb] & 1)   show1cell(aa,bb);
                    262:        if (know[cc][dd] & 1)   show1cell(cc,dd);
                    263:        }
                    264: 
                    265: /*
                    266:  *     movsphere()     Function to look for and move spheres of annihilation
                    267:  *
                    268:  *     This function works on the sphere linked list, first duplicating the list
                    269:  *     (the act of moving changes the list), then processing each sphere in order
                    270:  *     to move it.  They eat anything in their way, including stairs, volcanic
                    271:  *     shafts, potions, etc, except for upper level demons, who can dispel
                    272:  *     spheres.
                    273:  *     No value is returned.
                    274:  */
                    275: #define SPHMAX 20      /* maximum number of spheres movsphere can handle */
                    276: movsphere()
                    277:        {
                    278:        register int x,y,dir,len;
                    279:        register struct sphere *sp,*sp2;
                    280:        struct sphere sph[SPHMAX];
                    281: 
                    282:        /* first duplicate sphere list */
                    283:        for (sp=0,x=0,sp2=spheres; sp2; sp2=sp2->p)     /* look through sphere list */
                    284:          if (sp2->lev == level)        /* only if this level */
                    285:                {
                    286:                sph[x] = *sp2;  sph[x++].p = 0;  /* copy the struct */
                    287:                if (x>1)  sph[x-2].p = &sph[x-1]; /* link pointers */
                    288:                }
                    289:        if (x) sp= sph; /* if any spheres, point to them */
                    290:                else return;    /* no spheres */
                    291: 
                    292:        for (sp=sph; sp; sp=sp->p)      /* look through sphere list */
                    293:                {
                    294:                x = sp->x;        y = sp->y;
                    295:                if (item[x][y]!=OANNIHILATION) continue;        /* not really there */
                    296:                if (--(sp->lifetime) < 0)       /* has sphere run out of gas? */
                    297:                        {
                    298:                        rmsphere(x,y); /* delete sphere */
                    299:                        continue;
                    300:                        }
                    301:                switch(rnd((int)max(7,c[INTELLIGENCE]>>1))) /* time to move the sphere */
                    302:                        {
                    303:                        case 1:
                    304:                        case 2:         /* change direction to a random one */
                    305:                                                sp->dir = rnd(8);
                    306:                        default:        /* move in normal direction */
                    307:                                                dir = sp->dir;          len = sp->lifetime;
                    308:                                                rmsphere(x,y);
                    309:                                                newsphere(x+diroffx[dir],y+diroffy[dir],dir,len);
                    310:                        };
                    311:                }
                    312:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.