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

📄 hack.mon.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. *//* hack.mon.c - version 1.0.3 */#include "hack.h"#include "hack.mfndpos.h"#ifndef NULL#define	NULL	(char *) 0#endifextern struct monst *makemon();extern struct obj *mkobj_at();int warnlevel;		/* used by movemon and dochugw */long lastwarntime;int lastwarnlev;char *warnings[] = {	"white", "pink", "red", "ruby", "purple", "black"};movemon(){	register struct monst *mtmp;	register int fr;	warnlevel = 0;	while(1) {		/* find a monster that we haven't treated yet */		/* note that mtmp or mtmp->nmon might get killed		   while mtmp moves, so we cannot just walk down the		   chain (even new monsters might get created!) */		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)			if(mtmp->mlstmv < moves) goto next_mon;		/* treated all monsters */		break;	next_mon:		mtmp->mlstmv = moves;		/* most monsters drown in pools */		{ boolean inpool, iseel;		  inpool = (levl[mtmp->mx][mtmp->my].typ == POOL);		  iseel = (mtmp->data->mlet == ';');		  if(inpool && !iseel) {			if(cansee(mtmp->mx,mtmp->my))			    pline("%s drowns.", Monnam(mtmp));			mondead(mtmp);			continue;		  }		/* but eels have a difficult time outside */		  if(iseel && !inpool) {			if(mtmp->mhp > 1) mtmp->mhp--;			mtmp->mflee = 1;			mtmp->mfleetim += 2;		  }		}		if(mtmp->mblinded && !--mtmp->mblinded)			mtmp->mcansee = 1;		if(mtmp->mfleetim && !--mtmp->mfleetim)			mtmp->mflee = 0;		if(mtmp->mimic) continue;		if(mtmp->mspeed != MSLOW || !(moves%2)){			/* continue if the monster died fighting */			fr = -1;			if(Conflict && cansee(mtmp->mx,mtmp->my)				&& (fr = fightm(mtmp)) == 2)				continue;			if(fr<0 && dochugw(mtmp))				continue;		}		if(mtmp->mspeed == MFAST && dochugw(mtmp))			continue;	}	warnlevel -= u.ulevel;	if(warnlevel >= SIZE(warnings))		warnlevel = SIZE(warnings)-1;	if(warnlevel >= 0)	if(warnlevel > lastwarnlev || moves > lastwarntime + 5){	    register char *rr;	    switch(Warning & (LEFT_RING | RIGHT_RING)){	    case LEFT_RING:		rr = "Your left ring glows";		break;	    case RIGHT_RING:		rr = "Your right ring glows";		break;	    case LEFT_RING | RIGHT_RING:		rr = "Both your rings glow";		break;	    default:		rr = "Your fingertips glow";		break;	    }	    pline("%s %s!", rr, warnings[warnlevel]);	    lastwarntime = moves;	    lastwarnlev = warnlevel;	}	dmonsfree();	/* remove all dead monsters */}justswld(mtmp,name)register struct monst *mtmp;char *name;{	mtmp->mx = u.ux;	mtmp->my = u.uy;	u.ustuck = mtmp;	pmon(mtmp);	kludge("%s swallows you!",name);	more();	seeoff(1);	u.uswallow = 1;	u.uswldtim = 0;	swallowed();}youswld(mtmp,dam,die,name)register struct monst *mtmp;register dam,die;char *name;{	if(mtmp != u.ustuck) return;	kludge("%s digests you!",name);	u.uhp -= dam;	if(u.uswldtim++ >= die){	/* a3 */		pline("It totally digests you!");		u.uhp = -1;	}	if(u.uhp < 1) done_in_by(mtmp);	/* flags.botlx = 1;		/* should we show status line ? */}dochugw(mtmp) register struct monst *mtmp; {register x = mtmp->mx;register y = mtmp->my;register d = dochug(mtmp);register dd;	if(!d)		/* monster still alive */	if(Warning)	if(!mtmp->mpeaceful)	if(mtmp->data->mlevel > warnlevel)	if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))	if(dd < 100)	if(!canseemon(mtmp))		warnlevel = mtmp->data->mlevel;	return(d);}/* returns 1 if monster died moving, 0 otherwise */dochug(mtmp)register struct monst *mtmp;{	register struct permonst *mdat;	register tmp, nearby, scared;	if(mtmp->cham && !rn2(6))		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);	mdat = mtmp->data;	if(mdat->mlevel < 0)		panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);	/* regenerate monsters */	if((!(moves%20) || index(MREGEN, mdat->mlet)) &&	    mtmp->mhp < mtmp->mhpmax)		mtmp->mhp++;	if(mtmp->mfroz) return(0); /* frozen monsters don't do anything */	if(mtmp->msleep) {		/* wake up, or get out of here. */		/* ettins are hard to surprise */		/* Nymphs and Leprechauns do not easily wake up */		if(cansee(mtmp->mx,mtmp->my) &&			(!Stealth || (mdat->mlet == 'e' && rn2(10))) &&			(!index("NL",mdat->mlet) || !rn2(50)) &&			(Aggravate_monster || index("d1", mdat->mlet)				|| (!rn2(7) && !mtmp->mimic)))			mtmp->msleep = 0;		else return(0);	}	/* not frozen or sleeping: wipe out texts written in the dust */	wipe_engr_at(mtmp->mx, mtmp->my, 1);	/* confused monsters get unconfused with small probability */	if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;	/* some monsters teleport */	if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){		rloc(mtmp);		return(0);	}	if(mdat->mmove < rnd(6)) return(0);	/* fleeing monsters might regain courage */	if(mtmp->mflee && !mtmp->mfleetim	    && mtmp->mhp == mtmp->mhpmax && !rn2(25))		mtmp->mflee = 0;	nearby = (dist(mtmp->mx, mtmp->my) < 3);	scared = (nearby && (sengr_at("Elbereth", u.ux, u.uy) ||			sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)));	if(scared && !mtmp->mflee) {		mtmp->mflee = 1;		mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));	}	if(!nearby ||		mtmp->mflee ||		mtmp->mconf ||		(mtmp->minvis && !rn2(3)) ||		(index("BIuy", mdat->mlet) && !rn2(4)) ||		(mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||		(!mtmp->mcansee && !rn2(4)) ||		mtmp->mpeaceful	   ) {		tmp = m_move(mtmp,0);	/* 2: monster died moving */		if(tmp == 2 || (tmp && mdat->mmove <= 12))			return(tmp == 2);	}	if(!index("Ea", mdat->mlet) && nearby &&	 !mtmp->mpeaceful && u.uhp > 0 && !scared) {		if(mhitu(mtmp))			return(1);	/* monster died (e.g. 'y' or 'F') */	}	/* extra movement for fast monsters */	if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);	return(tmp == 2);}m_move(mtmp,after)register struct monst *mtmp;{	register struct monst *mtmp2;	register nx,ny,omx,omy,appr,nearer,cnt,i,j;	xchar gx,gy,nix,niy,chcnt;	schar chi;	boolean likegold, likegems, likeobjs;	char msym = mtmp->data->mlet;	schar mmoved = 0;	/* not strictly nec.: chi >= 0 will do */	coord poss[9];	int info[9];	if(mtmp->mfroz || mtmp->msleep)		return(0);	if(mtmp->mtrapped) {		i = mintrap(mtmp);		if(i == 2) return(2);	/* he died */		if(i == 1) return(0);	/* still in trap, so didnt move */	}	if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))		return(0);		/* do not leave hiding place */#ifndef NOWORM	if(mtmp->wormno)		goto not_special;#endif NOWORM	/* my dog gets a special treatment */	if(mtmp->mtame) {		return( dog_move(mtmp, after) );	}	/* likewise for shopkeeper */	if(mtmp->isshk) {		mmoved = shk_move(mtmp);		if(mmoved >= 0)			goto postmov;		mmoved = 0;		/* follow player outside shop */	}	/* and for the guard */	if(mtmp->isgd) {		mmoved = gd_move();		goto postmov;	}/* teleport if that lies in our nature ('t') or when badly wounded ('1') */	if((msym == 't' && !rn2(5))	|| (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))		|| levl[u.ux][u.uy].typ == STAIRS))) {		if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))			rloc(mtmp);		else			mnexto(mtmp);		mmoved = 1;		goto postmov;	}	/* spit fire ('D') or use a wand ('1') when appropriate */	if(index("D1", msym))		inrange(mtmp);	if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&	    mtmp->mcansee && rn2(5)) {		if(!Confusion)			pline("%s's gaze has confused you!", Monnam(mtmp));		else			pline("You are getting more and more confused.");		if(rn2(3)) mtmp->mcan = 1;		Confusion += d(3,4);		/* timeout */	}not_special:	if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);	appr = 1;	if(mtmp->mflee) appr = -1;	if(mtmp->mconf || Invis ||  !mtmp->mcansee ||		(index("BIy", msym) && !rn2(3)))		appr = 0;	omx = mtmp->mx;	omy = mtmp->my;	gx = u.ux;	gy = u.uy;	if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)		appr = -1;	/* random criterion for 'smell' or track finding ability	   should use mtmp->msmell or sth	 */	if(msym == '@' ||	  ('a' <= msym && msym <= 'z')) {	extern coord *gettrack();	register coord *cp;	schar mroom;		mroom = inroom(omx,omy);		if(mroom < 0 || mroom != inroom(u.ux,u.uy)){		    cp = gettrack(omx,omy);		    if(cp){			gx = cp->x;			gy = cp->y;		    }		}	}	/* look for gold or jewels nearby */	likegold = (index("LOD", msym) != NULL);	likegems = (index("ODu", msym) != NULL);	likeobjs = mtmp->mhide;#define	SRCHRADIUS	25	{ xchar mind = SRCHRADIUS;		/* not too far away */	  register int dd;	  if(likegold){		register struct gold *gold;		for(gold = fgold; gold; gold = gold->ngold)		  if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){		    mind = dd;		    gx = gold->gx;		    gy = gold->gy;		}	  }	  if(likegems || likeobjs){		register struct obj *otmp;		for(otmp = fobj; otmp; otmp = otmp->nobj)		if(likeobjs || otmp->olet == GEM_SYM)		if(msym != 'u' ||			objects[otmp->otyp].g_val != 0)		if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){		    mind = dd;		    gx = otmp->ox;		    gy = otmp->oy;		}	  }	  if(mind < SRCHRADIUS && appr == -1) {		if(dist(omx,omy) < 10) {		    gx = u.ux;		    gy = u.uy;		} else		    appr = 1;	  }	}	nix = omx;	niy = omy;	cnt = mfndpos(mtmp,poss,info,		msym == 'u' ? NOTONL :		(msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :		index(UNDEAD, msym) ? NOGARLIC : ALLOW_TRAPS);		/* ALLOW_ROCK for some monsters ? */	chcnt = 0;	chi = -1;	for(i=0; i<cnt; i++) {		nx = poss[i].x;		ny = poss[i].y;		for(j=0; j<MTSZ && j<cnt-1; j++)			if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)				if(rn2(4*(cnt-j))) goto nxti;#ifdef STUPID		/* some stupid compilers think that this is too complicated */		{ int d1 = DIST(nx,ny,gx,gy);		  int d2 = DIST(nix,niy,gx,gy);		  nearer = (d1 < d2);		}#else		nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));#endif STUPID		if((appr == 1 && nearer) || (appr == -1 && !nearer) ||			!mmoved ||			(!appr && !rn2(++chcnt))){			nix = nx;			niy = ny;			chi = i;			mmoved = 1;		}	nxti:	;	}	if(mmoved){		if(info[chi] & ALLOW_M){			mtmp2 = m_at(nix,niy);			if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&			  hitmm(mtmp2,mtmp) == 2) return(2);			return(0);		}		if(info[chi] & ALLOW_U){		  (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);		  return(0);		}		mtmp->mx = nix;		mtmp->my = niy;		for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];		mtmp->mtrack[0].x = omx;		mtmp->mtrack[0].y = omy;#ifndef NOWORM

⌨️ 快捷键说明

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