Source:NetHack 2.3e/dog.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to dog.c from the source code of NetHack 2.3e.

Warning! This is the source code from an old release. For newer releases, see Source code

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)dog.c	2.3	88/03/29
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include	"hack.h"
5.    extern struct monst *makemon();
6.    #include "edog.h"
7.    #include "mkroom.h"
8.    
9.    #ifdef	DOGNAME
10.   char dogname[63];
11.   #endif	/* DOGNAME */
12.   
13.   struct permonst li_dog =
14.   	{ "little dog", 'd',2,18,6,0,1,6,sizeof(struct edog) };
15.   struct permonst dog =
16.   	{ "dog", 'd',4,16,5,0,1,6,sizeof(struct edog) };
17.   struct permonst la_dog =
18.   	{ "large dog", 'd',6,15,4,0,2,4,sizeof(struct edog) };
19.   
20.   struct monst *
21.   makedog(){
22.   register struct monst *mtmp = makemon(&li_dog,u.ux,u.uy);
23.   	if(!mtmp) return((struct monst *) 0); /* dogs were genocided */
24.   #ifdef	DOGNAME
25.   	if (dogname[0]) {
26.   		register struct monst *mtmp2;
27.   		mtmp->mnamelth = strlen(dogname);
28.   		mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
29.   		*mtmp2 = *mtmp;
30.   		strcpy(NAME(mtmp2), dogname);
31.   		replmon(mtmp, mtmp2);
32.   		mtmp = mtmp2;
33.   		dogname[0] = '\0';	/* name only first dog */
34.   	}
35.   #endif	/* DOGNAME */
36.   	initedog(mtmp);
37.   	return(mtmp);
38.   }
39.   
40.   initedog(mtmp) register struct monst *mtmp; {
41.   	mtmp->mtame = mtmp->mpeaceful = 1;
42.   #ifdef WALKIES
43.   	mtmp->mleashed = 0;
44.   #endif
45.   	EDOG(mtmp)->hungrytime = 1000 + moves;
46.   	EDOG(mtmp)->eattime = 0;
47.   	EDOG(mtmp)->droptime = 0;
48.   	EDOG(mtmp)->dropdist = 10000;
49.   	EDOG(mtmp)->apport = 10;
50.   	EDOG(mtmp)->whistletime = 0;
51.   }
52.   
53.   /* attach the monsters that went down (or up) together with @ */
54.   struct monst *mydogs = 0;
55.   struct monst *fallen_down = 0;	/* monsters that fell through a trapdoor */
56.   	/* they will appear on the next level @ goes to, even if he goes up! */
57.   
58.   losedogs(){
59.   register struct monst *mtmp;
60.   	while(mtmp = mydogs){
61.   		mydogs = mtmp->nmon;
62.   		mtmp->nmon = fmon;
63.   		fmon = mtmp;
64.   		mnexto(mtmp);
65.   	}
66.   	while(mtmp = fallen_down){
67.   		fallen_down = mtmp->nmon;
68.   		mtmp->nmon = fmon;
69.   #ifdef WALKIES
70.   		mtmp->mleashed = 0;
71.   #endif
72.   		fmon = mtmp;
73.   		rloc(mtmp);
74.   	}
75.   }
76.   
77.   keepdogs(){
78.   register struct monst *mtmp;
79.   	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
80.   	    if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp)
81.   		&& !mtmp->msleep && !mtmp->mfroz) {
82.   #ifdef DGKMOD
83.   		/* Bug "fix" for worm changing levels collapsing dungeon
84.   		 */
85.   		if (mtmp->data->mlet == 'w') {
86.   			if (canseemon(mtmp) || (Blind && Telepat))
87.   				pline("The worm can't fit down the stairwell!");
88.   #ifdef WALKIES
89.   			pline("The leash slides off the slimy worm!");
90.   			mtmp->mleashed = 0;
91.   #endif
92.   			continue;
93.   		}
94.   #endif
95.   		relmon(mtmp);
96.   		mtmp->nmon = mydogs;
97.   		mydogs = mtmp;
98.   		unpmon(mtmp);
99.   		keepdogs();	/* we destroyed the link, so use recursion */
100.  		return;		/* (admittedly somewhat primitive) */
101.  	}
102.  }
103.  
104.  fall_down(mtmp) register struct monst *mtmp; {
105.  	relmon(mtmp);
106.  	mtmp->nmon = fallen_down;
107.  	fallen_down = mtmp;
108.  #ifdef WALKIES
109.  	if (mtmp->mleashed)  {
110.  
111.  		pline("The leash comes off!");
112.  		mtmp->mleashed = 0;
113.  	}
114.  #endif
115.  	unpmon(mtmp);
116.  	mtmp->mtame = 0;
117.  }
118.  
119.  /* return quality of food; the lower the better */
120.  dogfood(obj) register struct obj *obj; {
121.  	switch(obj->olet) {
122.  	case FOOD_SYM:
123.  	    return(
124.  		(obj->otyp == TRIPE_RATION) ? DOGFOOD :
125.  		(obj->otyp < CARROT) ? ACCFOOD :
126.  		(obj->otyp < CORPSE) ? MANFOOD :
127.  		(poisonous(obj) || obj->age + 50 <= moves ||
128.  		    obj->otyp == DEAD_COCKATRICE)
129.  			? POISON : CADAVER
130.  	    );
131.  	default:
132.  	    if(!obj->cursed) return(APPORT);
133.  	    /* fall into next case */
134.  	case BALL_SYM:
135.  	case CHAIN_SYM:
136.  	case ROCK_SYM:
137.  	    return(UNDEF);
138.  	}
139.  }
140.  
141.  /* return roomnumber or -1 */
142.  inroom(x,y) xchar x,y; {
143.  #ifndef QUEST
144.  	register struct mkroom *croom = &rooms[0];
145.  	while(croom->hx >= 0){
146.  		if(croom->hx >= x-1 && croom->lx <= x+1 &&
147.  		   croom->hy >= y-1 && croom->ly <= y+1)
148.  			return(croom - rooms);
149.  		croom++;
150.  	}
151.  #endif
152.  	return(-1);	/* not in room or on door */
153.  }
154.  
155.  tamedog(mtmp, obj)
156.  register struct monst *mtmp;
157.  register struct obj *obj;
158.  {
159.  	register struct monst *mtmp2;
160.  
161.  	/* worst case, at least he'll be peaceful. */
162.  	mtmp->mpeaceful = 1;
163.  	if(flags.moonphase == FULL_MOON && night() && rn2(6))
164.  		return(0);
165.  
166.  	/* If we cannot tame him, at least he's no longer afraid. */
167.  	mtmp->mflee = 0;
168.  	mtmp->mfleetim = 0;
169.  	if(mtmp->mtame || mtmp->mfroz ||
170.  #ifndef NOWORM
171.  	   mtmp->wormno ||
172.  #endif
173.  	   mtmp->isshk || mtmp->isgd || index(" @12", mtmp->data->mlet))
174.  		return(0);			/* no tame long worms? */
175.  	if(obj) {
176.  		if(dogfood(obj) >= MANFOOD) return(0);
177.  		if(cansee(mtmp->mx,mtmp->my)){
178.  			pline("%s devours the %s.", Monnam(mtmp),
179.  				objects[obj->otyp].oc_name);
180.  		}
181.  		obfree(obj, (struct obj *) 0);
182.  	}
183.  	mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
184.  	*mtmp2 = *mtmp;
185.  	mtmp2->mxlth = sizeof(struct edog);
186.  	if(mtmp->mnamelth) (void) strcpy(NAME(mtmp2), NAME(mtmp));
187.  	initedog(mtmp2);
188.  	replmon(mtmp,mtmp2);
189.  	return(1);
190.  }