예제 #1
0
void monai(Sint4 mon)
{
  Sint4 monox,monoy,dir,mdirp1,mdirp2,mdirp3,mdirp4,t;
  int clcoll[SPRITES],clfirst[TYPES],i,m,dig;
  bool push,bagf;
  monox=mondat[mon].x;
  monoy=mondat[mon].y;
  if (mondat[mon].xr==0 && mondat[mon].yr==0) {

    /* If we are here the monster needs to know which way to turn next. */

    /* Turn hobbin back into nobbin if it's had its time */

    if (mondat[mon].hnt>30+(levof10()<<1))
      if (!mondat[mon].nob) {
        mondat[mon].hnt=0;
        mondat[mon].nob=true;
      }

    /* Set up monster direction properties to chase Digger */

    dig=mondat[mon].chase;
    if (!digalive(dig))
      dig=(diggers-1)-dig;

    if (abs(diggery(dig)-mondat[mon].y)>abs(diggerx(dig)-mondat[mon].x)) {
      if (diggery(dig)<mondat[mon].y) { mdirp1=DIR_UP;    mdirp4=DIR_DOWN; }
                                 else { mdirp1=DIR_DOWN;  mdirp4=DIR_UP; }
      if (diggerx(dig)<mondat[mon].x) { mdirp2=DIR_LEFT;  mdirp3=DIR_RIGHT; }
                                 else { mdirp2=DIR_RIGHT; mdirp3=DIR_LEFT; }
    }
    else {
      if (diggerx(dig)<mondat[mon].x) { mdirp1=DIR_LEFT;  mdirp4=DIR_RIGHT; }
                                 else { mdirp1=DIR_RIGHT; mdirp4=DIR_LEFT; }
      if (diggery(dig)<mondat[mon].y) { mdirp2=DIR_UP;    mdirp3=DIR_DOWN; }
                                 else { mdirp2=DIR_DOWN;  mdirp3=DIR_UP; }
    }

    /* In bonus mode, run away from Digger */

    if (bonusmode) {
      t=mdirp1; mdirp1=mdirp4; mdirp4=t;
      t=mdirp2; mdirp2=mdirp3; mdirp3=t;
    }

    /* Adjust priorities so that monsters don't reverse direction unless they
       really have to */

    dir=reversedir(mondat[mon].dir);
    if (dir==mdirp1) {
      mdirp1=mdirp2;
      mdirp2=mdirp3;
      mdirp3=mdirp4;
      mdirp4=dir;
    }
    if (dir==mdirp2) {
      mdirp2=mdirp3;
      mdirp3=mdirp4;
      mdirp4=dir;
    }
    if (dir==mdirp3) {
      mdirp3=mdirp4;
      mdirp4=dir;
    }

    /* Introduce a random element on levels <6 : occasionally swap p1 and p3 */

    if (randno(levof10()+5)==1) /* Need to split for determinism */
      if (levof10()<6) {
        t=mdirp1;
        mdirp1=mdirp3;
        mdirp3=t;
      }

    /* Check field and find direction */

    if (fieldclear(mdirp1,mondat[mon].h,mondat[mon].v))
      dir=mdirp1;
    else
      if (fieldclear(mdirp2,mondat[mon].h,mondat[mon].v))
        dir=mdirp2;
      else
        if (fieldclear(mdirp3,mondat[mon].h,mondat[mon].v))
          dir=mdirp3;
        else
          if (fieldclear(mdirp4,mondat[mon].h,mondat[mon].v))
            dir=mdirp4;

    /* Hobbins don't care about the field: they go where they want. */

    if (!mondat[mon].nob)
      dir=mdirp1;

    /* Monsters take a time penalty for changing direction */

    if (mondat[mon].dir!=dir)
      mondat[mon].t++;

    /* Save the new direction */

    mondat[mon].dir=dir;
  }

  /* If monster is about to go off edge of screen, stop it. */

  if ((mondat[mon].x==292 && mondat[mon].dir==DIR_RIGHT) ||
      (mondat[mon].x==12 && mondat[mon].dir==DIR_LEFT) ||
      (mondat[mon].y==180 && mondat[mon].dir==DIR_DOWN) ||
      (mondat[mon].y==18 && mondat[mon].dir==DIR_UP))
    mondat[mon].dir=DIR_NONE;

  /* Change hdir for hobbin */

  if (mondat[mon].dir==DIR_LEFT || mondat[mon].dir==DIR_RIGHT)
    mondat[mon].hdir=mondat[mon].dir;

  /* Hobbins dig */

  if (!mondat[mon].nob)
    eatfield(mondat[mon].x,mondat[mon].y,mondat[mon].dir);

  /* (Draw new tunnels) and move monster */

  switch (mondat[mon].dir) {
    case DIR_RIGHT:
      if (!mondat[mon].nob)
        drawrightblob(mondat[mon].x,mondat[mon].y);
      mondat[mon].x+=4;
      break;
    case DIR_UP:
      if (!mondat[mon].nob)
        drawtopblob(mondat[mon].x,mondat[mon].y);
      mondat[mon].y-=3;
      break;
    case DIR_LEFT:
      if (!mondat[mon].nob)
        drawleftblob(mondat[mon].x,mondat[mon].y);
      mondat[mon].x-=4;
      break;
    case DIR_DOWN:
      if (!mondat[mon].nob)
        drawbottomblob(mondat[mon].x,mondat[mon].y);
      mondat[mon].y+=3;
      break;
  }

  /* Hobbins can eat emeralds */

  if (!mondat[mon].nob)
    hitemerald((mondat[mon].x-12)/20,(mondat[mon].y-18)/18,
               (mondat[mon].x-12)%20,(mondat[mon].y-18)%18,
               mondat[mon].dir);

  /* If Digger's gone, don't bother */

  if (!isalive()) {
    mondat[mon].x=monox;
    mondat[mon].y=monoy;
  }

  /* If monster's just started, don't move yet */

  if (mondat[mon].stime!=0) {
    mondat[mon].stime--;
    mondat[mon].x=monox;
    mondat[mon].y=monoy;
  }

  /* Increase time counter for hobbin */

  if (!mondat[mon].nob && mondat[mon].hnt<100)
    mondat[mon].hnt++;

  /* Draw monster */

  push=true;
  drawmon(mon,mondat[mon].nob,mondat[mon].hdir,mondat[mon].x,mondat[mon].y);
  for (i=0;i<TYPES;i++)
    clfirst[i]=first[i];
  for (i=0;i<SPRITES;i++)
    clcoll[i]=coll[i];
  incpenalty();

  /* Collision with another monster */

  if (clfirst[2]!=-1) {
    mondat[mon].t++; /* Time penalty */
    /* Ensure both aren't moving in the same dir. */
    i=clfirst[2];
    do {
      m=i-FIRSTMONSTER;
      if (mondat[mon].dir==mondat[m].dir && mondat[m].stime==0 &&
          mondat[mon].stime==0)
        mondat[m].dir=reversedir(mondat[m].dir);
      /* The kludge here is to preserve playback for a bug in previous
         versions. */
      if (!kludge)
        incpenalty();
      else
        if (!(m&1))
          incpenalty();
      i=clcoll[i];
    } while (i!=-1);
    if (kludge)
      if (clfirst[0]!=-1)
        incpenalty();
  }

  /* Check for collision with bag */

  i=clfirst[1];
  bagf=false;
  while (i!=-1) {
    if (bagexist(i-FIRSTBAG)) {
      bagf=true;
      break;
    }
    i=clcoll[i];
  }

  if (bagf) {
    mondat[mon].t++; /* Time penalty */
    mongotgold=false;
    if (mondat[mon].dir==DIR_RIGHT || mondat[mon].dir==DIR_LEFT) {
      push=pushbags(mondat[mon].dir,clfirst,clcoll);      /* Horizontal push */
      mondat[mon].t++; /* Time penalty */
    }
    else
      if (!pushudbags(clfirst,clcoll)) /* Vertical push */
        push=false;
    if (mongotgold) /* No time penalty if monster eats gold */
      mondat[mon].t=0;
    if (!mondat[mon].nob && mondat[mon].hnt>1)
      removebags(clfirst,clcoll); /* Hobbins eat bags */
  }

  /* Increase hobbin cross counter */

  if (mondat[mon].nob && clfirst[2]!=-1 && isalive())
    mondat[mon].hnt++;

  /* See if bags push monster back */

  if (!push) {
    mondat[mon].x=monox;
    mondat[mon].y=monoy;
    drawmon(mon,mondat[mon].nob,mondat[mon].hdir,mondat[mon].x,mondat[mon].y);
    incpenalty();
    if (mondat[mon].nob) /* The other way to create hobbin: stuck on h-bag */
      mondat[mon].hnt++;
    if ((mondat[mon].dir==DIR_UP || mondat[mon].dir==DIR_DOWN) &&
        mondat[mon].nob)
      mondat[mon].dir=reversedir(mondat[mon].dir); /* If vertical, give up */
  }

  /* Collision with Digger */

  if (clfirst[4]!=-1 && isalive())
    if (bonusmode) {
      killmon(mon);
      i=clfirst[4];
      while (i!=-1) {
        if (digalive(i-FIRSTDIGGER+curplayer))
          sceatm(i-FIRSTDIGGER+curplayer);
        i=clcoll[i];
      }
      soundeatm(); /* Collision in bonus mode */
    }
    else {
      i=clfirst[4];
      while (i!=-1) {
        if (digalive(i-FIRSTDIGGER+curplayer))
          killdigger(i-FIRSTDIGGER+curplayer,3,0); /* Kill Digger */
        i=clcoll[i];
      }
    }

  /* Update co-ordinates */

  mondat[mon].h=(mondat[mon].x-12)/20;
  mondat[mon].v=(mondat[mon].y-18)/18;
  mondat[mon].xr=(mondat[mon].x-12)%20;
  mondat[mon].yr=(mondat[mon].y-18)%18;
}
예제 #2
0
파일: digger.c 프로젝트: LibreGames/digger
static void
updatedigger(struct digger_draw_api *ddap, int n)
{
  int16_t dir,ddir,diggerox,diggeroy,nmon;
  bool push=true,bagf;
  int clfirst[TYPES],clcoll[SPRITES],i;
  readdirect(n-curplayer);
  dir=getdirect(n-curplayer);
  if (dir==DIR_RIGHT || dir==DIR_UP || dir==DIR_LEFT || dir==DIR_DOWN)
    ddir=dir;
  else
    ddir=DIR_NONE;
  if (digdat[n].rx==0 && (ddir==DIR_UP || ddir==DIR_DOWN))
    digdat[n].dob.dir=digdat[n].mdir=ddir;
  if (digdat[n].ry==0 && (ddir==DIR_RIGHT || ddir==DIR_LEFT))
    digdat[n].dob.dir=digdat[n].mdir=ddir;
  if (dir==DIR_NONE)
    digdat[n].mdir=DIR_NONE;
  else
    digdat[n].mdir=digdat[n].dob.dir;
  if ((digdat[n].dob.x==292 && digdat[n].mdir==DIR_RIGHT) ||
      (digdat[n].dob.x==12 && digdat[n].mdir==DIR_LEFT) ||
      (digdat[n].dob.y==180 && digdat[n].mdir==DIR_DOWN) ||
      (digdat[n].dob.y==18 && digdat[n].mdir==DIR_UP))
    digdat[n].mdir=DIR_NONE;
  diggerox=digdat[n].dob.x;
  diggeroy=digdat[n].dob.y;
  if (digdat[n].mdir!=DIR_NONE)
    eatfield(diggerox,diggeroy,digdat[n].mdir);
  switch (digdat[n].mdir) {
    case DIR_RIGHT:
      drawrightblob(digdat[n].dob.x,digdat[n].dob.y);
      digdat[n].dob.x+=4;
      break;
    case DIR_UP:
      drawtopblob(digdat[n].dob.x,digdat[n].dob.y);
      digdat[n].dob.y-=3;
      break;
    case DIR_LEFT:
      drawleftblob(digdat[n].dob.x,digdat[n].dob.y);
      digdat[n].dob.x-=4;
      break;
    case DIR_DOWN:
      drawbottomblob(digdat[n].dob.x,digdat[n].dob.y);
      digdat[n].dob.y+=3;
      break;
  }
  if (hitemerald((digdat[n].dob.x-12)/20,(digdat[n].dob.y-18)/18,
                 (digdat[n].dob.x-12)%20,(digdat[n].dob.y-18)%18,
                 digdat[n].mdir)) {
    if (digdat[n].emocttime==0)
      digdat[n].emn=0;
    scoreemerald(ddap, n);
    soundem();
    soundemerald(digdat[n].emn);

    digdat[n].emn++;
    if (digdat[n].emn==8) {
      digdat[n].emn=0;
      scoreoctave(ddap, n);
    }
    digdat[n].emocttime=9;
  }
  drawdig(n);
  for (i=0;i<TYPES;i++)
    clfirst[i]=first[i];
  for (i=0;i<SPRITES;i++)
    clcoll[i]=coll[i];
  incpenalty();

  i=clfirst[1];
  bagf=false;
  while (i!=-1) {
    if (bagexist(i-FIRSTBAG)) {
      bagf=true;
      break;
    }
    i=clcoll[i];
  }

  if (bagf) {
    if (digdat[n].mdir==DIR_RIGHT || digdat[n].mdir==DIR_LEFT) {
      push=pushbags(ddap, digdat[n].mdir,clfirst,clcoll);
      digdat[n].bagtime++;
    }
    else
      if (!pushudbags(ddap, clfirst,clcoll))
        push=false;
    if (!push) { /* Strange, push not completely defined */
      digdat[n].dob.x=diggerox;
      digdat[n].dob.y=diggeroy;
      digdat[n].dob.dir = digdat[n].mdir;
      drawdig(n);
      incpenalty();
      digdat[n].dob.dir=reversedir(digdat[n].mdir);
    }
  }
  if (clfirst[2]!=-1 && bonusmode && digdat[n].dob.alive)
    for (nmon=killmonsters(clfirst,clcoll);nmon!=0;nmon--) {
      soundeatm();
      sceatm(ddap, n);
    }
  if (clfirst[0]!=-1) {
    scorebonus(ddap, n);
    initbonusmode(ddap);
  }
  digdat[n].h=(digdat[n].dob.x-12)/20;
  digdat[n].rx=(digdat[n].dob.x-12)%20;
  digdat[n].v=(digdat[n].dob.y-18)/18;
  digdat[n].ry=(digdat[n].dob.y-18)%18;
}