Source:NetHack 3.2.0/dbridge.c

Below is the full text to dbridge.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/dbridge.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)dbridge.c	3.2	95/06/24	*/ 2.   /*	Copyright (c) 1989 by Jean-Christophe Collet		  */ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /*  6.     * This file contains the drawbridge manipulation (create, open, close,  7.     * destroy). 8.    *  9.     * Added comprehensive monster-handling, and the "entity" structure to  10. * deal with players as well. - 11/89 11.    */  12.    13.   #include "hack.h"  14. 15.  #ifdef OVLB 16.  static void FDECL(get_wall_for_db, (int *, int *)); 17.  static struct entity *FDECL(e_at, (int, int)); 18.  static void FDECL(m_to_e, (struct monst *, int, int, struct entity *)); 19.  static void FDECL(u_to_e, (struct entity *)); 20.  static void FDECL(set_entity, (int, int, struct entity *)); 21.  static const char *FDECL(e_nam, (struct entity *)); 22.  #ifdef D_DEBUG 23.  static const char *FDECL(Enam, (struct entity *)); /* unused */ 24.  #endif 25.  static const char *FDECL(E_phrase, (struct entity *, const char *)); 26.  static boolean FDECL(e_survives_at, (struct entity *, int, int)); 27.  static void FDECL(e_died, (struct entity *, int, int)); 28.  static boolean FDECL(automiss, (struct entity *)); 29.  static boolean FDECL(e_missed, (struct entity *, BOOLEAN_P)); 30.  static boolean FDECL(e_jumps, (struct entity *)); 31.  static void FDECL(do_entity, (struct entity *)); 32.  #endif /* OVLB */ 33.   34.   #ifdef OVL0 35.   36.   boolean 37.  is_pool(x,y) 38.  int x,y; 39.  {  40.          register schar ltyp = levl[x][y].typ; 41.         if(ltyp == POOL || ltyp == MOAT || ltyp == WATER) return TRUE; 42.         if(ltyp == DRAWBRIDGE_UP &&  43.   	       (levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE; 44.         return FALSE; 45.  }  46.    47.   boolean 48.  is_lava(x,y) 49.  int x,y; 50.  {  51.          register schar ltyp = levl[x][y].typ; 52.         if(ltyp == LAVAPOOL ||  53.   	  (ltyp == DRAWBRIDGE_UP && 54.  	   (levl[x][y].drawbridgemask & DB_UNDER) == DB_LAVA)) return TRUE; 55.         return FALSE; 56.  }  57.    58.   boolean 59.  is_ice(x,y) 60.  int x,y; 61.  {  62.   	register schar ltyp = levl[x][y].typ; 63.  	if (ltyp == ICE ||  64.   	    (ltyp == DRAWBRIDGE_UP && 65.  		(levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE)) return TRUE; 66.  	return FALSE; 67.  }  68.    69.   #endif /* OVL0 */ 70.   71.   #ifdef OVL1 72.   73.   /*  74.    * We want to know whether a wall (or a door) is the portcullis (passageway) 75.   * of an eventual drawbridge. 76.   *  77.    * Return value:  the direction of the drawbridge. 78.   */  79.    80.   int 81.  is_drawbridge_wall(x,y) 82.  int x,y; 83.  {  84.   	struct rm *lev; 85.   86.   	lev = &levl[x][y]; 87.  	if (lev->typ != DOOR && lev->typ != DBWALL) 88.  		return (-1); 89.   90.   	if (IS_DRAWBRIDGE(levl[x+1][y].typ) &&  91.   	    (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST) 92.  		return (DB_WEST); 93.  	if (IS_DRAWBRIDGE(levl[x-1][y].typ) &&  94.   	    (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST) 95.  		return (DB_EAST); 96.  	if (IS_DRAWBRIDGE(levl[x][y-1].typ) &&  97.   	    (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH) 98.  		return (DB_SOUTH); 99.  	if (IS_DRAWBRIDGE(levl[x][y+1].typ) &&  100.  	    (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH) 101. 		return (DB_NORTH); 102.  103.  	return (-1); 104. }  105.   106.  /*  107.   * Use is_db_wall where you want to verify that a  108. * drawbridge "wall" is UP in the location x, y 109. * (instead of UP or DOWN, as with is_drawbridge_wall). 110.  */  111.  boolean 112. is_db_wall(x,y) 113. int x,y; 114. {  115.  	return((boolean)( levl[x][y].typ == DBWALL )); 116. }  117.   118.   119.  /*  120.   * Return true with x,y pointing to the drawbridge if x,y initially indicate 121.  * a drawbridge or drawbridge wall. 122.  */  123.  boolean 124. find_drawbridge(x,y) 125. int *x,*y; 126. {  127.  	int dir; 128.  129.  	if (IS_DRAWBRIDGE(levl[*x][*y].typ)) 130. 		return TRUE; 131. 	dir = is_drawbridge_wall(*x,*y); 132. 	if (dir >= 0) { 133. 		switch(dir) { 134. 			case DB_NORTH: (*y)++; break; 135. 			case DB_SOUTH: (*y)--; break; 136. 			case DB_EAST:  (*x)--; break; 137. 			case DB_WEST:  (*x)++; break; 138. 		}  139.  		return TRUE; 140. 	}  141.  	return FALSE; 142. }  143.   144.  #endif /* OVL1 */ 145. #ifdef OVLB 146.  147.  /*  148.   * Find the drawbridge wall associated with a drawbridge. 149.  */  150.  static void 151. get_wall_for_db(x,y) 152. int *x,*y; 153. {  154.  	switch (levl[*x][*y].drawbridgemask & DB_DIR) { 155. 		case DB_NORTH: (*y)--; break; 156. 		case DB_SOUTH: (*y)++; break; 157. 		case DB_EAST:  (*x)++; break; 158. 		case DB_WEST:  (*x)--; break; 159. 	}  160.  }  161.   162.  /*  163.   * Creation of a drawbridge at pos x,y. 164.  *     dir is the direction. 165.  *     flag must be put to TRUE if we want the drawbridge to be opened. 166.  */  167.   168.  boolean 169. create_drawbridge(x,y,dir,flag) 170. int x,y,dir; 171. boolean flag; 172. {  173.  	int x2,y2; 174. 	boolean horiz; 175. 	boolean lava = levl[x][y].typ == LAVAPOOL; /* assume initialized map */ 176.  177.  	x2 = x; y2 = y;  178. switch(dir) { 179. 		case DB_NORTH: 180. 			horiz = TRUE; 181. 			y2--; 182. 			break; 183. 		case DB_SOUTH: 184. 			horiz = TRUE; 185. 			y2++; 186. 			break; 187. 		case DB_EAST: 188. 			horiz = FALSE; 189. 			x2++; 190. 			break; 191. 		default: 192. 			impossible("bad direction in create_drawbridge"); 193. 			/* fall through */ 194. 		case DB_WEST: 195. 			horiz = FALSE; 196. 			x2--; 197. 			break; 198. 	}  199.  	if (!IS_WALL(levl[x2][y2].typ)) 200. 		return(FALSE); 201. 	if (flag) {             /* We want the bridge open */ 202. 		levl[x][y].typ = DRAWBRIDGE_DOWN; 203. 		levl[x2][y2].typ = DOOR; 204. 		levl[x2][y2].doormask = D_NODOOR; 205. 	} else { 206. 		levl[x][y].typ = DRAWBRIDGE_UP; 207. 		levl[x2][y2].typ = DBWALL; 208. 		/* Drawbridges are non-diggable. */ 209.  		levl[x2][y2].wall_info = W_NONDIGGABLE; 210. 	}  211.  	levl[x][y].horizontal = !horiz; 212. 	levl[x2][y2].horizontal = horiz; 213. 	levl[x][y].drawbridgemask = dir; 214. 	if(lava) levl[x][y].drawbridgemask |= DB_LAVA; 215. 	return(TRUE); 216. }  217.   218.  struct entity { 219. 	struct monst *emon;	  /* youmonst for the player */ 220. 	struct permonst *edata;   /* must be non-zero for record to be valid */ 221. 	int ex, ey; 222. };  223.   224.  #define ENTITIES 2 225.  226.  static NEARDATA struct entity occupants[ENTITIES]; 227.  228.  static 229. struct entity * 230. e_at(x, y)  231. int x, y; 232. { 233.  	int entitycnt; 234. 	  235.  	for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++) 236. 		if ((occupants[entitycnt].edata) &&  237.  		    (occupants[entitycnt].ex == x) &&  238.  		    (occupants[entitycnt].ey == y)) 239. 			break; 240. #ifdef D_DEBUG 241. 	pline("entitycnt = %d", entitycnt); 242. 	wait_synch; 243. #endif 244. 	return((entitycnt == ENTITIES)?  245.  	       (struct entity *)0 : &(occupants[entitycnt])); 246. }  247.   248.  static void 249. m_to_e(mtmp, x, y, etmp) 250. struct monst *mtmp; 251. int x, y;  252. struct entity *etmp; 253. {  254.  	etmp->emon = mtmp; 255. 	if (mtmp) { 256. 		etmp->ex = x;  257. etmp->ey = y; 258. if (mtmp->wormno && (x != mtmp->mx || y != mtmp->my)) 259. 			etmp->edata = &mons[PM_LONG_WORM_TAIL]; 260. 		else 261. 			etmp->edata = mtmp->data; 262. 	} else 263. 		etmp->edata = (struct permonst *)0; 264. }  265.   266.  static void 267. u_to_e(etmp) 268. struct entity *etmp; 269. {  270.  	etmp->emon = &youmonst; 271. 	etmp->ex = u.ux; 272. 	etmp->ey = u.uy; 273. 	etmp->edata = uasmon; 274. }  275.   276.  static void 277. set_entity(x, y, etmp) 278. int x, y;  279. struct entity *etmp; 280. {  281.  	if ((x == u.ux) && (y == u.uy)) 282. 		u_to_e(etmp); 283. 	else if (MON_AT(x, y)) 284. 		m_to_e(m_at(x, y), x, y, etmp); 285. 	else 286. 		etmp->edata = (struct permonst *)0; 287. }  288.   289.  #define is_u(etmp) (etmp->emon == &youmonst) 290. #define e_canseemon(etmp) (is_u(etmp) ? (boolean)TRUE : canseemon(etmp->emon)) 291.  292.  /*  293.   * e_strg is a utility routine which is not actually in use anywhere, since 294.  * the specialized routines below suffice for all current purposes. 295.  */  296.   297.  /* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */ 298.  299.  static const char * 300. e_nam(etmp) 301. struct entity *etmp; 302. {  303.  	return(is_u(etmp)? "you" : mon_nam(etmp->emon)); 304. }  305.   306.  #ifdef D_DEBUG 307. /*  308.   * Enam is another unused utility routine:  E_phrase is preferable. 309.  */  310.   311.  static const char * 312. Enam(etmp) 313. struct entity *etmp; 314. {  315.  	return(is_u(etmp)? "You" : Monnam(etmp->emon)); 316. }  317.  #endif /* D_DEBUG */ 318.  319.  /*  320.   * Generates capitalized entity name, makes 2nd -> 3rd person conversion on  321. * verb, where necessary. 322.  */  323.   324.  static const char * 325. E_phrase(etmp, verb) 326. struct entity *etmp; 327. const char *verb; 328. {  329.  	static char wholebuf[80]; 330. 	char verbbuf[30]; 331.  332.  	Strcpy(wholebuf, is_u(etmp) ? "You" : Monnam(etmp->emon)); 333. 	if (!*verb) 334. 		return(wholebuf); 335. 	Strcat(wholebuf, " "); 336. 	verbbuf[0] = '\0'; 337. 	if (is_u(etmp)) 338. 		Strcpy(verbbuf, verb); 339. 	else { 340. 		if (!strcmp(verb, "are")) 341. 			Strcpy(verbbuf, "is"); 342. 		if (!strcmp(verb, "have")) 343. 			Strcpy(verbbuf, "has"); 344. 		if (!verbbuf[0]) { 345. 			Strcpy(verbbuf, verb); 346. 			switch (verbbuf[strlen(verbbuf) - 1]) { 347. 				case 'y': 348. 					verbbuf[strlen(verbbuf) - 1] = '\0'; 349. 					Strcat(verbbuf, "ies"); 350. 					break; 351. 				case 'h': 352. 				case 'o': 353. 				case 's': 354. 					Strcat(verbbuf, "es"); 355. 					break; 356. 				default: 357. 					Strcat(verbbuf, "s"); 358. 					break; 359. 			}  360.  		}  361.  	}  362.  	Strcat(wholebuf, verbbuf); 363. 	return(wholebuf); 364. }  365.   366.  /*  367.   * Simple-minded "can it be here?" routine 368.  */  369.   370.  static boolean 371. e_survives_at(etmp, x, y)  372. struct entity *etmp; 373. int x, y;  374. { 375.  	if (noncorporeal(etmp->edata)) 376. 		return(TRUE); 377. 	if (is_pool(x, y)) 378. 		return (boolean)((is_u(etmp) && 379. 				(Wwalking || Amphibious || Levitation)) ||  380.  			is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||  381.  			is_floater(etmp->edata)); 382. 	/* must force call to lava_effects in e_died if is_u */ 383. 	if (is_lava(x, y)) 384. 		return (boolean)((is_u(etmp) && Levitation) ||  385.  			    likes_lava(etmp->edata) || is_flyer(etmp->edata)); 386. 	if (is_db_wall(x, y)) 387. 		return((boolean)(passes_walls(etmp->edata))); 388. 	return(TRUE); 389. }  390.   391.  static void 392. e_died(etmp, dest, how) 393. struct entity *etmp; 394. int dest, how; 395. {  396.  	if (is_u(etmp)) { 397. 		if (how == DROWNING) 398. 			(void) drown; 399. 		else if (how == BURNING) 400. 			(void) lava_effects; 401. 		else { 402. 			coord xy; 403.  404.  			killer_format = KILLED_BY_AN; 405. 			killer = "falling drawbridge"; 406. 			done(how); 407. 			/* So, you didn't die */ 408. 			if (!e_survives_at(etmp, etmp->ex, etmp->ey)) { 409. 			    if (enexto(&xy, etmp->ex, etmp->ey, etmp->edata)) { 410. 				pline("A %s force teleports you away...",  411.  				      Hallucination ? "normal" : "strange"); 412. 				teleds(xy.x, xy.y); 413. 			    }  414.  			    /* otherwise on top of the drawbridge is the 415. 			     * only viable spot in the dungeon, so stay there 416. 			     */  417.  			}  418.  		}  419.  		/* we might have crawled out of the moat to survive */ 420. 		etmp->ex = u.ux,  etmp->ey = u.uy; 421. 	} else { 422. 		/* fake "digested to death" damage-type suppresses corpse */ 423. #define mk_message(dest) ((dest & 1) ? "" : (char *)0) 424. #define mk_corpse(dest)  ((dest & 2) ? AD_DGST : AD_PHYS) 425. 		/* if monsters are moving, one of them caused the destruction */ 426. 		if (flags.mon_moving) 427. 		    monkilled(etmp->emon, mk_message(dest), mk_corpse(dest)); 428. 		else		/* you caused it */ 429. 		    xkilled(etmp->emon, dest); 430. 		etmp->edata = (struct permonst *)0; 431. #undef mk_message 432. #undef mk_corpse 433. 	}  434.  }  435.   436.   437.  /*  438.   * These are never directly affected by a bridge or portcullis. 439.  */  440.   441.  static boolean 442. automiss(etmp) 443. struct entity *etmp; 444. {  445.  	return (boolean)(passes_walls(etmp->edata) ||  446.  			 noncorporeal(etmp->edata)); 447. }  448.   449.  /*  450.   * Does falling drawbridge or portcullis miss etmp? 451.  */  452.   453.  static boolean 454. e_missed(etmp, chunks) 455. struct entity *etmp; 456. boolean chunks; 457. {  458.  	int misses; 459.  460.  #ifdef D_DEBUG 461. 	if (chunks) 462. 		pline("Do chunks miss?"); 463. #endif 464. 	if (automiss(etmp)) 465. 		return(TRUE); 466.  467.  	if (is_flyer(etmp->edata) &&  468.  	    (is_u(etmp)? !Sleeping : 469. 	     (etmp->emon->mcanmove && !etmp->emon->msleep))) 470. 						 /* flying requires mobility */ 471. 		misses = 5;	/* out of 8 */ 472. 	else if (is_floater(etmp->edata) ||  473.  		    (is_u(etmp) && Levitation))	 /* doesn't require mobility */ 474. 		misses = 3; 475. 	else if (chunks && is_pool(etmp->ex, etmp->ey)) 476. 		misses = 2;				    /* sitting ducks */ 477. 	else 478. 		misses = 0; 479.  480.  	if (is_db_wall(etmp->ex, etmp->ey)) 481. 		misses -= 3;				    /* less airspace */ 482.  483.  #ifdef D_DEBUG 484. 	pline("Miss chance = %d (out of 8)", misses); 485. #endif 486.  487.  	return((boolean)((misses >= rnd(8))? TRUE : FALSE)); 488. }  489.   490.  /*  491.   * Can etmp jump from death? 492.  */  493.   494.  static boolean 495. e_jumps(etmp) 496. struct entity *etmp; 497. {  498.  	int tmp = 4;		/* out of 10 */ 499.  500.  	if (is_u(etmp)? (Sleeping || Fumbling) :  501.  		        (!etmp->emon->mcanmove || etmp->emon->msleep || 502. 			 !etmp->edata->mmove   || etmp->emon->wormno)) 503. 		return(FALSE); 504.  505.  	if (is_u(etmp)? Confusion : etmp->emon->mconf) 506. 		tmp -= 2; 507.  508.  	if (is_u(etmp)? Stunned : etmp->emon->mstun) 509. 		tmp -= 3; 510.  511.  	if (is_db_wall(etmp->ex, etmp->ey)) 512. 		tmp -= 2;			    /* less room to maneuver */ 513. 	  514.  #ifdef D_DEBUG 515. 	pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp); 516. #endif 517. 	return((boolean)((tmp >= rnd(10))? TRUE : FALSE)); 518. }  519.   520.  static void 521. do_entity(etmp) 522. struct entity *etmp; 523. {  524.  	int newx, newy, at_portcullis, oldx, oldy; 525. 	boolean must_jump = FALSE, relocates = FALSE, e_inview; 526. 	struct rm *crm; 527.  528.  	if (!etmp->edata) 529. 		return; 530.  531.  	e_inview = e_canseemon(etmp); 532. 	oldx = etmp->ex; 533. 	oldy = etmp->ey; 534. 	at_portcullis = is_db_wall(oldx, oldy); 535. 	crm = &levl[oldx][oldy]; 536.  537.  	if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) { 538. 		if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ))) 539. 			pline_The("%s passes through %s!",  540.  			      at_portcullis ? "portcullis" : "drawbridge",  541.  			      e_nam(etmp)); 542. 		return; 543. 	}  544.  	if (e_missed(etmp, FALSE)) { 545. 		if (at_portcullis) 546. 			pline_The("portcullis misses %s!",  547.  			      e_nam(etmp)); 548. #ifdef D_DEBUG 549. 		else 550. 			pline_The("drawbridge misses %s!",  551.  			      e_nam(etmp)); 552. #endif 553. 		if (e_survives_at(etmp, oldx, oldy)) 554. 			return; 555. 		else { 556. #ifdef D_DEBUG 557. 			pline("Mon can't survive here"); 558. #endif 559. 			if (at_portcullis) 560. 				must_jump = TRUE; 561. 			else 562. 				relocates = TRUE; /* just ride drawbridge in */ 563. 		}  564.  	} else { 565. 		if (crm->typ == DRAWBRIDGE_DOWN) { 566. 			pline("%s crushed underneath the drawbridge.",  567.  			      E_phrase(etmp, "are"));		  /* no jump */ 568. 			e_died(etmp, e_inview? 3 : 2, CRUSHING);/* no corpse */ 569. 			return;   /* Note: Beyond this point, we know we're  */ 570. 		}		  /* not at an opened drawbridge, since all  */ 571. 		must_jump = TRUE; /* *missable* creatures survive on the     */ 572. 	}			  /* square, and all the unmissed ones die. */ 573.  	if (must_jump) { 574. 	    if (at_portcullis) { 575. 		if (e_jumps(etmp)) { 576. 		    relocates = TRUE; 577. #ifdef D_DEBUG 578. 		    pline("Jump succeeds!"); 579. #endif 580. 		} else { 581. 		    if (e_inview) 582. 			pline("%s crushed by the falling portcullis!",  583.  			      E_phrase(etmp, "are")); 584. 		    else if (flags.soundok) 585. 			You_hear("a crushing sound."); 586. 		    e_died(etmp, e_inview? 3 : 2, CRUSHING); 587. 		    /* no corpse */ 588. 		    return; 589. 		}  590.  	    } else { /* tries to jump off bridge to original square */ 591. 		relocates = !e_jumps(etmp); 592. #ifdef D_DEBUG 593. 		pline("Jump %s!", (relocates)? "fails" : "succeeds"); 594. #endif 595. 	    }  596.  	}  597.   598.  /*  599.   * Here's where we try to do relocation. Assumes that etmp is not arriving 600.  * at the portcullis square while the drawbridge is falling, since this square 601.  * would be inaccessible (i.e. etmp started on drawbridge square) or  602. * unnecessary (i.e. etmp started here) in such a situation. 603.  */  604.  #ifdef D_DEBUG 605. 	pline("Doing relocation."); 606. #endif 607. 	newx = oldx; 608. 	newy = oldy; 609. 	(void)find_drawbridge(&newx, &newy); 610. 	if ((newx == oldx) && (newy == oldy)) 611. 		get_wall_for_db(&newx, &newy); 612. #ifdef D_DEBUG 613. 	pline("Checking new square for occupancy."); 614. #endif 615. 	if (relocates && (e_at(newx, newy))) { 616.  617.  /*  618.   * Standoff problem:  one or both entities must die, and/or both switch 619.  * places. Avoid infinite recursion by checking first whether the other 620.  * entity is staying put. Clean up if we happen to move/die in recursion. 621.  */  622.  		struct entity *other; 623.  624.  		other = e_at(newx, newy); 625. #ifdef D_DEBUG 626. 		pline("New square is occupied by %s", e_nam(other)); 627. #endif 628. 		if (e_survives_at(other, newx, newy) && automiss(other)) { 629. 			relocates = FALSE;	      /* "other" won't budge */ 630. #ifdef D_DEBUG 631. 			pline("%s suicide.", E_phrase(etmp, "commit")); 632. #endif 633. 		} else { 634.  635.  #ifdef D_DEBUG 636. 			pline("Handling %s", e_nam(other)); 637. #endif 638. 			while ((e_at(newx, newy) != 0) &&  639.  			       (e_at(newx, newy) != etmp)) 640. 				do_entity(other); 641. #ifdef D_DEBUG 642. 			pline("Checking existence of %s", e_nam(etmp)); 643. 			wait_synch; 644. #endif 645. 			if (e_at(oldx, oldy) != etmp) { 646. #ifdef D_DEBUG 647. 			    pline("%s moved or died in recursion somewhere",  648.  				  E_phrase(etmp, "have")); 649. 			    wait_synch; 650. #endif 651. 			    return; 652. 			}  653.  		}  654.  	}  655.  	if (relocates && !e_at(newx, newy)) {/* if e_at entity = worm tail */ 656. #ifdef D_DEBUG 657. 		pline("Moving %s", e_nam(etmp)); 658. #endif 659. 		if (!is_u(etmp)) { 660. 			remove_monster(etmp->ex, etmp->ey); 661. 			place_monster(etmp->emon, newx, newy); 662. 		} else { 663. 			u.ux = newx; 664. 			u.uy = newy; 665. 		}  666.  		etmp->ex = newx; 667. 		etmp->ey = newy; 668. 		e_inview = e_canseemon(etmp); 669. 	}  670.  #ifdef D_DEBUG 671. 	pline("Final disposition of %s", e_nam(etmp)); 672. 	wait_synch; 673. #endif 674. 	if (is_db_wall(etmp->ex, etmp->ey)) { 675. #ifdef D_DEBUG 676. 		pline("%s in portcullis chamber", E_phrase(etmp, "are")); 677. 		wait_synch; 678. #endif 679. 		if (e_inview) { 680. 			if (is_u(etmp)) { 681. 				You("tumble towards the closed portcullis!"); 682. 				if (automiss(etmp)) 683. 					You("pass through it!"); 684. 				else 685. 					pline_The("drawbridge closes in..."); 686. 			} else 687. 				pline("%s behind the drawbridge.",  688.  				      E_phrase(etmp, "disappear")); 689. 		}  690.  		if (!e_survives_at(etmp, etmp->ex, etmp->ey)) { 691. 			killer_format = KILLED_BY_AN; 692. 			killer = "closing drawbridge"; 693. 			e_died(etmp, 0, CRUSHING);	       /* no message */ 694. 			return; 695. 		}  696.  #ifdef D_DEBUG 697. 		pline("%s in here", E_phrase(etmp, "survive")); 698. #endif 699. 	} else { 700. #ifdef D_DEBUG 701. 		pline("%s on drawbridge square", E_phrase(etmp, "are")); 702. #endif 703. 		if (is_pool(etmp->ex, etmp->ey) && !e_inview) 704. 			if (flags.soundok) 705. 				You_hear("a splash."); 706. 		if (e_survives_at(etmp, etmp->ex, etmp->ey)) { 707. 			if (e_inview && !is_flyer(etmp->edata) &&  708.  			    !is_floater(etmp->edata)) 709. 				pline("%s from the bridge.",  710.  				      E_phrase(etmp, "fall")); 711. 			return; 712. 		}  713.  #ifdef D_DEBUG 714. 		pline("%s cannot survive on the drawbridge square",Enam(etmp)); 715. #endif 716. 		if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey)) 717. 		    if (e_inview && !is_u(etmp)) { 718. 			/* drown will supply msgs if nec. */ 719.  			boolean lava = is_lava(etmp->ex, etmp->ey); 720.  721.  			if (Hallucination) 722. 			    pline("%s the %s and disappears.",  723.  				  E_phrase(etmp, "drink"),  724.  				  lava ? "lava" : "moat"); 725. 			else 726. 			    pline("%s into the %s.",  727.  				  E_phrase(etmp, "fall"),  728.  				  lava ? "lava" : "moat"); 729. 		    }  730.  		killer_format = NO_KILLER_PREFIX; 731. 		killer = "fell from a drawbridge"; 732. 		e_died(etmp, e_inview ? 3 : 2,      /* CRUSHING is arbitrary */  733.  		       (is_pool(etmp->ex, etmp->ey)) ? DROWNING :  734.  		       (is_lava(etmp->ex, etmp->ey)) ? BURNING :  735.  						       CRUSHING); /*no corpse*/ 736. 		return; 737. 	}  738.  }  739.   740.  /*  741.   * Close the drawbridge located at x,y 742.  */  743.   744.  void 745. close_drawbridge(x,y) 746. int x,y; 747. {  748.  	register struct rm *lev1, *lev2; 749. 	int x2, y2; 750.  751.  	lev1 = &levl[x][y]; 752. 	if (lev1->typ != DRAWBRIDGE_DOWN) return; 753. 	x2 = x; y2 = y;  754. get_wall_for_db(&x2,&y2); 755. 	if (cansee(x,y) || cansee(x2,y2)) 756. 		You("see a drawbridge %s up!",  757.  		    (((u.ux == x || u.uy == y) && !Underwater) || 758. 		     distu(x2,y2) < distu(x,y)) ? "coming" : "going"); 759. 	lev1->typ = DRAWBRIDGE_UP; 760. 	lev2 = &levl[x2][y2]; 761. 	lev2->typ = DBWALL; 762. 	switch (lev1->drawbridgemask & DB_DIR) { 763. 		case DB_NORTH: 764. 		case DB_SOUTH: 765. 			lev2->horizontal = TRUE; 766. 			break; 767. 		case DB_WEST: 768. 		case DB_EAST: 769. 			lev2->horizontal = FALSE; 770. 			break; 771. 	}  772.  	lev2->wall_info = W_NONDIGGABLE; 773. 	set_entity(x, y, &(occupants[0])); 774. 	set_entity(x2, y2, &(occupants[1])); 775. 	do_entity(&(occupants[0]));		/* Do set_entity after first */ 776. 	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tail */ 777. 	do_entity(&(occupants[1])); 778. 	if(OBJ_AT(x,y) && flags.soundok) 779. 	    You_hear("smashing and crushing."); 780. 	(void) revive_nasty(x,y,(char *)0); 781. 	(void) revive_nasty(x2,y2,(char *)0); 782. 	delallobj(x, y); 783. 	newsym(x, y); 784. 	delallobj(x2, y2); 785. 	newsym(x2, y2); 786. 	block_point(x2,y2);	/* vision */ 787. }  788.   789.  /*  790.   * Open the drawbridge located at x,y 791.  */  792.   793.  void 794. open_drawbridge(x,y) 795. int x,y; 796. {  797.  	register struct rm *lev1, *lev2; 798. 	int x2, y2; 799.  800.  	lev1 = &levl[x][y]; 801. 	if (lev1->typ != DRAWBRIDGE_UP) return; 802. 	x2 = x; y2 = y;  803. get_wall_for_db(&x2,&y2); 804. 	if (cansee(x,y) || cansee(x2,y2)) 805. 		You("see a drawbridge %s down!",  806.  		    (distu(x2,y2) < distu(x,y)) ? "going" : "coming"); 807. 	lev1->typ = DRAWBRIDGE_DOWN; 808. 	lev2 = &levl[x2][y2]; 809. 	lev2->typ = DOOR; 810. 	lev2->doormask = D_NODOOR; 811. 	set_entity(x, y, &(occupants[0])); 812. 	set_entity(x2, y2, &(occupants[1])); 813. 	do_entity(&(occupants[0]));		/* do set_entity after first */ 814. 	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tails */ 815. 	do_entity(&(occupants[1])); 816. 	(void) revive_nasty(x,y,(char *)0); 817. 	delallobj(x, y); 818. 	newsym(x, y); 819. 	newsym(x2, y2); 820. 	unblock_point(x2,y2);	/* vision */ 821. 	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE; 822. }  823.   824.  /*  825.   * Let's destroy the drawbridge located at x,y 826.  */  827.   828.  void 829. destroy_drawbridge(x,y) 830. int x,y; 831. {  832.  	register struct rm *lev1, *lev2; 833. 	int x2, y2; 834. 	boolean e_inview; 835. 	struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]); 836.  837.  	lev1 = &levl[x][y]; 838. 	if (!IS_DRAWBRIDGE(lev1->typ)) 839. 		return; 840. 	x2 = x; y2 = y;  841. get_wall_for_db(&x2,&y2); 842. 	lev2 = &levl[x2][y2]; 843. 	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT ||  844.  	    (lev1->drawbridgemask & DB_UNDER) == DB_LAVA) { 845. 		struct obj *otmp; 846. 		boolean lava = (lev1->drawbridgemask & DB_UNDER) == DB_LAVA; 847. 		if (lev1->typ == DRAWBRIDGE_UP) { 848. 			if (cansee(x2,y2)) 849. 			    pline_The("portcullis of the drawbridge falls into the %s!",  850.  				  lava ? "lava" : "moat"); 851. 			else if (flags.soundok) 852. 				You_hear("a loud *SPLASH*!"); 853. 		} else { 854. 			if (cansee(x,y)) 855. 			    pline_The("drawbridge collapses into the %s!",  856.  				  lava ? "lava" : "moat"); 857. 			else if (flags.soundok) 858. 				You_hear("a loud *SPLASH*!"); 859. 		}  860.  		lev1->typ = lava ? LAVAPOOL : MOAT; 861. 		lev1->drawbridgemask = 0; 862. 		if ((otmp = sobj_at(BOULDER,x,y)) != 0) { 863. 		    obj_extract_self(otmp); 864. 		    (void) flooreffects(otmp,x,y,"fall"); 865. 		}  866.  	} else { 867. 		if (cansee(x,y)) 868. 			pline_The("drawbridge disintegrates!"); 869. 		else 870. 			You_hear("a loud *CRASH*!"); 871. 		lev1->typ = 872. 			((lev1->drawbridgemask & DB_ICE) ? ICE : ROOM); 873. 		lev1->icedpool = 874. 			((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0); 875. 	}  876.  	wake_nearto(x, y, 500); 877. 	lev2->typ = DOOR; 878. 	lev2->doormask = D_NODOOR; 879. 	newsym(x,y); 880. 	newsym(x2,y2); 881. 	if (!does_block(x2,y2,lev2)) unblock_point(x2,y2);	/* vision */ 882. 	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE; 883.  884.  	set_entity(x2, y2, etmp2); /* currently only automissers can be here */ 885. 	if (etmp2->edata) { 886. 		e_inview = e_canseemon(etmp2); 887. 		if (!automiss(etmp2)) { 888. 			if (e_inview) 889. 				pline("%s blown apart by flying debris.",  890.  				      E_phrase(etmp2, "are")); 891. 			killer_format = KILLED_BY_AN; 892. 			killer = "exploding drawbridge"; 893. 			e_died(etmp2, e_inview? 3 : 2, CRUSHING); /*no corpse*/ 894. 		}	     /* nothing which is vulnerable can survive this */ 895. 	}  896.  	set_entity(x, y, etmp1); 897. 	if (etmp1->edata) { 898. 		e_inview = e_canseemon(etmp1); 899. 		if (e_missed(etmp1, TRUE)) { 900. #ifdef D_DEBUG 901. 			pline("%s spared!", E_phrase(etmp1, "are")); 902. #endif 903. 		} else { 904. 			if (e_inview) { 905. 			    if (!is_u(etmp1) && Hallucination) 906. 				pline("%s into some heavy metal",  907.  				      E_phrase(etmp1, "get")); 908. 			    else 909. 				pline("%s hit by a huge chunk of metal!",  910.  				      E_phrase(etmp1, "are")); 911. 			} else { 912. 			    if (flags.soundok && !is_u(etmp1) && !is_pool(x,y)) 913. 				You_hear("a crushing sound."); 914. #ifdef D_DEBUG 915. 			    else 916. 				pline("%s from shrapnel",  917.  				      E_phrase(etmp1, "die")); 918. #endif 919. 			}  920.  			killer_format = KILLED_BY_AN; 921. 			killer = "collapsing drawbridge"; 922. 			e_died(etmp1, e_inview? 3 : 2, CRUSHING); /*no corpse*/ 923. 			if(lev1->typ == MOAT) do_entity(etmp1); 924. 		}  925.  	}  926.  }  927.   928.  #endif /* OVLB */ 929.  930.  /*dbridge.c*/