Source:Hack 1.0/hack.fight.c

Below is the full text to hack.fight.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.fight.c#line123 ]], for example.

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

1.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2.     3.    #include	"hack.h"  4.    extern struct permonst li_dog, dog, la_dog; 5.   extern char *exclam, *xname; 6.    7.    static boolean far_noise; 8.   static long noisetime; 9.    10.   /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ 11.  hitmm(magr,mdef) register struct monst *magr,*mdef; { 12.  register struct permonst *pa = magr->data, *pd = mdef->data; 13.  int hit; 14.  schar tmp; 15.  boolean vis; 16.  	if(index("Eauy", pa->mlet)) return(0); 17.  	tmp = pd->ac + pa->mlevel; 18.  	if(mdef->mconf || mdef->mfroz || mdef->msleep){ 19.  		tmp += 4; 20.  		if(mdef->msleep) mdef->msleep = 0; 21.  	}  22.   	hit = (tmp > rnd(20)); 23.  	if(hit) mdef->msleep = 0; 24.  	vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 25.  	if(vis){ 26.  		char buf[BUFSZ]; 27.  		if(mdef->mimic) seemimic(mdef); 28.  		if(magr->mimic) seemimic(magr); 29.  		(void) sprintf(buf,"%s %s", Monnam(magr),  30.   			hit ? "hits" : "misses"); 31.  		pline("%s %s.", buf, monnam(mdef)); 32.  	} else { 33.  		boolean far = (dist(magr->mx, magr->my) > 15); 34.  		if(far != far_noise || moves-noisetime > 10) { 35.  			far_noise = far; 36.  			noisetime = moves; 37.  			pline("You hear some noises%s.",  38.   				far ? " in the distance" : ""); 39.  		}  40.   	}  41.   	if(hit){ 42.  		if(magr->data->mlet == 'c' && !magr->cham) { 43.  			magr->orig_hp += 3; 44.  			if(vis) pline("%s is turned to stone!", Monnam(mdef)); 45.  			else if(mdef->mtame) 46.       pline("You have a peculiarly sad feeling for a moment, then it passes."); 47.  			monstone(mdef); 48.  			hit = 2; 49.  		} else 50.  		if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) { 51.  			magr->orig_hp += 1 + rn2(pd->mlevel+1); 52.  			if(magr->mtame && magr->orig_hp > 8*pa->mlevel){ 53.  				if(pa == &li_dog) magr->data = pa = &dog; 54.  				else if(pa == &dog) magr->data = pa = &la_dog; 55.  			}  56.   			if(vis) pline("%s is killed!", Monnam(mdef)); 57.  			else if(mdef->mtame) 58.  		pline("You have a sad feeling for a moment, then it passes."); 59.  			mondied(mdef); 60.  			hit = 2; 61.  		}  62.   	}  63.    return(hit); 64.  }  65.    66.   /* drop (perhaps) a cadaver and remove monster */ 67.  mondied(mdef) register struct monst *mdef; { 68.  register struct permonst *pd = mdef->data; 69.  		if(letter(pd->mlet) && rn2(3)){ 70.  			mksobj_at(pd->mlet,CORPSE,mdef->mx,mdef->my); 71.  			if(cansee(mdef->mx,mdef->my)){ 72.  				unpmon(mdef); 73.  				atl(mdef->mx,mdef->my,fobj->olet); 74.  			}  75.    stackobj(fobj); 76.  		}  77.    mondead(mdef); 78.  }  79.    80.   /* drop a rock and remove monster */ 81.  monstone(mdef) register struct monst *mdef; { 82.  	extern char mlarge[]; 83.  	if(index(mlarge, mdef->data->mlet)) 84.  		mksobj_at(ROCK_SYM, ENORMOUS_ROCK, mdef->mx, mdef->my); 85.  	else 86.  		mksobj_at(WEAPON_SYM, ROCK, mdef->mx, mdef->my); 87.  	if(cansee(mdef->mx, mdef->my)){ 88.  		unpmon(mdef); 89.  		atl(mdef->mx,mdef->my,fobj->olet); 90.  	}  91.    mondead(mdef); 92.  }  93.   		  94.    95.   fightm(mtmp) register struct monst *mtmp; { 96.  register struct monst *mon; 97.  	for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) { 98.  		if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3) 99.  		    if(rn2(4)) 100. 			return(hitmm(mtmp,mon)); 101. 	}  102.   return(-1); 103. }  104.   105.  hitu(mtmp,dam) 106. register struct monst *mtmp; 107. register dam; 108. {  109.  	register tmp; 110.  111.  	if(mtmp->mhide && mtmp->mundetected) { 112. 		mtmp->mundetected = 0; 113. 		if(!Blind) { 114. 			register struct obj *obj; 115. 			extern char * Xmonnam; 116. 			if(obj = o_at(mtmp->mx,mtmp->my)) 117. 				pline("%s was hidden under %s!",  118.  					Xmonnam(mtmp), doname(obj)); 119. 		}  120.  	}  121.   122.  	tmp = u.uac; 123. 	/* give people with Ac = -10 at least some vulnerability */ 124. 	if(tmp < 0) { 125. 		dam += tmp;		/* decrease damage */ 126. 		if(dam <= 0) dam = 1; 127. 		tmp = -rn2(-tmp); 128. 	}  129.  	tmp += mtmp->data->mlevel; 130. 	if(multi < 0) tmp += 4; 131. 	if(Invis || !mtmp->mcansee) tmp -= 2; 132. 	if(mtmp->mtrapped) tmp -= 2; 133. 	if(tmp <= rnd(20)) { 134. 		if(Blind) pline("It misses."); 135. 		else pline("%s misses.",Monnam(mtmp)); 136. 		return(0); 137. 	}  138.  	if(Blind) pline("It hits!"); 139. 	else pline("%s hits!",Monnam(mtmp)); 140. 	losehp_m(dam, mtmp); 141. 	return(1); 142. }  143.   144.  /* u is hit by sth, but not a monster */ 145. thitu(tlev,dam,name) 146. register tlev,dam; 147. register char *name; 148. {  149.  char buf[BUFSZ]; 150. 	setan(name,buf); 151. 	if(u.uac + tlev <= rnd(20)) { 152. 		if(Blind) pline("It misses."); 153. 		else pline("You are almost hit by %s!", buf); 154. 		return(0); 155. 	} else { 156. 		if(Blind) pline("You are hit!"); 157. 		else pline("You are hit by %s!", buf); 158. 		losehp(dam,name); 159. 		return(1); 160. 	}  161.  }  162.   163.  char mlarge[] = "bCDdegIlmnoPSsTUwY~,&"; 164.  165.  boolean 166. hmon(mon,obj,thrown)	/* return TRUE if mon still alive */ 167. register struct monst *mon; 168. register struct obj *obj; 169. register thrown; 170. {  171.  	register tmp; 172.  173.  	if(!obj){ 174. 		tmp = rnd(2);	/* attack with bare hands */ 175. 		if(mon->data->mlet == 'c' && !uarmg){ 176. 			pline("You hit the cockatrice with your bare hands"); 177. 			pline("You turn to stone ..."); 178. 			done_in_by(mon); 179. 		}  180.  	} else if(obj->olet == WEAPON_SYM) { 181. 	    if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG)) 182. 		tmp = rnd(2); 183. 	    else { 184. 		if(index(mlarge, mon->data->mlet)) { 185. 			tmp = rnd(objects[obj->otyp].wldam); 186. 			if(obj->otyp == TWO_HANDED_SWORD) tmp += d(2,6); 187. 			else if(obj->otyp == FLAIL) tmp += rnd(4); 188. 		} else { 189.  tmp = rnd(objects[obj->otyp].wsdam); 190. 		}  191.  		tmp += obj->spe; 192. 		if(!thrown && obj == uwep && obj->otyp == BOOMERANG  193.  		 && !rn2(3)){ 194. 		  pline("As you hit %s, the boomerang breaks into splinters.",  195.  				monnam(mon)); 196. 			freeinv(obj); 197. 			setworn((struct obj *) 0, obj->owornmask); 198. 			obfree(obj, (struct obj *) 0); 199. 			tmp++; 200. 		}  201.  	    }  202.  	    if(mon->data->mlet == 'O' && !strcmp(ONAME(obj), "Orcrist")) 203. 		tmp += rnd(10); 204. 	} else	switch(obj->otyp) { 205. 		case HEAVY_IRON_BALL: 206. 			tmp = rnd(25); break; 207. 		case EXPENSIVE_CAMERA: 208. 	pline("You succeed in destroying your camera. Congratulations!"); 209. 			freeinv(obj); 210. 			if(obj->owornmask) 211. 				setworn((struct obj *) 0, obj->owornmask); 212. 			obfree(obj, (struct obj *) 0); 213. 			return(TRUE); 214. 		case DEAD_COCKATRICE: 215. 			pline("You hit %s with the cockatrice corpse",  216.  				monnam(mon)); 217. 			pline("%s is turned to stone!", Monnam(mon)); 218. 			killed(mon); 219. 			return(FALSE); 220. 		case CLOVE_OF_GARLIC: 221. 			if(index(" VWZ", mon->data->mlet)) 222. 				mon->mflee = 1; 223. 			tmp = 1; 224. 			break; 225. 		default: 226. 			/* non-weapons can damage because of their weight */ 227. 			/* (but not too much) */ 228. 			tmp = obj->owt/10; 229. 			if(tmp < 1) tmp = 1; 230. 			else tmp = rnd(tmp); 231. 			if(tmp > 6) tmp = 6; 232. 		}  233.   234.  	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ 235.  236.  	tmp += u.udaminc + dbon; 237. 	if(u.uswallow) 238. 		if(mon->data->mlet == 'P') { 239. 			if((tmp -= u.uswldtim) <= 0) { 240. 				pline("Your arms are no longer able to hit."); 241. 				return(TRUE); 242. 			}  243.  		}  244.  	if(tmp < 1) tmp = 1; 245. 	mon->mhp -= tmp; 246. 	if(mon->mhp < 1) { 247. 		killed(mon); 248. 		return(FALSE); 249. 	}  250.   251.  	if(thrown) {	/* this assumes that we cannot throw plural things */ 252. 		hit( xname(obj)		/* or: objects[obj->otyp].oc_name */,  253.  			mon, exclam(tmp) ); 254. 		return(TRUE); 255. 	}  256.  	if(Blind) pline("You hit it."); 257. 	else pline("You hit %s%s", monnam(mon), exclam(tmp)); 258.  259.  	if(u.umconf) { 260. 		if(!Blind) { 261. 			pline("Your hands stop glowing blue."); 262. 			if(!mon->mfroz && !mon->msleep) 263. 				pline("%s appears confused.",Monnam(mon)); 264. 		}  265.  		mon->mconf = 1; 266. 		u.umconf = 0; 267. 	}  268.  	return(TRUE);	/* mon still alive */ 269. }