void initmonsters(void) { Sint4 i; for (i=0;i<MONSTERS;i++) mondat[i].flag=false; nextmonster=0; mongaptime=45-(levof10()<<1); totalmonsters=levof10()+5; switch (levof10()) { case 1: maxmononscr=3; break; case 2: case 3: case 4: case 5: case 6: case 7: maxmononscr=4; break; case 8: case 9: case 10: maxmononscr=5; } nextmontime=10; unbonusflag=true; }
void initbags(void) { Sint4 bag,x,y; pushcount=0; goldtime=150-levof10()*10; for (bag=0;bag<BAGS;bag++) bagdat[bag].exist=FALSE; bag=0; for (x=0;x<MWIDTH;x++) for (y=0;y<MHEIGHT;y++) if (getlevch(x,y,levplan())=='B') if (bag<BAGS) { bagdat[bag].exist=TRUE; bagdat[bag].gt=0; bagdat[bag].fallh=0; bagdat[bag].dir=DIR_NONE; bagdat[bag].wobbling=FALSE; bagdat[bag].wt=15; bagdat[bag].unfallen=TRUE; bagdat[bag].x=x*20+12; bagdat[bag].y=y*18+18; bagdat[bag].h=x; bagdat[bag].v=y; bagdat[bag].xr=0; bagdat[bag++].yr=0; } if (curplayer==0) memcpy(bagdat1,bagdat,BAGS*sizeof(struct bag)); else memcpy(bagdat2,bagdat,BAGS*sizeof(struct bag)); }
void initbonusmode(void) { int i; bonusmode=TRUE; erasebonus(); ginten(1); bonustimeleft=250-levof10()*20; startbonustimeleft=20; for (i=0;i<diggers;i++) digdat[i].msc=1; }
static void initbonusmode(struct digger_draw_api *ddap) { int i; bonusmode=true; erasebonus(ddap); ddap->ginten(1); bonustimeleft=250-levof10()*20; startbonustimeleft=20; for (i=0;i<diggers;i++) digdat[i].msc=1; }
void domonsters(void) { Sint4 i; if (nextmontime>0) nextmontime--; else { if (nextmonster<totalmonsters && nmononscr()<maxmononscr && isalive() && !bonusmode) createmonster(); if (unbonusflag && nextmonster==totalmonsters && nextmontime==0) if (isalive()) { unbonusflag=false; createbonus(); } } for (i=0;i<MONSTERS;i++) if (mondat[i].flag) { if (mondat[i].hnt>10-levof10()) { if (mondat[i].nob) { mondat[i].nob=false; mondat[i].hnt=0; } } if (mondat[i].alive) if (mondat[i].t==0) { monai(i); if (randno(15-levof10())==0) /* Need to split for determinism */ if (mondat[i].nob && mondat[i].alive) monai(i); } else mondat[i].t--; else mondie(i); } }
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; }
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); } } } } }
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); } } } }