Annotation of 43BSDReno/games/larn/movem.c, revision 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.