Source:NetHack 1.3d/mhitu.c

Below is the full text to mhitu.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/mhitu.c#line123 ]], for example.

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

1.   /*	SCCS Id: @(#)mhitu.c	1.3	87/07/14 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* mhitu.c - version 1.0.3 */ 4.    5.    #include	"hack.h"  6.    extern struct monst *makemon; 7.   #ifdef KAA 8.   extern char pl_character[]; 9.   #endif 10.   11.   /*  12.    * mhitu: monster hits you 13.   *	  returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise 14.   */  15.   mhitu(mtmp) 16.  register struct monst *mtmp; 17.  {  18.   	register struct permonst *mdat = mtmp->data; 19.  	register int tmp, ctmp; 20.   21.   	nomul(0); 22.   23.   	/* If swallowed, can only be affected by hissers and by u.ustuck */ 24.  	if(u.uswallow) { 25.  		if(mtmp != u.ustuck) { 26.  			if(mdat->mlet == 'c' && !rn2(13)) { 27.  				pline("Outside, you hear %s's hissing!",  28.   					monnam(mtmp)); 29.  				pline("%s gets turned to stone!",  30.   					Monnam(u.ustuck)); 31.  				pline("And the same fate befalls you."); 32.  				done_in_by(mtmp); 33.  				/* "notreached": not return(1); */ 34.  			}  35.   			return(0); 36.  		}  37.   		switch(mdat->mlet) {	/* now mtmp == u.ustuck */ 38.  		case ',': 39.  			youswld(mtmp, (u.uac > 0) ? u.uac+4 : 4,  40.   				5, Monnam(mtmp)); 41.  			break; 42.  		case '\'': 43.  			youswld(mtmp,rnd(6),7,Monnam(mtmp)); 44.  			break; 45.  		case 'P': 46.  			youswld(mtmp,d(2,4),12,Monnam(mtmp)); 47.  			break; 48.  		default: 49.  			/* This is not impossible! */ 50.   #ifdef DGKMOD 51.  			/* If the swallowing monster changes into a monster 52.  			 * that is not capable of swallowing you, you get 53.  			 * regurgitated - dgk 54.  			 */  55.   			pline("You get regurgitated!"); 56.  			u.ux = mtmp->mx; 57.  			u.uy = mtmp->my; 58.  			u.uswallow = 0; 59.  			u.ustuck = 0; 60.  			mnexto(mtmp); 61.  			setsee; 62.  			docrt; 63.  			break; 64.  #else 65.  			pline("The mysterious monster totally digests you."); 66.  			u.uhp = 0; 67.  #endif /* DGKMOD /**/ 68.  		}  69.   		if(u.uhp < 1) done_in_by(mtmp); 70.  		return(0); 71.  	}  72.    73.   	if(mdat->mlet == 'c' && Stoned) 74.  		return(0); 75.   76.   	/* make eels visible the moment they hit/miss us */ 77.  	if(mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx,mtmp->my)){ 78.  		mtmp->minvis = 0; 79.  		pmon(mtmp); 80.  	}  81.   	if(!index("1&DuxynNF",mdat->mlet)) 82.  		tmp = hitu(mtmp,d(mdat->damn,mdat->damd)); 83.  	else 84.  		tmp = 0; 85.  	if(index(UNDEAD, mdat->mlet) && midnight) 86.  		tmp += hitu(mtmp,d(mdat->damn,mdat->damd)); 87.   88.   	ctmp = tmp && !mtmp->mcan && 89.  	  (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50)); 90.  	switch(mdat->mlet) { 91.  	case '1': 92.  		if(wiz_hit(mtmp)) return(1);	/* he disappeared */ 93.  		break; 94.  	case '&': 95.  		demon_hit(mtmp); 96.  		break; 97.  	case ',': 98.  		if(tmp) justswld(mtmp,Monnam(mtmp)); 99.  		break; 100. 	case '\'': 101. 		if (tmp) justswld(mtmp,Monnam(mtmp)); 102. 		break; 103. 	case ';': 104. 		if(ctmp) { 105. 			if(!u.ustuck && !rn2(10)) { 106. 				pline("%s swings itself around you!",  107.  					Monnam(mtmp)); 108. 				u.ustuck = mtmp; 109. 			} else if(u.ustuck == mtmp &&  110.  			    levl[mtmp->mx][mtmp->my].typ == POOL) { 111. 				pline("%s drowns you ...", Monnam(mtmp)); 112. 				done("drowned"); 113. 			}  114.  		}  115.  		break; 116. 	case 'A': 117. 		if(ctmp && rn2(2)) { 118. 		    if(Poison_resistance) 119. 			pline("The sting doesn't seem to affect you."); 120. 		    else { 121. 			pline("You feel weaker!"); 122. 			losestr(1); 123. 		    }  124.  		}  125.  		break; 126. 	case 'C': 127. 		(void) hitu(mtmp,rnd(6)); 128. 		break; 129. 	case 'c': 130. 		if(!rn2(5)) { 131. 		    if (mtmp->mcan) 132. 			pline("You hear a cough from %s!", monnam(mtmp)); 133. 		    else { 134. 			pline("You hear %s's hissing!", monnam(mtmp)); 135. 			if(!rn2(20) || (flags.moonphase == NEW_MOON 136. 			    && !carrying(DEAD_LIZARD) && u.usym != 'c')) { 137. 				Stoned = 5; 138. 				/* pline("You get turned to stone!"); */ 139. 				/* done_in_by(mtmp); */ 140. 			}  141.  		    }  142.  		}  143.  		break; 144. 	case 'D': 145. 		if(rn2(6) || mtmp->mcan) { 146. 			(void) hitu(mtmp,d(3,10)); 147. 			(void) hitu(mtmp,rnd(8)); 148. 			(void) hitu(mtmp,rnd(8)); 149. 			break; 150. 		}  151.  		kludge("%s breathes fire!",Monnam(mtmp)); 152. 		buzz(-1,mtmp->mx,mtmp->my,u.ux-mtmp->mx,u.uy-mtmp->my); 153. 		break; 154. 	case 'd': 155. 		(void) hitu(mtmp,d(2, (flags.moonphase == FULL_MOON) ? 3 : 4)); 156.  		break; 157. 	case 'e': 158. 		(void) hitu(mtmp,d(3,6)); 159. 		break; 160. 	case 'F': 161. 		if(mtmp->mcan) break; 162. 		kludge("%s explodes!", Monnam(mtmp)); 163. 		if(Cold_resistance) pline("You don't seem affected by it."); 164. 		else { 165. 			xchar dn; 166. 			if(17-(u.ulevel/2) > rnd(20)) { 167. 				pline("You get blasted!"); 168. 				dn = 6; 169. 			} else { 170. 				pline("You duck the blast..."); 171. 				dn = 3; 172. 			}  173.  			losehp_m(d(dn,6), mtmp); 174. 		}  175.  		mondead(mtmp); 176. 		return(1); 177. 	case 'g': 178. 		if(ctmp && multi >= 0 && !rn2(3)) { 179. 		/* fix so we don't know what hit us when blind  KAA */ 180. 		    if (Blind) 181. 			pline("You are frozen by its juices!"); 182. 		    else 183. 			pline("You are frozen by %s's juices!",monnam(mtmp)); 184. 		    nomul(-rnd(10)); 185. 		}  186.  		break; 187. 	case 'h': 188. 		if(ctmp && multi >= 0 && !rn2(5)) { 189. 		    nomul(-rnd(10)); 190. 		    if (Blind) 191. 			pline("You are put to sleep by its bite!"); 192. 		    else 193. 			pline("You are put to sleep by %s's bite!",monnam(mtmp)); 194. 		}  195.  		break; 196. 	case 'j': 197. 		tmp = hitu(mtmp,rnd(3)); 198. 		tmp &= hitu(mtmp,rnd(3)); 199. 		if(tmp){ 200. 			(void) hitu(mtmp,rnd(4)); 201. 			(void) hitu(mtmp,rnd(4)); 202. 		}  203.  		break; 204. 	case 'k': 205. 		if((hitu(mtmp,rnd(4)) || !rn2(3)) && ctmp){ 206. 			poisoned("bee's sting",mdat->mname); 207. 		}  208.  		break; 209. 	case 'L': 210. #ifdef KAA 211. 		if (u.usym=='L') break; 212. #endif 213. 		if(!mtmp->mcan && tmp) stealgold(mtmp); 214. 		break; 215. 	case 'N': 216. #ifdef KAA 217. 		if (u.usym=='N') { 218. 			if (mtmp->minvent) 219. 	pline("%s brags about the goods some dungeon explorer provided.",  220.  	Monnam(mtmp)); 221. 			else 222. 	pline("%s makes some remarks about how difficult theft is lately.",  223.  	Monnam(mtmp)); 224. 			rloc(mtmp); 225. 		} else 226. #endif 227. 		if(mtmp->mcan && !Blind) { 228. 		pline("%s tries to seduce you, but you seem not interested.",  229.  			Amonnam(mtmp, "plain")); 230. 			if(rn2(3)) rloc(mtmp); 231. 		} else if(steal(mtmp)) { 232. 			rloc(mtmp); 233. 			mtmp->mflee = 1; 234. 		}  235.  		break; 236. 	case 'n': 237. 		if(!uwep  238.  #ifdef KAA  239.  		   && u.usym == '@'  240.  #endif  241.  		   && !uarm && !uarmh && !uarms && !uarmg) { 242. 		    pline("%s hits! (I hope you don't mind)",  243.  			Monnam(mtmp)); 244. 			u.uhp += rnd(7); 245. 			if(!rn2(7)) u.uhpmax++; 246. 			if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; 247. 			flags.botl = 1; 248. 			if(!rn2(50)) rloc(mtmp); 249. 		} else { 250. #ifdef KAA 251. 			if (pl_character[0] == 'P' && u.usym == '@') { 252. 			    if (!(moves % 5)) 253. 				pline("Doc, I can't help you unless you cooperate."); 254. 			} else { 255. #endif 256. 				(void) hitu(mtmp,d(2,6)); 257. 				(void) hitu(mtmp,d(2,6)); 258. #ifdef KAA 259. 			}  260.  #endif 261. 		}  262.  		break; 263. 	case 'o': 264. 		tmp = hitu(mtmp,rnd(6)); 265. 		if(hitu(mtmp,rnd(6)) && tmp &&	/* hits with both paws */  266.  		    !u.ustuck && rn2(2)) { 267. 			u.ustuck = mtmp; 268. 			kludge("%s has grabbed you!", Monnam(mtmp)); 269. 			losehp_m(d(2,8), mtmp); 270. 		} else if(u.ustuck == mtmp) { 271. 			losehp_m(d(2,8), mtmp); 272. 			pline("You are being crushed."); 273. 		}  274.  		break; 275. 	case 'P': 276. 		if(ctmp && !rn2(4)) 277. 			justswld(mtmp,Monnam(mtmp)); 278. 		else 279. 			(void) hitu(mtmp,d(2,4)); 280. 		break; 281. 	case 'Q': 282. #ifdef KAA 283. 		if(ctmp) { 284. 			pline("Your position suddenly seems very uncertain!"); 285. 			tele; 286. 		}  287.  #else 288. 		(void) hitu(mtmp,rnd(2)); 289. 		(void) hitu(mtmp,rnd(2)); 290. #endif 291. 		break; 292. 	case 'R': 293. 		if(ctmp && uarmh && !uarmh->rustfree &&  294.  		   (int) uarmh->spe >= -1) { 295. 			pline("Your helmet rusts!"); 296. 			uarmh->spe--; 297. 		} else 298. 		if(ctmp && uarm && !uarm->rustfree &&	/* Mike Newton */  299.  		 uarm->otyp < STUDDED_LEATHER_ARMOR &&  300.  		 (int) uarm->spe >= -1) { 301. 			pline("Your armor rusts!"); 302. 			uarm->spe--; 303. 		}  304.  		break; 305. 	case 'S': 306. 		if(ctmp && !rn2(8)) { 307. 			poisoned("snake's bite",mdat->mname); 308. 		}  309.  		break; 310. 	case 's': 311. 		if(ctmp && !rn2(8)) { 312. 			poisoned("scorpion's sting",mdat->mname); 313. 		}  314.  		(void) hitu(mtmp,rnd(8)); 315. 		(void) hitu(mtmp,rnd(8)); 316. 		break; 317. 	case 'T': 318. 		(void) hitu(mtmp,rnd(6)); 319. 		(void) hitu(mtmp,rnd(6)); 320. 		break; 321. 	case 't': 322. 		if(!rn2(5)) rloc(mtmp); 323. 		break; 324. 	case 'u': 325. 		mtmp->mflee = 1; 326. 		break; 327. 	case 'U': 328. 		(void) hitu(mtmp,d(3,4)); 329. 		(void) hitu(mtmp,d(3,4)); 330. 		break; 331. 	case 'v': 332. 		if(ctmp && !u.ustuck) u.ustuck = mtmp; 333. 		break; 334. 	case 'V': 335. 		if(tmp)  losehp_m(4, mtmp); 336. 		if(ctmp) losexp; 337. 		break; 338. 	case 'W': 339. 		if(ctmp) losexp; 340. 		break; 341. #ifndef NOWORM 342. 	case 'w': 343. 		if(tmp) wormhit(mtmp); 344. #endif 345. 		break; 346. 	case 'X': 347. 		(void) hitu(mtmp,rnd(5)); 348. 		(void) hitu(mtmp,rnd(5)); 349. 		(void) hitu(mtmp,rnd(5)); 350. 		break; 351. 	case 'x': 352. 		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 353. #ifdef KAA 354. 		  if (mtmp->mcan) 355. 		    pline("%s nuzzles against your %s leg!",  356.  			  Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 357. 		  else { 358. #endif 359. 		    pline("%s pricks your %s leg!",  360.  			  Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 361. 		    set_wounded_legs(side, rnd(50)); 362. 		    losehp_m(2, mtmp); 363. #ifdef KAA 364. 		  }  365.  #endif 366. 		  break; 367. 		}  368.  	case 'y': 369. 		if(mtmp->mcan) break; 370. 		mondead(mtmp); 371. 		if(!Blind && (u.usym != 'y')) { 372. 			pline("You are blinded by a blast of light!"); 373. 			Blind = d(4,12); 374. 			seeoff(0); 375. 		}  376.  		return(1); 377. 	case 'Y': 378. 		(void) hitu(mtmp,rnd(6)); 379. 		break; 380. 	}  381.  	if(u.uhp < 1) done_in_by(mtmp); 382. 	return(0); 383. }  384.   385.  hitu(mtmp,dam) 386. register struct monst *mtmp; 387. register dam; 388. {  389.  	register tmp, res; 390.  391.  	nomul(0); 392. 	if (mtmp->mfroz || mtmp->mhp <= 0) return(0); 393. 	/* If you are a 'a' or 'E' the monster might not get a second hit */ 394. 	if(u.uswallow) return(0); 395.  396.  	if(mtmp->mhide && mtmp->mundetected) { 397. 		mtmp->mundetected = 0; 398. 		if(!Blind) { 399. 			register struct obj *obj; 400. 			extern char * Xmonnam; 401. 			if(obj = o_at(mtmp->mx,mtmp->my)) 402. 				pline("%s was hidden under %s!",  403.  					Xmonnam(mtmp), doname(obj)); 404. 		}  405.  	}  406.   407.  	tmp = u.uac; 408. 	/* give people with Ac = -10 at least some vulnerability */ 409. 	if(tmp < 0) { 410. 		dam += tmp;		/* decrease damage */ 411. 		if(dam <= 0) dam = 1; 412. 		tmp = -rn2(-tmp); 413. 	}  414.  	tmp += mtmp->data->mlevel; 415. 	if(multi < 0) tmp += 4; 416. 	if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2; 417. 	if(mtmp->mtrapped) tmp -= 2; 418. 	if(tmp <= rnd(20)) { 419. 		if(Blind) pline("It misses."); 420. 		else pline("%s misses.",Monnam(mtmp)); 421. 		res = 0; 422. 	} else { 423. 		if(Blind) pline("It hits!"); 424. 		else pline("%s hits!",Monnam(mtmp)); 425. 		if (u.usym == 'a' && !rn2(4)) { 426. 			pline("%s is splashed by your acid!",Monnam(mtmp)); 427. 			mtmp->mhp -= rnd(10); 428. 			if(mtmp->mhp <= 0) { 429. 				pline("%s dies!",Monnam(mtmp)); 430. 				xkilled(mtmp,0); 431. 			}  432.  		}  433.  		losehp_m(dam, mtmp); 434. 		res = 1; 435. 	}  436.  	stop_occupation; 437. 	if(u.usym=='E' && mtmp->mcansee && rn2(2)) { 438. 		pline("%s is frozen by your gaze!",Monnam(mtmp)); 439. 		mtmp->mfroz = 1; 440. 	}  441.  	return(res); 442. }  443.   444.  #define	Athome	(Inhell && !mtmp->cham) 445.  446.  #ifdef HARD 447. demon_talk(mtmp)		/* returns 1 if we pay him off. */ 448.  register struct monst *mtmp; 449. {  450.  	char	*xmonnam, *Xmonnam; 451. 	int	demand, offer; 452.  453.  	if(!strcmp(mtmp->data->mname, "demon")) {  /* not for regular '&'s */ 454.  455.  	    pline("%s mutters something about awful working conditions.",  456.  		  Xmonnam(mtmp)); 457. 	    return(0); 458. 	}  459.   460.  	if(u.usym == '&') {	/* Won't blackmail their own. */ 461.   462.  	    pline("%s says, 'Good hunting %s.' and vanishes",  463.  		  Xmonnam(mtmp), flags.female ? "Sister" : "Brother"); 464. 	    mondead(mtmp); 465. 	    return(1); 466. 	}  467.   468.  	demand = (u.ugold * (rnd(80) + 20 * Athome)) / 100; 469. 	if(!demand)  {		/* you have no gold */ 470. 	    mtmp->mpeaceful = 0; 471. 	    return(0); 472. 	} else { 473. 	    char buf[80]; 474.  475.  	    pline("%s demands %d Zorkmids for safe passage.",  476.  		  Xmonnam(mtmp), demand); 477. 	    pline("how many will you offer him?"); 478. 	    getlin(buf); 479. 	    sscanf(buf, "%d", &offer); 480.  481.  	    if(offer >= u.ugold) { 482. 		pline("You give %s all your gold.", xmonnam(mtmp)); 483. 		offer = u.ugold; 484. 	    } else pline("You give %s %d Zorkmids.", xmonnam(mtmp), offer); 485. 	    u.ugold -= offer; 486.  487.  	    if(offer >= demand) { 488. 		pline("%s vanishes laughing about cowardly mortals.",  489.  		      Xmonnam(mtmp)); 490. 	    } else { 491. 		if(rnd(40) > (demand - offer)) { 492. 		    pline("%s scowls at you menacingly, then vanishes.",  493.  			  Xmonnam(mtmp)); 494. 		} else { 495. 		    pline("%s gets angry...", Xmonnam(mtmp)); 496. 		    mtmp->mpeaceful = 0; 497. 		    return(0); 498. 		}  499.  	    }  500.  	}  501.  	mondead(mtmp); 502. 	return(1); 503. }  504.  #endif 505.  506.  demon_hit(mtmp) 507. register struct monst *mtmp; 508. {  509.  	register struct	obj	*otmp; 510. 	int	onum, nobj = 0, 511. 		ml = mtmp->data->mlevel; 512.  513.  	if(!mtmp->cham && !mtmp->mcan && !rn2(13)) { 514. 		(void) makemon(PM_DEMON,u.ux,u.uy); 515. 	} else { 516. 	    switch((!mtmp->mcan) ? rn2(ml - 5 - !Athome) : 0)   { 517. #ifdef HARD 518. 		case 12: 519. 		case 11: 520. 		case 10: 521. 		case 9:			/* the wiz */ 522. 			(void) hitu(mtmp, 1); 523. 			pline("Oh no, he's using the touch of death!"); 524. 			if (rn2(ml) > 12)  { 525.  526.  			    if(Confusion) 527. 				pline("You have an out of body experience."); 528. 			    else  { 529. 				killer = "touch of death"; 530. 				done("died"); 531. 			    }  532.  			} else pline("Lucky for you, it didn't work!"); 533. 			break; 534. 		case 8:			/* demon princes */ 535. 			(void) hitu(mtmp, 1); 536. 			if(!destroy_arm) pline("Your skin itches."); 537. 			break; 538. 		case 7: 539. 			(void) hitu(mtmp, 1); 540. 			for (otmp = invent; otmp; otmp = otmp->nobj)  nobj++; 541. 			onum = rn2(nobj); 542. 			for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj; 543. 			otmp->cursed++; 544. 			break; 545. 		case 6:			/* demon lords */ 546. 			(void) hitu(mtmp, 1); 547. 			pline("You suddenly feel weaker!"); 548. 			losestr(rnd(ml - 6)); 549. 			break; 550. 		case 5: 551. 			(void) hitu(mtmp, 1); 552. 			if (Confusion)	pline("Hey, that tickles!"); 553. 			else		pline("Huh, What? Where am I?"); 554. 			HConfusion += rn1(7, 16); 555. 			break; 556. #endif /* HARD /**/ 557. 		default:		/* demons and chamelons as demons */ 558. 			(void) hitu(mtmp,d(2,5 + Athome)); 559. 			(void) hitu(mtmp,d(2,5 + Athome)); 560. 			(void) hitu(mtmp,rnd(2 + Athome)); 561. 			(void) hitu(mtmp,rnd(2 + Athome)); 562. 			(void) hitu(mtmp,rn1(4,1 + Athome)); 563. 			break; 564. 	    }  565.  	}  566.  	return(0); 567. }