Source:NetHack 3.4.0/dbridge.c

Below is the full text to dbridge.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4	2000/02/05	*/ 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); 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. 		killer = 0; 414. 		/* fake "digested to death" damage-type suppresses corpse */ 415. #define mk_message(dest) ((dest & 1) ? "" : (char *)0) 416. #define mk_corpse(dest)  ((dest & 2) ? AD_DGST : AD_PHYS) 417. 		/* if monsters are moving, one of them caused the destruction */ 418. 		if (flags.mon_moving) 419. 		    monkilled(etmp->emon, mk_message(dest), mk_corpse(dest)); 420. 		else		/* you caused it */ 421. 		    xkilled(etmp->emon, dest); 422. 		etmp->edata = (struct permonst *)0; 423. #undef mk_message 424. #undef mk_corpse 425. 	}  426.  }  427.   428.   429.  /*  430.   * These are never directly affected by a bridge or portcullis. 431.  */  432.   433.  STATIC_OVL boolean 434. automiss(etmp) 435. struct entity *etmp; 436. {  437.  	return (boolean)((is_u(etmp) ? Passes_walls : 438. 			passes_walls(etmp->edata)) || noncorporeal(etmp->edata)); 439. }  440.   441.  /*  442.   * Does falling drawbridge or portcullis miss etmp? 443.  */  444.   445.  STATIC_OVL boolean 446. e_missed(etmp, chunks) 447. struct entity *etmp; 448. boolean chunks; 449. {  450.  	int misses; 451.  452.  #ifdef D_DEBUG 453. 	if (chunks) 454. 		pline("Do chunks miss?"); 455. #endif 456. 	if (automiss(etmp)) 457. 		return(TRUE); 458.  459.  	if (is_flyer(etmp->edata) &&  460.  	    (is_u(etmp)? !Sleeping : 461. 	     (etmp->emon->mcanmove && !etmp->emon->msleeping))) 462. 						 /* flying requires mobility */ 463. 		misses = 5;	/* out of 8 */ 464. 	else if (is_floater(etmp->edata) ||  465.  		    (is_u(etmp) && Levitation))	 /* doesn't require mobility */ 466. 		misses = 3; 467. 	else if (chunks && is_pool(etmp->ex, etmp->ey)) 468. 		misses = 2;				    /* sitting ducks */ 469. 	else 470. 		misses = 0; 471.  472.  	if (is_db_wall(etmp->ex, etmp->ey)) 473. 		misses -= 3;				    /* less airspace */ 474.  475.  #ifdef D_DEBUG 476. 	pline("Miss chance = %d (out of 8)", misses); 477. #endif 478.  479.  	return((boolean)((misses >= rnd(8))? TRUE : FALSE)); 480. }  481.   482.  /*  483.   * Can etmp jump from death? 484.  */  485.   486.  STATIC_OVL boolean 487. e_jumps(etmp) 488. struct entity *etmp; 489. {  490.  	int tmp = 4;		/* out of 10 */ 491.  492.  	if (is_u(etmp)? (Sleeping || Fumbling) :  493.  		        (!etmp->emon->mcanmove || etmp->emon->msleeping || 494. 			 !etmp->edata->mmove   || etmp->emon->wormno)) 495. 		return(FALSE); 496.  497.  	if (is_u(etmp)? Confusion : etmp->emon->mconf) 498. 		tmp -= 2; 499.  500.  	if (is_u(etmp)? Stunned : etmp->emon->mstun) 501. 		tmp -= 3; 502.  503.  	if (is_db_wall(etmp->ex, etmp->ey)) 504. 		tmp -= 2;			    /* less room to maneuver */ 505.  506.  #ifdef D_DEBUG 507. 	pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp); 508. #endif 509. 	return((boolean)((tmp >= rnd(10))? TRUE : FALSE)); 510. }  511.   512.  STATIC_OVL void 513. do_entity(etmp) 514. struct entity *etmp; 515. {  516.  	int newx, newy, at_portcullis, oldx, oldy; 517. 	boolean must_jump = FALSE, relocates = FALSE, e_inview; 518. 	struct rm *crm; 519.  520.  	if (!etmp->edata) 521. 		return; 522.  523.  	e_inview = e_canseemon(etmp); 524. 	oldx = etmp->ex; 525. 	oldy = etmp->ey; 526. 	at_portcullis = is_db_wall(oldx, oldy); 527. 	crm = &levl[oldx][oldy]; 528.  529.  	if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) { 530. 		if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ))) 531. 			pline_The("%s passes through %s!",  532.  			      at_portcullis ? "portcullis" : "drawbridge",  533.  			      e_nam(etmp)); 534. 		return; 535. 	}  536.  	if (e_missed(etmp, FALSE)) { 537. 		if (at_portcullis) 538. 			pline_The("portcullis misses %s!",  539.  			      e_nam(etmp)); 540. #ifdef D_DEBUG 541. 		else 542. 			pline_The("drawbridge misses %s!",  543.  			      e_nam(etmp)); 544. #endif 545. 		if (e_survives_at(etmp, oldx, oldy)) 546. 			return; 547. 		else { 548. #ifdef D_DEBUG 549. 			pline("Mon can't survive here"); 550. #endif 551. 			if (at_portcullis) 552. 				must_jump = TRUE; 553. 			else 554. 				relocates = TRUE; /* just ride drawbridge in */ 555. 		}  556.  	} else { 557. 		if (crm->typ == DRAWBRIDGE_DOWN) { 558. 			pline("%s crushed underneath the drawbridge.",  559.  			      E_phrase(etmp, "are"));		  /* no jump */ 560. 			e_died(etmp, e_inview? 3 : 2, CRUSHING);/* no corpse */ 561. 			return;   /* Note: Beyond this point, we know we're  */ 562. 		}		  /* not at an opened drawbridge, since all  */ 563. 		must_jump = TRUE; /* *missable* creatures survive on the     */ 564. 	}			  /* square, and all the unmissed ones die. */ 565.  	if (must_jump) { 566. 	    if (at_portcullis) { 567. 		if (e_jumps(etmp)) { 568. 		    relocates = TRUE; 569. #ifdef D_DEBUG 570. 		    pline("Jump succeeds!"); 571. #endif 572. 		} else { 573. 		    if (e_inview) 574. 			pline("%s crushed by the falling portcullis!",  575.  			      E_phrase(etmp, "are")); 576. 		    else if (flags.soundok) 577. 			You_hear("a crushing sound."); 578. 		    e_died(etmp, e_inview? 3 : 2, CRUSHING); 579. 		    /* no corpse */ 580. 		    return; 581. 		}  582.  	    } else { /* tries to jump off bridge to original square */ 583. 		relocates = !e_jumps(etmp); 584. #ifdef D_DEBUG 585. 		pline("Jump %s!", (relocates)? "fails" : "succeeds"); 586. #endif 587. 	    }  588.  	}  589.   590.  /*  591.   * Here's where we try to do relocation. Assumes that etmp is not arriving 592.  * at the portcullis square while the drawbridge is falling, since this square 593.  * would be inaccessible (i.e. etmp started on drawbridge square) or  594. * unnecessary (i.e. etmp started here) in such a situation. 595.  */  596.  #ifdef D_DEBUG 597. 	pline("Doing relocation."); 598. #endif 599. 	newx = oldx; 600. 	newy = oldy; 601. 	(void)find_drawbridge(&newx, &newy); 602. 	if ((newx == oldx) && (newy == oldy)) 603. 		get_wall_for_db(&newx, &newy); 604. #ifdef D_DEBUG 605. 	pline("Checking new square for occupancy."); 606. #endif 607. 	if (relocates && (e_at(newx, newy))) { 608.  609.  /*  610.   * Standoff problem:  one or both entities must die, and/or both switch 611.  * places. Avoid infinite recursion by checking first whether the other 612.  * entity is staying put. Clean up if we happen to move/die in recursion. 613.  */  614.  		struct entity *other; 615.  616.  		other = e_at(newx, newy); 617. #ifdef D_DEBUG 618. 		pline("New square is occupied by %s", e_nam(other)); 619. #endif 620. 		if (e_survives_at(other, newx, newy) && automiss(other)) { 621. 			relocates = FALSE;	      /* "other" won't budge */ 622. #ifdef D_DEBUG 623. 			pline("%s suicide.", E_phrase(etmp, "commit")); 624. #endif 625. 		} else { 626.  627.  #ifdef D_DEBUG 628. 			pline("Handling %s", e_nam(other)); 629. #endif 630. 			while ((e_at(newx, newy) != 0) &&  631.  			       (e_at(newx, newy) != etmp)) 632. 				do_entity(other); 633. #ifdef D_DEBUG 634. 			pline("Checking existence of %s", e_nam(etmp)); 635. 			wait_synch; 636. #endif 637. 			if (e_at(oldx, oldy) != etmp) { 638. #ifdef D_DEBUG 639. 			    pline("%s moved or died in recursion somewhere",  640.  				  E_phrase(etmp, "have")); 641. 			    wait_synch; 642. #endif 643. 			    return; 644. 			}  645.  		}  646.  	}  647.  	if (relocates && !e_at(newx, newy)) {/* if e_at entity = worm tail */ 648. #ifdef D_DEBUG 649. 		pline("Moving %s", e_nam(etmp)); 650. #endif 651. 		if (!is_u(etmp)) { 652. 			remove_monster(etmp->ex, etmp->ey); 653. 			place_monster(etmp->emon, newx, newy); 654. 			update_monster_region(etmp->emon); 655. 		} else { 656. 			u.ux = newx; 657. 			u.uy = newy; 658. 		}  659.  		etmp->ex = newx; 660. 		etmp->ey = newy; 661. 		e_inview = e_canseemon(etmp); 662. 	}  663.  #ifdef D_DEBUG 664. 	pline("Final disposition of %s", e_nam(etmp)); 665. 	wait_synch; 666. #endif 667. 	if (is_db_wall(etmp->ex, etmp->ey)) { 668. #ifdef D_DEBUG 669. 		pline("%s in portcullis chamber", E_phrase(etmp, "are")); 670. 		wait_synch; 671. #endif 672. 		if (e_inview) { 673. 			if (is_u(etmp)) { 674. 				You("tumble towards the closed portcullis!"); 675. 				if (automiss(etmp)) 676. 					You("pass through it!"); 677. 				else 678. 					pline_The("drawbridge closes in..."); 679. 			} else 680. 				pline("%s behind the drawbridge.",  681.  				      E_phrase(etmp, "disappear")); 682. 		}  683.  		if (!e_survives_at(etmp, etmp->ex, etmp->ey)) { 684. 			killer_format = KILLED_BY_AN; 685. 			killer = "closing drawbridge"; 686. 			e_died(etmp, 0, CRUSHING);	       /* no message */ 687. 			return; 688. 		}  689.  #ifdef D_DEBUG 690. 		pline("%s in here", E_phrase(etmp, "survive")); 691. #endif 692. 	} else { 693. #ifdef D_DEBUG 694. 		pline("%s on drawbridge square", E_phrase(etmp, "are")); 695. #endif 696. 		if (is_pool(etmp->ex, etmp->ey) && !e_inview) 697. 			if (flags.soundok) 698. 				You_hear("a splash."); 699. 		if (e_survives_at(etmp, etmp->ex, etmp->ey)) { 700. 			if (e_inview && !is_flyer(etmp->edata) &&  701.  			    !is_floater(etmp->edata)) 702. 				pline("%s from the bridge.",  703.  				      E_phrase(etmp, "fall")); 704. 			return; 705. 		}  706.  #ifdef D_DEBUG 707. 		pline("%s cannot survive on the drawbridge square",Enam(etmp)); 708. #endif 709. 		if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey)) 710. 		    if (e_inview && !is_u(etmp)) { 711. 			/* drown will supply msgs if nec. */ 712.  			boolean lava = is_lava(etmp->ex, etmp->ey); 713.  714.  			if (Hallucination) 715. 			    pline("%s the %s and disappears.",  716.  				  E_phrase(etmp, "drink"),  717.  				  lava ? "lava" : "moat"); 718. 			else 719. 			    pline("%s into the %s.",  720.  				  E_phrase(etmp, "fall"),  721.  				  lava ? "lava" : "moat"); 722. 		    }  723.  		killer_format = NO_KILLER_PREFIX; 724. 		killer = "fell from a drawbridge"; 725. 		e_died(etmp, e_inview ? 3 : 2,      /* CRUSHING is arbitrary */  726.  		       (is_pool(etmp->ex, etmp->ey)) ? DROWNING :  727.  		       (is_lava(etmp->ex, etmp->ey)) ? BURNING :  728.  						       CRUSHING); /*no corpse*/ 729. 		return; 730. 	}  731.  }  732.   733.  /*  734.   * Close the drawbridge located at x,y 735.  */  736.   737.  void 738. close_drawbridge(x,y) 739. int x,y; 740. {  741.  	register struct rm *lev1, *lev2; 742. 	struct trap *t; 743. 	int x2, y2; 744.  745.  	lev1 = &levl[x][y]; 746. 	if (lev1->typ != DRAWBRIDGE_DOWN) return; 747. 	x2 = x; y2 = y;  748. get_wall_for_db(&x2,&y2); 749. 	if (cansee(x,y) || cansee(x2,y2)) 750. 		You("see a drawbridge %s up!",  751.  		    (((u.ux == x || u.uy == y) && !Underwater) || 752. 		     distu(x2,y2) < distu(x,y)) ? "coming" : "going"); 753. 	lev1->typ = DRAWBRIDGE_UP; 754. 	lev2 = &levl[x2][y2]; 755. 	lev2->typ = DBWALL; 756. 	switch (lev1->drawbridgemask & DB_DIR) { 757. 		case DB_NORTH: 758. 		case DB_SOUTH: 759. 			lev2->horizontal = TRUE; 760. 			break; 761. 		case DB_WEST: 762. 		case DB_EAST: 763. 			lev2->horizontal = FALSE; 764. 			break; 765. 	}  766.  	lev2->wall_info = W_NONDIGGABLE; 767. 	set_entity(x, y, &(occupants[0])); 768. 	set_entity(x2, y2, &(occupants[1])); 769. 	do_entity(&(occupants[0]));		/* Do set_entity after first */ 770. 	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tail */ 771. 	do_entity(&(occupants[1])); 772. 	if(OBJ_AT(x,y) && flags.soundok) 773. 	    You_hear("smashing and crushing."); 774. 	(void) revive_nasty(x,y,(char *)0); 775. 	(void) revive_nasty(x2,y2,(char *)0); 776. 	delallobj(x, y); 777. 	delallobj(x2, y2); 778. 	if ((t = t_at(x, y)) != 0) deltrap(t); 779. 	if ((t = t_at(x2, y2)) != 0) deltrap(t); 780. 	newsym(x, y); 781. 	newsym(x2, y2); 782. 	block_point(x2,y2);	/* vision */ 783. }  784.   785.  /*  786.   * Open the drawbridge located at x,y 787.  */  788.   789.  void 790. open_drawbridge(x,y) 791. int x,y; 792. {  793.  	register struct rm *lev1, *lev2; 794. 	struct trap *t; 795. 	int x2, y2; 796.  797.  	lev1 = &levl[x][y]; 798. 	if (lev1->typ != DRAWBRIDGE_UP) return; 799. 	x2 = x; y2 = y;  800. get_wall_for_db(&x2,&y2); 801. 	if (cansee(x,y) || cansee(x2,y2)) 802. 		You("see a drawbridge %s down!",  803.  		    (distu(x2,y2) < distu(x,y)) ? "going" : "coming"); 804. 	lev1->typ = DRAWBRIDGE_DOWN; 805. 	lev2 = &levl[x2][y2]; 806. 	lev2->typ = DOOR; 807. 	lev2->doormask = D_NODOOR; 808. 	set_entity(x, y, &(occupants[0])); 809. 	set_entity(x2, y2, &(occupants[1])); 810. 	do_entity(&(occupants[0]));		/* do set_entity after first */ 811. 	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tails */ 812. 	do_entity(&(occupants[1])); 813. 	(void) revive_nasty(x,y,(char *)0); 814. 	delallobj(x, y); 815. 	if ((t = t_at(x, y)) != 0) deltrap(t); 816. 	if ((t = t_at(x2, y2)) != 0) deltrap(t); 817. 	newsym(x, y); 818. 	newsym(x2, y2); 819. 	unblock_point(x2,y2);	/* vision */ 820. 	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE; 821. }  822.   823.  /*  824.   * Let's destroy the drawbridge located at x,y 825.  */  826.   827.  void 828. destroy_drawbridge(x,y) 829. int x,y; 830. {  831.  	register struct rm *lev1, *lev2; 832. 	struct trap *t; 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. 	if ((t = t_at(x, y)) != 0) deltrap(t); 880. 	if ((t = t_at(x2, y2)) != 0) deltrap(t); 881. 	newsym(x,y); 882. 	newsym(x2,y2); 883. 	if (!does_block(x2,y2,lev2)) unblock_point(x2,y2);	/* vision */ 884. 	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE; 885.  886.  	set_entity(x2, y2, etmp2); /* currently only automissers can be here */ 887. 	if (etmp2->edata) { 888. 		e_inview = e_canseemon(etmp2); 889. 		if (!automiss(etmp2)) { 890. 			if (e_inview) 891. 				pline("%s blown apart by flying debris.",  892.  				      E_phrase(etmp2, "are")); 893. 			killer_format = KILLED_BY_AN; 894. 			killer = "exploding drawbridge"; 895. 			e_died(etmp2, e_inview? 3 : 2, CRUSHING); /*no corpse*/ 896. 		}	     /* nothing which is vulnerable can survive this */ 897. 	}  898.  	set_entity(x, y, etmp1); 899. 	if (etmp1->edata) { 900. 		e_inview = e_canseemon(etmp1); 901. 		if (e_missed(etmp1, TRUE)) { 902. #ifdef D_DEBUG 903. 			pline("%s spared!", E_phrase(etmp1, "are")); 904. #endif 905. 		} else { 906. 			if (e_inview) { 907. 			    if (!is_u(etmp1) && Hallucination) 908. 				pline("%s into some heavy metal!",  909.  				      E_phrase(etmp1, "get")); 910. 			    else 911. 				pline("%s hit by a huge chunk of metal!",  912.  				      E_phrase(etmp1, "are")); 913. 			} else { 914. 			    if (flags.soundok && !is_u(etmp1) && !is_pool(x,y)) 915. 				You_hear("a crushing sound."); 916. #ifdef D_DEBUG 917. 			    else 918. 				pline("%s from shrapnel",  919.  				      E_phrase(etmp1, "die")); 920. #endif 921. 			}  922.  			killer_format = KILLED_BY_AN; 923. 			killer = "collapsing drawbridge"; 924. 			e_died(etmp1, e_inview? 3 : 2, CRUSHING); /*no corpse*/ 925. 			if(lev1->typ == MOAT) do_entity(etmp1); 926. 		}  927.  	}  928.  }  929.   930.  #endif /* OVLB */ 931.  932.  /*dbridge.c*/