PropertyValue
rdfs:label
  • Source:NetHack 3.4.0/dbridge.c
rdfs:comment
  • 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
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • 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*/