abstract
| - 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*/
|