Source:NetHack 3.3.0/dbridge.c

Below is the full text to dbridge.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.3	97/05/25	*/ 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.          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_OVL 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_OVL 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_OVL 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_OVL 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 = youmonst.data; 274. }  275.   276.  STATIC_OVL 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_OVL 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_OVL 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_OVL 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 || Swimming ||  380.  				Flying || Levitation)) ||  381.  			is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||  382.  			is_floater(etmp->edata)); 383. 	/* must force call to lava_effects in e_died if is_u */ 384. 	if (is_lava(x, y)) 385. 		return (boolean)((is_u(etmp) && (Levitation || Flying)) ||  386.  			    likes_lava(etmp->edata) || is_flyer(etmp->edata)); 387. 	if (is_db_wall(x, y)) 388. 		return((boolean)(is_u(etmp) ? Passes_walls : 389. 			passes_walls(etmp->edata))); 390. 	return(TRUE); 391. }  392.   393.  STATIC_OVL void 394. e_died(etmp, dest, how) 395. struct entity *etmp; 396. int dest, how; 397. {  398.  	if (is_u(etmp)) { 399. 		if (how == DROWNING) 400. 			(void) drown; 401. 		else if (how == BURNING) 402. 			(void) lava_effects; 403. 		else { 404. 			coord xy; 405.  406.  			killer_format = KILLED_BY_AN; 407. 			killer = "falling drawbridge"; 408. 			done(how); 409. 			/* So, you didn't die */ 410. 			if (!e_survives_at(etmp, etmp->ex, etmp->ey)) { 411. 			    if (enexto(&xy, etmp->ex, etmp->ey, etmp->edata)) { 412. 				pline("A %s force teleports you away...",  413.  				      Hallucination ? "normal" : "strange"); 414. 				teleds(xy.x, xy.y); 415. 			    }  416.  			    /* otherwise on top of the drawbridge is the 417. 			     * only viable spot in the dungeon, so stay there 418. 			     */  419.  			}  420.  		}  421.  		/* we might have crawled out of the moat to survive */ 422. 		etmp->ex = u.ux,  etmp->ey = u.uy; 423. 	} else { 424. 		/* fake "digested to death" damage-type suppresses corpse */ 425. #define mk_message(dest) ((dest & 1) ? "" : (char *)0) 426. #define mk_corpse(dest)  ((dest & 2) ? AD_DGST : AD_PHYS) 427. 		/* if monsters are moving, one of them caused the destruction */ 428. 		if (flags.mon_moving) 429. 		    monkilled(etmp->emon, mk_message(dest), mk_corpse(dest)); 430. 		else		/* you caused it */ 431. 		    xkilled(etmp->emon, dest); 432. 		etmp->edata = (struct permonst *)0; 433. #undef mk_message 434. #undef mk_corpse 435. 	}  436.  }  437.   438.   439.  /*  440.   * These are never directly affected by a bridge or portcullis. 441.  */  442.   443.  STATIC_OVL boolean 444. automiss(etmp) 445. struct entity *etmp; 446. {  447.  	return (boolean)((is_u(etmp) ? Passes_walls : 448. 			passes_walls(etmp->edata)) || noncorporeal(etmp->edata)); 449. }  450.   451.  /*  452.   * Does falling drawbridge or portcullis miss etmp? 453.  */  454.   455.  STATIC_OVL boolean 456. e_missed(etmp, chunks) 457. struct entity *etmp; 458. boolean chunks; 459. {  460.  	int misses; 461.  462.  #ifdef D_DEBUG 463. 	if (chunks) 464. 		pline("Do chunks miss?"); 465. #endif 466. 	if (automiss(etmp)) 467. 		return(TRUE); 468.  469.  	if (is_flyer(etmp->edata) &&  470.  	    (is_u(etmp)? !Sleeping : 471. 	     (etmp->emon->mcanmove && !etmp->emon->msleeping))) 472. 						 /* flying requires mobility */ 473. 		misses = 5;	/* out of 8 */ 474. 	else if (is_floater(etmp->edata) ||  475.  		    (is_u(etmp) && Levitation))	 /* doesn't require mobility */ 476. 		misses = 3; 477. 	else if (chunks && is_pool(etmp->ex, etmp->ey)) 478. 		misses = 2;				    /* sitting ducks */ 479. 	else 480. 		misses = 0; 481.  482.  	if (is_db_wall(etmp->ex, etmp->ey)) 483. 		misses -= 3;				    /* less airspace */ 484.  485.  #ifdef D_DEBUG 486. 	pline("Miss chance = %d (out of 8)", misses); 487. #endif 488.  489.  	return((boolean)((misses >= rnd(8))? TRUE : FALSE)); 490. }  491.   492.  /*  493.   * Can etmp jump from death? 494.  */  495.   496.  STATIC_OVL boolean 497. e_jumps(etmp) 498. struct entity *etmp; 499. {  500.  	int tmp = 4;		/* out of 10 */ 501.  502.  	if (is_u(etmp)? (Sleeping || Fumbling) :  503.  		        (!etmp->emon->mcanmove || etmp->emon->msleeping || 504. 			 !etmp->edata->mmove   || etmp->emon->wormno)) 505. 		return(FALSE); 506.  507.  	if (is_u(etmp)? Confusion : etmp->emon->mconf) 508. 		tmp -= 2; 509.  510.  	if (is_u(etmp)? Stunned : etmp->emon->mstun) 511. 		tmp -= 3; 512.  513.  	if (is_db_wall(etmp->ex, etmp->ey)) 514. 		tmp -= 2;			    /* less room to maneuver */ 515.  516.  #ifdef D_DEBUG 517. 	pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp); 518. #endif 519. 	return((boolean)((tmp >= rnd(10))? TRUE : FALSE)); 520. }  521.   522.  STATIC_OVL void 523. do_entity(etmp) 524. struct entity *etmp; 525. {  526.  	int newx, newy, at_portcullis, oldx, oldy; 527. 	boolean must_jump = FALSE, relocates = FALSE, e_inview; 528. 	struct rm *crm; 529.  530.  	if (!etmp->edata) 531. 		return; 532.  533.  	e_inview = e_canseemon(etmp); 534. 	oldx = etmp->ex; 535. 	oldy = etmp->ey; 536. 	at_portcullis = is_db_wall(oldx, oldy); 537. 	crm = &levl[oldx][oldy]; 538.  539.  	if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) { 540. 		if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ))) 541. 			pline_The("%s passes through %s!",  542.  			      at_portcullis ? "portcullis" : "drawbridge",  543.  			      e_nam(etmp)); 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*/