⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monster.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	monster.c		Larn is copyrighted 1986 by Noah Morgan.  * *	This file contains the following functions: *	---------------------------------------------------------------------------- * *	createmonster(monstno) 		Function to create a monster next to the player *		int monstno; * *	int cgood(x,y,itm,monst)	Function to check location for emptiness *		int x,y,itm,monst; * *	createitem(it,arg) 			Routine to place an item next to the player *		int it,arg; * *	cast() 				Subroutine called by parse to cast a spell for the user * *	speldamage(x) 		Function to perform spell functions cast by the player *		int x; * *	loseint()			Routine to decrement your int (intelligence) if > 3 * *	isconfuse() 		Routine to check to see if player is confused * *	nospell(x,monst)	Routine to return 1 if a spell doesn't affect a monster *		int x,monst; * *	fullhit(xx)			Function to return full damage against a monst (aka web) *		int xx; * *	direct(spnum,dam,str,arg)	Routine to direct spell damage 1 square in 1 dir *		int spnum,dam,arg; *		char *str; * *	godirect(spnum,dam,str,delay,cshow)		Function to perform missile attacks *		int spnum,dam,delay; *		char *str,cshow; * *	ifblind(x,y)	Routine to put "monster" or the monster name into lastmosnt *		int x,y; * *	tdirect(spnum)			Routine to teleport away a monster *		int spnum; * *	omnidirect(sp,dam,str)  Routine to damage all monsters 1 square from player *		int sp,dam; *		char *str; * *	dirsub(x,y)			Routine to ask for direction, then modify x,y for it *		int *x,*y; * *	vxy(x,y)		  	Routine to verify/fix (*x,*y) for being within bounds *		int *x,*y; * *	dirpoly(spnum)		Routine to ask for a direction and polymorph a monst *		int spnum; * *	hitmonster(x,y) 	Function to hit a monster at the designated coordinates *		int x,y; * *	hitm(x,y,amt)		Function to just hit a monster at a given coordinates *		int x,y,amt; * *	hitplayer(x,y) 		Function for the monster to hit the player from (x,y) *		int x,y; * *	dropsomething(monst) 	Function to create an object when a monster dies *		int monst; * *	dropgold(amount) 		Function to drop some gold around player *		int amount; * *	something(level) 		Function to create a random item around player *		int level; * *	newobject(lev,i) 		Routine to return a randomly selected new object *		int lev,*i; * *  spattack(atckno,xx,yy) 	Function to process special attacks from monsters *  	int atckno,xx,yy; * *	checkloss(x) 	Routine to subtract hp from user and flag bottomline display *		int x; * *	annihilate()   Routine to annihilate monsters around player, playerx,playery * *	newsphere(x,y,dir,lifetime)  Function to create a new sphere of annihilation *		int x,y,dir,lifetime; * *	rmsphere(x,y)		Function to delete a sphere of annihilation from list *		int x,y; * *	sphboom(x,y)		Function to perform the effects of a sphere detonation *		int x,y; * *	genmonst()			Function to ask for monster and genocide from game * */#include "header.h"struct isave	/* used for altar reality */	{	char type;	/* 0=item,  1=monster */	char id;	/* item number or monster number */	short arg;	/* the type of item or hitpoints of monster */	};/* *	createmonster(monstno) 		Function to create a monster next to the player *		int monstno; * *	Enter with the monster number (1 to MAXMONST+8) *	Returns no value. */createmonster(mon)	int mon;	{	register int x,y,k,i;	if (mon<1 || mon>MAXMONST+8)	/* check for monster number out of bounds */		{		beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;		}	while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */	for (k=rnd(8), i= -8; i<0; i++,k++)	/* choose direction, then try all */		{		if (k>8) k=1;	/* wraparound the diroff arrays */		x = playerx + diroffx[k];		y = playery + diroffy[k];		if (cgood(x,y,0,1))	/* if we can create here */			{			mitem[x][y] = mon;			hitp[x][y] = monster[mon].hitpoints;			stealth[x][y]=know[x][y]=0;			switch(mon)				{				case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;				};			return;			}		}	}/* *	int cgood(x,y,itm,monst)	  Function to check location for emptiness *		int x,y,itm,monst; * *	Routine to return TRUE if a location does not have itm or monst there *	returns FALSE (0) otherwise *	Enter with itm or monst TRUE or FALSE if checking it *	Example:  if itm==TRUE check for no item at this location *			  if monst==TRUE check for no monster at this location *	This routine will return FALSE if at a wall or the dungeon exit on level 1 */int cgood(x,y,itm,monst)	register int x,y;	int itm,monst;	{	if ((y>=0) && (y<=MAXY-1) && (x>=0) && (x<=MAXX-1)) /* within bounds? */	  if (item[x][y]!=OWALL)	/* can't make anything on walls */		if (itm==0 || (item[x][y]==0))	/* is it free of items? */		  if (monst==0 || (mitem[x][y]==0))	/* is it free of monsters? */		    if ((level!=1) || (x!=33) || (y!=MAXY-1)) /* not exit to level 1 */			  return(1);	return(0);	}/* *	createitem(it,arg) 		Routine to place an item next to the player *		int it,arg; * *	Enter with the item number and its argument (iven[], ivenarg[]) *	Returns no value, thus we don't know about createitem() failures. */createitem(it,arg)	int it,arg;	{	register int x,y,k,i;	if (it >= MAXOBJ) return;	/* no such object */	for (k=rnd(8), i= -8; i<0; i++,k++)	/* choose direction, then try all */		{		if (k>8) k=1;	/* wraparound the diroff arrays */		x = playerx + diroffx[k];		y = playery + diroffy[k];		if (cgood(x,y,1,0))	/* if we can create here */			{			item[x][y] = it;  know[x][y]=0;  iarg[x][y]=arg;  return;			}		}	}/* *	cast() 		Subroutine called by parse to cast a spell for the user * *	No arguments and no return value. */static char eys[] = "\nEnter your spell: ";cast()	{	register int i,j,a,b,d;	cursors();	if (c[SPELLS]<=0) {	lprcat("\nYou don't have any spells!");	return;	}	lprcat(eys);		--c[SPELLS];	while ((a=getchar())=='D')		{ seemagic(-1); cursors();  lprcat(eys); }	if (a=='\33') goto over; /*	to escape casting a spell	*/	if ((b=getchar())=='\33') goto over; /*	to escape casting a spell	*/	if ((d=getchar())=='\33')		{ over: lprcat(aborted); c[SPELLS]++; return; } /*	to escape casting a spell	*/#ifdef EXTRA	c[SPELLSCAST]++;#endif	for (lprc('\n'),j= -1,i=0; i<SPNUM; i++) /*seq search for his spell, hash?*/		if ((spelcode[i][0]==a) && (spelcode[i][1]==b) && (spelcode[i][2]==d))			if (spelknow[i])				{  speldamage(i);  j = 1;  i=SPNUM; }	if (j == -1) lprcat("  Nothing Happened ");	bottomline();	}static int dirsub();/* *	speldamage(x) 		Function to perform spell functions cast by the player *		int x; * *	Enter with the spell number, returns no value. *	Please insure that there are 2 spaces before all messages here */speldamage(x)	int x;	{	register int i,j,clev;	int xl,xh,yl,yh;	register char *p,*kn,*pm;	if (x>=SPNUM) return;	/* no such spell */	if (c[TIMESTOP])  { lprcat("  It didn't seem to work"); return; }  /* not if time stopped */	clev = c[LEVEL];	if ((rnd(23)==7) || (rnd(18) > c[INTELLIGENCE]))		{ lprcat("  It didn't work!");  return; }	if (clev*3+2 < x) { lprcat("  Nothing happens.  You seem inexperienced at this"); return; }	switch(x)		{/* ----- LEVEL 1 SPELLS ----- */		case 0:	if (c[PROTECTIONTIME]==0)	c[MOREDEFENSES]+=2; /* protection field +2 */				c[PROTECTIONTIME] += 250;   return;		case 1: i = rnd(((clev+1)<<1)) + clev + 3;				godirect(x,i,(clev>=2)?"  Your missiles hit the %s":"  Your missile hit the %s",100,'+'); /* magic missile */				return;		case 2:	if (c[DEXCOUNT]==0)	c[DEXTERITY]+=3; /*	dexterity	*/				c[DEXCOUNT] += 400;  	return;		case 3: i=rnd(3)+1;				p="  While the %s slept, you smashed it %d times";			ws:	direct(x,fullhit(i),p,i); /*	sleep	*/	return;		case 4:	/*	charm monster	*/	c[CHARMCOUNT] += c[CHARISMA]<<1;	return;		case 5:	godirect(x,rnd(10)+15+clev,"  The sound damages the %s",70,'@'); /*	sonic spear */				return;/* ----- LEVEL 2 SPELLS ----- */		case 6: i=rnd(3)+2;	p="  While the %s is entangled, you hit %d times";				goto ws; /* web */		case 7:	if (c[STRCOUNT]==0) c[STREXTRA]+=3;	/*	strength	*/				c[STRCOUNT] += 150+rnd(100);    return;		case 8:	yl = playery-5;     /* enlightenment */				yh = playery+6;   xl = playerx-15;   xh = playerx+16;				vxy(&xl,&yl);   vxy(&xh,&yh); /* check bounds */				for (i=yl; i<=yh; i++) /* enlightenment	*/					for (j=xl; j<=xh; j++)	know[j][i]=1;				draws(xl,xh+1,yl,yh+1);	return;		case 9:	raisehp(20+(clev<<1));  return;  /* healing */		case 10:	c[BLINDCOUNT]=0;	return;	/* cure blindness	*/		case 11:	createmonster(makemonst(level+1)+8);  return;		case 12:	if (rnd(11)+7 <= c[WISDOM]) direct(x,rnd(20)+20+clev,"  The %s believed!",0);					else lprcat("  It didn't believe the illusions!");					return;		case 13:	/* if he has the amulet of invisibility then add more time */					for (j=i=0; i<26; i++)						if (iven[i]==OAMULET) j+= 1+ivenarg[i];					c[INVISIBILITY] += (j<<7)+12;   return;/* ----- LEVEL 3 SPELLS ----- */		case 14:	godirect(x,rnd(25+clev)+25+clev,"  The fireball hits the %s",40,'*'); return; /*	fireball */		case 15:	godirect(x,rnd(25)+20+clev,"  Your cone of cold strikes the %s",60,'O');	/*	cold */					return;		case 16:	dirpoly(x);  return;	/*	polymorph */		case 17:	c[CANCELLATION]+= 5+clev;	return;	/*	cancellation	*/		case 18:	c[HASTESELF]+= 7+clev;  return;  /*	haste self	*/		case 19:	omnidirect(x,30+rnd(10),"  The %s gasps for air");	/* cloud kill */					return;		case 20:	xh = min(playerx+1,MAXX-2);		yh = min(playery+1,MAXY-2);					for (i=max(playerx-1,1); i<=xh; i++) /* vaporize rock */					  for (j=max(playery-1,1); j<=yh; j++)						{						kn = &know[i][j];    pm = &mitem[i][j];						switch(*(p= &item[i][j]))						  {						  case OWALL: if (level < MAXLEVEL+MAXVLEVEL-1)											*p = *kn = 0;										break;						  case OSTATUE: if (c[HARDGAME]<3)											 {											 *p=OBOOK; iarg[i][j]=level;  *kn=0;											 }										break;							  case OTHRONE: *pm=GNOMEKING;  *kn=0;  *p= OTHRONE2;										hitp[i][j]=monster[GNOMEKING].hitpoints; break;						  case OALTAR:	*pm=DEMONPRINCE;  *kn=0;										hitp[i][j]=monster[DEMONPRINCE].hitpoints; break;						  };						switch(*pm)							{							case XORN:	ifblind(i,j);  hitm(i,j,200); break; /* Xorn takes damage from vpr */							}						}					return;/* ----- LEVEL 4 SPELLS ----- */		case 21:	direct(x,100+clev,"  The %s shrivels up",0); /* dehydration */					return;		case 22:	godirect(x,rnd(25)+20+(clev<<1),"  A lightning bolt hits the %s",1,'~');	/*	lightning */					return;		case 23:	i=min(c[HP]-1,c[HPMAX]/2);	/* drain life */					direct(x,i+i,"",0);	c[HP] -= i;  	return;		case 24:	if (c[GLOBE]==0) c[MOREDEFENSES] += 10;					c[GLOBE] += 200;  loseint();  /* globe of invulnerability */					return;		case 25:	omnidirect(x,32+clev,"  The %s struggles for air in your flood!"); /* flood */					return;		case 26:	if (rnd(151)==63) { beep(); lprcat("\nYour heart stopped!\n"); nap(4000);  died(270); return; }					if (c[WISDOM]>rnd(10)+10) direct(x,2000,"  The %s's heart stopped",0); /* finger of death */					else lprcat("  It didn't work"); return;/* ----- LEVEL 5 SPELLS ----- */		case 27:	c[SCAREMONST] += rnd(10)+clev;  return;  /* scare monster */		case 28:	c[HOLDMONST] += rnd(10)+clev;  return;  /* hold monster */		case 29:	c[TIMESTOP] += rnd(20)+(clev<<1);  return;  /* time stop */		case 30:	tdirect(x);  return;  /* teleport away */		case 31:	omnidirect(x,35+rnd(10)+clev,"  The %s cringes from the flame"); /* magic fire */					return;/* ----- LEVEL 6 SPELLS ----- */		case 32:	if ((rnd(23)==5) && (wizard==0)) /* sphere of annihilation */						{						beep(); lprcat("\nYou have been enveloped by the zone of nothingness!\n");						nap(4000);  died(258); return;						}					xl=playerx; yl=playery;					loseint();					i=dirsub(&xl,&yl); /* get direction of sphere */					newsphere(xl,yl,i,rnd(20)+11);	/* make a sphere */					return;		case 33:	genmonst();  spelknow[33]=0;  /* genocide */					loseint();					return;		case 34:	/* summon demon */					if (rnd(100) > 30) { direct(x,150,"  The demon strikes at the %s",0);  return; }					if (rnd(100) > 15) { lprcat("  Nothing seems to have happened");  return; }					lprcat("  The demon turned on you and vanished!"); beep();					i=rnd(40)+30;  lastnum=277;					losehp(i); /* must say killed by a demon */ return;		case 35:	/* walk through walls */					c[WTW] += rnd(10)+5;	return;		case 36:	/* alter reality */					{					struct isave *save;	/* pointer to item save structure */					int sc;	sc=0;	/* # items saved */					save = (struct isave *)malloc(sizeof(struct isave)*MAXX*MAXY*2);					for (j=0; j<MAXY; j++)						for (i=0; i<MAXX; i++) /* save all items and monsters */							{							xl = item[i][j];							if (xl && xl!=OWALL && xl!=OANNIHILATION) 								{								save[sc].type=0;  save[sc].id=item[i][j];								save[sc++].arg=iarg[i][j];								}							if (mitem[i][j]) 								{								save[sc].type=1;  save[sc].id=mitem[i][j];								save[sc++].arg=hitp[i][j];								}							item[i][j]=OWALL;   mitem[i][j]=0;							if (wizard) know[i][j]=1; else know[i][j]=0;							}					eat(1,1);	if (level==1) item[33][MAXY-1]=0;					for (j=rnd(MAXY-2), i=1; i<MAXX-1; i++) item[i][j]=0;					while (sc>0) /* put objects back in level */						{						--sc;						if (save[sc].type == 0)							{							int trys;							for (trys=100, i=j=1; --trys>0 && item[i][j]; i=rnd(MAXX-1), j=rnd(MAXY-1));							if (trys) { item[i][j]=save[sc].id; iarg[i][j]=save[sc].arg; }							}						else							{ /* put monsters back in */							int trys;							for (trys=100, i=j=1; --trys>0 && (item[i][j]==OWALL || mitem[i][j]); i=rnd(MAXX-1), j=rnd(MAXY-1));							if (trys) { mitem[i][j]=save[sc].id; hitp[i][j]=save[sc].arg; }							}						}					loseint();					draws(0,MAXX,0,MAXY);  if (wizard==0) spelknow[36]=0;					free((char*)save);	 positionplayer();  return;					}		case 37:	/* permanence */ adjtime(-99999L);  spelknow[37]=0; /* forget */					loseint();					return;		default:	lprintf("  spell %d not available!",(long)x); beep();  return;		};	}/* *	loseint()		Routine to subtract 1 from your int (intelligence) if > 3 * *	No arguments and no return value */loseint()	{	if (--c[INTELLIGENCE]<3)  c[INTELLIGENCE]=3;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -