Ejemplo n.º 1
0
static void
updatefire(struct digger_draw_api *ddap, int n)
{
  int16_t pix=0, fx, fy;
  int clfirst[TYPES],clcoll[SPRITES],i;
  bool clflag;
  if (digdat[n].notfiring) {
    if (digdat[n].rechargetime!=0) {
      digdat[n].rechargetime--;
      if (digdat[n].rechargetime == 0) {
        CALL_METHOD(&digdat[n].dob, recharge);
      }
    } else {
      if (getfirepflag(n-curplayer)) {
        if (digdat[n].dob.alive) {
          CALL_METHOD(&digdat[n].dob, discharge);
          digdat[n].rechargetime=levof10()*3+60;
          digdat[n].notfiring=false;
          switch (digdat[n].dob.dir) {
            case DIR_RIGHT:
              fx = digdat[n].dob.x + 8;
              fy = digdat[n].dob.y + 4;
              break;
            case DIR_UP:
              fx = digdat[n].dob.x + 4;
              fy = digdat[n].dob.y;
              break;
            case DIR_LEFT:
              fx = digdat[n].dob.x;
              fy = digdat[n].dob.y + 4;
              break;
            case DIR_DOWN:
              fx = digdat[n].dob.x + 4;
              fy = digdat[n].dob.y + 8;
              break;
            default:
              abort();
          }
          bullet_obj_init(&digdat[n].bob, n - curplayer, digdat[n].dob.dir, fx, fy);
          CALL_METHOD(&digdat[n].bob, put);
          soundfire(n);
        }
      }
    }
  }
  else {
    switch (digdat[n].bob.dir) {
      case DIR_RIGHT:
        digdat[n].bob.x+=8;
        pix=ddap->ggetpix(digdat[n].bob.x,digdat[n].bob.y+4)|
            ddap->ggetpix(digdat[n].bob.x+4,digdat[n].bob.y+4);
        break;
      case DIR_UP:
        digdat[n].bob.y-=7;
        pix=0;
        for (i=0;i<7;i++)
          pix|=ddap->ggetpix(digdat[n].bob.x+4,digdat[n].bob.y+i);
        pix&=0xc0;
        break;
      case DIR_LEFT:
        digdat[n].bob.x-=8;
        pix=ddap->ggetpix(digdat[n].bob.x,digdat[n].bob.y+4)|
            ddap->ggetpix(digdat[n].bob.x+4,digdat[n].bob.y+4);
        break;
      case DIR_DOWN:
        digdat[n].bob.y+=7;
        pix=0;
        for (i=0;i<7;i++)
          pix|=ddap->ggetpix(digdat[n].bob.x,digdat[n].bob.y+i);
        pix&=0x3;
        break;       
    }
    CALL_METHOD(&digdat[n].bob, animate);
    for (i=0;i<TYPES;i++)
      clfirst[i]=first[i];
    for (i=0;i<SPRITES;i++)
      clcoll[i]=coll[i];
    incpenalty();
    i=clfirst[2];
    while (i!=-1) {
      killmon(i-FIRSTMONSTER);
      scorekill(ddap, n);
      CALL_METHOD(&digdat[n].bob, explode);
      i=clcoll[i];
    }
    i=clfirst[4];
    while (i!=-1) {
      if (i-FIRSTDIGGER+curplayer!=n && !digdat[i-FIRSTDIGGER+curplayer].invin
          && digdat[i-FIRSTDIGGER+curplayer].dob.alive) {
        killdigger(i-FIRSTDIGGER+curplayer,3,0);
        CALL_METHOD(&digdat[n].bob, explode);
      }
      i=clcoll[i];
    }
    if (clfirst[0]!=-1 || clfirst[1]!=-1 || clfirst[2]!=-1 || clfirst[3]!=-1 ||
        clfirst[4]!=-1)
      clflag=true;
    else
      clflag=false;
    if (clfirst[0]!=-1 || clfirst[1]!=-1 || clfirst[3]!=-1) {
      CALL_METHOD(&digdat[n].bob, explode);
      i=clfirst[3];
      while (i!=-1) {
        if (digdat[i-FIRSTFIREBALL+curplayer].bob.expsn==0) {
          CALL_METHOD(&digdat[i-FIRSTFIREBALL+curplayer].bob, explode);
        }
        i=clcoll[i];
      }
    }
    switch (digdat[n].bob.dir) {
      case DIR_RIGHT:
        if (digdat[n].bob.x>296) {
          CALL_METHOD(&digdat[n].bob, explode);
        } else {
          if (pix!=0 && !clflag) {
            digdat[n].bob.x-=8;
            CALL_METHOD(&digdat[n].bob, animate);
            CALL_METHOD(&digdat[n].bob, explode);
          }
        }
        break;
      case DIR_UP:
        if (digdat[n].bob.y<15) {
          CALL_METHOD(&digdat[n].bob, explode);
        } else {
          if (pix!=0 && !clflag) {
            digdat[n].bob.y+=7;
            CALL_METHOD(&digdat[n].bob, animate);
            CALL_METHOD(&digdat[n].bob, explode);
          }
        }
        break;
      case DIR_LEFT:
        if (digdat[n].bob.x<16) {
          CALL_METHOD(&digdat[n].bob, explode);
        } else {
          if (pix!=0 && !clflag) {
            digdat[n].bob.x+=8;
            CALL_METHOD(&digdat[n].bob, animate);
            CALL_METHOD(&digdat[n].bob, explode);
          }
        }
        break;
      case DIR_DOWN:
        if (digdat[n].bob.y>183) {
          CALL_METHOD(&digdat[n].bob, explode);
        } else {
          if (pix!=0 && !clflag) {
            digdat[n].bob.y-=7;
            CALL_METHOD(&digdat[n].bob, animate);
            CALL_METHOD(&digdat[n].bob, explode);
          }
        }
    }
  }
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
void updatefire(int n)
{
  Sint4 pix;
  int clfirst[TYPES],clcoll[SPRITES],i;
  bool clflag;
  if (digdat[n].notfiring) {
    if (digdat[n].rechargetime!=0)
      digdat[n].rechargetime--;
    else
      if (getfirepflag(n-curplayer))
        if (digdat[n].alive) {
          digdat[n].rechargetime=levof10()*3+60;
          digdat[n].notfiring=FALSE;
          switch (digdat[n].dir) {
            case DIR_RIGHT:
              digdat[n].fx=digdat[n].x+8;
              digdat[n].fy=digdat[n].y+4;
              break;
            case DIR_UP:
              digdat[n].fx=digdat[n].x+4;
              digdat[n].fy=digdat[n].y;
              break;
            case DIR_LEFT:
              digdat[n].fx=digdat[n].x;
              digdat[n].fy=digdat[n].y+4;
              break;
            case DIR_DOWN:
              digdat[n].fx=digdat[n].x+4;
              digdat[n].fy=digdat[n].y+8;
          }
          digdat[n].fdir=digdat[n].dir;
          movedrawspr(FIRSTFIREBALL+n-curplayer,digdat[n].fx,digdat[n].fy);
          soundfire(n);
        }
  }
  else {
    switch (digdat[n].fdir) {
      case DIR_RIGHT:
        digdat[n].fx+=8;
        pix=ggetpix(digdat[n].fx,digdat[n].fy+4)|
            ggetpix(digdat[n].fx+4,digdat[n].fy+4);
        break;
      case DIR_UP:
        digdat[n].fy-=7;
        pix=0;
        for (i=0;i<7;i++)
          pix|=ggetpix(digdat[n].fx+4,digdat[n].fy+i);
        pix&=0xc0;
        break;
      case DIR_LEFT:
        digdat[n].fx-=8;
        pix=ggetpix(digdat[n].fx,digdat[n].fy+4)|
            ggetpix(digdat[n].fx+4,digdat[n].fy+4);
        break;
      case DIR_DOWN:
        digdat[n].fy+=7;
        pix=0;
        for (i=0;i<7;i++)
          pix|=ggetpix(digdat[n].fx,digdat[n].fy+i);
        pix&=0x3;
        break;       
    }
    drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
    for (i=0;i<TYPES;i++)
      clfirst[i]=first[i];
    for (i=0;i<SPRITES;i++)
      clcoll[i]=coll[i];
    incpenalty();
    i=clfirst[2];
    while (i!=-1) {
      killmon(i-FIRSTMONSTER);
      scorekill(n);
      digdat[n].expsn=1;
      i=clcoll[i];
    }
    i=clfirst[4];
    while (i!=-1) {
      if (i-FIRSTDIGGER+curplayer!=n && !digdat[i-FIRSTDIGGER+curplayer].invin
          && digdat[i-FIRSTDIGGER+curplayer].alive) {
        killdigger(i-FIRSTDIGGER+curplayer,3,0);
        digdat[n].expsn=1;
      }
      i=clcoll[i];
    }
    if (clfirst[0]!=-1 || clfirst[1]!=-1 || clfirst[2]!=-1 || clfirst[3]!=-1 ||
        clfirst[4]!=-1)
      clflag=TRUE;
    else
      clflag=FALSE;
    if (clfirst[0]!=-1 || clfirst[1]!=-1 || clfirst[3]!=-1) {
      digdat[n].expsn=1;
      i=clfirst[3];
      while (i!=-1) {
        if (digdat[i-FIRSTFIREBALL+curplayer].expsn==0)
          digdat[i-FIRSTFIREBALL+curplayer].expsn=1;
        i=clcoll[i];
      }
    }
    switch (digdat[n].fdir) {
      case DIR_RIGHT:
        if (digdat[n].fx>296)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fx-=8;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
        break;
      case DIR_UP:
        if (digdat[n].fy<15)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fy+=7;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
        break;
      case DIR_LEFT:
        if (digdat[n].fx<16)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fx+=8;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
        break;
      case DIR_DOWN:
        if (digdat[n].fy>183)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fy-=7;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
    }
  }
}