Source:SLASH'EM 0.0.7E7F2/dbridge.c

Below is the full text to dbridge.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/dbridge.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

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