Source:NetHack 3.0.0/hack.c

Below is the full text to hack.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/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.    /* NetHack may be freely redistributed. See license for details. */ 3.     4.    #include "hack.h"  5. 6.   #if defined(UNIX) && !defined(LINT) 7.   static	const char	SCCS_Id[] = "@(#)hack.c	3.0\t88/10/25"; 8.   #endif 9.    10.   /* called on movement: 11.  	1. when throwing ball+chain far away 12.  	2. when teleporting 13.  	3. when walking out of a lit room 14.   */  15.   void 16.  unsee { 17.  	register xchar x,y; 18.  	register struct rm *lev; 19.   20.   	if(seehx){ 21.  		seehx = 0; 22.  	} else 23.  	for(x = u.ux-1; x < u.ux+2; x++) 24.  	    for(y = u.uy-1; y < u.uy+2; y++) { 25.  		if(!isok(x, y)) continue; 26.  		lev = &levl[x][y]; 27.  		if(!lev->lit && lev->scrsym == ROOM_SYM) { 28.  			lev->scrsym = STONE_SYM; 29.  			lev->new = 1; 30.  			on_scr(x,y); 31.  		}  32.   	    }  33.   }  34.    35.   /* called: 36.  	in apply.c:  seeoff(0)	- when taking a picture of yourself 37.  				- when donning a blindfold 38.  	in do.c:     seeoff(0)	- blind after drinking potion 39.  	in do.c:     seeoff(1)	- go up or down the stairs 40.  	in eat.c:    seeoff(0)	- blind after eating rotten food 41.  	in mhitu.c:  seeoff(0)	- blinded by a glowing eye 42.  	in mhitu.c:  seeoff(1)	- swallowed 43.  	in mthrow.c: seeoff(0)	- hit by a cream pie. 44.  	in potion.c: seeoff(0)	- quaffing or sniffing a potion of blindness 45.  	in spell.c:  seeoff(0)	- due to a cursed spellbook 46.  	in trap.c:   seeoff(1)	- fall through trapdoor 47.   */  48.   void 49.  seeoff(mode) {	/* 1 to redo @, 0 to leave them */ 50.  		/* 1 means misc movement, 0 means blindness */ 51.  	register xchar x,y; 52.  	register struct rm *lev; 53.   54.   	if(u.udispl && mode){ 55.  		u.udispl = 0; 56.  		levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); 57.  	}  58.   	if(seehx) { 59.  		seehx = 0; 60.  	} else 61.  	    if(!mode) { 62.  		for(x = u.ux-1; x < u.ux+2; x++) 63.  		    for(y = u.uy-1; y < u.uy+2; y++) { 64.  			if(!isok(x, y)) continue; 65.  			lev = &levl[x][y]; 66.  			if(lev->mmask) unpmon(m_at(x,y)); 67.  			if(!lev->lit && lev->scrsym == ROOM_SYM) { 68.  			    lev->seen = 0; 69.  			    atl(x, y, (char)STONE_SYM); 70.  			}  71.   		    }  72.   	    }  73.   }  74.    75.   static int 76.  moverock { 77.  	register xchar rx, ry; 78.  	register struct obj *otmp; 79.  	register struct trap *ttmp; 80.  	register struct	monst *mtmp; 81.  	xchar oldrx, oldry; 82.   83.   #ifdef POLYSELF 84.  	if (passes_walls(uasmon)) return 0; 85.  #endif 86.  	while(otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) { 87.  		rx = u.ux+2*u.dx; 88.  		ry = u.uy+2*u.dy; 89.  		nomul(0); 90.  #ifdef POLYSELF 91.  		if (verysmall(uasmon)) { 92.  		    pline("You're too small to push that boulder."); 93.  		    goto cannot_push; 94.  		}  95.   #endif 96.  		if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&  97.   		    (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy)) &&  98.   		    !sobj_at(BOULDER, rx, ry)) { 99.  			if(levl[rx][ry].mmask) { 100. 			    mtmp = m_at(rx,ry); 101. 			    if(canseemon(mtmp)) 102. 				pline("There's %s on the other side.",  103.  				      mon_nam(mtmp)); 104. 			    else 105. 				You("hear a monster behind the boulder."); 106. 			    if(flags.verbose) 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 SPIKED_PIT: 113. 			    case PIT: 114. 				You("push the boulder into a pit!"); 115. 				deltrap(ttmp); 116. 				delobj(otmp); 117. 				if(flags.verbose) 118. 				    pline("It completely fills the pit!"); 119. 				continue; 120. 			    case TRAPDOOR: 121. 				pline("The boulder falls into and plugs a hole in the ground!"); 122. 				deltrap(ttmp); 123. 				delobj(otmp); 124. 				continue; 125. 			    case LEVEL_TELEP: 126. 			    case TELEP_TRAP: 127. 				You("push the boulder and suddenly it disappears!"); 128. 				rloco(otmp); 129. 				continue; 130. 			    }  131.  			if(levl[rx][ry].typ == DOOR &&  132.  				(levl[rx][ry].doormask & (D_LOCKED | D_CLOSED))) 133. 				goto nopushmsg; 134. 			if(is_pool(rx,ry)) { 135. #ifdef STRONGHOLD 136. 				if(levl[rx][ry].typ == DRAWBRIDGE_UP) 137. 				    levl[rx][ry].drawbridgemask |= DB_FLOOR; 138. 				else 139. #endif 140. 				    levl[rx][ry].typ = ROOM; 141. 				mnewsym(rx,ry); 142. 				if(!Blind) prl(rx,ry); 143. 				You("push the boulder into the water."); 144. 				if(flags.verbose && !Blind) 145. 				    pline("Now you can cross the water!"); 146. 				delobj(otmp); 147. 				continue; 148. 			}  149.  			oldrx = otmp->ox; 150. 			oldry = otmp->oy; 151. 			otmp->ox = rx; 152. 			otmp->oy = ry; 153. 			set_omask(oldrx, oldry); 154. 			levl[rx][ry].omask = 1; 155. 			/* pobj(otmp); */ 156. 			if(cansee(rx,ry)) atl(rx,ry,otmp->olet); 157. 			newsym(u.ux+u.dx, u.uy+u.dy); 158.  159.  			{  160.  #ifdef LINT	/* static long lastmovetime; */ 161. 			long lastmovetime; 162. 			lastmovetime = 0; 163. #else 164. 			static long lastmovetime; 165. #endif 166. 			/* note: this var contains garbage initially and 167. 			   after a restore */ 168. 			if(moves > lastmovetime+2 || moves < lastmovetime) 169. 			pline("With great effort you move the boulder."); 170. 			lastmovetime = moves; 171. 			}  172.  		} else { 173. nopushmsg: 174. 		    You("try to move the boulder, but in vain."); 175. 	    cannot_push: 176. #ifdef POLYSELF 177. 		    if (throws_rocks(uasmon)) { 178. 			if(!flags.pickup) 179. 				pline("However, you easily can push it aside."); 180. 			else 181. 				pline("However, you easily can pick it up."); 182. 			break; 183. 		    }  184.  #endif 185. 		    if((!invent || inv_weight+90 <= 0) &&  186.  			(!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)  187.  					&& IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))  188.  #ifdef POLYSELF  189.  			|| verysmall(uasmon)  190.  #endif  191.  									) 192. 		    {  193.  			pline("However, you can squeeze yourself into a small opening."); 194. 			break; 195. 		    } else 196. 			return (-1); 197. 		}  198.  	}  199.  	return (0); 200. }  201.   202.  void 203. movobj(obj, ox, oy) 204. register struct obj *obj; 205. register xchar ox, oy; 206. {  207.  	register xchar ox2 = obj->ox, oy2= obj->oy; 208.  209.  	/* Some dirty programming to get display right */ 210. 	freeobj(obj); 211. 	unpobj(obj); 212. 	obj->nobj = fobj; 213. 	fobj = obj; 214. 	obj->ox = ox; 215. 	obj->oy = oy; 216. 	set_omask(ox2,oy2); 217. 	levl[ox][oy].omask = 1; 218. }  219.   220.  #ifdef SINKS 221. static 222. void 223. dosinkfall { 224. 	register struct obj *obj; 225.  226.  # ifdef POLYSELF 227. 	if (is_floater(uasmon)) { 228. 		You("wobble unsteadily for a moment."); 229. 	} else { 230. # endif 231. 		You("crash to the floor!"); 232. 		losehp((rn1(10, 20 - (int)ACURR(A_CON))),"fall onto a sink"); 233. 		if(levl[u.ux][u.uy].omask) 234. 		for(obj=fobj; obj; obj=obj->nobj) 235. 		    if(obj->ox == u.ux && obj->oy == u.uy &&  236.  		       obj->olet == WEAPON_SYM) { 237. 			You("fell on %s.",doname(obj)); 238. 			losehp(rn2(3),"fall onto a sink"); 239. 		    }  240.  # ifdef POLYSELF 241. 	}  242.  # endif 243.  244.  	HLevitation = (HLevitation & ~TIMEOUT) + 1; 245. 	if(uleft && uleft->otyp == RIN_LEVITATION) { 246. 	    obj = uleft; 247. 	    Ring_off(obj); 248. 	    off_msg(obj); 249. 	}  250.  	if(uright && uright->otyp == RIN_LEVITATION) { 251. 	    obj = uright; 252. 	    Ring_off(obj); 253. 	    off_msg(obj); 254. 	}  255.  	if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { 256. 	    obj = uarmf; 257. 	    (void)Boots_off; 258. 	    off_msg(obj); 259. 	}  260.  	HLevitation--; 261. }  262.  #endif 263.  264.  static boolean 265. is_edge(x,y) 266. register xchar x,y; 267. /* return true if (x,y) is on the edge of a room 268.  * we cannot rely on IS_DOOR(levl[x][y].typ) because some of the stronghold 269.  * "rooms" are actually outside areas without doors 270.  */  271.  {  272.  	register int roomno = inroom(x,y); 273.  274.  	if(roomno < 0) return FALSE; 275. 	return((x == rooms[roomno].lx - 1) || (x == rooms[roomno].hx + 1) ||  276.  	       (y == rooms[roomno].ly - 1) || (y == rooms[roomno].hy + 1)); 277. }  278.   279.  boolean 280. may_dig(x,y) 281. register xchar x,y; 282. /* intended to be called only on ROCKs */ 283. {  284.  return (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE))); 285. }  286.   287.  static boolean 288. bad_rock(x,y) 289. register xchar x,y; 290. {  291.  	return(IS_ROCK(levl[x][y].typ)  292.  #ifdef POLYSELF  293.  		    && !passes_walls(uasmon)  294.  		    && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y))  295.  #endif  296.  	); 297. }  298.   299.  void 300. domove { 301. 	register struct monst *mtmp = (struct monst *)0; 302. 	register struct rm *tmpr,*ust; 303. 	register xchar x,y; 304. 	struct trap *trap; 305.  306.  	u_wipe_engr(rnd(5)); 307.  308.  	if(inv_weight > 0){ 309. 		You("collapse under your load."); 310. 		nomul(0); 311. 		return; 312. 	}  313.  	if(u.uswallow) { 314. 		u.dx = u.dy = 0; 315. 		x = u.ux = u.ustuck->mx; 316. 		y = u.uy = u.ustuck->my; 317. 	} else { 318. 		x = u.ux + u.dx; 319. 		y = u.uy + u.dy; 320. 		if(Stunned || (Confusion && !rn2(5))) { 321. 			register int tries = 0; 322.  323.  			do { 324. 				if(tries++ > 50) { 325. 					nomul(0); 326. 					return; 327. 				}  328.  				confdir; 329. 				x = u.ux + u.dx; 330. 				y = u.uy + u.dy; 331. 			} while(!isok(x, y) || bad_rock(x, y)); 332. 		}  333.  		if(!isok(x, y)) { 334. 			nomul(0); 335. 			return; 336. 		}  337.  		if((trap = t_at(x, y)) && trap->tseen) 338. 			nomul(0); 339. 		if(u.ustuck && (x != u.ustuck->mx || 340. 				y != u.ustuck->my)) { 341. 			if(dist(u.ustuck->mx, u.ustuck->my) > 2) { 342. 				/* perhaps it fled (or was teleported or ... ) */ 343. 				u.ustuck = 0; 344. 			} else { 345. #ifdef POLYSELF 346. 				/* If polymorphed into a sticking monster, 347. 				 * u.ustuck means it's stuck to you, not you 348. 				 * to it. 349. 				 */  350.  				if (sticks(uasmon)) { 351. 					kludge("You release %s.",  352.  						mon_nam(u.ustuck)); 353. 					u.ustuck = 0; 354. 				} else { 355. #endif 356. 					kludge("You cannot escape from %s!",  357.  						mon_nam(u.ustuck)); 358. 					nomul(0); 359. 					return; 360. #ifdef POLYSELF 361. 				}  362.  #endif 363. 			}  364.  		}  365.  	}  366.   367.  	u.ux0 = u.ux; 368. 	u.uy0 = u.uy; 369. 	/* attack monster */ 370. 	tmpr = &levl[x][y]; 371. 	if (tmpr->mmask) { 372. 		mtmp = m_at(x,y); 373. 		/* Don't attack if you're running */ 374. 		if (flags.run && !mtmp->mimic &&  375.  		    (Blind ? Telepat : (!mtmp->minvis || See_invisible))) { 376. 			nomul(0); 377. 			flags.move = 0; 378. 			return; 379. 		}  380.  	}  381.  	if(mtmp || u.uswallow) { 382. 		nomul(0); 383. 		gethungry; 384. 		if(multi < 0) return;	/* we just fainted */ 385.  386.  		/* try to attack; note that it might evade */ 387. 		if(attack(u.uswallow ? u.ustuck : mtmp)) 388. 			return; 389. 	}  390.  	/* not attacking an animal, so we try to move */ 391. #ifdef POLYSELF 392. 	if(!uasmon->mmove) { 393. 		You("are rooted %s.", Levitation ? "in place"  394.  			: "to the ground"); 395. 		nomul(0); 396. 		return; 397. 	}  398.  #endif 399. 	if(u.utrap) { 400. 		if(u.utraptype == TT_PIT) { 401. 		    if(flags.verbose) 402. 			You("are still in a pit."); 403. 		    u.utrap--; 404. 		} else if (u.utraptype == TT_WEB) { 405. 		    if(flags.verbose) 406. 		    	You("are stuck to the web."); 407. 		    u.utrap--; 408. 		} else { 409. 		    if(flags.verbose) 410. 			You("are caught in a bear trap."); 411. 		    if((u.dx && u.dy) || !rn2(5)) u.utrap--; 412. 		}  413.  		return; 414. 	}  415.  	/* check for physical obstacles */ 416. #ifdef POLYSELF 417. 	if (!passes_walls(uasmon)) { 418. #endif 419. #ifdef STRONGHOLD 420. 	    if(dlevel == stronghold_level && is_db_wall(x,y)) { 421. 		    pline("The drawbridge is up!"); 422. 		    nomul(0); 423. 		    return; 424. 	    }  425.  #endif 426. 	    if(IS_DOOR(tmpr->typ) && (tmpr->doormask & (D_LOCKED | D_CLOSED))  427.  #ifdef POLYSELF  428.  	       && !amorphous(uasmon)  429.  #endif  430.  	      ){ 431. 		    flags.move = 0; 432. 		    if(x == u.ux || y == u.uy) { 433. 		        if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) 434. 			    pline("Ouch!  You bump into a door."); 435. 		        else pline("That door is closed."); 436. 		    }  437.  		    nomul(0); 438. 		    return; 439. 	    }  440.  #ifdef POLYSELF 441. 	}  442.  #endif 443. 	ust = &levl[u.ux][u.uy]; 444. 	if(bad_rock(x,y) ||  445.  	   (u.dx && u.dy && (IS_DOOR(tmpr->typ) || IS_DOOR(ust->typ)))){ 446. 		flags.move = 0; 447. 		nomul(0); 448. 		return; 449. 	}  450.  	if(moverock < 0) return; 451. 	if(u.dx && u.dy && bad_rock(u.ux,y) &&  452.  			   bad_rock(x,u.uy)) { 453. #ifdef POLYSELF 454. 	    if (bigmonst(uasmon)) { 455. 		Your("body is too large to fit through."); 456. 		nomul(0); 457. 		return; 458. 	    }  459.  #endif 460. 	    if (invent && inv_weight+40 > 0) { 461. 		You("are carrying too much to get through."); 462. 		nomul(0); 463. 		return; 464. 	    }  465.  	}  466.  	if(Punished &&  467.  	   dist2(x, y, uchain->ox, uchain->oy) > 2) { 468. 		if(carried(uball)) { 469. 			movobj(uchain, u.ux, u.uy); 470. 			goto nodrag; 471. 		}  472.   473.  		if(dist2(x, y, uball->ox, uball->oy) < 3) { 474. 			/* leave ball, move chain under/over ball */ 475. 			movobj(uchain, uball->ox, uball->oy); 476. 			goto nodrag; 477. 		}  478.   479.  		if(inv_weight + (int)(uball->owt >> 1) > 0) { 480. 			You("cannot %sdrag the heavy iron ball.",  481.  			invent ? "carry all that and also " : ""); 482. 			nomul(0); 483. 			return; 484. 		}  485.   486.  		movobj(uball, uchain->ox, uchain->oy); 487. 		unpobj(uball);		/* BAH %% */ 488. 		uchain->ox = u.ux; 489. 		uchain->oy = u.uy; 490. 		ust->omask = 1; 491. 		nomul(-2); 492. 		nomovemsg = ""; 493. 	nodrag:	; 494. 	}  495.  #ifdef POLYSELF 496. 	if (tunnels(uasmon) && !needspick(uasmon) && IS_ROCK(tmpr->typ)) { 497. 		static char *digtxt; 498.  499.  		if(dig_pos.x != x || dig_pos.y != y  500.  		    || dig_level != dlevel || dig_down) { 501. 			dig_down = FALSE; 502. 			dig_pos.x = x;  503. dig_pos.y = y; 504. dig_level = dlevel; 505. 			dig_effort = 30; 506. 			You("start chewing a hole in the rock."); 507. 			return; 508. 		} else if ((dig_effort += 30) < 100)  { 509. 		    if(flags.verbose) 510. 			You("continue chewing the rock up."); 511. 		    return; 512. 		} else { 513. 			if (IS_WALL(tmpr->typ)) { 514. 				digtxt = "You chew a hole in the wall."; 515. 				tmpr->typ = DOOR; 516. 			} else if (tmpr->typ==SDOOR) { 517. 				digtxt = "You chew through a secret door."; 518. 				tmpr->typ = DOOR; 519. 				if(!(tmpr->doormask & D_TRAPPED)) 520. 					tmpr->doormask = D_BROKEN; 521. 			} else { 522. 				digtxt = "You chew a passage through the rock."; 523. 				tmpr->typ = CORR; 524. 			}  525.  			mnewsym(x, y); 526. 			prl(x, y); 527. 			pline(digtxt); 528. 			if(IS_DOOR(tmpr->typ) && (tmpr->doormask & D_TRAPPED)) { 529. 				b_trapped("door"); 530. 				tmpr->doormask = D_NODOOR; 531. 			}  532.  			dig_level = -1; 533. 		}  534.  	}  535.  #endif 536. 	u.ux += u.dx; 537. 	u.uy += u.dy; 538. 	if(flags.run) { 539. 		if(IS_DOOR(tmpr->typ) ||  540.  #ifdef POLYSELF  541.  		(IS_ROCK(tmpr->typ)) ||  542.  #endif  543.  		(xupstair == u.ux && yupstair == u.uy) ||  544.  		(xdnstair == u.ux && ydnstair == u.uy)  545.  #ifdef STRONGHOLD  546.  		|| (xupladder == u.ux && yupladder == u.uy)  547.  		|| (xdnladder == u.ux && ydnladder == u.uy)  548.  #endif  549.  #ifdef FOUNTAINS  550.  		|| IS_FOUNTAIN(tmpr->typ)  551.  #endif  552.  #ifdef THRONES  553.  		|| IS_THRONE(tmpr->typ)  554.  #endif  555.  #ifdef SINKS  556.  		|| IS_SINK(tmpr->typ)  557.  #endif  558.  #ifdef ALTARS  559.  		|| IS_ALTAR(tmpr->typ)  560.  #endif  561.  		) 562. 			nomul(0); 563. 	}  564.  #ifdef POLYSELF 565. 	if (hides_under(uasmon)) 566. 	    u.uundetected = (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask); 567. 	else if (u.dx || u.dy) { /* i.e. piercer */ 568. 	    if (u.usym == S_MIMIC_DEF) 569. 		u.usym = S_MIMIC; 570. 	    u.uundetected = 0; 571. 	}  572.  #endif 573.  574.  /*  575.  	if(u.udispl) { 576. 		u.udispl = 0; 577. 		newsym(u.ux0,u.uy0); 578. 	}  579.  */  580.  	if(!Blind) { 581. 	    register xchar backx = u.ux0 - u.dx;   /* one step beyond old pos */ 582. 	    register xchar backy = u.uy0 - u.dy; 583. 	    register xchar frontx = u.ux + u.dx;   /* one step beyond new pos */ 584. 	    register xchar fronty = u.uy + u.dy; 585. 	    register boolean newedge = is_edge(u.ux,u.uy); 586. 	    register boolean oldedge = is_edge(u.ux0,u.uy0); 587.  588.  	    /* ust is old position, tmpr is new position */ 589. 	    if(oldedge && newedge && inroom(u.ux0,u.uy0) == inroom(u.ux,u.uy)) { 590. 		/* moving along wall */ 591. 		nose1(backx,backy); 592. 		prl1(frontx,fronty); 593.  594.  	    } else if(oldedge || newedge) { 595. 		if(isok(backx,backy) && levl[backx][backy].lit) 596. 		    setsee; 597. 		else 598. 		    nose1(backx,backy); 599.  600.  		if(isok(frontx,fronty) && levl[frontx][fronty].lit) 601. 		    setsee; 602. 		else { 603. 		    prl1(frontx,fronty); 604. 		    prl1(u.ux,u.uy);    /* make sure side walls are seen */ 605. 		}  606.   607.  	    } else if(!tmpr->lit) { 608. 		/* we haven't crossed an edge, so old & new are both light or  609. * both dark. if both light, we need do nothing. 610. 		 */  611.  		nose1(backx,backy); 612. 		prl1(frontx,fronty); 613. 	    }  614.   615.  	} else { 616. 		pru; 617. 	}  618.  #ifdef WALKIES 619. 	check_leash(u.ux0,u.uy0); 620. #endif 621. 	if(u.ux0 != u.ux || u.uy0 != u.uy) u.umoved = TRUE; 622. 	spoteffects; 623. }  624.   625.  void 626. spoteffects 627. {  628.  	register struct trap *trap; 629.  630.  	if(is_pool(u.ux,u.uy) && !(Levitation || Wwalking 631. #ifdef POLYSELF 632. 	    || is_flyer(uasmon) 633. #endif 634. 	    ))  635.  		drown;	/* not necessarily fatal */ 636. 	else { 637. 		(void) inshop; 638. #ifdef SINKS 639. 		if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 640. 			dosinkfall; 641. #endif 642. 		if(!flags.nopick &&  643.  		   (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask)) 644. 			pickup(1); 645. 		else read_engr_at(u.ux,u.uy); 646. 		if(trap = t_at(u.ux,u.uy)) 647. 			dotrap(trap);	/* fall into pit, arrow trap, etc. */ 648. 	}  649.   650.  }  651.   652.  int 653. dopickup { 654. 	/* uswallow case added by GAN 01/29/87 */ 655. 	if(u.uswallow)  { 656. 		if (is_animal(u.ustuck->data)) { 657. 		    You("pick up %s's tongue.", mon_nam(u.ustuck)); 658. 		    pline("But it's kind of slimy, so you drop it."); 659. 		} else 660. 		    pline("You don't %s anything in here to pick up.",  661.  			  Blind ? "feel" : "see"); 662. 		return(1); 663. 	}  664.  	if(levl[u.ux][u.uy].omask == 0 && levl[u.ux][u.uy].gmask == 0) { 665. 		pline("There is nothing here to pick up."); 666. 		return(0); 667. 	}  668.  	if(Levitation) { 669. 		You("cannot reach the floor."); 670. 		return(1); 671. 	}  672.  	pickup(0); 673. 	return(1); 674. }  675.   676.  /* stop running if we see something interesting */ 677. /* turn around a corner if that is the only way we can proceed */ 678. /* do not turn left or right twice */ 679. void 680. lookaround { 681. 	register int x, y, i, x0, y0, m0, i0 = 9, corrct = 0, noturn = 0; 682. 	register struct monst *mtmp; 683. #ifdef LINT 684. 	/* suppress "used before set" message */ 685. 	x0 = y0 = 0; 686. #endif 687. 	if(Blind || flags.run == 0) return; 688. 	for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) { 689. 		if(x == u.ux && y == u.uy) continue; 690. 		if(levl[x][y].mmask && (mtmp = m_at(x,y)) && !mtmp->mimic &&  691.  		    (!mtmp->minvis || See_invisible)) { 692. 			if((flags.run != 1 && !mtmp->mtame) || (x == u.ux+u.dx && y == u.uy+u.dy)) 693. 				goto stop; 694. 		} else mtmp = 0; 695. 		if(levl[x][y].typ == STONE) continue; 696. 		if(x == u.ux-u.dx && y == u.uy-u.dy) continue; 697. 		{  698.  		register uchar sym = levl[x][y].scrsym; 699.  700.  		if (IS_ROCK(levl[x][y].typ) || sym == ROOM_SYM) continue; 701. 		else if (sym == DOOR_SYM) { 702. 			if(x != u.ux && y != u.uy) continue; 703. 			if(flags.run != 1) goto stop; 704. 			goto bcorr; 705. 		} else if (sym == CORR_SYM) { 706. 		bcorr: 707. 			if(levl[u.ux][u.uy].typ != ROOM) { 708. 			    if(flags.run == 1 || flags.run == 3) { 709. 				i = dist2(x,y,u.ux+u.dx,u.uy+u.dy); 710. 				if(i > 2) continue; 711. 				if(corrct == 1 && dist2(x,y,x0,y0) != 1) 712. 					noturn = 1; 713. 				if(i < i0) { 714. 					i0 = i;  715. x0 = x; 716. y0 = y; 717. m0 = mtmp ? 1 : 0; 718.  				}  719.  			    }  720.  			    corrct++; 721. 			}  722.  			continue; 723. 		} else if (sym == TRAP_SYM) { 724. 			if(flags.run == 1) goto bcorr;	/* if you must */ 725. 			if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 726. 			continue; 727. 		} else if (sym == POOL_SYM) { 728. 			/* pools only stop you if directly in front, and stop 729. 			 * you even if you are running 730. 			 */  731.  			if(!Levitation &&  732.  #ifdef POLYSELF  733.  				!is_flyer(uasmon) &&  734.  #endif  735.  				/* No Wwalking check; otherwise they'd be able  736.  				 * to test boots by trying to SHIFT-direction  737.  				 * into a pool and seeing if the game allowed it  738.  				 */  739.  				x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 740. 			continue; 741. 		} else {		/* e.g. objects or trap or stairs */ 742. 			if(flags.run == 1) goto bcorr; 743. 			if(mtmp) continue;		/* d */ 744. 		}  745.  		stop: 746. 			nomul(0); 747. 			return; 748. 		}  749.  	}  750.  	if(corrct > 1 && flags.run == 2) goto stop; 751. 	if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&  752.  		(corrct == 1 || (corrct == 2 && i0 == 1))) { 753. 		/* make sure that we do not turn too far */ 754. 		if(i0 == 2) { 755. 		    if(u.dx == y0-u.uy && u.dy == u.ux-x0) 756. 			i = 2;		/* straight turn right */ 757. 		    else 758. 			i = -2;		/* straight turn left */ 759. 		} else if(u.dx && u.dy) { 760. 		    if((u.dx == u.dy && y0 == u.uy) ||  761.  			(u.dx != u.dy && y0 != u.uy)) 762. 			i = -1;		/* half turn left */ 763. 		    else 764. 			i = 1;		/* half turn right */ 765. 		} else { 766. 		    if((x0-u.ux == y0-u.uy && !u.dy) ||  767.  			(x0-u.ux != y0-u.uy && u.dy)) 768. 			i = 1;		/* half turn right */ 769. 		    else 770. 			i = -1;		/* half turn left */ 771. 		}  772.  		i += u.last_str_turn; 773. 		if(i <= 2 && i >= -2) { 774. 			u.last_str_turn = i;  775. u.dx = x0-u.ux, u.dy = y0-u.uy; 776. 		}  777.  	}  778.  }  779.   780.  /* something like lookaround, but we are not running */ 781. /* react only to monsters that might hit us */ 782. int 783. monster_nearby { 784. 	register int x,y; 785. 	register struct monst *mtmp; 786.  787.  	if(!Blind) 788. 	for(x = u.ux-1; x <= u.ux+1; x++) 789. 	    for(y = u.uy-1; y <= u.uy+1; y++) { 790. 		if(x == u.ux && y == u.uy) continue; 791. 		if(levl[x][y].mmask && (mtmp = m_at(x,y)) && !mtmp->mimic &&  792.  		   !mtmp->mtame && !mtmp->mpeaceful &&  793.  		   !noattacks(mtmp->data) &&  794.  		   !mtmp->mfroz && !mtmp->msleep &&  /* aplvax!jcn */  795.  		   (!mtmp->minvis || See_invisible) &&  796.  		   !onscary(u.ux, u.uy, mtmp)) 797. 			return(1); 798. 	}  799.  	return(0); 800. }  801.   802.  int 803. cansee(x,y) 804. xchar x,y; 805. {  806.  	if(Blind || u.uswallow) return(0); 807. 	if(dist(x,y) < 3) return(1); 808. 	if(IS_ROCK(levl[x][y].typ) && levl[u.ux][u.uy].typ == CORR &&  809.  							!levl[u.ux][u.uy].lit) 810. 		return(0); 811. 	if(levl[x][y].lit &&  812.  		((seelx <= x && x <= seehx && seely <= y && y <= seehy) || 813. 		(seelx2 <= x && x <= seehx2 && seely2 <= y && y <= seehy2))) 814. 		return(1); 815. 	return(0); 816. }  817.   818.  int 819. sgn(a) 820. 	register int a;  821. { 822.  	return((a > 0) ? 1 : (a == 0) ? 0 : -1); 823. }  824.   825.  void 826. getcorners(lx1,hx1,ly1,hy1,lx2,hx2,ly2,hy2) 827. xchar *lx1,*hx1,*ly1,*hy1,*lx2,*hx2,*ly2,*hy2; 828. /* return corners of one or two rooms player is in, so we can tell what areas 829.  * can be seen, or otherwise affected by room-specific things. (two rooms are 830.   * possible when in a doorway of the stronghold) 831.  * the player is already known to be in at least one room 832.  */  833.  {  834.  	register int uroom1,uroom2; 835. 	register xchar ux,uy; 836.  837.  	uroom1 = inroom(u.ux,u.uy); 838. 	*lx1 = rooms[uroom1].lx - 1; 839. 	*hx1 = rooms[uroom1].hx + 1; 840. 	*ly1 = rooms[uroom1].ly - 1; 841. 	*hy1 = rooms[uroom1].hy + 1; 842.  843.  	if(!IS_DOOR(levl[u.ux][u.uy].typ)) { 844. 		*lx2 = 1; 845. 		*hx2 = 0; 846. 		*ly2 = 1; 847. 		*hy2 = 0; 848. 	} else { 849. 		for(ux = u.ux-1; ux <= u.ux+1; ux++) 850. 			for(uy = u.uy-1; uy <= u.uy+1; uy++) { 851. 				if(IS_ROCK(levl[ux][uy].typ) ||  852.  					IS_DOOR(levl[ux][uy].typ)) continue; 853. 				/* might have side-by-side walls, in which case 854. 				 * should only be able to see one room */ 855. 				uroom2 = inroom(ux,uy); 856. 				if(uroom2 >= 0 && uroom2 != uroom1 &&  857.  				   rooms[uroom2].rlit) { 858. 					*lx2 = rooms[uroom2].lx - 1; 859. 					*ly2 = rooms[uroom2].ly - 1; 860. 					*hx2 = rooms[uroom2].hx + 1; 861. 					*hy2 = rooms[uroom2].hy + 1; 862. 					return; 863. 				}  864.  			}  865.  		*lx2 = 1; 866. 		*hx2 = 0; 867. 		*ly2 = 1; 868. 		*hy2 = 0; 869. 	}  870.  }  871.   872.  void 873. setsee { 874. 	register int x, y;  875. 876. 	if(Blind) { 877. 		pru; 878. 		return; 879. 	}  880.  	if(!levl[u.ux][u.uy].lit) { 881. 		seelx = u.ux-1; 882. 		seehx = u.ux+1; 883. 		seely = u.uy-1; 884. 		seehy = u.uy+1; 885. 		seelx2 = seely2 = 1; 886. 		seehx2 = seehy2 = 0; 887. 	} else { 888. 		getcorners(&seelx,&seehx,&seely,&seehy,  889.  			   &seelx2,&seehx2,&seely2,&seehy2); 890. 	}  891.  	for(y = seely; y <= seehy; y++) 892. 		for(x = seelx; x <= seehx; x++) { 893. 			prl(x,y); 894. 	}  895.  	for(y = seely2; y <= seehy2; y++) 896. 		for(x = seelx2; x <= seehx2; x++) { 897. 			prl(x,y); 898. 	}  899.  	if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ 900. 	else { 901. 	    if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); 902. 	    if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); 903. 	    if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); 904. 	    if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); 905. 	}  906.  }  907.   908.  void 909. nomul(nval) 910. 	register int nval; 911. {  912.  	if(multi < nval) return;	/* This is a bug fix by ab@unido */ 913. 	multi = nval; 914. 	flags.mv = flags.run = 0; 915. }  916.   917.  void 918. losehp(n, knam) 919. 	register int n;  920. register char *knam; 921. {  922.  #ifdef POLYSELF 923. 	if (u.mtimedone) { 924. 		u.mh -= n;  925. if (u.mhmax < u.mh) u.mhmax = u.mh; 926. 		flags.botl = 1; 927. 		if (u.mh < 1) rehumanize; 928. 		return; 929. 	}  930.  #endif 931. 	u.uhp -= n;  932. if(u.uhp > u.uhpmax) 933. 		u.uhpmax = u.uhp;	/* perhaps n was negative */ 934. 	flags.botl = 1; 935. 	if(u.uhp < 1) { 936. 		killer = knam;	/* the thing that killed you */ 937. 		You("die..."); 938. 		done("died"); 939. 	} else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){ 940. 		wailmsg = moves; 941. 		if(index("WEV", pl_character[0])) { 942. 			if (u.uhp == 1) 943. 				pline("%s is about to die.", pl_character); 944. 			else if (4 <= (!!(HTeleportation & INTRINSIC)) +  945.  				    (!!(HSee_invisible & INTRINSIC)) +  946.  				    (!!(HPoison_resistance & INTRINSIC)) +  947.  				    (!!(HCold_resistance & INTRINSIC)) +  948.  				    (!!(HShock_resistance & INTRINSIC)) +  949.  				    (!!(HFire_resistance & INTRINSIC)) +  950.  				    (!!(HSleep_resistance & INTRINSIC)) +  951.  				    (!!(HDisint_resistance & INTRINSIC)) +  952.  				    (!!(HTeleport_control & INTRINSIC)) +  953.  				    (!!(Fast & INTRINSIC)) +  954.  				    (!!(HInvis & INTRINSIC))) 955. 				pline("%s, all your powers will be lost...",  956.  					pl_character); 957. 			else 958. 				pline("%s, your life force is running out.",  959.  					pl_character); 960. 		} else { 961. 			if(u.uhp == 1) 962. 				You("hear the wailing of the Banshee..."); 963. 			else 964. 				You("hear the howling of the CwnAnnwn..."); 965. 		}  966.  	}  967.  }  968.   969.  int 970. weight_cap { 971. 	register int carrcap; 972.  973.  #ifdef HARD 974. 	carrcap = 5 * (((ACURR(A_STR) > 18) ? 20 : ACURR(A_STR)) + u.ulevel); 975. #else 976. 	carrcap = 5 * u.ulevel;      /* New strength stewr 870807 */ 977. 	if (ACURR(A_STR) < 19) carrcap += 5 * ACURR(A_STR); 978. 	if (ACURR(A_STR) > 18) carrcap += ACURR(A_STR) - 18 + 90; 979. 	if (ACURR(A_STR) > 68) carrcap += ACURR(A_STR) - 68; 980. 	if (ACURR(A_STR) > 93) carrcap += ACURR(A_STR) - 93; 981. 	if (ACURR(A_STR) > 108) carrcap += 2 * (ACURR(A_STR) - 108); 982. 	if (ACURR(A_STR) > 113) carrcap += 5 * (ACURR(A_STR) - 113); 983. 	if (ACURR(A_STR) == 118) carrcap += 100; 984. #endif 985. #ifdef POLYSELF 986. 	if (u.mtimedone) { 987. 		/* consistent with can_carry in mon.c */ 988. 		if (u.usym==S_NYMPH) carrcap = MAX_CARR_CAP; 989. 		else if (!uasmon->cwt) 990. 			carrcap = (carrcap * uasmon->mlevel * 6)/45; 991. 		else carrcap = (carrcap * uasmon->cwt / 45); 992. 	}  993.  #endif 994. 	if(Levitation) 			/* pugh@cornell */ 995. 		carrcap = MAX_CARR_CAP; 996. 	else { 997. 		if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 998. 		if(Wounded_legs & LEFT_SIDE) carrcap -= 10; 999. 		if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; 1000. 	} 1001. 	return(carrcap); 1002. } 1003.  1004. int 1005. inv_weight { 1006. 	register struct obj *otmp = invent; 1007. #ifdef LINT	/* long to int conversion */ 1008. 	register int wt = 0; 1009. #else 1010. 	register int wt = (int)((u.ugold + 500L)/1000L); 1011. #endif /* LINT */ 1012. 	while(otmp){ 1013. #ifdef POLYSELF 1014. 		if (otmp->otyp != BOULDER || !throws_rocks(uasmon)) 1015. #endif 1016. 			wt += otmp->owt; 1017. 		otmp = otmp->nobj; 1018. 	} 1019. 	return(wt - weight_cap); 1020. } 1021.  1022. int 1023. inv_cnt { 1024. 	register struct obj *otmp = invent; 1025. 	register int ct = 0; 1026. 1027. 	while(otmp){ 1028. 		ct++; 1029. 		otmp = otmp->nobj; 1030. 	} 1031. 	return(ct); 1032. } 1033.  1034. #ifdef STUPID_CPP	/* otherwise these functions are macros in hack.h */ 1035. char 1036. yn { 1037. 	return(yn_function(ynchars, 'n')); 1038. } 1039.  1040. char 1041. ynq { 1042. 	return(yn_function(ynqchars, 'q')); 1043. } 1044.  1045. char 1046. ynaq { 1047. 	return(yn_function(ynaqchars, 'y')); 1048. } 1049.  1050. char 1051. nyaq { 1052. 	return(yn_function(nyaqchars, 'n')); 1053. } 1054.  1055. int 1056. max(a,b) int a,b; { 1057. 	return((a > b) ? a : b); 1058. } 1059.  1060. int 1061. min(a,b) int a,b; { 1062. 	return((a < b) ? a : b); 1063. } 1064.  1065. char * 1066. plur(x) long x; { 1067. 	return((x == 1L) ? "" : "s"); 1068. } 1069.  1070. void 1071. makeknown(x) unsigned x; { 1072. 	objects[x].oc_name_known = 1; 1073. } 1074. #endif /* STUPID_CPP */