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