📄 monster.c
字号:
} tmp = 0; if (monster[mster].attack>0) if (((dam + bias + 8) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1)) { if (spattack(monster[mster].attack,x,y)) { flushall(); return; } tmp = 1; bias -= 2; cursors(); } if (((dam + bias) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1)) { lprintf("\n The %s hit you ",lastmonst); tmp = 1; if ((dam -= c[AC]) < 0) dam=0; if (dam > 0) { losehp(dam); bottomhp(); flushall(); } } if (tmp == 0) lprintf("\n The %s missed ",lastmonst); }/* * dropsomething(monst) Function to create an object when a monster dies * int monst; * * Function to create an object near the player when certain monsters are killed * Enter with the monster number * Returns nothing of value. */dropsomething(monst) int monst; { switch(monst) { case ORC: case NYMPH: case ELF: case TROGLODYTE: case TROLL: case ROTHE: case VIOLETFUNGI: case PLATINUMDRAGON: case GNOMEKING: case REDDRAGON: something(level); return; case LEPRECHAUN: if (rnd(101)>=75) creategem(); if (rnd(5)==1) dropsomething(LEPRECHAUN); return; } }/* * dropgold(amount) Function to drop some gold around player * int amount; * * Enter with the number of gold pieces to drop * Returns nothing of value. */dropgold(amount) register int amount; { if (amount > 250) createitem(OMAXGOLD,amount/100); else createitem(OGOLDPILE,amount); }/* * something(level) Function to create a random item around player * int level; * * Function to create an item from a designed probability around player * Enter with the cave level on which something is to be dropped * Returns nothing of value. */something(level) int level; { register int j; int i; if (level<0 || level>MAXLEVEL+MAXVLEVEL) return; /* correct level? */ if (rnd(101)<8) something(level); /* possibly more than one item */ j = newobject(level,&i); createitem(j,i); }/* * newobject(lev,i) Routine to return a randomly selected new object * int lev,*i; * * Routine to return a randomly selected object to be created * Returns the object number created, and sets *i for its argument * Enter with the cave level and a pointer to the items arg */static char nobjtab[] = { 0, OSCROLL, OSCROLL, OSCROLL, OSCROLL, OPOTION, OPOTION, OPOTION, OPOTION, OGOLDPILE, OGOLDPILE, OGOLDPILE, OGOLDPILE, OBOOK, OBOOK, OBOOK, OBOOK, ODAGGER, ODAGGER, ODAGGER, OLEATHER, OLEATHER, OLEATHER, OREGENRING, OPROTRING, OENERGYRING, ODEXRING, OSTRRING, OSPEAR, OBELT, ORING, OSTUDLEATHER, OSHIELD, OFLAIL, OCHAIN, O2SWORD, OPLATE, OLONGSWORD };newobject(lev,i) register int lev,*i; { register int tmp=32,j; if (level<0 || level>MAXLEVEL+MAXVLEVEL) return(0); /* correct level? */ if (lev>6) tmp=37; else if (lev>4) tmp=35; j = nobjtab[tmp=rnd(tmp)]; /* the object type */ switch(tmp) { case 1: case 2: case 3: case 4: *i=newscroll(); break; case 5: case 6: case 7: case 8: *i=newpotion(); break; case 9: case 10: case 11: case 12: *i=rnd((lev+1)*10)+lev*10+10; break; case 13: case 14: case 15: case 16: *i=lev; break; case 17: case 18: case 19: if (!(*i=newdagger())) return(0); break; case 20: case 21: case 22: if (!(*i=newleather())) return(0); break; case 23: case 32: case 35: *i=rund(lev/3+1); break; case 24: case 26: *i=rnd(lev/4+1); break; case 25: *i=rund(lev/4+1); break; case 27: *i=rnd(lev/2+1); break; case 30: case 33: *i=rund(lev/2+1); break; case 28: *i=rund(lev/3+1); if (*i==0) return(0); break; case 29: case 31: *i=rund(lev/2+1); if (*i==0) return(0); break; case 34: *i=newchain(); break; case 36: *i=newplate(); break; case 37: *i=newsword(); break; } return(j); }/* * spattack(atckno,xx,yy) Function to process special attacks from monsters * int atckno,xx,yy; * * Enter with the special attack number, and the coordinates (xx,yy) * of the monster that is special attacking * Returns 1 if must do a show1cell(xx,yy) upon return, 0 otherwise * * atckno monster effect * --------------------------------------------------- * 0 none * 1 rust monster eat armor * 2 hell hound breathe light fire * 3 dragon breathe fire * 4 giant centipede weakening sing * 5 white dragon cold breath * 6 wraith drain level * 7 waterlord water gusher * 8 leprechaun steal gold * 9 disenchantress disenchant weapon or armor * 10 ice lizard hits with barbed tail * 11 umber hulk confusion * 12 spirit naga cast spells taken from special attacks * 13 platinum dragon psionics * 14 nymph steal objects * 15 bugbear bite * 16 osequip bite * * char rustarm[ARMORTYPES][2]; * special array for maximum rust damage to armor from rustmonster * format is: { armor type , minimum attribute */#define ARMORTYPES 6static char rustarm[ARMORTYPES][2] = { OSTUDLEATHER,-2, ORING,-4, OCHAIN,-5, OSPLINT,-6, OPLATE,-8, OPLATEARMOR,-9 };static char spsel[] = { 1, 2, 3, 5, 6, 8, 9, 11, 13, 14 };spattack(x,xx,yy) int x,xx,yy; { register int i,j=0,k,m; register char *p=0; if (c[CANCELLATION]) return(0); vxy(&xx,&yy); /* verify x & y coordinates */ switch(x) { case 1: /* rust your armor, j=1 when rusting has occurred */ m = k = c[WEAR]; if ((i=c[SHIELD]) != -1) if (--ivenarg[i] < -1) ivenarg[i]= -1; else j=1; if ((j==0) && (k != -1)) { m = iven[k]; for (i=0; i<ARMORTYPES; i++) if (m == rustarm[i][0]) /* find his armor in table */ { if (--ivenarg[k]< rustarm[i][1]) ivenarg[k]= rustarm[i][1]; else j=1; break; } } if (j==0) /* if rusting did not occur */ switch(m) { case OLEATHER: p = "\nThe %s hit you -- Your lucky you have leather on"; break; case OSSPLATE: p = "\nThe %s hit you -- Your fortunate to have stainless steel armor!"; break; } else { beep(); p = "\nThe %s hit you -- your armor feels weaker"; } break; case 2: i = rnd(15)+8-c[AC]; spout: p="\nThe %s breathes fire at you!"; if (c[FIRERESISTANCE]) p="\nThe %s's flame doesn't phase you!"; else spout2: if (p) { lprintf(p,lastmonst); beep(); } checkloss(i); return(0); case 3: i = rnd(20)+25-c[AC]; goto spout; case 4: if (c[STRENGTH]>3) { p="\nThe %s stung you! You feel weaker"; beep(); --c[STRENGTH]; } else p="\nThe %s stung you!"; break; case 5: p="\nThe %s blasts you with his cold breath"; i = rnd(15)+18-c[AC]; goto spout2; case 6: lprintf("\nThe %s drains you of your life energy!",lastmonst); loselevel(); beep(); return(0); case 7: p="\nThe %s got you with a gusher!"; i = rnd(15)+25-c[AC]; goto spout2; case 8: if (c[NOTHEFT]) return(0); /* he has a device of no theft */ if (c[GOLD]) { p="\nThe %s hit you -- Your purse feels lighter"; if (c[GOLD]>32767) c[GOLD]>>=1; else c[GOLD] -= rnd((int)(1+(c[GOLD]>>1))); if (c[GOLD] < 0) c[GOLD]=0; } else p="\nThe %s couldn't find any gold to steal"; lprintf(p,lastmonst); disappear(xx,yy); beep(); bottomgold(); return(1); case 9: for(j=50; ; ) /* disenchant */ { i=rund(26); m=iven[i]; /* randomly select item */ if (m>0 && ivenarg[i]>0 && m!=OSCROLL && m!=OPOTION) { if ((ivenarg[i] -= 3)<0) ivenarg[i]=0; lprintf("\nThe %s hits you -- you feel a sense of loss",lastmonst); srcount=0; beep(); show3(i); bottomline(); return(0); } if (--j<=0) { p="\nThe %s nearly misses"; break; } break; } break; case 10: p="\nThe %s hit you with his barbed tail"; i = rnd(25)-c[AC]; goto spout2; case 11: p="\nThe %s has confused you"; beep(); c[CONFUSE]+= 10+rnd(10); break; case 12: /* performs any number of other special attacks */ return(spattack(spsel[rund(10)],xx,yy)); case 13: p="\nThe %s flattens you with his psionics!"; i = rnd(15)+30-c[AC]; goto spout2; case 14: if (c[NOTHEFT]) return(0); /* he has device of no theft */ if (emptyhanded()==1) { p="\nThe %s couldn't find anything to steal"; break; } lprintf("\nThe %s picks your pocket and takes:",lastmonst); beep(); if (stealsomething()==0) lprcat(" nothing"); disappear(xx,yy); bottomline(); return(1); case 15: i= rnd(10)+ 5-c[AC]; spout3: p="\nThe %s bit you!"; goto spout2; case 16: i= rnd(15)+10-c[AC]; goto spout3; }; if (p) { lprintf(p,lastmonst); bottomline(); } return(0); }/* * checkloss(x) Routine to subtract hp from user and flag bottomline display * int x; * * Routine to subtract hitpoints from the user and flag the bottomline display * Enter with the number of hit points to lose * Note: if x > c[HP] this routine could kill the player! */checkloss(x) int x; { if (x>0) { losehp(x); bottomhp(); } }/* * annihilate() Routine to annihilate all monsters around player (playerx,playery) * * Gives player experience, but no dropped objects * Returns the experience gained from all monsters killed */annihilate() { int i,j; register long k; register char *p; for (k=0, i=playerx-1; i<=playerx+1; i++) for (j=playery-1; j<=playery+1; j++) if (!vxy(&i,&j)) /* if not out of bounds */ if (*(p= &mitem[i][j])) /* if a monster there */ if (*p<DEMONLORD+2) { k += monster[*p].experience; *p=know[i][j]=0; } else { lprintf("\nThe %s barely escapes being annihilated!",monster[*p].name); hitp[i][j] = (hitp[i][j]>>1) + 1; /* lose half hit points*/ } if (k>0) { lprcat("\nYou hear loud screams of agony!"); raiseexperience((long)k); } return(k); }/* * newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation * int x,y,dir,lifetime; * * Enter with the coordinates of the sphere in x,y * the direction (0-8 diroffx format) in dir, and the lifespan of the * sphere in lifetime (in turns) * Returns the number of spheres currently in existence */newsphere(x,y,dir,life) int x,y,dir,life; { int m; struct sphere *sp; if (((sp=(struct sphere *)malloc(sizeof(struct sphere)))) == 0) return(c[SPHCAST]); /* can't malloc, therefore failure */ if (dir>=9) dir=0; /* no movement if direction not found */ if (level==0) vxy(&x,&y); /* don't go out of bounds */ else { if (x<1) x=1; if (x>=MAXX-1) x=MAXX-2; if (y<1) y=1; if (y>=MAXY-1) y=MAXY-2; } if ((m=mitem[x][y]) >= DEMONLORD+4) /* demons dispel spheres */ { know[x][y]=1; show1cell(x,y); /* show the demon (ha ha) */ cursors(); lprintf("\nThe %s dispels the sphere!",monster[m].name); beep(); rmsphere(x,y); /* remove any spheres that are here */ return(c[SPHCAST]); } if (m==DISENCHANTRESS) /* disenchantress cancels spheres */ { cursors(); lprintf("\nThe %s causes cancellation of the sphere!",monster[m].name); beep();boom: sphboom(x,y); /* blow up stuff around sphere */ rmsphere(x,y); /* remove any spheres that are here */ return(c[SPHCAST]); } if (c[CANCELLATION]) /* cancellation cancels spheres */ { cursors(); lprcat("\nAs the cancellation takes effect, you hear a great earth shaking blast!"); beep(); goto boom; } if (item[x][y]==OANNIHILATION) /* collision of spheres detonates spheres */ { cursors(); lprcat("\nTwo spheres of annihilation collide! You hear a great earth shaking blast!"); beep(); rmsphere(x,y); goto boom; } if (playerx==x && playery==y) /* collision of sphere and player! */ { cursors(); lprcat("\nYou have been enveloped by the zone of nothingness!\n"); beep(); rmsphere(x,y); /* remove any spheres that are here */ nap(4000); died(258); } item[x][y]=OANNIHILATION; mitem[x][y]=0; know[x][y]=1; show1cell(x,y); /* show the new sphere */ sp->x=x; sp->y=y; sp->lev=level; sp->dir=dir; sp->lifetime=life; sp->p=0; if (spheres==0) spheres=sp; /* if first node in the sphere list */ else /* add sphere to beginning of linked list */ { sp->p = spheres; spheres = sp; } return(++c[SPHCAST]); /* one more sphere in the world */ }/* * rmsphere(x,y) Function to delete a sphere of annihilation from list * int x,y; * * Enter with the coordinates of the sphere (on current level) * Returns the number of spheres currently in existence */rmsphere(x,y) int x,y; { register struct sphere *sp,*sp2=0; for (sp=spheres; sp; sp2=sp,sp=sp->p) if (level==sp->lev) /* is sphere on this level? */ if ((x==sp->x) && (y==sp->y)) /* locate sphere at this location */ { item[x][y]=mitem[x][y]=0; know[x][y]=1; show1cell(x,y); /* show the now missing sphere */ --c[SPHCAST]; if (sp==spheres) { sp2=sp; spheres=sp->p; free((char*)sp2); } else { sp2->p = sp->p; free((char*)sp); } break; } return(c[SPHCAST]); /* return number of spheres in the world */ }/* * sphboom(x,y) Function to perform the effects of a sphere detonation * int x,y; * * Enter with the coordinates of the blast, Returns no value */sphboom(x,y) int x,y; { register int i,j; if (c[HOLDMONST]) c[HOLDMONST]=1; if (c[CANCELLATION]) c[CANCELLATION]=1; for (j=max(1,x-2); j<min(x+3,MAXX-1); j++) for (i=max(1,y-2); i<min(y+3,MAXY-1); i++) { item[j][i]=mitem[j][i]=0; show1cell(j,i); if (playerx==j && playery==i) { cursors(); beep(); lprcat("\nYou were too close to the sphere!"); nap(3000); died(283); /* player killed in explosion */ } } }/* * genmonst() Function to ask for monster and genocide from game * * This is done by setting a flag in the monster[] structure */genmonst() { register int i,j; cursors(); lprcat("\nGenocide what monster? "); for (i=0; (!isalpha(i)) && (i!=' '); i=getchar()); lprc(i); for (j=0; j<MAXMONST; j++) /* search for the monster type */ if (monstnamelist[j]==i) /* have we found it? */ { monster[j].genocided=1; /* genocided from game */ lprintf(" There will be no more %s's",monster[j].name); /* now wipe out monsters on this level */ newcavelevel(level); draws(0,MAXX,0,MAXY); bot_linex(); return; } lprcat(" You sense failure!"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -