Source:NetHack 1.4f/hack.c

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