Source:NetHack 2.2a/mhitu.c

Below is the full text to mhitu.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/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	2.1	87/10/18 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include	"hack.h"  5.    extern struct monst *makemon; 6.   extern struct obj *carrying; 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] == 'H' && 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. #ifdef SPIDERS 313. 			poisoned("giant spider's bite",mdat->mname); 314. #else 315. 			poisoned("scorpion's sting",mdat->mname); 316. #endif 317. 		}  318.  		(void) hitu(mtmp,rnd(8)); 319. 		(void) hitu(mtmp,rnd(8)); 320. 		break; 321. 	case 'T': 322. 		(void) hitu(mtmp,rnd(6)); 323. 		(void) hitu(mtmp,rnd(6)); 324. 		break; 325. 	case 't': 326. 		if(!rn2(5)) rloc(mtmp); 327. 		break; 328. 	case 'u': 329. 		mtmp->mflee = 1; 330. 		break; 331. 	case 'U': 332. 		(void) hitu(mtmp,d(3,4)); 333. 		(void) hitu(mtmp,d(3,4)); 334. 		break; 335. 	case 'v': 336. 		if(ctmp && !u.ustuck) u.ustuck = mtmp; 337. 		break; 338. 	case 'V': 339. 		if(tmp)  losehp_m(4, mtmp); 340. 		if(ctmp) losexp; 341. 		break; 342. 	case 'W': 343. 		if(ctmp) losexp; 344. 		break; 345. #ifndef NOWORM 346. 	case 'w': 347. 		if(tmp) wormhit(mtmp); 348. #endif 349. 		break; 350. 	case 'X': 351. 		(void) hitu(mtmp,rnd(5)); 352. 		(void) hitu(mtmp,rnd(5)); 353. 		(void) hitu(mtmp,rnd(5)); 354. 		break; 355. 	case 'x': 356. 		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 357. #ifdef KAA 358. 		  if (mtmp->mcan) 359. 		    pline("%s nuzzles against your %s leg!",  360.  			  Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 361. 		  else { 362. #endif 363. 		    pline("%s pricks your %s leg!",  364.  			  Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 365. 		    set_wounded_legs(side, rnd(50)); 366. 		    losehp_m(2, mtmp); 367. #ifdef KAA 368. 		  }  369.  #endif 370. 		  break; 371. 		}  372.  	case 'y': 373. 		if(mtmp->mcan) break; 374. 		mondead(mtmp); 375. 		if(!Blind && (u.usym != 'y')) { 376. 			pline("You are blinded by a blast of light!"); 377. 			Blinded = d(4,12); 378. 			seeoff(0); 379. 		}  380.  		return(1); 381. 	case 'Y': 382. 		(void) hitu(mtmp,rnd(6)); 383. 		break; 384. #ifdef RPH 385. 	case '8': 386. 		if (canseemon(mtmp) && !mtmp->mcan) { 387.  388.  		        pline ("You look upon %s.", monnam(mtmp)); 389. 			pline ("You turn to stone."); 390. 			done_in_by(mtmp); 391. 	    	}  392.  		(void) hitu(mtmp,d(2,6)); 393. 		(void) hitu(mtmp,d(2,6)); 394. 		break; 395. #endif 396. 	}  397.  	if(u.uhp < 1) done_in_by(mtmp); 398. 	return(0); 399. }  400.   401.  hitu(mtmp,dam) 402. register struct monst *mtmp; 403. register dam; 404. {  405.  	register tmp, res; 406.  407.  	nomul(0); 408. 	if (mtmp->mfroz || mtmp->mhp <= 0) return(0); 409. 	/* If you are a 'a' or 'E' the monster might not get a second hit */ 410. 	if(u.uswallow) return(0); 411.  412.  	if(mtmp->mhide && mtmp->mundetected) { 413. 		mtmp->mundetected = 0; 414. 		if(!Blind) { 415. 			register struct obj *obj; 416. 			extern char * Xmonnam; 417. 			if(obj = o_at(mtmp->mx,mtmp->my)) 418. 				pline("%s was hidden under %s!",  419.  					Xmonnam(mtmp), doname(obj)); 420. 		}  421.  	}  422.   423.  	tmp = u.uac; 424. 	/* give people with Ac = -10 at least some vulnerability */ 425. 	if(tmp < 0) { 426. 		dam += tmp;		/* decrease damage */ 427. 		if(dam <= 0) dam = 1; 428. 		tmp = -rn2(-tmp); 429. 	}  430.  	tmp += mtmp->data->mlevel; 431. 	if(multi < 0) tmp += 4; 432. 	if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2; 433. 	if(mtmp->mtrapped) tmp -= 2; 434. 	if(tmp <= rnd(20)) { 435. 		if(Blind) pline("It misses."); 436. 		else pline("%s misses.",Monnam(mtmp)); 437. 		res = 0; 438. 	} else { 439. 		if(Blind) pline("It hits!"); 440. 		else pline("%s hits!",Monnam(mtmp)); 441. 		if (u.usym == 'a' && !rn2(4)) { 442. 			pline("%s is splashed by your acid!",Monnam(mtmp)); 443. 			mtmp->mhp -= rnd(10); 444. 			if(mtmp->mhp <= 0) { 445. 				pline("%s dies!",Monnam(mtmp)); 446. 				xkilled(mtmp,0); 447. 			}  448.  		}  449.  		losehp_m(dam, mtmp); 450. 		res = 1; 451. 	}  452.  	stop_occupation; 453. 	if(u.usym=='E' && mtmp->mcansee && rn2(2)) { 454. 		pline("%s is frozen by your gaze!",Monnam(mtmp)); 455. 		mtmp->mfroz = 1; 456. 	}  457.  	return(res); 458. }  459.   460.  #define	Athome	(Inhell && !mtmp->cham) 461.  462.  #ifdef HARD 463. demon_talk(mtmp)		/* returns 1 if we pay him off. */ 464.  register struct monst *mtmp; 465. {  466.  	char	*xmonnam, *Xmonnam; 467. 	int	demand, offer; 468.  469.  	if(uwep && !strcmp(ONAME(uwep), "Excalibur")) { 470.  471.  	    pline("%s looks very angry.", Xmonnam(mtmp, 1)); 472. 	    mtmp->mpeaceful = mtmp->mtame = 0; 473. 	    return(0); 474. 	}  475.  	if(!strcmp(mtmp->data->mname, "demon")) {  /* not for regular '&'s */ 476.  477.  	    pline("%s mutters something about awful working conditions.",  478.  		  Xmonnam(mtmp, 1)); 479. 	    return(0); 480. 	}  481.   482.  	/* Slight advantage given. */ 483.  	if(!strcmp(mtmp->data->mname, "demon prince") && mtmp->minvis) { 484.  485.  	    if (!Blind) pline("%s appears before you.", Xmonnam(mtmp, 1)); 486. 	    mtmp->minvis = 0; 487. 	    pmon(mtmp); 488. 	}  489.  	if(u.usym == '&') {	/* Won't blackmail their own. */ 490.   491.  	    pline("%s says, 'Good hunting %s.' and vanishes",  492.  		  Xmonnam(mtmp, 1), flags.female ? "Sister" : "Brother"); 493. 	    rloc(mtmp); 494. 	    return(1); 495. 	}  496.  	demand = (u.ugold * (rnd(80) + 20 * Athome)) / 100; 497. 	if(!demand)  {		/* you have no gold */ 498. 	    mtmp->mpeaceful = 0; 499. 	    return(0); 500. 	} else { 501. 	    char buf[80]; 502.  503.  	    pline("%s demands %d Zorkmids for safe passage.",  504.  		  Xmonnam(mtmp, 1), demand); 505. 	    pline("how many will you offer him?"); 506. 	    getlin(buf); 507. 	    sscanf(buf, "%d", &offer); 508.  509.  	    if(offer >= u.ugold) { 510. 		pline("You give %s all your gold.", xmonnam(mtmp, 0)); 511. 		offer = u.ugold; 512. 	    } else pline("You give %s %d Zorkmids.", xmonnam(mtmp, 0), offer); 513. 	    u.ugold -= offer; 514.  515.  	    if(offer >= demand) { 516. 		pline("%s vanishes laughing about cowardly mortals.",  517.  		      Xmonnam(mtmp)); 518. 	    } else { 519. 		if(rnd(40) > (demand - offer)) { 520. 		    pline("%s scowls at you menacingly, then vanishes.",  521.  			  Xmonnam(mtmp)); 522. 		} else { 523. 		    pline("%s gets angry...", Xmonnam(mtmp)); 524. 		    mtmp->mpeaceful = 0; 525. 		    return(0); 526. 		}  527.  	    }  528.  	}  529.  	mondead(mtmp); 530. 	return(1); 531. }  532.  #endif 533.  534.  demon_hit(mtmp) 535. register struct monst *mtmp; 536. {  537.  	register struct	obj	*otmp; 538. 	int	onum, nobj = 0, 539. 		ml = mtmp->data->mlevel; 540.  541.  	if(!mtmp->cham && !mtmp->mcan && !rn2(13)) { 542. 		(void) makemon(PM_DEMON,u.ux,u.uy); 543. 	} else { 544. 	    switch((!mtmp->mcan) ? rn2(ml - 5 - !Athome) : 0)   { 545. #ifdef HARD 546. 		case 12: 547. 		case 11: 548. 		case 10: 549. 		case 9:			/* the wiz */ 550. 			(void) hitu(mtmp, 1); 551. 			pline("Oh no, he's using the touch of death!"); 552. 			if (rn2(ml) > 12)  { 553.  554.  			    if(Confusion) 555. 				pline("You have an out of body experience."); 556. 			    else  { 557. 				killer = "touch of death"; 558. 				done("died"); 559. 			    }  560.  			} else pline("Lucky for you, it didn't work!"); 561. 			break; 562. 		case 8:			/* demon princes */ 563. 			(void) hitu(mtmp, 1); 564. 			if(!destroy_arm) pline("Your skin itches."); 565. 			break; 566. 		case 7: 567. 			(void) hitu(mtmp, 1); 568. 			for (otmp = invent; otmp; otmp = otmp->nobj)  nobj++; 569. 			onum = rn2(nobj); 570. 			for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj; 571. 			otmp->cursed++; 572. 			break; 573. 		case 6:			/* demon lords */ 574. 			(void) hitu(mtmp, 1); 575. 			pline("You suddenly feel weaker!"); 576. 			losestr(rnd(ml - 6)); 577. 			break; 578. 		case 5: 579. 			(void) hitu(mtmp, 1); 580. 			if (Confusion)	pline("Hey, that tickles!"); 581. 			else		pline("Huh, What? Where am I?"); 582. 			HConfusion += rn1(7, 16); 583. 			break; 584. #endif /* HARD /**/ 585. 		default:		/* demons and chamelons as demons */ 586. 			(void) hitu(mtmp,d(2,5 + Athome)); 587. 			(void) hitu(mtmp,d(2,5 + Athome)); 588. 			(void) hitu(mtmp,rnd(2 + Athome)); 589. 			(void) hitu(mtmp,rnd(2 + Athome)); 590. 			(void) hitu(mtmp,rn1(4,1 + Athome)); 591. 			break; 592. 	    }  593.  	}  594.  	return(0); 595. }