Source:NetHack 3.1.0/dbridge.c

Below is the full text to dbridge.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/10/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 *, XCHAR_P, XCHAR_P, struct entity *)); 19.  static void FDECL(u_to_e, (struct entity *)); 20.  static void FDECL(set_entity, (int, int, struct entity *)); 21.  static char *FDECL(e_nam, (struct entity *)); 22.  #ifdef D_DEBUG 23.  static char *FDECL(Enam, (struct entity *)); /* unused */ 24.  #endif 25.  static 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( 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].diggable = 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 struct entity NEARDATA 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. xchar 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 284. 		if (MON_AT(x, y)) 285. 			m_to_e(m_at(x, y), x, y, etmp); 286. 		else 287. 			etmp->edata = (struct permonst *)0; 288. }  289.   290.  #define is_u(etmp) (etmp->emon == &youmonst) 291. #define e_canseemon(etmp) (is_u(etmp) ? (boolean)TRUE : canseemon(etmp->emon)) 292.  293.  /*  294.   * e_strg is a utility routine which is not actually in use anywhere, since 295.  * the specialized routines below suffice for all current purposes. 296.  */  297.   298.  /* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */ 299.  300.  static char * 301. e_nam(etmp) 302. struct entity *etmp; 303. {  304.  	return(is_u(etmp)? "you" : mon_nam(etmp->emon)); 305. }  306.   307.  #ifdef D_DEBUG 308. /*  309.   * Enam is another unused utility routine:  E_phrase is preferable. 310.  */  311.   312.  static char * 313. Enam(etmp) 314. struct entity *etmp; 315. {  316.  	return(is_u(etmp)? "You" : Monnam(etmp->emon)); 317. }  318.  #endif /* D_DEBUG */ 319.  320.  /*  321.   * Generates capitalized entity name, makes 2nd -> 3rd person conversion on  322. * verb, where necessary. 323.  */  324.   325.  static char * 326. E_phrase(etmp, verb) 327. struct entity *etmp; 328. const char *verb; 329. {  330.  	static char wholebuf[80]; 331. 	char verbbuf[30]; 332.  333.  	if (is_u(etmp)) 334. 		Strcpy(wholebuf, "You"); 335. 	else 336. 		Strcpy(wholebuf, Monnam(etmp->emon)); 337. 	if (!*verb) 338. 		return(wholebuf); 339. 	Strcat(wholebuf, " "); 340. 	verbbuf[0] = '\0'; 341. 	if (is_u(etmp)) 342. 		Strcpy(verbbuf, verb); 343. 	else { 344. 		if (!strcmp(verb, "are")) 345. 			Strcpy(verbbuf, "is"); 346. 		if (!strcmp(verb, "have")) 347. 			Strcpy(verbbuf, "has"); 348. 		if (!verbbuf[0]) { 349. 			Strcpy(verbbuf, verb); 350. 			switch (verbbuf[strlen(verbbuf) - 1]) { 351. 				case 'y': 352. 					verbbuf[strlen(verbbuf) - 1] = '\0'; 353. 					Strcat(verbbuf, "ies"); 354. 					break; 355. 				case 'h': 356. 				case 'o': 357. 				case 's': 358. 					Strcat(verbbuf, "es"); 359. 					break; 360. 				default: 361. 					Strcat(verbbuf, "s"); 362. 					break; 363. 			}  364.  		}  365.  	}  366.  	Strcat(wholebuf, verbbuf); 367. 	return(wholebuf); 368. }  369.   370.  /*  371.   * Simple-minded "can it be here?" routine 372.  */  373.   374.  static boolean 375. e_survives_at(etmp, x, y)  376. struct entity *etmp; 377. int x, y;  378. { 379.  	if (noncorporeal(etmp->edata)) 380. 		return(TRUE); 381. 	if (is_pool(x, y)) 382. 		return((is_u(etmp) && (Wwalking || Magical_breathing || Levitation)) ||  383.  		       is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||  384.  		       is_floater(etmp->edata)); 385. 	/* must force call to lava_effects in e_died if is_u */ 386. 	if (is_lava(x, y)) 387. 		return(is_u(etmp) ? !!Levitation : resists_fire(etmp->edata)); 388. 	if (is_db_wall(x, y)) 389. 		return(passes_walls(etmp->edata)); 390. 	return(TRUE); 391. }  392.   393.  static 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. 		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, 412. 							    etmp->edata)) { 413. 				pline("A %s force teleports you away...",  414.  				      Hallucination ? "normal" : "strange"); 415. 				teleds(xy.x, xy.y); 416. 			    }  417.  			    /* otherwise on top of the drawbridge is the 418. 			     * only viable spot in the dungeon, so stay there 419. 			     */  420.  			}  421.  		}  422.  	} else { 423. 		xkilled(etmp->emon, dest); 424. 		etmp->edata = (struct permonst *)0; 425. 	}  426.  }  427.   428.   429.  /*  430.   * These are never directly affected by a bridge or portcullis. 431.  */  432.   433.  static boolean 434. automiss(etmp) 435. struct entity *etmp; 436. {  437.  	return(passes_walls(etmp->edata) || noncorporeal(etmp->edata)); 438. }  439.   440.  /*  441.   * Does falling drawbridge or portcullis miss etmp? 442.  */  443.   444.  static boolean 445. e_missed(etmp, chunks) 446. struct entity *etmp; 447. boolean chunks; 448. {  449.  	int misses; 450.  451.  #ifdef D_DEBUG 452. 	if (chunks) 453. 		pline("Do chunks miss?"); 454. #endif 455. 	if (automiss(etmp)) 456. 		return(TRUE); 457.  458.  	if (is_flyer(etmp->edata) &&  459.  	    (is_u(etmp)? !Sleeping : 460. 	     (etmp->emon->mcanmove && !etmp->emon->msleep))) 461. 						 /* flying requires mobility */ 462. 		misses = 5;	/* out of 8 */ 463. 	else 464. 		if (is_floater(etmp->edata) ||  465.  		    (is_u(etmp) && Levitation))	 /* doesn't require mobility */ 466. 			misses = 3; 467. 		else 468. 			if (chunks && is_pool(etmp->ex, etmp->ey)) 469. 				misses = 2; 		    /* sitting ducks */ 470. 			else 471. 				misses = 0; 472.  473.  	if (is_db_wall(etmp->ex, etmp->ey)) 474. 		misses -= 3;				    /* less airspace */ 475.  476.  #ifdef D_DEBUG 477. 	pline("Miss chance = %d (out of 8)", misses); 478. #endif 479.  480.  	return((misses >= rnd(8))? TRUE : FALSE); 481. }  482.   483.  /*  484.   * Can etmp jump from death? 485.  */  486.   487.  static boolean 488. e_jumps(etmp) 489. struct entity *etmp; 490. {  491.  	int tmp = 4; 		/* out of 10 */ 492.  493.  	if (is_u(etmp)? (Sleeping || Fumbling) :  494.  		        (!etmp->emon->mcanmove || etmp->emon->msleep || 495. 			 !etmp->edata->mmove   || etmp->emon->wormno)) 496. 		return(FALSE); 497.  498.  	if (is_u(etmp)? Confusion : etmp->emon->mconf) 499. 		tmp -= 2; 500.  501.  	if (is_u(etmp)? Stunned : etmp->emon->mstun) 502. 		tmp -= 3; 503.  504.  	if (is_db_wall(etmp->ex, etmp->ey)) 505. 		tmp -= 2;			    /* less room to maneuver */ 506. 	  507.  #ifdef D_DEBUG 508. 	pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp); 509. #endif 510. 	return((tmp >= rnd(10))? TRUE : FALSE); 511. }  512.   513.  static void 514. do_entity(etmp) 515. struct entity *etmp; 516. {  517.  	int newx, newy, at_portcullis, oldx, oldy; 518. 	boolean must_jump = FALSE, relocates = FALSE, e_inview; 519. 	struct rm *crm; 520.  521.  	if (!etmp->edata) 522. 		return; 523.  524.  	e_inview = e_canseemon(etmp); 525.  526.  	oldx = etmp->ex; 527. 	oldy = etmp->ey; 528.  529.  	at_portcullis = is_db_wall(oldx, oldy); 530.  531.  	crm = &levl[oldx][oldy]; 532.  533.  	if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) { 534. 		char edifice[20]; 535.  536.  		if (e_inview) { 537. 			*edifice = '\0'; 538. 			if ((crm->typ == DRAWBRIDGE_DOWN) ||  539.  		    	    (crm->typ == DRAWBRIDGE_UP)) 540. 				Strcpy(edifice, "drawbridge"); 541. 			else 542.      				if (at_portcullis) 543. 					Strcpy(edifice, "portcullis"); 544. 			if (*edifice) 545. 				pline("The %s passes through %s!", edifice,  546.  			      	      e_nam(etmp)); 547. 		}  548.  		return; 549. 	}  550.  	if (e_missed(etmp, FALSE)) { 551. 		if (at_portcullis) 552. 			pline("The portcullis misses %s!",  553.  			      e_nam(etmp)); 554. #ifdef D_DEBUG 555. 		else 556. 			pline("The drawbridge misses %s!",  557.  			      e_nam(etmp)); 558. #endif 559. 		if (e_survives_at(etmp, oldx, oldy)) 560. 			return; 561. 		else { 562. #ifdef D_DEBUG 563. 			pline("Mon can't survive here"); 564. #endif 565. 			if (at_portcullis) 566. 				must_jump = TRUE; 567. 			else 568. 				relocates = TRUE; /* just ride drawbridge in */ 569. 		}  570.  	} else { 571. 		if (crm->typ == DRAWBRIDGE_DOWN) { 572. 			pline("%s crushed underneath the drawbridge.",  573.  		      	      E_phrase(etmp, "are"));	   	  /* no jump */ 574. 			e_died(etmp, e_inview? 3 : 2, CRUSHING);/* no corpse */ 575. 			return;   /* Note: Beyond this point, we know we're  */ 576. 		}                 /* not at an opened drawbridge, since all  */ 577. 		must_jump = TRUE; /* *missable* creatures survive on the     */ 578. 	}			  /* square, and all the unmissed ones die. */ 579.  	if (must_jump) { 580. 	    if (at_portcullis) { 581. 		if (e_jumps(etmp)) { 582. 		    relocates = TRUE; 583. #ifdef D_DEBUG 584. 		    pline("Jump succeeds!"); 585. #endif 586. 		} else { 587. 		    if (e_inview) 588. 			pline("%s crushed by the falling portcullis!",  589.  			      E_phrase(etmp, "are")); 590. 		    else if (flags.soundok) 591. 			You("hear a crushing sound."); 592. 		    e_died(etmp, e_inview? 3 : 2, CRUSHING); 593. 		    /* no corpse */ 594. 		    return; 595. 		}  596.  	    } else { /* tries to jump off bridge to original square */ 597. 		relocates = !e_jumps(etmp); 598. #ifdef D_DEBUG 599. 		pline("Jump %s!", (relocates)? "fails" : "succeeds"); 600. #endif 601. 	    }  602.  	}  603.   604.  /*  605.   * Here's where we try to do relocation. Assumes that etmp is not arriving 606.  * at the portcullis square while the drawbridge is falling, since this square 607.  * would be inaccessible (i.e. etmp started on drawbridge square) or  608. * unnecessary (i.e. etmp started here) in such a situation. 609.  */  610.  #ifdef D_DEBUG 611. 	pline("Doing relocation."); 612. #endif 613. 	newx = oldx; 614. 	newy = oldy; 615. 	(void)find_drawbridge(&newx, &newy); 616. 	if ((newx == oldx) && (newy == oldy)) 617. 		get_wall_for_db(&newx, &newy); 618. #ifdef D_DEBUG 619. 	pline("Checking new square for occupancy."); 620. #endif 621. 	if (relocates && (e_at(newx, newy))) { 622.  623.  /*  624.   * Standoff problem:  one or both entities must die, and/or both switch 625.  * places. Avoid infinite recursion by checking first whether the other 626.  * entity is staying put. Clean up if we happen to move/die in recursion. 627.  */  628.  		struct entity *other; 629.  630.  		other = e_at(newx, newy); 631. #ifdef D_DEBUG 632. 		pline("New square is occupied by %s", e_nam(other)); 633. #endif 634. 		if (e_survives_at(other, newx, newy) && automiss(other)) { 635. 			relocates = FALSE;     	      /* "other" won't budge */ 636. #ifdef D_DEBUG 637. 			pline("%s suicide.", E_phrase(etmp, "commit")); 638. #endif 639. 		} else { 640.  641.  #ifdef D_DEBUG 642. 			pline("Handling %s", e_nam(other)); 643. #endif 644. 			while ((e_at(newx, newy)) &&  645.  			       (e_at(newx, newy) != etmp)) 646. 		       		do_entity(other); 647. #ifdef D_DEBUG 648. 			pline("Checking existence of %s", e_nam(etmp)); 649. 			wait_synch; 650. #endif 651. 			if (e_at(oldx, oldy) != etmp) { 652. #ifdef D_DEBUG 653. 			    pline("%s moved or died in recursion somewhere",  654.  				  E_phrase(etmp, "have")); 655. 			    wait_synch; 656. #endif 657. 			    return; 658. 			}  659.  		}  660.  	}  661.  	if (relocates && !e_at(newx, newy)) {/* if e_at entity = worm tail */ 662. #ifdef D_DEBUG 663. 		pline("Moving %s", e_nam(etmp)); 664. #endif 665. 		if (!is_u(etmp)) { 666. 			remove_monster(etmp->ex, etmp->ey); 667. 			place_monster(etmp->emon, newx, newy); 668. 		} else { 669. 			u.ux = newx; 670. 			u.uy = newy; 671. 		}  672.  		etmp->ex = newx; 673. 		etmp->ey = newy; 674. 		e_inview = e_canseemon(etmp); 675. 	}  676.  #ifdef D_DEBUG 677. 	pline("Final disposition of %s", e_nam(etmp)); 678. 	wait_synch; 679. #endif 680. 	if (is_db_wall(etmp->ex, etmp->ey)) { 681. #ifdef D_DEBUG 682. 		pline("%s in portcullis chamber", E_phrase(etmp, "are")); 683. 		wait_synch; 684. #endif 685. 		if (e_inview) { 686. 			if (is_u(etmp)) { 687. 				You("tumble towards the closed portcullis!"); 688. 				if (automiss(etmp)) 689. 					You("pass through it!"); 690. 				else 691. 					pline("The drawbridge closes in..."); 692. 			} else 693. 				pline("%s behind the drawbridge.",  694.  		      	      	      E_phrase(etmp, "disappear")); 695. 		}  696.  		if (!e_survives_at(etmp, etmp->ex, etmp->ey)) { 697. 			killer_format = KILLED_BY_AN; 698. 			killer = "closing drawbridge"; 699. 			e_died(etmp, 0, CRUSHING); 	       /* no message */ 700. 			return; 701. 		}  702.  #ifdef D_DEBUG 703. 		pline("%s in here", E_phrase(etmp, "survive")); 704. #endif 705. 	} else { 706. #ifdef D_DEBUG 707. 		pline("%s on drawbridge square", E_phrase(etmp, "are")); 708. #endif 709. 		if (is_pool(etmp->ex, etmp->ey) && !e_inview) 710. 			if (flags.soundok) 711. 				You("hear a splash."); 712. 		if (e_survives_at(etmp, etmp->ex, etmp->ey)) { 713. 			if (e_inview && !is_flyer(etmp->edata) &&  714.  			    !is_floater(etmp->edata)) 715. 				pline("%s from the bridge.",  716.  		      	      	      E_phrase(etmp, "fall")); 717. 			return; 718. 		}  719.  #ifdef D_DEBUG 720. 		pline("%s cannot survive on the drawbridge square",Enam(etmp)); 721. #endif 722. 		if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey)) 723. 		    if (e_inview && !is_u(etmp)) { 724. 			/* drown will supply msgs if nec. */ 725.  			boolean lava = is_lava(etmp->ex, etmp->ey); 726.  727.  			if (Hallucination) 728. 			    pline("%s the %s and disappears.",  729.  				  E_phrase(etmp, "drink"),  730.  				  lava ? "lava" : "moat"); 731. 			else 732. 			    pline("%s into the %s.",  733.  				  E_phrase(etmp, "fall"),  734.  				  lava ? "lava" : "moat"); 735. 		    }  736.  		killer_format = NO_KILLER_PREFIX; 737. 		killer = "fell from a drawbridge"; 738. 		e_died(etmp, e_inview ? 3 : 2,      /* CRUSHING is arbitrary */  739.  		       (is_pool(etmp->ex, etmp->ey)) ? DROWNING :  740.  		       (is_lava(etmp->ex, etmp->ey)) ? BURNING :  741.  						       CRUSHING); /*no corpse*/ 742. 		return; 743. 	}  744.  }  745.   746.  /*  747.   * Close the drawbridge located at x,y 748.  */  749.   750.  void 751. close_drawbridge(x,y) 752. int x,y; 753. {  754.  	register struct rm *lev1, *lev2; 755. 	int x2, y2; 756.  757.  	lev1 = &levl[x][y]; 758. 	if (lev1->typ != DRAWBRIDGE_DOWN) return; 759. 	x2 = x; y2 = y;  760. get_wall_for_db(&x2,&y2); 761. 	if (cansee(x,y))  /* change msgs if you are a w-walker at portcullis */ 762. 		You("see a drawbridge %s up!",  763.  		    ((u.ux == x2) && (u.uy == y2))? "coming" : "going"); 764. 	lev1->typ = DRAWBRIDGE_UP; 765. 	lev2 = &levl[x2][y2]; 766. 	lev2->typ = DBWALL; 767. 	switch (lev1->drawbridgemask & DB_DIR) { 768. 		case DB_NORTH: 769. 		case DB_SOUTH: 770. 			lev2->horizontal = TRUE; 771. 			break; 772. 		case DB_WEST: 773. 		case DB_EAST: 774. 			lev2->horizontal = FALSE; 775. 			break; 776. 	}  777.  	lev2->diggable = W_NONDIGGABLE; 778. 	set_entity(x, y, &(occupants[0])); 779. 	set_entity(x2, y2, &(occupants[1])); 780. 	do_entity(&(occupants[0]));		/* Do set_entity after first */ 781. 	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tail */ 782. 	do_entity(&(occupants[1])); 783. 	if(OBJ_AT(x,y) && flags.soundok) 784. 	    You("hear smashing and crushing."); 785. 	(void) revive_nasty(x,y,NULL); 786. 	(void) revive_nasty(x2,y2,NULL); 787. 	delallobj(x, y); 788. 	newsym(x, y); 789. 	delallobj(x2, y2); 790. 	newsym(x2, y2); 791. 	block_point(x2,y2);	/* vision */ 792. }  793.   794.  /*  795.   * Open the drawbridge located at x,y 796.  */  797.   798.  void 799. open_drawbridge(x,y) 800. int x,y; 801. {  802.  	register struct rm *lev1, *lev2; 803. 	int x2, y2; 804.  805.  	lev1 = &levl[x][y]; 806. 	if (lev1->typ != DRAWBRIDGE_UP) return; 807. 	x2 = x; y2 = y;  808. get_wall_for_db(&x2,&y2); 809. 	if (cansee(x,y))  /* change msgs if you are a w-walker at portcullis */ 810. 		You("see a drawbridge %s down!",  811.  		    ((x2 == u.ux) && (y2 == u.uy))? "going" : "coming"); 812. 	lev1->typ = DRAWBRIDGE_DOWN; 813. 	lev2 = &levl[x2][y2]; 814. 	lev2->typ = DOOR; 815. 	lev2->doormask = D_NODOOR; 816. 	set_entity(x, y, &(occupants[0])); 817. 	set_entity(x2, y2, &(occupants[1])); 818. 	do_entity(&(occupants[0]));		/* do set_entity after first */ 819. 	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tails */ 820. 	do_entity(&(occupants[1])); 821. 	spoteffects;  /* if underwater, hero is now on solid ground */ 822. 	(void) revive_nasty(x,y,NULL); 823. 	delallobj(x, y); 824. 	newsym(x, y); 825. 	newsym(x2, y2); 826. 	unblock_point(x2,y2);	/* vision */ 827. 	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE; 828. }  829.   830.  /*  831.   * Let's destroy the drawbridge located at x,y 832.  */  833.   834.  void 835. destroy_drawbridge(x,y) 836. int x,y; 837. {  838.  	register struct rm *lev1, *lev2; 839. 	int x2, y2; 840. 	boolean e_inview; 841. 	struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]); 842.  843.  	lev1 = &levl[x][y]; 844. 	if (!IS_DRAWBRIDGE(lev1->typ)) 845. 		return; 846. 	x2 = x; y2 = y;  847. get_wall_for_db(&x2,&y2); 848. 	lev2 = &levl[x2][y2]; 849. 	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT ||  850.  	    (lev1->drawbridgemask & DB_UNDER) == DB_LAVA) { 851. 		struct obj *otmp; 852. 		boolean lava = (lev1->drawbridgemask & DB_UNDER) == DB_LAVA; 853. 		if (lev1->typ == DRAWBRIDGE_UP) { 854. 			if (cansee(x2,y2)) 855. 			    pline("The portcullis of the drawbridge falls into the %s!",  856.  				  lava ? "lava" : "moat"); 857. 			else if (flags.soundok) 858. 				You("hear a loud *SPLASH*!"); 859. 		} else { 860. 			if (cansee(x,y)) 861. 			    pline("The drawbridge collapses into the %s!",  862.  				  lava ? "lava" : "moat"); 863. 			else if (flags.soundok) 864. 				You("hear a loud *SPLASH*!"); 865. 		}  866.  		lev1->typ = lava ? LAVAPOOL : MOAT; 867. 		lev1->drawbridgemask = 0; 868. 		if(otmp = sobj_at(BOULDER,x,y)) { 869. 		    freeobj(otmp); 870. 		    (void) flooreffects(otmp,x,y,"fall"); 871. 		}  872.  	} else { 873. 		if (cansee(x,y)) 874. 			pline("The drawbridge disintegrates!"); 875. 		else 876. 			You("hear a loud *CRASH*!"); 877. 		lev1->typ = 878. 			((lev1->drawbridgemask & DB_ICE) ? ICE : ROOM); 879. 		lev1->icedpool = 880. 			((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0); 881. 	}  882.  	wake_nearby; 883. 	lev2->typ = DOOR; 884. 	lev2->doormask = D_NODOOR; 885. 	newsym(x,y); 886. 	newsym(x2,y2); 887. 	if (!does_block(x2,y2,lev2)) unblock_point(x2,y2);	/* vision */ 888. 	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE; 889.  890.  	set_entity(x2, y2, etmp2); /* currently only automissers can be here */ 891. 	if (etmp2->edata) { 892. 		e_inview = e_canseemon(etmp2); 893. 		if (!automiss(etmp2)) { 894. 			if (e_inview) 895. 				pline("%s blown apart by flying debris.",  896.  			      	      E_phrase(etmp2, "are")); 897. 			killer_format = KILLED_BY_AN; 898. 			killer = "exploding drawbridge"; 899. 			e_died(etmp2, e_inview? 3 : 2, CRUSHING); /*no corpse*/ 900. 		}	     /* nothing which is vulnerable can survive this */ 901. 	}  902.  	set_entity(x, y, etmp1); 903. 	if (etmp1->edata) { 904. 		e_inview = e_canseemon(etmp1); 905. 		if (e_missed(etmp1, TRUE)) { 906. #ifdef D_DEBUG 907. 			pline("%s spared!", E_phrase(etmp1, "are")); 908. #endif 909. 		} else { 910. 			if (e_inview) { 911. 			    if (!is_u(etmp1) && Hallucination) 912. 				pline("%s into some heavy metal",  913.  				      E_phrase(etmp1, "get")); 914. 			    else 915. 				pline("%s hit by a huge chunk of metal!",  916.  				      E_phrase(etmp1, "are")); 917. 			} else { 918. 			    if (flags.soundok && !is_u(etmp1) && !is_pool(x,y)) 919. 				You("hear a crushing sound"); 920. #ifdef D_DEBUG 921. 			    else 922. 				pline("%s from shrapnel",  923.  				      E_phrase(etmp1, "die")); 924. #endif 925. 			}  926.  			killer_format = KILLED_BY_AN; 927. 			killer = "collapsing drawbridge"; 928. 			e_died(etmp1, e_inview? 3 : 2, CRUSHING); /*no corpse*/ 929. 			if(lev1->typ == MOAT) do_entity(etmp1); 930. 		}  931.  	}  932.  }  933.   934.   935.  #endif /* OVLB */ 936.  937.  /*dbridge.c*/