Source:NetHack 2.3e/hack.c

Below is the full text to hack.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/hack.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, 1985. */ 2.     3.    #include   4.    #include "hack.h"  5.    #ifdef UNIX 6.   static	char	SCCS_Id[] = "@(#)hack.c	2.3\t88/02/18"; 7.   #endif 8.   extern char news0; 9.   extern char *nomovemsg; 10.  extern char *exclam; 11.  extern struct obj *addinv; 12.  extern boolean hmon; 13.   14.   /* called on movement: 15.  	1. when throwing ball+chain far away 16.  	2. when teleporting 17.  	3. when walking out of a lit room 18.   */  19.   unsee { 20.  	register x,y; 21.  	register struct rm *lev; 22.   23.   /*  24.   	if(u.udispl){ 25.  		u.udispl = 0; 26.  		newsym(u.udisx, u.udisy); 27.  	}  28.   */  29.   #ifndef QUEST 30.  	if(seehx){ 31.  		seehx = 0; 32.  	} else 33.  #endif 34.  	for(x = u.ux-1; x < u.ux+2; x++) 35.  	  for(y = u.uy-1; y < u.uy+2; y++) { 36.  		if(!isok(x, y)) continue; 37.  		lev = &levl[x][y]; 38.  		if(!lev->lit && lev->scrsym == ROOM_SYM) { 39.  			lev->scrsym = STONE_SYM; 40.  			lev->new = 1; 41.  			on_scr(x,y); 42.  		}  43.   	}  44.   }  45.    46.   /* called: 47.  	in apply.c:  seeoff(0)	- when taking a picture of yourself 48.  				- when donning a blindfold 49.  	in do.c:     seeoff(0)	- blind after drinking potion 50.  	in do.c:     seeoff(1)	- go up or down the stairs 51.  	in eat.c:    seeoff(0)	- blind after eating rotten food 52.  	in mhitu.c:  seeoff(0)	- blinded by a yellow light 53.  	in mon.c:    seeoff(1)	- swallowed 54.  	in potion.c: seeoff(0)	- quaffing or sniffing a potion of blindness 55.  	in spell.c:  seeoff(0)	- due to a cursed spellbook 56.  	in trap.c:   seeoff(1)	- fall through trapdoor 57.  	in wizard.c: seeoff(0)	- hit by a cream pie. 58.   */  59.   seeoff(mode)	/* 1 to redo @, 0 to leave them */ 60.  {	/* 1 means misc movement, 0 means blindness */ 61.  	register x,y; 62.  	register struct rm *lev; 63.   64.   	if(u.udispl && mode){ 65.  		u.udispl = 0; 66.  		levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); 67.  	}  68.   #ifndef QUEST 69.  	if(seehx) { 70.  		seehx = 0; 71.  	} else 72.  #endif 73.  	if(!mode) { 74.  		for(x = u.ux-1; x < u.ux+2; x++) 75.  			for(y = u.uy-1; y < u.uy+2; y++) { 76.  				if(!isok(x, y)) continue; 77.  				lev = &levl[x][y]; 78.  				if(!lev->lit && lev->scrsym == ROOM_SYM) 79.  					lev->seen = 0; 80.  			}  81.   	}  82.   }  83.    84.   static 85.  moverock { 86.  	register xchar rx, ry; 87.  	register struct obj *otmp; 88.  	register struct trap *ttmp; 89.  	register struct	monst *mtmp; 90.  	struct monst *m_at; 91.   92.   	while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) { 93.  		rx = u.ux+2*u.dx; 94.  		ry = u.uy+2*u.dy; 95.  		nomul(0); 96.  		if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&  97.   		    (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) &&  98.   		    !sobj_at(ENORMOUS_ROCK, rx, ry)) { 99.  			if((mtmp = m_at(rx,ry))) { 100. 			    if(canseemon(mtmp)) 101. 				pline("There's %s on the other side.", monnam(mtmp)); 102. 			    else 103. 				pline("You hear a monster behind the rock."); 104. 			    pline("Perhaps that's why you cannot move it."); 105. 			    goto cannot_push; 106. 			}  107.  			if(ttmp = t_at(rx,ry)) 108. 			    switch(ttmp->ttyp) { 109. 			    case PIT: 110. 				pline("You push the rock into a pit!"); 111. 				deltrap(ttmp); 112. 				delobj(otmp); 113. 				pline("It completely fills the pit!"); 114. 				continue; 115. 			    case TELEP_TRAP: 116. 				pline("You push the rock and suddenly it disappears!"); 117. 				delobj(otmp); 118. 				continue; 119. 			    }  120.  			if(levl[rx][ry].typ == POOL) { 121. 				levl[rx][ry].typ = ROOM; 122. 				mnewsym(rx,ry); 123. 				prl(rx,ry); 124. 				pline("You push the rock into the water."); 125. 				pline("Now you can cross the water!"); 126. 				delobj(otmp); 127. 				continue; 128. 			}  129.  			otmp->ox = rx; 130. 			otmp->oy = ry; 131. 			/* pobj(otmp); */ 132. 			if(cansee(rx,ry)) atl(rx,ry,otmp->olet); 133. 			if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy); 134.  135.  			{ static long lastmovetime; 136. 			/* note: this var contains garbage initially and 137. 			   after a restore */ 138. 			if(moves > lastmovetime+2 || moves < lastmovetime) 139. 			pline("With great effort you move the enormous rock."); 140. 			lastmovetime = moves; 141. 			}  142.  		} else { 143. 		    pline("You try to move the enormous rock, but in vain."); 144. 	    cannot_push: 145. #ifdef KAA 146. 		    if (u.usym=='9') { 147. # ifdef DGKMOD 148. 			if(!flags.pickup) 149. 				pline("You easily can push it aside."); 150. 			else 151. # endif 152. 				pline("However, you easily can pick it up."); 153. 			break; 154. 		    }  155.  #endif 156. 		    if((!invent || inv_weight+90 <= 0) &&  157.  			(!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)  158.  					&& IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){ 159. 			pline("However, you can squeeze yourself into a small opening."); 160. 			break; 161. 		    } else 162. 			return (-1); 163. 		}  164.  	}  165.  	return (0); 166. }  167.   168.  domove 169. {  170.  	register struct monst *mtmp; 171. 	register struct rm *tmpr,*ust; 172. 	struct trap *trap; 173.  174.  	u_wipe_engr(rnd(5)); 175.  176.  	if(inv_weight > 0){ 177. 		pline("You collapse under your load."); 178. 		nomul(0); 179. 		return; 180. 	}  181.  	if(u.uswallow) { 182. 		u.dx = u.dy = 0; 183. 		u.ux = u.ustuck->mx; 184. 		u.uy = u.ustuck->my; 185. 	} else { 186. 		if(Confusion) { 187. 			do { 188. 				confdir; 189. 			} while(!isok(u.ux+u.dx, u.uy+u.dy) ||  190.  			    IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ)); 191. 		}  192.  		if(!isok(u.ux+u.dx, u.uy+u.dy)){ 193. 			nomul(0); 194. 			return; 195. 		}  196.  	}  197.   198.  	ust = &levl[u.ux][u.uy]; 199. 	u.ux0 = u.ux; 200. 	u.uy0 = u.uy; 201. 	if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen) 202. 		nomul(0); 203. 	if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx || 204. 		u.uy+u.dy != u.ustuck->my)) { 205. 		if(dist(u.ustuck->mx, u.ustuck->my) > 2){ 206. 			/* perhaps it fled (or was teleported or ... ) */ 207. 			u.ustuck = 0; 208. 		} else { 209. 			if(Blind) pline("You cannot escape from it!"); 210. 			else pline("You cannot escape from %s!",  211.  				monnam(u.ustuck)); 212. 			nomul(0); 213. 			return; 214. 		}  215.  	}  216.  	if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) { 217. 	/* attack monster */ 218.  219.  #ifdef SAFE_ATTACK 220. 		/* Don't attack if you're running */ 221. 		if (flags.run && !mtmp->mimic  222.  		&& (Blind ? Telepat : (!mtmp->minvis || See_invisible))) { 223. 			nomul(0); 224. 			flags.move = 0; 225. 			return; 226. 		}  227.  #endif 228. 		nomul(0); 229. 		gethungry; 230. 		if(multi < 0) return;	/* we just fainted */ 231.  232.  		/* try to attack; note that it might evade */ 233. 		if(attack(u.uswallow ? u.ustuck : mtmp)) 234. 			return; 235. 	}  236.  	/* not attacking an animal, so we try to move */ 237. 	if(u.utrap) { 238. 		if(u.utraptype == TT_PIT) { 239. 			pline("You are still in a pit."); 240. 			u.utrap--; 241. #ifdef SPIDERS 242. 		} else if (u.utraptype == TT_WEB) { 243. 		    	pline("You are stuck to the web."); 244. 			u.utrap--; 245. #endif 246. 		} else { 247. 			pline("You are caught in a bear trap."); 248. 			if((u.dx && u.dy) || !rn2(5)) u.utrap--; 249. 		}  250.  		return; 251. 	}  252.  	tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; 253. 	if(IS_ROCK(tmpr->typ) ||  254.  	   (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){ 255. 		flags.move = 0; 256. 		nomul(0); 257. 		return; 258. 	}  259.  	if(moverock < 0) return; 260. 	if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) &&  261.  		IS_ROCK(levl[u.ux+u.dx][u.uy].typ) &&  262.  		invent && inv_weight+40 > 0) { 263. 		pline("You are carrying too much to get through."); 264. 		nomul(0); 265. 		return; 266. 	}  267.  	if(Punished &&  268.  	   DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){ 269. 		if(carried(uball)) { 270. 			movobj(uchain, u.ux, u.uy); 271. 			goto nodrag; 272. 		}  273.   274.  		if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){ 275. 			/* leave ball, move chain under/over ball */ 276. 			movobj(uchain, uball->ox, uball->oy); 277. 			goto nodrag; 278. 		}  279.   280.  		if(inv_weight + (int) uball->owt/2 > 0) { 281. 			pline("You cannot %sdrag the heavy iron ball.",  282.  			invent ? "carry all that and also " : ""); 283. 			nomul(0); 284. 			return; 285. 		}  286.   287.  		movobj(uball, uchain->ox, uchain->oy); 288. 		unpobj(uball);		/* BAH %% */ 289. 		uchain->ox = u.ux; 290. 		uchain->oy = u.uy; 291. 		nomul(-2); 292. 		nomovemsg = ""; 293. 	nodrag:	; 294. 	}  295.  	u.ux += u.dx; 296. 	u.uy += u.dy; 297. 	if(flags.run) { 298. 		if(tmpr->typ == DOOR ||  299.  		(xupstair == u.ux && yupstair == u.uy) ||  300.  		(xdnstair == u.ux && ydnstair == u.uy)  301.  #ifdef FOUNTAINS  302.  		|| IS_FOUNTAIN(levl[u.ux][u.uy].typ)  303.  #endif  304.  #ifdef NEWCLASS  305.  		|| IS_THRONE(levl[u.ux][u.uy].typ)  306.  #endif  307.  #ifdef SINKS  308.  		|| IS_SINK(levl[u.ux][u.uy].typ)  309.  #endif  310.  		) 311. 			nomul(0); 312. 	}  313.   314.  #ifdef SINKS 315. 	if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 316. 		dosinkfall; 317. #endif 318. 	if(tmpr->typ == POOL && !Levitation) 319. 		drown;	/* not necessarily fatal */ 320.  321.  /*  322.  	if(u.udispl) { 323. 		u.udispl = 0; 324. 		newsym(u.ux0,u.uy0); 325. 	}  326.  */  327.  	if(!Blind) { 328. #ifdef QUEST 329. 		setsee; 330. #else 331. 		if(ust->lit) { 332. 			if(tmpr->lit) { 333. 				if(tmpr->typ == DOOR) 334. 					prl1(u.ux+u.dx,u.uy+u.dy); 335. 				else if(ust->typ == DOOR) 336. 					nose1(u.ux0-u.dx,u.uy0-u.dy); 337. 			} else { 338. 				unsee; 339. 				prl1(u.ux+u.dx,u.uy+u.dy); 340. 			}  341.  		} else { 342. 			if(tmpr->lit) setsee; 343. 			else { 344. 				prl1(u.ux+u.dx,u.uy+u.dy); 345. 				if(tmpr->typ == DOOR) { 346. 					if(u.dy) { 347. 						prl(u.ux-1,u.uy); 348. 						prl(u.ux+1,u.uy); 349. 					} else { 350. 						prl(u.ux,u.uy-1); 351. 						prl(u.ux,u.uy+1); 352. 					}  353.  				}  354.  			}  355.  			nose1(u.ux0-u.dx,u.uy0-u.dy); 356. 		}  357.  #endif /* QUEST /**/ 358. 	} else { 359. 		pru; 360. 	}  361.  	if(!flags.nopick) pickup(1); 362. 	if(trap) dotrap(trap);		/* fall into pit, arrow trap, etc. */ 363. 	(void) inshop; 364. 	if(!Blind) read_engr_at(u.ux,u.uy); 365. }  366.   367.  movobj(obj, ox, oy) 368. register struct obj *obj; 369. register int ox, oy; 370. {  371.  	/* Some dirty programming to get display right */ 372. 	freeobj(obj); 373. 	unpobj(obj); 374. 	obj->nobj = fobj; 375. 	fobj = obj; 376. 	obj->ox = ox; 377. 	obj->oy = oy; 378. }  379.   380.  dopickup{ 381. 	/* uswallow case added by GAN 01/29/87 */ 382. 	if(u.uswallow)  { 383. 		pline("You pick up %s's tongue.",monnam(u.ustuck)); 384. 		pline("But it's kind of slimy, so you drop it."); 385. 		return(1); 386. 	}  387.  	if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) { 388. 		pline("There is nothing here to pick up."); 389. 		return(0); 390. 	}  391.  	if(Levitation) { 392. 		pline("You cannot reach the floor."); 393. 		return(1); 394. 	}  395.  	pickup(0); 396. 	return(1); 397. }  398.   399.  pickup(all) 400. {  401.  	register struct gold *gold; 402. 	register struct obj *obj, *obj2; 403. 	register int wt; 404. 	char buf[BUFSZ]; 405. 	register char *ip; 406. 	register char sym; 407. 	register int oletct = 0, iletct = 0; 408. 	char olets[20], ilets[20]; 409.  410.  	if(Levitation) return; 411. #ifdef DGKMOD 412. 	if (all && !flags.pickup) { 413. 		int ct = 0; 414.  415.  		for (obj = fobj; obj; obj = obj->nobj) 416. 			if (obj->ox == u.ux && obj->oy == u.uy) 417. 				if (!Punished || obj != uchain) 418. 					ct++; 419. 		/* If gold is the only thing here, pick it up. 420. 		 */  421.  		if (!ct && g_at(u.ux, u.uy)) { 422. 			if (flags.run) nomul(0); 423. 			while (gold = g_at(u.ux,u.uy)) { 424. 				pline("%ld gold piece%s.", gold->amount,  425.  					plur(gold->amount)); 426. 				u.ugold += gold->amount; 427. 				flags.botl = 1; 428. 				freegold(gold); 429. 			}  430.  			if (Invisible) newsym(u.ux,u.uy); 431. 		}  432.   433.  		/* If there are objects here, take a look. 434. 		 */  435.  		if (ct) { 436. 			if (flags.run) 437. 				nomul(0); 438. 			nscr; 439. 			if (ct < 5) 440. 				dolook; 441. 			else 442. 				pline("There are several objects here."); 443. 		}  444.  		return; 445. 	}  446.  #endif 447. 	while(gold = g_at(u.ux,u.uy)) { 448. 		pline("%ld gold piece%s.", gold->amount, plur(gold->amount)); 449. 		u.ugold += gold->amount; 450. 		flags.botl = 1; 451. 		freegold(gold); 452. 		if(flags.run) nomul(0); 453. 		if(Invisible) newsym(u.ux,u.uy); 454. 	}  455.  	/* check for more than one object */ 456. 	if(!all) { 457. 		register int ct = 0; 458.  459.  		for(obj = fobj; obj; obj = obj->nobj) 460. 			if(obj->ox == u.ux && obj->oy == u.uy) ct++; 461. 		if(g_at(u.ux,u.uy)) 462. 			ct++; 463. 		if(ct < 2) 464. 			all++; 465. 		else 466. 			pline("There are several objects here."); 467. 	}  468.   469.  	/* added by GAN 10/24/86 to allow selective picking up */ 470. 	if(!all)  { 471. 		register struct obj *otmp = fobj; 472.  473.  		if(g_at(u.ux,u.uy)) ilets[iletct++] = GOLD_SYM; 474. 		ilets[iletct] = 0; 475. 		while(otmp) { 476. 			if(!index(ilets, otmp->olet) &&  477.  			   otmp->ox == u.ux && otmp->oy == u.uy)  { 478. 				ilets[iletct++] = otmp->olet; 479. 				ilets[iletct] = 0; 480. 			}  481.  			otmp = otmp->nobj; 482. 		}         483.  		if(iletct == 1) 484. 			strcpy(buf,ilets); 485. 		else  { 486. 			ilets[iletct++] = ' '; 487. 			ilets[iletct++] = 'a'; 488. 			ilets[iletct++] = 'A'; 489. 			ilets[iletct] = 0; 490.  491.  			if(iletct = 3) 492. 			pline("What kinds of thing do you want to pick up? [%s] ", ilets); 493. 			getlin(buf); 494. 			if(buf[0] == '\033') { 495. 				clrlin; 496. 				return; 497. 			}  498.  #ifdef KJSMODS 499. 			else if(!buf[0]) strcpy(buf,"A"); 500. #endif 501. 		}  502.  		ip = buf; 503. 		olets[0] = 0; 504. 		while(sym = *ip++){ 505. 			/* new A function (selective all) added by  506. * GAN 01/09/87 507. 			 */  508.  			if(sym == 'A')  { 509. 				for(oletct = 0; ilets[oletct] != ' '; oletct++) 510. 					olets[oletct] = ilets[oletct]; 511. 				olets[oletct] = 0; 512. 				break; 513. 			}  514.  			if(sym == ' ') continue; 515. 			if(sym == 'a') all++; else 516. 			if(index(ilets, sym)){ 517. 				if(!index(olets, sym)){ 518. 					olets[oletct++] = sym; 519. 					olets[oletct] = 0; 520. 				}  521.  			}  522.  			else pline("There are no %c's here.", sym); 523. 		}         524.  	}  525.   526.  	if(all || index(olets, GOLD_SYM)) 527. 		while(gold = g_at(u.ux,u.uy)) { 528. 			pline("%ld gold piece%s.", gold->amount,  529.  			   plur(gold->amount)); 530. 			u.ugold += gold->amount; 531. 			flags.botl = 1; 532. 			freegold(gold); 533. 			if(flags.run) nomul(0); 534. 			if(Invis) newsym(u.ux,u.uy); 535. 	}  536.   537.   538.  	for(obj = fobj; obj; obj = obj2) { 539. 	    obj2 = obj->nobj;   /* perhaps obj will be picked up */ 540. 	    if(obj->ox == u.ux && obj->oy == u.uy) { 541. 		if(flags.run) nomul(0); 542.  543.  		if(!all)  { 544. 			char c;  545. 546. 			if(!index(olets,obj->olet)) continue; 547.   548.  			pline("Pick up %s ? [ynaq]", doname(obj)); 549. 			while(!index("ynaq ", (c = readchar))) 550. 				bell; 551. 			if(c == 'q') return; 552. 			if(c == 'n') continue; 553. 			if(c == 'a') all = 1; 554. 		}  555.    556.  		if(obj->otyp == DEAD_COCKATRICE && !uarmg && u.usym != 'c') { 557. 		    pline("Touching the dead cockatrice is a fatal mistake."); 558. 		    pline("You turn to stone."); 559. 		    pline("You die..."); 560. 		    killer = "cockatrice cadaver"; 561. 		    done("died"); 562. 		}         563.    564.  		if(obj->otyp == SCR_SCARE_MONSTER){ 565. 		  if(!obj->spe) obj->spe = 1; 566. 		  else { 567. 		    /* Note: perhaps the 1st pickup failed: you cannot 568. 			carry anymore, and so we never dropped it - 569. 			lets assume that treading on it twice also 570. 			destroys the scroll */ 571. 		    pline("The scroll turns to dust as you pick it up."); 572. #ifdef KAA 573. 			if(!(objects[SCR_SCARE_MONSTER].oc_name_known) &&  574.  			   !(objects[SCR_SCARE_MONSTER].oc_uname)) 575. 				docall(obj); 576. #endif 577. 		    delobj(obj); 578. 		    continue; 579. 		  }  580.  		}  581.  		    582.  		/* do not pick up uchain */ 583. 		if(Punished && obj == uchain) 584. 			continue; 585.  586.  				   587.  		wt = inv_weight + obj->owt; 588. 		if(wt > 0) { 589. 			if(obj->quan > 1) { 590. 				/* see how many we can lift */ 591. 				extern struct obj *splitobj; 592. 				int savequan = obj->quan; 593. 				int iw = inv_weight; 594. 				int qq; 595. 				for(qq = 1; qq < savequan; qq++){ 596. 					obj->quan = qq; 597. 					if(iw + weight(obj) > 0) 598. 						break; 599. 				}  600.  				obj->quan = savequan; 601. 				qq--; 602. 				/* we can carry qq of them */ 603. 				if(!qq) goto too_heavy; 604. 			pline("You can only carry %s of the %s lying here.",  605.  					(qq == 1) ? "one" : "some",  606.  					doname(obj)); 607. 				{  608.  				register struct obj *obj3; 609.  610.  				obj3 = splitobj(obj, qq); 611. 				if(obj3->otyp == SCR_SCARE_MONSTER) 612. 					if(obj3->spe) obj->spe = 0; 613. 				}  614.  				/* note: obj2 is set already, so well never 615. 				 * encounter the other half; if it should be  616. * otherwise then write 617. 				 *      obj2 = splitobj(obj,qq); 618. 				 */  619.  				goto lift_some; 620. 			}           621.  		too_heavy: 622. 			pline("There %s %s here, but %s.",  623.  				(obj->quan == 1) ? "is" : "are",  624.  				doname(obj),  625.  				!invent ? "it is too heavy for you to lift"  626.  				/* There is no such word as "anymore". KAA */  627.  					: "you cannot carry any more"); 628. 				if(obj->otyp == SCR_SCARE_MONSTER) 629. 					if(obj->spe) obj->spe = 0; 630. 			break; 631. 		}  632.  	lift_some: 633. 		if(inv_cnt >= 52) { 634. 		    pline("Your knapsack cannot accommodate any more items."); 635. 				if(obj->otyp == SCR_SCARE_MONSTER) 636. 					if(obj->spe) obj->spe = 0; 637. 		    break; 638. 		}  639.  		freeobj(obj); 640. 		if(Invisible) newsym(u.ux,u.uy); 641. 		addtobill(obj);       /* sets obj->unpaid if necessary */ 642. 		if(wt > -5) pline("You have a little trouble lifting"); 643. 		{ int pickquan = obj->quan; 644. 		  int mergquan; 645. #ifdef KAA 646. 		if(!Blind) if(obj->olet != WEAPON_SYM) obj->dknown = 1; 647. #else 648. 		if(!Blind) obj->dknown = 1;     /* this is done by prinv, 649. 				 but addinv needs it already for merging */ 650. #endif 651. 		obj = addinv(obj);    /* might merge it with other objects */ 652. 		  mergquan = obj->quan; 653. 		  obj->quan = pickquan; /* to fool prinv */ 654. 		prinv(obj); 655. 		  obj->quan = mergquan; 656. 		}  657.  	    }  658.  	}  659.  }  660.   661.  /* stop running if we see something interesting */ 662. /* turn around a corner if that is the only way we can proceed */ 663. /* do not turn left or right twice */ 664. lookaround{ 665. register x,y,i,x0,y0,m0,i0 = 9; 666. register int corrct = 0, noturn = 0; 667. register struct monst *mtmp; 668. #ifdef LINT 669. 	/* suppress "used before set" message */ 670. 	x0 = y0 = 0; 671. #endif 672. 	if(Blind || flags.run == 0) return; 673. 	if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return; 674. #ifdef QUEST 675. 	if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop; 676. #endif 677. 	for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 678. 		if(x == u.ux && y == u.uy) continue; 679. 		if(!levl[x][y].typ) continue; 680. 		if((mtmp = m_at(x,y)) && !mtmp->mimic &&  681.  		    (!mtmp->minvis || See_invisible)){ 682. 			if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy)) 683. 				goto stop; 684. 		} else mtmp = 0; /* invisible M cannot influence us */ 685. 		if(x == u.ux-u.dx && y == u.uy-u.dy) continue; 686. 		{  687.  		register uchar sym = levl[x][y].scrsym; 688.  689.  		if (sym == VWALL_SYM || sym == HWALL_SYM  690.  		    || sym == ROOM_SYM || sym == STONE_SYM  691.  		    || IS_CORNER(sym)) 692. 			continue; 693. 		else if (sym == DOOR_SYM) { 694. 			if(x != u.ux && y != u.uy) continue; 695. 			if(flags.run != 1) goto stop; 696. 			goto corr; 697. 		} else if (sym == CORR_SYM) { 698. 		corr: 699. 			if(flags.run == 1 || flags.run == 3) { 700. 				i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); 701. 				if(i > 2) continue; 702. 				if(corrct == 1 && DIST(x,y,x0,y0) != 1) 703. 					noturn = 1; 704. 				if(i < i0) { 705. 					i0 = i;  706. x0 = x; 707. y0 = y; 708. m0 = mtmp ? 1 : 0; 709.  				}  710.  			}  711.  			corrct++; 712. 			continue; 713. 		} else if (sym == TRAP_SYM) { 714. 			if(flags.run == 1) goto corr;	/* if you must */ 715. 			if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 716. 			continue; 717. 		} else {		/* e.g. objects or trap or stairs */ 718. 			if(flags.run == 1) goto corr; 719. 			if(mtmp) continue;		/* d */ 720. 		}  721.  		stop: 722. 			nomul(0); 723. 			return; 724. 		}  725.  	}  726.  #ifdef QUEST 727. 	if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop; 728. #endif 729. 	if(corrct > 1 && flags.run == 2) goto stop; 730. 	if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&  731.  		(corrct == 1 || (corrct == 2 && i0 == 1))) { 732. 		/* make sure that we do not turn too far */ 733. 		if(i0 == 2) { 734. 		    if(u.dx == y0-u.uy && u.dy == u.ux-x0) 735. 			i = 2;		/* straight turn right */ 736. 		    else 737. 			i = -2;		/* straight turn left */ 738. 		} else if(u.dx && u.dy) { 739. 		    if((u.dx == u.dy && y0 == u.uy) ||  740.  			(u.dx != u.dy && y0 != u.uy)) 741. 			i = -1;		/* half turn left */ 742. 		    else 743. 			i = 1;		/* half turn right */ 744. 		} else { 745. 		    if((x0-u.ux == y0-u.uy && !u.dy) ||  746.  			(x0-u.ux != y0-u.uy && u.dy)) 747. 			i = 1;		/* half turn right */ 748. 		    else 749. 			i = -1;		/* half turn left */ 750. 		}  751.  		i += u.last_str_turn; 752. 		if(i <= 2 && i >= -2) { 753. 			u.last_str_turn = i;  754. u.dx = x0-u.ux, u.dy = y0-u.uy; 755. 		}  756.  	}  757.  }  758.   759.  /* something like lookaround, but we are not running */ 760. /* react only to monsters that might hit us */ 761. monster_nearby { 762. register int x,y; 763. register struct monst *mtmp; 764. 	if(!Blind) 765. 	for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 766. 		if(x == u.ux && y == u.uy) continue; 767. 		if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame &&  768.  			!mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) &&  769.  			!mtmp->mfroz && !mtmp->msleep &&  /* aplvax!jcn */  770.  			(!mtmp->minvis || See_invisible)) 771. 			return(1); 772. 	}  773.  	return(0); 774. }  775.   776.  #ifdef QUEST 777. cansee(x,y) xchar x,y; { 778. register int dx,dy,adx,ady,sdx,sdy,dmax,d; 779. 	if(Blind) return(0); 780. 	if(!isok(x,y)) return(0); 781. 	d = dist(x,y); 782. 	if(d < 3) return(1); 783. 	if(d > u.uhorizon*u.uhorizon) return(0); 784. 	if(!levl[x][y].lit) 785. 		return(0); 786. 	dx = x - u.ux;	adx = abs(dx);	sdx = sgn(dx); 787. 	dy = y - u.uy;  ady = abs(dy);	sdy = sgn(dy); 788. 	if(dx == 0 || dy == 0 || adx == ady){ 789. 		dmax = (dx == 0) ? ady : adx; 790. 		for(d = 1; d <= dmax; d++) 791. 			if(!rroom(sdx*d,sdy*d)) 792. 				return(0); 793. 		return(1); 794. 	} else if(ady > adx){ 795. 		for(d = 1; d <= ady; d++){ 796. 			if(!rroom(sdx*( (d*adx)/ady ), sdy*d) ||  797.  			   !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d)) 798. 				return(0); 799. 		}  800.  		return(1); 801. 	} else { 802. 		for(d = 1; d <= adx; d++){ 803. 			if(!rroom(sdx*d, sdy*( (d*ady)/adx )) ||  804.  			   !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 ))) 805. 				return(0); 806. 		}  807.  		return(1); 808. 	}  809.  }  810.   811.  rroom(x,y) register int x,y; { 812. 	return(IS_ROOM(levl[u.ux+x][u.uy+y].typ)); 813. }  814.   815.  #else 816.  817.  cansee(x,y) xchar x,y; { 818. 	if(Blind || u.uswallow) return(0); 819. 	if(dist(x,y) < 3) return(1); 820. 	if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y &&  821.  		y <= seehy) return(1); 822. 	return(0); 823. }  824.  #endif /* QUEST /**/ 825.  826.  sgn(a) register int a; { 827. 	return((a > 0) ? 1 : (a == 0) ? 0 : -1); 828. }  829.   830.  #ifdef QUEST 831. setsee 832. {  833.  	register x,y; 834.  835.  	if(Blind) { 836. 		pru; 837. 		return; 838. 	}  839.  	for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++) 840. 		for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) { 841. 			if(cansee(x,y)) 842. 				prl(x,y); 843. 	}  844.  }  845.   846.  #else 847.  848.  setsee 849. {  850.  	register x,y; 851.  852.  	if(Blind) { 853. 		pru; 854. 		return; 855. 	}  856.  	if(!levl[u.ux][u.uy].lit) { 857. 		seelx = u.ux-1; 858. 		seehx = u.ux+1; 859. 		seely = u.uy-1; 860. 		seehy = u.uy+1; 861. 	} else { 862. 		for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--); 863. 		for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++); 864. 		for(seely = u.uy; levl[u.ux][seely-1].lit; seely--); 865. 		for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++); 866. 	}  867.  	for(y = seely; y <= seehy; y++) 868. 		for(x = seelx; x <= seehx; x++) { 869. 			prl(x,y); 870. 	}  871.  	if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ 872. 	else { 873. 	    if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); 874. 	    if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); 875. 	    if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); 876. 	    if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); 877. 	}  878.  }  879.  #endif /* QUEST /**/ 880.  881.  nomul(nval) 882. register nval; 883. {  884.  #ifdef DGKMOD 885. 	if(multi < nval) return;	/* This is a bug fix by ab@unido */ 886. #else 887. 	if(multi < 0) return; 888. #endif 889. 	multi = nval; 890. 	flags.mv = flags.run = 0; 891. }  892.   893.  abon 894. {  895.  #ifdef KAA 896. 	if (u.usym != '@') return(mons[u.umonnum].mlevel-3); 897. #endif 898. 	if(u.ustr == 3) return(-3); 899. 	else if(u.ustr < 6) return(-2); 900. 	else if(u.ustr < 8) return(-1); 901. 	else if(u.ustr < 17) return(0); 902. 	else if(u.ustr < 69) return(1);	/* up to 18/50 */ 903. 	else if(u.ustr < 118) return(2); 904. 	else return(3); 905. }  906.   907.  dbon 908. {  909.  	if (u.usym != '@') return(0); 910.  911.  	if(u.ustr < 6) return(-1); 912. 	else if(u.ustr < 16) return(0); 913. 	else if(u.ustr < 18) return(1); 914. 	else if(u.ustr == 18) return(2);	/* up to 18 */ 915. 	else if(u.ustr < 94) return(3);		/* up to 18/75 */ 916. 	else if(u.ustr < 109) return(4);	/* up to 18/90 */ 917. 	else if(u.ustr < 118) return(5);	/* up to 18/99 */ 918. 	else return(6); 919. }  920.   921.  losestr(num)	/* may kill you; cause may be poison or monster like 'A' */ 922. register num; 923. {  924.  	u.ustr -= num; 925. 	while(u.ustr < 3) { 926. 		u.ustr++; 927. 		u.uhp -= 6; 928. 		u.uhpmax -= 6; 929. 	}  930.  	flags.botl = 1; 931. }  932.   933.  losehp(n,knam) 934. register n;  935. register char *knam; 936. {  937.  #ifdef KAA 938. 	if (u.mtimedone) { 939. 		u.mh -= n;  940. if (u.mhmax < u.mh) u.mhmax = u.mh; 941. 		flags.botl = 1; 942. 		if (u.mh < 1) rehumanize; 943. 		return; 944. 	}  945.  #endif 946. 	u.uhp -= n;  947. if(u.uhp > u.uhpmax) 948. 		u.uhpmax = u.uhp;	/* perhaps n was negative */ 949. 	flags.botl = 1; 950. 	if(u.uhp < 1) { 951. 		killer = knam;	/* the thing that killed you */ 952. 		pline("You die..."); 953. 		done("died"); 954. 	}  955.  }  956.   957.  losehp_m(n,mtmp) 958. register n;  959. register struct monst *mtmp; 960. {  961.  #ifdef KAA 962. 	if (u.mtimedone) { 963. 		u.mh -= n;  964. flags.botl = 1; 965. 		if (u.mh < 1) rehumanize; 966. 		return; 967. 	}  968.  #endif 969. 	u.uhp -= n;  970. flags.botl = 1; 971. 	if(u.uhp < 1) 972. 		done_in_by(mtmp); 973. }  974.   975.  losexp	/* hit by V or W */ 976. {  977.  	register num; 978. 	extern long newuexp; 979.  980.  	if (u.usym == 'V' || u.usym=='W') return; 981.  982.  	if(u.ulevel > 1) 983. 		pline("Goodbye level %u.", u.ulevel--); 984. 	else 985. 		u.uhp = -1; 986. 	num = rnd(10); 987. 	u.uhp -= num; 988. 	u.uhpmax -= num; 989. #ifdef SPELLS 990. 	num = rnd(u.ulevel/2+1) + 1;		/* M. Stephenson */ 991. 	u.uen -= num; 992. 	if (u.uen < 0)		u.uen = 0; 993. 	u.uenmax -= num; 994. 	if (u.uenmax < 0)	u.uenmax = 0; 995. #endif 996. 	u.uexp = newuexp; 997. 	flags.botl = 1; 998. }  999.   1000. inv_weight{ 1001. register struct obj *otmp = invent; 1002. register int wt = (u.ugold + 500)/1000; 1003. register int carrcap; 1004. #ifdef KAA 1005. 	if (u.mtimedone) { 1006. 		if (u.usym == '9') carrcap = MAX_CARR_CAP * 4; 1007. 		else if (u.usym == 'N') carrcap = MAX_CARR_CAP; 1008. 		else if (mons[u.umonnum].mlevel <= 3) 1009. 			carrcap = 5*mons[u.umonnum].mlevel + 30; 1010. 		else carrcap = 5*mons[u.umonnum].mlevel + 100; 1011. 	} 1012. #endif 1013. 	if(Levitation)			/* pugh@cornell */ 1014. 		carrcap = MAX_CARR_CAP; 1015. 	else { 1016. #ifdef HARD 1017. 		carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); 1018. #else 1019. 	       carrcap = 5*u.ulevel;      /* New strength stewr 870807 */ 1020. 		if (u.ustr < 19) carrcap += 5*u.ustr; 1021. 		if (u.ustr > 18) carrcap += u.ustr - 18 + 90; 1022. 		if (u.ustr > 68) carrcap += u.ustr - 68; 1023. 		if (u.ustr > 93) carrcap += u.ustr - 93; 1024. 		if (u.ustr > 108) carrcap += 2*(u.ustr - 108); 1025. 		if (u.ustr > 113) carrcap += 5*(u.ustr - 113); 1026. 		if (u.ustr == 118) carrcap += 100; 1027. #endif 1028. 		if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 1029. 		if(Wounded_legs & LEFT_SIDE) carrcap -= 10; 1030. 		if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; 1031. 	} 1032. 	while(otmp){ 1033. 		wt += otmp->owt; 1034. 		otmp = otmp->nobj; 1035. 	} 1036. 	return(wt - carrcap); 1037. } 1038.  1039. inv_cnt{ 1040. register struct obj *otmp = invent; 1041. register int ct = 0; 1042. 	while(otmp){ 1043. 		ct++; 1044. 		otmp = otmp->nobj; 1045. 	} 1046. 	return(ct); 1047. } 1048.  1049. long 1050. newuexp 1051. { 1052. 	return(10*(1L << (u.ulevel-1))); 1053. } 1054.  1055. change_luck(n) 1056. 	register schar n; 1057. { 1058. 	u.uluck += n;  1059. if (u.uluck < 0 && u.uluck < LUCKMIN)	u.uluck = LUCKMIN; 1060. 	if (u.uluck > 0 && u.uluck > LUCKMAX)	u.uluck = LUCKMAX; 1061. } 1062.  1063. #ifdef SINKS 1064. dosinkfall { 1065. register struct obj *obj; 1066. 	pline("You crash to the floor!"); 1067. 	losehp(rn2(15) + 3*u.ulevel,"fall onto a sink"); 1068. 	for(obj=fobj; obj; obj=obj->nobj) 1069. 	   if(obj->ox == u.ux && obj->oy == u.uy && obj->olet == WEAPON_SYM) { 1070. 		pline("You fell on %s.",doname(obj)); 1071. 		losehp(rn2(3),"fall onto a sink"); 1072. 	   }  1073.  1074. 	Levitation += 1; 1075. 	if(uleft && uleft->otyp == RIN_LEVITATION) { 1076. 	   obj = uleft; 1077. 	   ringoff(obj); 1078. 	   off_msg(obj); 1079. 	} 1080. 	if(uright && uright->otyp == RIN_LEVITATION) { 1081. 	   obj = uright; 1082. 	   ringoff(obj); 1083. 	   off_msg(obj); 1084. 	} 1085. 	Levitation = 0; 1086. } 1087. #endif