Source:NetHack 1.3d/hack.c

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