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

📄 hack.dog.c

📁 早期freebsd实现
💻 C
字号:
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. *//* hack.dog.c - version 1.0.3 */#include	"hack.h"#include	"hack.mfndpos.h"extern struct monst *makemon();#include "def.edog.h"#include "def.mkroom.h"struct permonst li_dog =	{ "little dog", 'd',2,18,6,1,6,sizeof(struct edog) };struct permonst dog =	{ "dog", 'd',4,16,5,1,6,sizeof(struct edog) };struct permonst la_dog =	{ "large dog", 'd',6,15,4,2,4,sizeof(struct edog) };makedog(){register struct monst *mtmp = makemon(&li_dog,u.ux,u.uy);	if(!mtmp) return; /* dogs were genocided */	initedog(mtmp);}initedog(mtmp) register struct monst *mtmp; {	mtmp->mtame = mtmp->mpeaceful = 1;	EDOG(mtmp)->hungrytime = 1000 + moves;	EDOG(mtmp)->eattime = 0;	EDOG(mtmp)->droptime = 0;	EDOG(mtmp)->dropdist = 10000;	EDOG(mtmp)->apport = 10;	EDOG(mtmp)->whistletime = 0;}/* attach the monsters that went down (or up) together with @ */struct monst *mydogs = 0;struct monst *fallen_down = 0;	/* monsters that fell through a trapdoor */	/* they will appear on the next level @ goes to, even if he goes up! */losedogs(){register struct monst *mtmp;	while(mtmp = mydogs){		mydogs = mtmp->nmon;		mtmp->nmon = fmon;		fmon = mtmp;		mnexto(mtmp);	}	while(mtmp = fallen_down){		fallen_down = mtmp->nmon;		mtmp->nmon = fmon;		fmon = mtmp;		rloc(mtmp);	}}keepdogs(){register struct monst *mtmp;	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)	    if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp)		&& !mtmp->msleep && !mtmp->mfroz) {		relmon(mtmp);		mtmp->nmon = mydogs;		mydogs = mtmp;		unpmon(mtmp);		keepdogs();	/* we destroyed the link, so use recursion */		return;		/* (admittedly somewhat primitive) */	}}fall_down(mtmp) register struct monst *mtmp; {	relmon(mtmp);	mtmp->nmon = fallen_down;	fallen_down = mtmp;	unpmon(mtmp);	mtmp->mtame = 0;}/* return quality of food; the lower the better */#define	DOGFOOD	0#define	CADAVER	1#define	ACCFOOD	2#define	MANFOOD	3#define	APPORT	4#define	POISON	5#define	UNDEF	6dogfood(obj) register struct obj *obj; {	switch(obj->olet) {	case FOOD_SYM:	    return(		(obj->otyp == TRIPE_RATION) ? DOGFOOD :		(obj->otyp < CARROT) ? ACCFOOD :		(obj->otyp < CORPSE) ? MANFOOD :		(poisonous(obj) || obj->age + 50 <= moves ||		    obj->otyp == DEAD_COCKATRICE)			? POISON : CADAVER	    );	default:	    if(!obj->cursed) return(APPORT);	    /* fall into next case */	case BALL_SYM:	case CHAIN_SYM:	case ROCK_SYM:	    return(UNDEF);	}}/* return 0 (no move), 1 (move) or 2 (dead) */dog_move(mtmp, after) register struct monst *mtmp; {register int nx,ny,omx,omy,appr,nearer,j;int udist,chi,i,whappr;register struct monst *mtmp2;register struct permonst *mdat = mtmp->data;register struct edog *edog = EDOG(mtmp);struct obj *obj;struct trap *trap;xchar cnt,chcnt,nix,niy;schar dogroom,uroom;xchar gx,gy,gtyp,otyp;	/* current goal */coord poss[9];int info[9];#define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy))#define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy))	if(moves <= edog->eattime) return(0);	/* dog is still eating */	omx = mtmp->mx;	omy = mtmp->my;	whappr = (moves - EDOG(mtmp)->whistletime < 5);	if(moves > edog->hungrytime + 500 && !mtmp->mconf){		mtmp->mconf = 1;		mtmp->mhpmax /= 3;		if(mtmp->mhp > mtmp->mhpmax)			mtmp->mhp = mtmp->mhpmax;		if(cansee(omx,omy))			pline("%s is confused from hunger.", Monnam(mtmp));		else	pline("You feel worried about %s.", monnam(mtmp));	} else	if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){		if(cansee(omx,omy))			pline("%s dies from hunger.", Monnam(mtmp));		else		pline("You have a sad feeling for a moment, then it passes.");		mondied(mtmp);		return(2);	}	dogroom = inroom(omx,omy);	uroom = inroom(u.ux,u.uy);	udist = dist(omx,omy);	/* maybe we tamed him while being swallowed --jgm */	if(!udist) return(0);	/* if we are carrying sth then we drop it (perhaps near @) */	/* Note: if apport == 1 then our behaviour is independent of udist */	if(mtmp->minvent){		if(!rn2(udist) || !rn2((int) edog->apport))		if(rn2(10) < edog->apport){			relobj(mtmp, (int) mtmp->minvis);			if(edog->apport > 1) edog->apport--;			edog->dropdist = udist;		/* hpscdi!jon */			edog->droptime = moves;		}	} else {		if(obj = o_at(omx,omy)) if(!index("0_", obj->olet)){		    if((otyp = dogfood(obj)) <= CADAVER){			nix = omx;			niy = omy;			goto eatobj;		    }		    if(obj->owt < 10*mtmp->data->mlevel)		    if(rn2(20) < edog->apport+3)		    if(rn2(udist) || !rn2((int) edog->apport)){			freeobj(obj);			unpobj(obj);			/* if(levl[omx][omy].scrsym == obj->olet)				newsym(omx,omy); */			mpickobj(mtmp,obj);		    }		}	}	/* first we look for food */	gtyp = UNDEF;	/* no goal as yet */#ifdef LINT	gx = gy = 0;	/* suppress 'used before set' message */#endif LINT	for(obj = fobj; obj; obj = obj->nobj) {		otyp = dogfood(obj);		if(otyp > gtyp || otyp == UNDEF) continue;		if(inroom(obj->ox,obj->oy) != dogroom) continue;		if(otyp < MANFOOD &&		 (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) {			if(otyp < gtyp || (otyp == gtyp &&				DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){				gx = obj->ox;				gy = obj->oy;				gtyp = otyp;			}		} else		if(gtyp == UNDEF && dogroom >= 0 &&		   uroom == dogroom &&		   !mtmp->minvent && edog->apport > rn2(8)){			gx = obj->ox;			gy = obj->oy;			gtyp = APPORT;		}	}	if(gtyp == UNDEF ||	  (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){		if(dogroom < 0 || dogroom == uroom){			gx = u.ux;			gy = u.uy;#ifndef QUEST		} else {			int tmp = rooms[dogroom].fdoor;			    cnt = rooms[dogroom].doorct;			gx = gy = FAR;	/* random, far away */			while(cnt--){			    if(dist(gx,gy) >				dist(doors[tmp].x, doors[tmp].y)){					gx = doors[tmp].x;					gy = doors[tmp].y;				}				tmp++;			}			/* here gx == FAR e.g. when dog is in a vault */			if(gx == FAR || (gx == omx && gy == omy)){				gx = u.ux;				gy = u.uy;			}#endif QUEST		}		appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0;		if(after && udist <= 4 && gx == u.ux && gy == u.uy)			return(0);		if(udist > 1){			if(!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||			   whappr ||			   (mtmp->minvent && rn2((int) edog->apport)))				appr = 1;		}		/* if you have dog food he'll follow you more closely */		if(appr == 0){			obj = invent;			while(obj){				if(obj->otyp == TRIPE_RATION){					appr = 1;					break;				}				obj = obj->nobj;			}		}	} else	appr = 1;	/* gtyp != UNDEF */	if(mtmp->mconf) appr = 0;	if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){	extern coord *gettrack();	register coord *cp;		cp = gettrack(omx,omy);		if(cp){			gx = cp->x;			gy = cp->y;		}	}	nix = omx;	niy = omy;	cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS);	chcnt = 0;	chi = -1;	for(i=0; i<cnt; i++){		nx = poss[i].x;		ny = poss[i].y;		if(info[i] & ALLOW_M){			mtmp2 = m_at(nx,ny);			if(mtmp2->data->mlevel >= mdat->mlevel+2 ||			  mtmp2->data->mlet == 'c')				continue;			if(after) return(0); /* hit only once each move */			if(hitmm(mtmp, mtmp2) == 1 && rn2(4) &&			  mtmp2->mlstmv != moves &&			  hitmm(mtmp2,mtmp) == 2) return(2);			return(0);		}		/* dog avoids traps */		/* but perhaps we have to pass a trap in order to follow @ */		if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){			if(!trap->tseen && rn2(40)) continue;			if(rn2(10)) continue;		}		/* dog eschewes cursed objects */		/* but likes dog food */		obj = fobj;		while(obj){		    if(obj->ox != nx || obj->oy != ny)			goto nextobj;		    if(obj->cursed) goto nxti;		    if(obj->olet == FOOD_SYM &&			(otyp = dogfood(obj)) < MANFOOD &&			(otyp < ACCFOOD || edog->hungrytime <= moves)){			/* Note: our dog likes the food so much that he			might eat it even when it conceals a cursed object */			nix = nx;			niy = ny;			chi = i;		     eatobj:			edog->eattime =			    moves + obj->quan * objects[obj->otyp].oc_delay;			if(edog->hungrytime < moves)			    edog->hungrytime = moves;			edog->hungrytime +=			    5*obj->quan * objects[obj->otyp].nutrition;			mtmp->mconf = 0;			if(cansee(nix,niy))			    pline("%s ate %s.", Monnam(mtmp), doname(obj));			/* perhaps this was a reward */			if(otyp != CADAVER)			edog->apport += 200/(edog->dropdist+moves-edog->droptime);			delobj(obj);			goto newdogpos;		    }		nextobj:		    obj = obj->nobj;		}		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;/* Some stupid C compilers cannot compute the whole expression at once. */		nearer = GDIST(nx,ny);		nearer -= GDIST(nix,niy);		nearer *= appr;		if((nearer == 0 && !rn2(++chcnt)) || nearer<0 ||			(nearer > 0 && !whappr &&				((omx == nix && omy == niy && !rn2(3))				|| !rn2(12))			)){			nix = nx;			niy = ny;			if(nearer < 0) chcnt = 0;			chi = i;		}	nxti:	;	}newdogpos:	if(nix != omx || niy != omy){		if(info[chi] & ALLOW_U){			(void) hitu(mtmp, d(mdat->damn, mdat->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;	}	if(mintrap(mtmp) == 2)	/* he died */		return(2);	pmon(mtmp);	return(1);}/* return roomnumber or -1 */inroom(x,y) xchar x,y; {#ifndef QUEST	register struct mkroom *croom = &rooms[0];	while(croom->hx >= 0){		if(croom->hx >= x-1 && croom->lx <= x+1 &&		   croom->hy >= y-1 && croom->ly <= y+1)			return(croom - rooms);		croom++;	}#endif QUEST	return(-1);	/* not in room or on door */}tamedog(mtmp, obj)register struct monst *mtmp;register struct obj *obj;{	register struct monst *mtmp2;	if(flags.moonphase == FULL_MOON && night() && rn2(6))		return(0);	/* If we cannot tame him, at least he's no longer afraid. */	mtmp->mflee = 0;	mtmp->mfleetim = 0;	if(mtmp->mtame || mtmp->mfroz ||#ifndef NOWORM		mtmp->wormno ||#endif NOWORM		mtmp->isshk || mtmp->isgd || index(" &@12", mtmp->data->mlet))		return(0); /* no tame long worms? */	if(obj) {		if(dogfood(obj) >= MANFOOD) return(0);		if(cansee(mtmp->mx,mtmp->my)){			pline("%s devours the %s.", Monnam(mtmp),				objects[obj->otyp].oc_name);		}		obfree(obj, (struct obj *) 0);	}	mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);	*mtmp2 = *mtmp;	mtmp2->mxlth = sizeof(struct edog);	if(mtmp->mnamelth) (void) strcpy(NAME(mtmp2), NAME(mtmp));	initedog(mtmp2);	replmon(mtmp,mtmp2);	return(1);}

⌨️ 快捷键说明

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