Difference between revisions of "Source:NetHack 3.1.0/trap.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.1.0/trap.c moved to Source:NetHack 3.1.0/trap.c: Robot: moved page) |
(No difference)
|
Latest revision as of 07:41, 4 March 2008
Below is the full text to trap.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/trap.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)trap.c 3.1 92/12/10 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. #ifdef OVLB 8. const char *traps[TRAPNUM] = { 9. "", 10. "n arrow trap", 11. " dart trap", 12. " falling rock trap", 13. " squeaky board", 14. " bear trap", 15. " land mine", 16. " sleeping gas trap", 17. " rust trap", 18. " fire trap", 19. " pit", 20. " spiked pit", 21. " trapdoor", 22. " teleportation trap", 23. " level teleporter", 24. " magic portal", 25. " web", 26. " statue trap", 27. " magic trap", 28. "n anti-magic field" 29. #ifdef POLYSELF 30. ," polymorph trap" 31. #endif 32. }; 33. 34. #endif /* OVLB */ 35. 36. static void FDECL(domagicportal,(struct trap *)); 37. static void NDECL(dofiretrap); 38. static void NDECL(domagictrap); 39. static boolean FDECL(emergency_disrobe,(boolean *)); 40. STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int)); 41. 42. #ifdef OVLB 43. 44. static int FDECL(teleok, (int,int,BOOLEAN_P)); 45. static void NDECL(vtele); 46. static void FDECL(no_fall_through, (BOOLEAN_P)); 47. 48. /* Generic rust-armor function. Returns TRUE if a message was printed; 49. * "print", if set, means to print a message (and thus to return TRUE) even 50. * if the item could not be rusted; otherwise a message is printed and TRUE is 51. * returned only for rustable items. 52. */ 53. boolean 54. rust_dmg(otmp, ostr, type, print) 55. register struct obj *otmp; 56. register const char *ostr; 57. int type; 58. boolean print; 59. { 60. static const char NEARDATA *action[] = { "smoulder", "rust", "rot", "corrode" }; 61. static const char NEARDATA *msg[] = { "burnt", "rusted", "rotten", "corroded" }; 62. boolean vulnerable = FALSE; 63. boolean plural; 64. boolean grprot = FALSE; 65. 66. if (!otmp) return(FALSE); 67. switch(type) { 68. case 0: 69. case 2: vulnerable = is_flammable(otmp); break; 70. case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break; 71. case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break; 72. } 73. 74. if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE)) 75. return FALSE; 76. 77. plural = is_gloves(otmp) || is_boots(otmp); 78. 79. if (!vulnerable) 80. if (flags.verbose) 81. Your("%s %s not affected.", ostr, plural ? "are" : "is"); 82. else if (otmp->oeroded < MAX_ERODE) { 83. if (grprot && otmp->greased) 84. grease_protect(otmp,ostr,plural); 85. else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) { 86. if (flags.verbose) 87. pline("Somehow, your %s %s not affected.", 88. ostr, plural ? "are" : "is"); 89. } else { 90. Your("%s %s%s%s!", ostr, action[type], 91. plural ? "" : "s", 92. otmp->oeroded+1 == MAX_ERODE ? " completely" : 93. otmp->oeroded ? " further" : ""); 94. otmp->oeroded++; 95. } 96. } else 97. if (flags.verbose) 98. Your("%s %s%s completely %s.", ostr, 99. Blind ? "feel" : "look", 100. plural ? "" : "s", msg[type]); 101. return(TRUE); 102. } 103. 104. void 105. grease_protect(otmp,ostr,plu) 106. register struct obj *otmp; 107. register const char *ostr; 108. register boolean plu; 109. { 110. static const char txt[] = "protected by the layer of grease!"; 111. 112. if (ostr) 113. Your("%s %s %s",ostr,plu ? "are" : "is",txt); 114. else 115. Your("%s %s",aobjnam(otmp,"are"),txt); 116. if (!rn2(2)) { 117. pline("The grease dissolves."); 118. otmp->greased = 0; 119. } 120. } 121. 122. struct trap * 123. maketrap(x,y,typ) 124. register int x, y, typ; 125. { 126. register struct trap *ttmp; 127. register boolean oldplace; 128. 129. if (ttmp = t_at(x,y)) { 130. oldplace = TRUE; 131. if (u.utrap && (x == u.ux) && (y == u.uy) && 132. ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) || 133. (u.utraptype == TT_WEB && typ != WEB) || 134. (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT))) 135. u.utrap = 0; 136. } else { 137. oldplace = FALSE; 138. ttmp = newtrap(); 139. ttmp->tx = x; 140. ttmp->ty = y; 141. } 142. ttmp->ttyp = typ; 143. switch(typ) { 144. case STATUE_TRAP: /* create a "living" statue */ 145. (void) mkcorpstat(STATUE, &mons[rndmonnum()], x, y, FALSE); 146. break; 147. case PIT: 148. case SPIKED_PIT: 149. case TRAPDOOR: 150. levl[x][y].doormask = 0; /* subsumes altarmask, icedpool... */ 151. if (IS_ROOM(levl[x][y].typ)) 152. levl[x][y].typ = ROOM; 153. break; 154. } 155. ttmp->tseen = 0; 156. ttmp->once = 0; 157. ttmp->dst.dnum = -1; 158. ttmp->dst.dlevel = -1; 159. if (!oldplace) { 160. ttmp->ntrap = ftrap; 161. ftrap = ttmp; 162. } 163. return(ttmp); 164. } 165. 166. static int 167. teleok(x, y, trapok) 168. register int x, y; 169. boolean trapok; 170. { /* might throw him into a POOL 171. * removed by GAN 10/20/86 172. */ 173. #ifdef STUPID 174. boolean tmp1, tmp2, tmp3, tmp4; 175. # ifdef POLYSELF 176. tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) || 177. passes_walls(uasmon)) && !MON_AT(x, y); 178. # else 179. tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y); 180. # endif 181. tmp2 = !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y)); 182. tmp3 = !(is_pool(x,y) && 183. !(Levitation || Wwalking || Magical_breathing 184. # ifdef POLYSELF 185. || is_flyer(uasmon) || is_swimmer(uasmon) 186. || is_clinger(uasmon) 187. # endif 188. )) && !closed_door(x,y); 189. tmp4 = !is_lava(x,y); 190. return(tmp1 && tmp2 && tmp3 && tmp4); 191. #else 192. return( isok(x,y) && 193. # ifdef POLYSELF 194. (!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) && 195. # else 196. !IS_ROCK(levl[x][y].typ) && 197. # endif 198. !MON_AT(x, y) && 199. !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y)) && 200. !(is_pool(x,y) && 201. !(Levitation || Wwalking || Magical_breathing 202. # ifdef POLYSELF 203. || is_flyer(uasmon) || is_swimmer(uasmon) 204. || is_clinger(uasmon) 205. # endif 206. )) && !is_lava(x,y) && !closed_door(x,y)); 207. #endif 208. /* Note: gold is permitted (because of vaults) */ 209. } 210. 211. boolean 212. safe_teleds() 213. { 214. register int nux, nuy; 215. short tcnt = 0; 216. 217. do { 218. nux = rnd(COLNO-1); 219. nuy = rn2(ROWNO); 220. } while (!teleok(nux, nuy, tcnt>200) && tcnt++ < 400); 221. 222. if (tcnt < 400) { 223. teleds(nux, nuy); 224. return TRUE; 225. } else 226. return FALSE; 227. } 228. 229. static void 230. vtele() 231. { 232. register struct mkroom *croom = search_special(VAULT); 233. coord c; 234. 235. if(croom && somexy(croom, &c) && teleok(c.x,c.y,FALSE)) { 236. teleds(c.x,c.y); 237. return; 238. } 239. tele(); 240. } 241. 242. static void 243. no_fall_through(td) 244. boolean td; 245. { 246. /* floor objects get a chance of falling down. the case 247. * where the hero does NOT fall down is treated here. the 248. * case where the hero does fall down is treated in goto_level(). 249. * reason: the target level of the fall is not determined here, 250. * and it need not be the next level. if we want falling 251. * objects to arrive near the player, we must call impact_drop() 252. * _after_ the target level is determined. 253. */ 254. impact_drop((struct obj *)0, u.ux, u.uy, 0); 255. if (!td) { 256. display_nhwindow(WIN_MESSAGE, FALSE); 257. pline("The opening under you closes up."); 258. } 259. } 260. 261. void 262. fall_through(td) 263. boolean td; /* td == TRUE : trapdoor */ 264. { 265. register int newlevel = dunlev(&u.uz); 266. 267. if(Blind && Levitation) return; 268. 269. do { 270. newlevel++; 271. } while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz)); 272. 273. if(td) pline("A trap door opens up under you!"); 274. else pline("The floor opens up under you!"); 275. 276. if(Levitation || u.ustuck || !Can_fall_thru(&u.uz) 277. #ifdef POLYSELF 278. || is_flyer(uasmon) || is_clinger(uasmon) 279. #endif 280. || (Inhell && !u.uevent.invoked && 281. newlevel == dunlevs_in_dungeon(&u.uz)) 282. ) { 283. You("don't fall in."); 284. no_fall_through(td); 285. return; 286. } 287. #ifdef WALKIES 288. if(!next_to_u()) { 289. You("are jerked back by your pet!"); 290. no_fall_through(td); 291. return; 292. } 293. #endif 294. if(*u.ushops) shopdig(1); 295. if(Is_stronghold(&u.uz)) goto_hell(TRUE, TRUE); 296. else { 297. d_level dtmp; 298. dtmp.dnum = u.uz.dnum; 299. dtmp.dlevel = newlevel; 300. goto_level(&dtmp, FALSE, TRUE, FALSE); 301. if(!td) pline("The hole in the ceiling above you closes up."); 302. } 303. } 304. 305. void 306. dotrap(trap) 307. register struct trap *trap; 308. { 309. register int ttype = trap->ttyp; 310. register struct monst *mtmp; 311. register struct obj *otmp; 312. 313. nomul(0); 314. if(trap->tseen && !Fumbling && 315. #ifdef POLYSELF 316. !((ttype == PIT || ttype == SPIKED_PIT) && !is_clinger(uasmon)) && 317. #else 318. !(ttype == PIT || ttype == SPIKED_PIT) && 319. #endif 320. !(ttype == MAGIC_PORTAL || ttype == ANTI_MAGIC) && !rn2(5)) 321. You("escape a%s.", traps[ttype]); 322. else { 323. seetrap(trap); 324. switch(ttype) { 325. case ARROW_TRAP: 326. pline("An arrow shoots out at you!"); 327. otmp = mksobj(ARROW, TRUE, FALSE); 328. otmp->quan = 1L; 329. otmp->owt = weight(otmp); 330. if(thitu(8,dmgval(otmp,uasmon),otmp,"arrow")) 331. obfree(otmp, (struct obj *)0); 332. else { 333. place_object(otmp, u.ux, u.uy); 334. otmp->nobj = fobj; 335. fobj = otmp; 336. stackobj(otmp); 337. newsym(u.ux, u.uy); 338. } 339. break; 340. case DART_TRAP: 341. pline("A little dart shoots out at you!"); 342. otmp = mksobj(DART, TRUE, FALSE); 343. otmp->quan = 1L; 344. otmp->owt = weight(otmp); 345. if (!rn2(6)) otmp->opoisoned = 1; 346. if(thitu(7,dmgval(otmp,uasmon),otmp,"little dart")) { 347. if (otmp->opoisoned) 348. poisoned("dart",A_CON,"poison dart",10); 349. obfree(otmp, (struct obj *)0); 350. } else { 351. place_object(otmp, u.ux, u.uy); 352. otmp->nobj = fobj; 353. fobj = otmp; 354. stackobj(otmp); 355. newsym(u.ux, u.uy); 356. } 357. break; 358. case ROCKTRAP: 359. { 360. int dmg = d(2,6); /* should be std ROCK dmg? */ 361. 362. otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE); 363. otmp->quan = 1L; 364. otmp->owt = weight(otmp); 365. 366. pline("A trap door in the ceiling opens and a rock falls on your %s!", 367. body_part(HEAD)); 368. 369. if (uarmh) 370. if(is_metallic(uarmh)) { 371. pline("Fortunately, you are wearing a hard helmet."); 372. dmg = 2; 373. } else if (flags.verbose) 374. Your("%s does not protect you.", xname(uarmh)); 375. 376. stackobj(otmp); 377. newsym(u.ux,u.uy); /* map the rock */ 378. 379. losehp(dmg, "falling rock", KILLED_BY_AN); 380. exercise(A_STR, FALSE); 381. } 382. break; 383. 384. case SQKY_BOARD: /* stepped on a squeaky board */ 385. if (Levitation 386. #ifdef POLYSELF 387. || is_flyer(uasmon) || is_clinger(uasmon) 388. #endif 389. ) { 390. if (Hallucination) You("notice a crease in the linoleum."); 391. else You("notice a loose board below you."); 392. } else { 393. pline("A board beneath you squeaks loudly."); 394. wake_nearby(); 395. } 396. break; 397. 398. case BEAR_TRAP: 399. if(Levitation 400. #ifdef POLYSELF 401. || is_flyer(uasmon)) { 402. You("%s over a bear trap.", 403. Levitation ? "float" : "fly"); 404. #else 405. ) { 406. You("float over a bear trap."); 407. #endif 408. break; 409. } 410. #ifdef POLYSELF 411. if(amorphous(uasmon)) { 412. pline("A bear trap closes harmlessly through you."); 413. break; 414. } 415. #endif 416. u.utrap = rn1(4, 4); 417. u.utraptype = TT_BEARTRAP; 418. pline("A bear trap closes on your %s!", 419. body_part(FOOT)); 420. #ifdef POLYSELF 421. if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) 422. You("howl in anger!"); 423. #endif 424. exercise(A_DEX, FALSE); 425. break; 426. 427. case SLP_GAS_TRAP: 428. if(Sleep_resistance) { 429. You("are enveloped in a cloud of gas!"); 430. break; 431. } 432. pline("A cloud of gas puts you to sleep!"); 433. flags.soundok = 0; 434. nomul(-rnd(25)); 435. u.usleep = 1; 436. nomovemsg = "You wake up."; 437. afternmv = Hear_again; 438. break; 439. 440. case RUST_TRAP: 441. #ifdef POLYSELF 442. if (u.umonnum == PM_IRON_GOLEM) { 443. pline("A gush of water hits you!"); 444. You("are covered with rust!"); 445. rehumanize(); 446. break; 447. } else 448. if (u.umonnum == PM_GREMLIN && rn2(3)) { 449. pline("A gush of water hits you!"); 450. if(mtmp = cloneu()) { 451. mtmp->mhpmax = (u.mhmax /= 2); 452. You("multiply."); 453. } 454. break; 455. } 456. #endif 457. /* Unlike monsters, traps cannot aim their rust attacks at 458. * you, so instead of looping through and taking either the 459. * first rustable one or the body, we take whatever we get, 460. * even if it is not rustable. 461. */ 462. switch (rn2(5)) { 463. case 0: 464. pline("A gush of water hits you on the %s!", 465. body_part(HEAD)); 466. (void) rust_dmg(uarmh, "helmet", 1, TRUE); 467. break; 468. case 1: 469. pline("A gush of water hits your left %s!", 470. body_part(ARM)); 471. if (rust_dmg(uarms, "shield", 1, TRUE)) break; 472. if (uwep && bimanual(uwep)) 473. goto two_hand; 474. /* Two goto statements in a row--aaarrrgggh! */ 475. glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE); 476. /* Not "metal gauntlets" since it gets called 477. * even if it's leather for the message 478. */ 479. break; 480. case 2: 481. pline("A gush of water hits your right %s!", 482. body_part(ARM)); 483. two_hand: erode_weapon(FALSE); 484. goto glovecheck; 485. default: 486. pline("A gush of water hits you!"); 487. if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE); 488. else if (uarm) 489. (void) rust_dmg(uarm, "armor", 1, TRUE); 490. #ifdef TOURIST 491. else if (uarmu) 492. (void) rust_dmg(uarmu, "shirt", 1, TRUE); 493. #endif 494. } 495. break; 496. 497. case FIRE_TRAP: 498. dofiretrap(); 499. break; 500. 501. case PIT: 502. if (Levitation 503. #ifdef POLYSELF 504. || is_flyer(uasmon) || is_clinger(uasmon) 505. #endif 506. ) { 507. if(Blind) break; 508. if(trap->tseen) 509. You("see a pit below you."); 510. else { 511. pline("A pit opens up under you!"); 512. You("don't fall in!"); 513. } 514. break; 515. } 516. You("fall into a pit!"); 517. #ifdef POLYSELF 518. if (!passes_walls(uasmon)) 519. #endif 520. u.utrap = rn1(6,2); 521. u.utraptype = TT_PIT; 522. losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX); 523. if (Punished && !carried(uball)) { 524. unplacebc(); 525. ballfall(); 526. placebc(); 527. } 528. selftouch("Falling, you"); 529. exercise(A_STR, FALSE); 530. vision_full_recalc = 1; /* vision limits change */ 531. break; 532. case SPIKED_PIT: 533. if (Levitation 534. #ifdef POLYSELF 535. || is_flyer(uasmon) || is_clinger(uasmon) 536. #endif 537. ) { 538. if(Blind) break; 539. pline("A pit full of spikes opens up under you!"); 540. You("don't fall in!"); 541. break; 542. } 543. You("fall into a pit!"); 544. You("land on a set of sharp iron spikes!"); 545. #ifdef POLYSELF 546. if (!passes_walls(uasmon)) 547. #endif 548. u.utrap = rn1(6,2); 549. u.utraptype = TT_PIT; 550. losehp(rnd(10),"fell into a pit of iron spikes", 551. NO_KILLER_PREFIX); 552. if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8); 553. if (Punished && !carried(uball)) { 554. unplacebc(); 555. ballfall(); 556. placebc(); 557. } 558. selftouch("Falling, you"); 559. vision_full_recalc = 1; /* vision limits change */ 560. exercise(A_STR, FALSE); 561. exercise(A_DEX, FALSE); 562. break; 563. 564. case TRAPDOOR: 565. if(!Can_fall_thru(&u.uz)) 566. panic("Trapdoors cannot exist on this level."); 567. fall_through(TRUE); 568. break; 569. 570. case TELEP_TRAP: 571. if(In_endgame(&u.uz) || Antimagic) { 572. if(Antimagic) 573. shieldeff(u.ux, u.uy); 574. You("feel a wrenching sensation."); 575. #ifdef WALKIES 576. } else if(!next_to_u()) { 577. You(shudder_for_moment); 578. #endif 579. } else if(trap->once) { 580. deltrap(trap); 581. newsym(u.ux,u.uy); /* get rid of trap symbol */ 582. vtele(); 583. } else 584. tele(); 585. break; 586. case LEVEL_TELEP: 587. You("%s onto a level teleport trap!", 588. Levitation ? (const char *)"float" : 589. #ifdef POLYSELF 590. locomotion(uasmon, "step")); 591. #else 592. (const char *)"step"); 593. #endif 594. if(Antimagic) { 595. shieldeff(u.ux, u.uy); 596. } 597. if(Antimagic || In_endgame(&u.uz)) { 598. You("feel a wrenching sensation."); 599. break; 600. } 601. if(!Blind) 602. You("are momentarily blinded by a flash of light."); 603. else 604. You("are momentarily disoriented."); 605. deltrap(trap); 606. newsym(u.ux,u.uy); /* get rid of trap symbol */ 607. level_tele(); 608. break; 609. 610. case WEB: /* Our luckless player has stumbled into a web. */ 611. #ifdef POLYSELF 612. if (amorphous(uasmon)) { 613. if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE) 614. { 615. deltrap(trap); 616. newsym(u.ux,u.uy);/* update position */ 617. You("dissolve a spider web."); 618. break; 619. } 620. You("flow through a spider web."); 621. break; 622. } 623. if (uasmon->mlet == S_SPIDER) { 624. pline("There is a spider web here."); 625. break; 626. } 627. #endif 628. You("%s into a spider web!", 629. Levitation ? (const char *)"float" : 630. #ifdef POLYSELF 631. locomotion(uasmon, "stumble")); 632. #else 633. (const char *)"stumble"); 634. #endif 635. u.utraptype = TT_WEB; 636. 637. /* Time stuck in the web depends on your strength. */ 638. { 639. register int str = ACURR(A_STR); 640. 641. if (str == 3) u.utrap = rn1(6,6); 642. else if (str < 6) u.utrap = rn1(6,4); 643. else if (str < 9) u.utrap = rn1(4,4); 644. else if (str < 12) u.utrap = rn1(4,2); 645. else if (str < 15) u.utrap = rn1(2,2); 646. else if (str < 18) u.utrap = rnd(2); 647. else if (str < 69) u.utrap = 1; 648. else { 649. u.utrap = 0; 650. You("tear through the web!"); 651. deltrap(trap); 652. newsym(u.ux,u.uy); /* get rid of trap symbol */ 653. } 654. } 655. break; 656. 657. case STATUE_TRAP: 658. deltrap(trap); 659. newsym(u.ux,u.uy); /* get rid of trap symbol */ 660. for(otmp=level.objects[u.ux][u.uy]; 661. otmp; otmp = otmp->nexthere) 662. if(otmp->otyp == STATUE) 663. if(mtmp=makemon(&mons[otmp->corpsenm],u.ux,u.uy)) { 664. pline("The statue comes to life!"); 665. /* mimic statues become seen mimics */ 666. if(mtmp->m_ap_type) seemimic(mtmp); 667. delobj(otmp); 668. break; 669. } 670. break; 671. 672. case MAGIC_TRAP: /* A magic trap. */ 673. if (!rn2(30)) { 674. deltrap(trap); 675. newsym(u.ux,u.uy); /* update position */ 676. You("are caught in a magical explosion!"); 677. losehp(rnd(10), "magical explosion", KILLED_BY_AN); 678. Your("body absorbs some of the magical energy!"); 679. u.uen = (u.uenmax += 2); 680. } else domagictrap(); 681. break; 682. 683. case ANTI_MAGIC: 684. if(Antimagic) { 685. shieldeff(u.ux, u.uy); 686. You("feel momentarily lethargic."); 687. } else drain_en(rnd((int)u.ulevel) + 1); 688. break; 689. 690. #ifdef POLYSELF 691. case POLY_TRAP: 692. if(Antimagic) { 693. shieldeff(u.ux, u.uy); 694. You("feel momentarily different."); 695. /* Trap did nothing; don't remove it --KAA */ 696. } else { 697. deltrap(trap); /* delete trap before polymorph */ 698. newsym(u.ux,u.uy); /* get rid of trap symbol */ 699. You("feel a change coming over you."); 700. polyself(); 701. } 702. break; 703. #endif 704. 705. case LANDMINE: { 706. if (Levitation 707. #ifdef POLYSELF 708. || is_flyer(uasmon) 709. #endif 710. ) { 711. You("see a trigger in a pile of soil below you."); 712. if (rn2(3)) break; 713. pline("KAABLAMM!!! The air currents set it off!"); 714. } else { 715. pline("KAABLAMM!!! You triggered a land mine!"); 716. set_wounded_legs(LEFT_SIDE, rn1(35, 41)); 717. set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); 718. } 719. losehp(rnd(16), "land mine", KILLED_BY_AN); 720. /* wake everything on the level */ 721. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 722. if(mtmp->msleep) mtmp->msleep = 0; 723. } 724. deltrap(t_at(u.ux, u.uy)); /* mines only explode once */ 725. newsym(u.ux,u.uy); /* get rid of trap symbol */ 726. } 727. break; 728. 729. case MAGIC_PORTAL: 730. #ifdef WALKIES 731. if(!next_to_u()) 732. You(shudder_for_moment); 733. else 734. #endif 735. domagicportal(trap); 736. break; 737. 738. default: 739. impossible("You hit a trap of type %u", trap->ttyp); 740. } 741. } 742. } 743. 744. #endif /* OVLB */ 745. 746. #ifdef WALKIES 747. 748. STATIC_DCL boolean FDECL(teleport_pet, (struct monst *)); 749. 750. #ifdef OVLB 751. 752. STATIC_OVL boolean 753. teleport_pet(mtmp) 754. register struct monst *mtmp; 755. { 756. register struct obj *otmp; 757. 758. if(mtmp->mleashed) { 759. otmp = get_mleash(mtmp); 760. if(!otmp) 761. impossible("%s is leashed, without a leash.", Monnam(mtmp)); 762. if(otmp->cursed) { 763. # ifdef SOUNDS 764. yelp(mtmp); 765. # endif 766. return FALSE; 767. } else { 768. Your("leash goes slack."); 769. m_unleash(mtmp); 770. return TRUE; 771. } 772. } 773. return TRUE; 774. } 775. 776. #endif /* OVLB */ 777. 778. #endif /* WALKIES */ 779. 780. #ifdef OVLB 781. 782. void 783. seetrap(trap) 784. register struct trap *trap; 785. { 786. if(!trap->tseen) { 787. trap->tseen = 1; 788. newsym(trap->tx, trap->ty); 789. } 790. } 791. 792. #endif /* OVLB */ 793. #ifdef OVL1 794. 795. int 796. mintrap(mtmp) 797. register struct monst *mtmp; 798. { 799. register struct trap *trap = t_at(mtmp->mx, mtmp->my); 800. boolean trapkilled = FALSE, tdoor = FALSE; 801. struct permonst *mptr = mtmp->data; 802. struct obj *otmp; 803. 804. if(!trap) { 805. mtmp->mtrapped = 0; /* perhaps teleported? */ 806. } else if (mtmp->mtrapped) { /* was in trap */ 807. if(!rn2(40)) 808. if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 809. ((trap->ttyp == PIT) || 810. (trap->ttyp == SPIKED_PIT))) { 811. if (!rn2(2)) { 812. mtmp->mtrapped = 0; 813. fill_pit(mtmp->mx, mtmp->my); 814. } 815. } else 816. mtmp->mtrapped = 0; 817. } else { 818. register int tt = trap->ttyp; 819. 820. /* A bug fix for dumb messages by ab@unido. 821. */ 822. int in_sight = canseemon(mtmp); 823. 824. if(mtmp->mtrapseen & (1 << tt)) { 825. /* it has been in such a trap - perhaps it escapes */ 826. if(rn2(4)) return(0); 827. } 828. mtmp->mtrapseen |= (1 << tt); 829. switch (tt) { 830. case ARROW_TRAP: 831. otmp = mksobj(ARROW, TRUE, FALSE); 832. otmp->quan = 1L; 833. otmp->owt = weight(otmp); 834. if(in_sight) seetrap(trap); 835. if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 836. break; 837. case DART_TRAP: 838. otmp = mksobj(DART, TRUE, FALSE); 839. otmp->quan = 1L; 840. otmp->owt = weight(otmp); 841. if (!rn2(6)) otmp->opoisoned = 1; 842. if(in_sight) seetrap(trap); 843. if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 844. break; 845. case ROCKTRAP: 846. otmp = mksobj(ROCK, TRUE, FALSE); 847. otmp->quan = 1L; 848. otmp->owt = weight(otmp); 849. if(in_sight) seetrap(trap); 850. if(!is_whirly(mptr) && !passes_walls(mptr) && 851. thitm(0, mtmp, otmp, d(2, 6))) 852. trapkilled = TRUE; 853. break; 854. 855. case SQKY_BOARD: { 856. register struct monst *ztmp = fmon; 857. 858. if(is_flyer(mptr)) break; 859. /* stepped on a squeaky board */ 860. if (in_sight) { 861. pline("A board beneath %s squeaks loudly.", mon_nam(mtmp)); 862. seetrap(trap); 863. } else 864. You("hear a distant squeak."); 865. /* wake up nearby monsters */ 866. while(ztmp) { 867. if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40) 868. if(ztmp->msleep) ztmp->msleep = 0; 869. ztmp = ztmp->nmon; 870. } 871. break; 872. } 873. 874. case BEAR_TRAP: 875. if(mptr->msize > MZ_SMALL && 876. !amorphous(mptr) && !is_flyer(mptr)) { 877. mtmp->mtrapped = 1; 878. if(in_sight) { 879. pline("%s is caught in a bear trap!", 880. Monnam(mtmp)); 881. seetrap(trap); 882. } else 883. if((mptr == &mons[PM_OWLBEAR] 884. || mptr == &mons[PM_BUGBEAR]) 885. && flags.soundok) 886. You("hear the roaring of an angry bear!"); 887. } 888. break; 889. 890. case SLP_GAS_TRAP: 891. if(!resists_sleep(mptr) && 892. !mtmp->msleep && mtmp->mcanmove) { 893. mtmp->mcanmove = 0; 894. mtmp->mfrozen = rnd(25); 895. if (in_sight) { 896. pline("%s suddenly falls asleep!", 897. Monnam(mtmp)); 898. seetrap(trap); 899. } 900. } 901. break; 902. 903. case RUST_TRAP: 904. if (in_sight) { 905. pline("A gush of water hits %s!", mon_nam(mtmp)); 906. seetrap(trap); 907. } 908. if (mptr == &mons[PM_IRON_GOLEM]) { 909. if (in_sight) 910. pline("%s falls to pieces!", Monnam(mtmp)); 911. else if(mtmp->mtame) 912. pline("May %s rust in peace.", 913. mon_nam(mtmp)); 914. mondied(mtmp); 915. trapkilled = TRUE; 916. } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { 917. struct monst *mtmp2 = clone_mon(mtmp); 918. 919. if (mtmp2) { 920. mtmp2->mhpmax = (mtmp->mhpmax /= 2); 921. if(in_sight) 922. pline("%s multiplies.", Monnam(mtmp)); 923. } 924. } 925. break; 926. 927. case FIRE_TRAP: 928. if (in_sight) 929. pline("A tower of flame bursts from the floor under %s!", 930. mon_nam(mtmp)); 931. if(resists_fire(mptr)) { 932. if (in_sight) { 933. shieldeff(mtmp->mx,mtmp->my); 934. pline("%s is uninjured.", Monnam(mtmp)); 935. } 936. } else { 937. int num=rnd(6); 938. 939. if (thitm(0, mtmp, (struct obj *)0, num)) 940. trapkilled = TRUE; 941. else mtmp->mhpmax -= num; 942. } 943. (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 944. (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 945. (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 946. if (in_sight) seetrap(trap); 947. break; 948. 949. case PIT: 950. case SPIKED_PIT: 951. if ( !is_flyer(mptr) && 952. (!mtmp->wormno || (count_wsegs(mtmp) < 6)) && 953. !is_clinger(mptr) ) { 954. if (!passes_walls(mptr)) 955. mtmp->mtrapped = 1; 956. if(in_sight) { 957. pline("%s falls into a pit!", Monnam(mtmp)); 958. seetrap(trap); 959. } 960. if(thitm(0, mtmp, (struct obj *)0, 961. rnd((tt==PIT) ? 6 : 10))) 962. trapkilled = TRUE; 963. } 964. break; 965. 966. case TRAPDOOR: 967. if(!Can_fall_thru(&u.uz)) 968. panic("Trapdoors cannot exist on this level."); 969. 970. if ( (mptr == &mons[PM_WUMPUS]) || 971. (mtmp->wormno && count_wsegs(mtmp) > 5) ) break; 972. tdoor = TRUE; 973. /* Fall through */ 974. case LEVEL_TELEP: 975. /* long worms w/tails can now change levels! - Norm */ 976. if (!is_flyer(mptr)) { 977. register int nlev; 978. d_level tolevel; 979. #ifdef WALKIES 980. if(teleport_pet(mtmp)) { 981. #endif 982. if(tdoor) { 983. if(Is_stronghold(&u.uz)) 984. assign_level(&tolevel, &valley_level); 985. else if(Is_botlevel(&u.uz)) { 986. pline("%s avoids the trap.", 987. Monnam(mtmp)); 988. break; 989. } else get_level(&tolevel,depth(&u.uz)+1); 990. } else { 991. #ifdef MULDGN 992. if(Is_knox(&u.uz)) { 993. rloc(mtmp); 994. break; 995. } 996. #endif 997. nlev = rnd(3); 998. if(!rn2(2)) nlev = -(nlev); 999. nlev = dunlev(&u.uz) + nlev; 1000. if(nlev > dunlevs_in_dungeon(&u.uz)) { 1001. nlev = dunlevs_in_dungeon(&u.uz); 1002. /* teleport up if already on bottom */ 1003. if (Is_botlevel(&u.uz)) 1004. nlev -= rnd(3); 1005. } 1006. if (nlev < 1) { 1007. nlev = 1; 1008. if (dunlev(&u.uz) == 1) { 1009. nlev += rnd(3); 1010. if (nlev > 1011. dunlevs_in_dungeon(&u.uz)) 1012. nlev = 1013. dunlevs_in_dungeon(&u.uz); 1014. } 1015. } 1016. /* can't seem to go anywhere */ 1017. /* (possible in short dungeons) */ 1018. if (nlev == dunlev(&u.uz)) { 1019. rloc(mtmp); 1020. break; 1021. } 1022. nlev = dungeons[u.uz.dnum].depth_start + 1023. nlev; 1024. get_level(&tolevel, nlev); 1025. } 1026. if(in_sight) { 1027. pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp)); 1028. seetrap(trap); 1029. } 1030. migrate_to_level(mtmp, 1031. ledger_no(&tolevel), 0); 1032. return(3); /* no longer on this level */ 1033. #ifdef WALKIES 1034. } 1035. #endif 1036. } 1037. break; 1038. 1039. case TELEP_TRAP: 1040. case MAGIC_PORTAL: 1041. #ifdef WALKIES 1042. if(teleport_pet(mtmp)) { 1043. #endif 1044. /* Note: don't remove the trap if a vault. Other- 1045. * wise the monster will be stuck there, since 1046. * the guard isn't going to come for it... 1047. * Also: don't remove if magic portal. In short, 1048. * don't remove :-) 1049. */ 1050. if (in_sight) { 1051. pline("%s suddenly disappears!", 1052. Monnam(mtmp)); 1053. seetrap(trap); 1054. } 1055. if (trap->once) vloc(mtmp); 1056. else rloc(mtmp); 1057. #ifdef WALKIES 1058. } 1059. #endif 1060. break; 1061. 1062. case WEB: 1063. /* Monster in a web. */ 1064. if (mptr->mlet == S_SPIDER) break; 1065. if (amorphous(mptr)) { 1066. if (acidic(mptr) || 1067. mptr == &mons[PM_GELATINOUS_CUBE]) { 1068. if (in_sight) 1069. pline("%s dissolves a spider web.", 1070. Monnam(mtmp)); 1071. deltrap(trap); 1072. break; 1073. } 1074. if (in_sight) 1075. pline("%s flows through a spider web.", 1076. Monnam(mtmp)); 1077. break; 1078. } 1079. switch (monsndx(mptr)) { 1080. case PM_FIRE_ELEMENTAL: 1081. if (in_sight) 1082. pline("%s burns a spider web!", Monnam(mtmp)); 1083. deltrap(trap); 1084. break; 1085. case PM_OWLBEAR: /* Eric Backus */ 1086. case PM_BUGBEAR: 1087. if (!in_sight) { 1088. You("hear the roaring of a confused bear!"); 1089. mtmp->mtrapped = 1; 1090. break; 1091. } 1092. /* fall though */ 1093. default: 1094. if (in_sight) 1095. pline("%s is caught in a spider web.", 1096. Monnam(mtmp)); 1097. mtmp->mtrapped = 1; 1098. break; 1099. } 1100. break; 1101. 1102. case STATUE_TRAP: 1103. break; 1104. 1105. case MAGIC_TRAP: 1106. /* A magic trap. Monsters immune. */ 1107. break; 1108. case ANTI_MAGIC: 1109. break; 1110. 1111. case LANDMINE: { 1112. register struct monst *mntmp = fmon; 1113. 1114. if(rn2(3)) 1115. break; /* monsters usually don't set it off */ 1116. if(is_flyer(mptr)) { 1117. if (in_sight) { 1118. pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp)); 1119. seetrap(trap); 1120. } 1121. if (rn2(3)) break; 1122. if (in_sight) 1123. pline("The air currents set it off!"); 1124. } else if(in_sight) 1125. pline("KAABLAMM!!! %s triggers a land mine!", 1126. Monnam(mtmp)); 1127. if (!in_sight) 1128. pline("Kaablamm! You hear an explosion in the distance!"); 1129. deltrap(trap); 1130. if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 1131. trapkilled = TRUE; 1132. /* wake everything on the level */ 1133. while(mntmp) { 1134. if(mntmp->msleep) 1135. mntmp->msleep = 0; 1136. mntmp = mntmp->nmon; 1137. } 1138. if (unconscious()) { 1139. multi = -1; 1140. nomovemsg="The explosion awakens you!"; 1141. } 1142. break; 1143. } 1144. 1145. #ifdef POLYSELF 1146. case POLY_TRAP: 1147. if(!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1148. (void) newcham(mtmp, (struct permonst *)0); 1149. if (in_sight) seetrap(trap); 1150. } 1151. break; 1152. #endif 1153. 1154. default: 1155. impossible("Some monster encountered a strange trap of type %d.", tt); 1156. } 1157. } 1158. if(trapkilled) return 2; 1159. return mtmp->mtrapped; 1160. } 1161. 1162. #endif /* OVL1 */ 1163. #ifdef OVLB 1164. 1165. void 1166. selftouch(arg) 1167. const char *arg; 1168. { 1169. if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE) 1170. #ifdef POLYSELF 1171. && !resists_ston(uasmon) 1172. #endif 1173. ){ 1174. pline("%s touch the cockatrice corpse.", arg); 1175. #ifdef POLYSELF 1176. if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 1177. return; 1178. #endif 1179. You("turn to stone..."); 1180. killer_format = KILLED_BY; 1181. killer = "touching a cockatrice corpse"; 1182. done(STONING); 1183. } 1184. } 1185. 1186. void 1187. float_up() 1188. { 1189. if(u.utrap) { 1190. if(u.utraptype == TT_PIT) { 1191. u.utrap = 0; 1192. You("float up, out of the pit!"); 1193. vision_full_recalc = 1; /* vision limits change */ 1194. fill_pit(u.ux, u.uy); 1195. } else if (u.utraptype == TT_INFLOOR) { 1196. Your("body pulls upward, but your %s are still stuck.", 1197. makeplural(body_part(LEG))); 1198. } else { 1199. You("float up, only your %s is still stuck.", 1200. body_part(LEG)); 1201. } 1202. } 1203. else if(Is_waterlevel(&u.uz)) 1204. pline("It feels as though you'd lost some weight."); 1205. else if(u.uinwater) 1206. spoteffects(); 1207. else if (Hallucination) 1208. pline("Up, up, and awaaaay! You're walking on air!"); 1209. else if(Is_airlevel(&u.uz)) 1210. You("gain control over your movements."); 1211. else 1212. You("start to float in the air!"); 1213. } 1214. 1215. void 1216. fill_pit(x, y) 1217. int x, y; 1218. { 1219. struct obj *otmp; 1220. struct trap *t; 1221. 1222. if ((t = t_at(x, y)) && 1223. ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) && 1224. (otmp = sobj_at(BOULDER, x, y))) { 1225. freeobj(otmp); 1226. (void) flooreffects(otmp, x, y, "settle"); 1227. } 1228. } 1229. 1230. int 1231. float_down() 1232. { 1233. register struct trap *trap = (struct trap *)0; 1234. boolean no_msg = FALSE; 1235. 1236. if(Levitation) return(0); /* maybe another ring/potion/boots */ 1237. 1238. if (Punished && !carried(uball) && 1239. (is_pool(uball->ox, uball->oy) || 1240. ((trap = t_at(uball->ox, uball->oy)) && 1241. ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) || 1242. (trap->ttyp == TRAPDOOR))))) { 1243. u.ux0 = u.ux; 1244. u.uy0 = u.uy; 1245. u.ux = uball->ox; 1246. u.uy = uball->oy; 1247. movobj(uchain, uball->ox, uball->oy); 1248. newsym(u.ux0, u.uy0); 1249. vision_full_recalc = 1; /* in case the hero moved. */ 1250. } 1251. /* check for falling into pool - added by GAN 10/20/86 */ 1252. #ifdef POLYSELF 1253. if(!is_flyer(uasmon)) { 1254. #endif 1255. /* kludge alert: 1256. * drown() and lava_effects() print various messages almost 1257. * every time they're called which conflict with the "fall 1258. * into" message below. Thus, we want to avoid printing 1259. * confusing, duplicate or out-of-order messages. 1260. * Use knowledge of the two routines as a hack -- this 1261. * should really handled differently -dlc 1262. */ 1263. if(is_pool(u.ux,u.uy) && !Wwalking && !u.uinwater) 1264. no_msg = drown(); 1265. 1266. if(is_lava(u.ux,u.uy)) { 1267. (void) lava_effects(); 1268. no_msg = TRUE; 1269. } 1270. #ifdef POLYSELF 1271. } 1272. #endif 1273. if (!trap) { 1274. if(Is_airlevel(&u.uz)) 1275. You("begin to tumble in place."); 1276. if(Is_waterlevel(&u.uz) && !no_msg) 1277. You("feel heavier."); 1278. /* u.uinwater msgs already in spoteffects()/drown() */ 1279. else if (!u.uinwater && !no_msg) { 1280. if (Hallucination) 1281. pline("Bummer! You've %s.", 1282. is_pool(u.ux,u.uy) ? 1283. "splashed down" : "hit the ground"); 1284. else 1285. You("float gently to the %s.", 1286. is_pool(u.ux,u.uy) ? "water" : "ground"); 1287. } 1288. trap = t_at(u.ux,u.uy); 1289. } 1290. 1291. if(trap) 1292. switch(trap->ttyp) { 1293. case STATUE_TRAP: 1294. break; 1295. case TRAPDOOR: 1296. if(!Can_fall_thru(&u.uz) || u.ustuck) 1297. break; 1298. /* fall into next case */ 1299. default: 1300. dotrap(trap); 1301. } 1302. if(!flags.nopick && OBJ_AT(u.ux, u.uy) && 1303. !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && 1304. (!is_pool(u.ux,u.uy) || Underwater)) 1305. pickup(1); 1306. return 0; 1307. } 1308. 1309. 1310. void 1311. tele() 1312. { 1313. coord cc; 1314. 1315. /* Disable teleportation in stronghold && Vlad's Tower */ 1316. if(level.flags.noteleport) { 1317. #ifdef WIZARD 1318. if (!wizard) { 1319. #endif 1320. pline("A mysterious force prevents you from teleporting!"); 1321. return; 1322. #ifdef WIZARD 1323. } 1324. #endif 1325. } 1326. 1327. /* don't show trap if "Sorry..." */ 1328. if(!Blinded) make_blinded(0L,FALSE); 1329. 1330. if((u.uhave.amulet || Is_wiz1_level(&u.uz) || Is_wiz2_level(&u.uz) || 1331. Is_wiz3_level(&u.uz)) && !rn2(3)) { 1332. You("feel disoriented for a moment."); 1333. return; 1334. } 1335. if(Teleport_control 1336. #ifdef WIZARD 1337. || wizard 1338. #endif 1339. ) { 1340. if (unconscious()) 1341. pline("Being unconscious, you cannot control your teleport."); 1342. else { 1343. pline("To what position do you want to be teleported?"); 1344. cc.x = u.ux; 1345. cc.y = u.uy; 1346. getpos(&cc, TRUE, "the desired position");/* force valid*/ 1347. if(cc.x == -10) return; /* abort */ 1348. /* possible extensions: introduce a small error if 1349. magic power is low; allow transfer to solid rock */ 1350. if(teleok(cc.x, cc.y, FALSE)){ 1351. teleds(cc.x, cc.y); 1352. return; 1353. } 1354. pline("Sorry..."); 1355. } 1356. } 1357. 1358. (void) safe_teleds(); 1359. } 1360. 1361. void 1362. teleds(nux, nuy) 1363. register int nux,nuy; 1364. { 1365. if (Punished) unplacebc(); 1366. u.utrap = 0; 1367. u.ustuck = 0; 1368. u.ux0 = u.ux; 1369. u.uy0 = u.uy; 1370. u.ux = nux; 1371. u.uy = nuy; 1372. fill_pit(u.ux0, u.uy0); /* do this now so that cansee() is correct */ 1373. #ifdef POLYSELF 1374. if (hides_under(uasmon)) 1375. u.uundetected = OBJ_AT(nux, nuy); 1376. else 1377. u.uundetected = 0; 1378. if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC; 1379. #endif 1380. if(Punished) placebc(); 1381. if(u.uswallow){ 1382. u.uswldtim = u.uswallow = 0; 1383. docrt(); 1384. } 1385. initrack(); /* teleports mess up tracking monsters without this */ 1386. /* 1387. * Make sure the hero disappears from the old location. This will 1388. * not happen if she is teleported within sight of her previous 1389. * location. Force a full vision recalculation because the hero 1390. * is now in a new location. 1391. */ 1392. newsym(u.ux0,u.uy0); 1393. vision_full_recalc = 1; 1394. nomul(0); 1395. spoteffects(); 1396. } 1397. 1398. int 1399. dotele() 1400. { 1401. struct trap *trap; 1402. boolean castit = FALSE; 1403. register int sp_no = 0; 1404. 1405. trap = t_at(u.ux, u.uy); 1406. if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP)) 1407. trap = 0; 1408. 1409. if (trap) { 1410. if (trap->once) { 1411. pline("This is a vault teleport, usable once only."); 1412. if (yn("Jump in?") == 'n') 1413. trap = 0; 1414. else { 1415. deltrap(trap); 1416. newsym(u.ux, u.uy); 1417. } 1418. } 1419. if (trap) 1420. #ifdef POLYSELF 1421. You("%s onto the teleportation trap.", 1422. locomotion(uasmon, "jump")); 1423. #else 1424. You("jump onto the teleportation trap."); 1425. #endif 1426. } 1427. if(!trap && (!Teleportation || 1428. (u.ulevel < (pl_character[0] == 'W' ? 8 : 12) 1429. #ifdef POLYSELF 1430. && !can_teleport(uasmon) 1431. #endif 1432. ) 1433. )) { 1434. /* Try to use teleport away spell. */ 1435. castit = objects[SPE_TELEPORT_AWAY].oc_name_known; 1436. if (castit) { 1437. for (sp_no = 0; sp_no < MAXSPELL && 1438. spl_book[sp_no].sp_id != NO_SPELL && 1439. spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++); 1440. 1441. if (sp_no == MAXSPELL || 1442. spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY) 1443. castit = FALSE; 1444. } 1445. #ifdef WIZARD 1446. if (!wizard) { 1447. #endif 1448. if (!castit) { 1449. if (!Teleportation) 1450. You("don't know that spell."); 1451. else You("are not able to teleport at will."); 1452. return(0); 1453. } 1454. #ifdef WIZARD 1455. } 1456. #endif 1457. } 1458. 1459. if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) { 1460. You("lack the strength for a teleport spell."); 1461. #ifdef WIZARD 1462. if(!wizard) 1463. #endif 1464. return(1); 1465. } 1466. if(!trap && 1467. check_capacity("Your concentration falters from carrying so much.")) 1468. return 1; 1469. 1470. if (castit) { 1471. exercise(A_WIS, TRUE); 1472. if (spelleffects(++sp_no, TRUE)) 1473. return(1); 1474. else 1475. #ifdef WIZARD 1476. if (!wizard) 1477. #endif 1478. return(0); 1479. } 1480. #ifdef WALKIES 1481. if(next_to_u()) { 1482. #endif 1483. if (trap && trap->once) vtele(); 1484. else tele(); 1485. #ifdef WALKIES 1486. (void) next_to_u(); 1487. } else { 1488. You(shudder_for_moment); 1489. return(0); 1490. } 1491. #endif 1492. if (!trap) morehungry(100); 1493. return(1); 1494. } 1495. 1496. 1497. void 1498. level_tele() 1499. { 1500. register int newlev; 1501. d_level newlevel; 1502. 1503. if((u.uhave.amulet || In_endgame(&u.uz)) 1504. #ifdef WIZARD 1505. && !wizard 1506. #endif 1507. ) { 1508. You("feel very disoriented for a moment."); 1509. return; 1510. } 1511. if(Teleport_control 1512. #ifdef WIZARD 1513. || wizard 1514. #endif 1515. ) { 1516. char buf[BUFSZ]; 1517. 1518. do { 1519. getlin("To what level do you want to teleport? [type a number]", 1520. buf); 1521. } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1]))); 1522. newlev = atoi(buf); 1523. 1524. /* no dungeon escape via this route */ 1525. if(newlev == 0) { 1526. if(ynq("Go to Nowhere. Are you sure?") != 'y') return; 1527. You("scream in agony as your body begins to warp..."); 1528. display_nhwindow(WIN_MESSAGE, FALSE); 1529. You("cease to exist."); 1530. killer_format = NO_KILLER_PREFIX; 1531. killer = "committed suicide"; 1532. done(DIED); 1533. return; 1534. } 1535. #ifdef MULDGN 1536. /* if in Knox and the requested level > 0, stay put. 1537. * we let negative values requests fall into the "heaven" loop. 1538. */ 1539. if(Is_knox(&u.uz) && newlev > 0) { 1540. You(shudder_for_moment); 1541. return; 1542. } 1543. /* if in Quest, the player sees "Home 1", etc., on the status 1544. * line, instead of the logical depth of the level. controlled 1545. * level teleport request is likely to be relativized to the 1546. * status line, and consequently it should be incremented to 1547. * the value of the logical depth of the target level. 1548. * 1549. * we let negative values requests fall into the "heaven" loop. 1550. */ 1551. if(In_quest(&u.uz) && newlev > 0) 1552. newlev = newlev + dungeons[u.uz.dnum].depth_start - 1; 1553. #endif 1554. } else { /* involuntary level tele */ 1555. #ifdef MULDGN 1556. if(Is_knox(&u.uz)) { 1557. You(shudder_for_moment); 1558. return; 1559. } 1560. #endif 1561. if(rn2(5)) newlev = rnd((int)depth(&u.uz) + 3); 1562. else { 1563. You(shudder_for_moment); 1564. return; 1565. } 1566. if(newlev == depth(&u.uz)) { 1567. /* if in a single-level dungeon... */ 1568. if(dunlevs_in_dungeon(&u.uz) == 1) { 1569. You(shudder_for_moment); 1570. return; 1571. } 1572. else if(dunlev(&u.uz) == 1) newlev++; 1573. else if(dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz)) newlev--; 1574. else if(In_hell(&u.uz)) newlev--; 1575. else newlev++; 1576. } 1577. } 1578. 1579. #ifdef WALKIES 1580. if(!next_to_u()) { 1581. You(shudder_for_moment); 1582. return; 1583. } 1584. #endif 1585. if(newlev < 0) { 1586. if(newlev <= -10) { 1587. You("arrive in heaven."); 1588. verbalize("Thou art early, but we'll admit thee."); 1589. killer_format = NO_KILLER_PREFIX; 1590. killer = "went to heaven prematurely"; 1591. done(DIED); 1592. return; 1593. } else if (newlev == -9) { 1594. You("feel deliriously happy. "); 1595. pline("(In fact, you're on Cloud 9!) "); 1596. display_nhwindow(WIN_MESSAGE, FALSE); 1597. } else 1598. You("are now high above the clouds..."); 1599. 1600. if(Levitation || is_floater(uasmon)) { 1601. You("float gently down to earth."); 1602. u.uz.dnum = 0; /* he might have been in another dgn */ 1603. newlev = 1; 1604. } 1605. #ifdef POLYSELF 1606. else if(is_flyer(uasmon)) { 1607. You("fly down to earth."); 1608. u.uz.dnum = 0; /* he might have been in another dgn */ 1609. newlev = 1; 1610. } 1611. #endif 1612. else { 1613. d_level save_dlevel; 1614. 1615. assign_level(&save_dlevel, &u.uz); 1616. pline("Unfortunately, you don't know how to fly."); 1617. You("plummet a few thousand feet to your death."); 1618. u.uz.dnum = 0; 1619. u.uz.dlevel = 0; 1620. killer_format = NO_KILLER_PREFIX; 1621. killer = 1622. self_pronoun("teleported out of the dungeon and fell to %s death","his"); 1623. done(DIED); 1624. assign_level(&u.uz, &save_dlevel); 1625. flags.botl = 1; 1626. return; 1627. } 1628. } 1629. 1630. # ifdef WIZARD 1631. if (In_endgame(&u.uz)) { /* must already be wizard */ 1632. newlevel.dnum = u.uz.dnum; 1633. newlevel.dlevel = newlev; 1634. goto_level(&newlevel, FALSE, FALSE, FALSE); 1635. return; 1636. } 1637. # endif 1638. 1639. /* calls done(ESCAPED) if newlevel==0 */ 1640. if(u.uz.dnum == medusa_level.dnum && 1641. newlev >= dungeons[u.uz.dnum].depth_start + 1642. dunlevs_in_dungeon(&u.uz)) { 1643. 1644. goto_hell(TRUE, FALSE); 1645. } else { 1646. /* if invocation did not yet occur, teleporting into 1647. * the last level of Gehennom is forbidden. 1648. */ 1649. if(Inhell && !u.uevent.invoked && 1650. newlev >= (dungeons[u.uz.dnum].depth_start + 1651. dunlevs_in_dungeon(&u.uz) - 1)) { 1652. newlev = dungeons[u.uz.dnum].depth_start + 1653. dunlevs_in_dungeon(&u.uz) - 2; 1654. pline("Sorry..."); 1655. } 1656. #ifdef MULDGN 1657. /* no teleporting out of quest dungeon */ 1658. if(In_quest(&u.uz) && newlev < depth(&qstart_level)) 1659. newlev = depth(&qstart_level); 1660. #endif 1661. /* the player thinks of levels purely in logical terms, so 1662. * we must translate newlev to a number relative to the 1663. * current dungeon. 1664. */ 1665. get_level(&newlevel, newlev); 1666. goto_level(&newlevel, FALSE, FALSE, FALSE); 1667. } 1668. } 1669. 1670. static void 1671. dofiretrap() 1672. { 1673. 1674. register int num; 1675. 1676. /* changed to be in conformance with 1677. * SCR_FIRE by GAN 11/02/86 1678. */ 1679. 1680. pline("A tower of flame bursts from the floor!"); 1681. if(Fire_resistance) { 1682. shieldeff(u.ux, u.uy); 1683. You("are uninjured."); 1684. } else { 1685. num = rnd(6); 1686. u.uhpmax -= num; 1687. losehp(num,"burst of flame", KILLED_BY_AN); 1688. } 1689. destroy_item(SCROLL_CLASS, AD_FIRE); 1690. destroy_item(SPBOOK_CLASS, AD_FIRE); 1691. destroy_item(POTION_CLASS, AD_FIRE); 1692. } 1693. 1694. static void 1695. domagicportal(ttmp) 1696. register struct trap *ttmp; 1697. { 1698. struct d_level target_level; 1699. 1700. /* if landed from another portal, do nothing */ 1701. /* problem: level teleport landing escapes the check */ 1702. if(!on_level(&u.uz, &u.uz0)) return; 1703. 1704. You("activated a magic portal!"); 1705. You("feel dizzy for a moment, but the sensation passes."); 1706. 1707. /* prevent the poor shnook, whose amulet was stolen */ 1708. /* while in the endgame, from accidently triggering */ 1709. /* the portal to the next level, and thus losing the */ 1710. /* game */ 1711. if(In_endgame(&u.uz) && !u.uhave.amulet) return; 1712. 1713. target_level = ttmp->dst; 1714. goto_level(&target_level, FALSE, FALSE, TRUE); 1715. } 1716. 1717. static void 1718. domagictrap() 1719. { 1720. register int fate = rnd(20); 1721. 1722. /* What happened to the poor sucker? */ 1723. 1724. if (fate < 10) { 1725. 1726. /* Most of the time, it creates some monsters. */ 1727. register int cnt = rnd(4); 1728. 1729. /* below checks for blindness added by GAN 10/30/86 */ 1730. if (!Blind) { 1731. You("are momentarily blinded by a flash of light!"); 1732. make_blinded((long)rn1(5,10),FALSE); 1733. } else 1734. You("hear a deafening roar!"); 1735. while(cnt--) 1736. (void) makemon((struct permonst *) 0, u.ux, u.uy); 1737. } 1738. else 1739. switch (fate) { 1740. 1741. case 10: 1742. case 11: 1743. /* sometimes nothing happens */ 1744. break; 1745. case 12: /* a flash of fire */ 1746. dofiretrap(); 1747. break; 1748. 1749. /* odd feelings */ 1750. case 13: pline("A shiver runs up and down your %s!", 1751. body_part(SPINE)); 1752. break; 1753. case 14: You(Hallucination ? 1754. "hear the moon howling at you." : 1755. "hear distant howling."); 1756. break; 1757. case 15: You("suddenly yearn for %s.", 1758. Hallucination ? "Cleveland" : 1759. "your distant homeland"); 1760. break; 1761. case 16: Your("pack shakes violently!"); 1762. break; 1763. case 17: You(Hallucination ? 1764. "smell hamburgers." : 1765. "smell charred flesh."); 1766. break; 1767. 1768. /* very occasionally something nice happens. */ 1769. 1770. case 19: 1771. /* tame nearby monsters */ 1772. { register int i,j; 1773. register struct monst *mtmp; 1774. 1775. /* below pline added by GAN 10/30/86 */ 1776. (void) adjattrib(A_CHA,1,FALSE); 1777. for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) { 1778. if(!isok(u.ux+i, u.uy+j)) continue; 1779. mtmp = m_at(u.ux+i, u.uy+j); 1780. if(mtmp) 1781. (void) tamedog(mtmp, (struct obj *)0); 1782. } 1783. break; 1784. } 1785. 1786. case 20: 1787. /* uncurse stuff */ 1788. { register struct obj *obj; 1789. 1790. /* below plines added by GAN 10/30/86 */ 1791. You(Hallucination ? 1792. "feel in touch with the Universal Oneness." : 1793. "feel like someone is helping you."); 1794. for(obj = invent; obj ; obj = obj->nobj) 1795. if(obj->owornmask || obj->otyp == LOADSTONE) 1796. uncurse(obj); 1797. if(Punished) unpunish(); 1798. break; 1799. } 1800. default: break; 1801. } 1802. } 1803. 1804. void 1805. water_damage(obj,force) 1806. register struct obj *obj; 1807. register boolean force; 1808. { 1809. /* Scrolls, spellbooks, potions, weapons and 1810. pieces of armor may get affected by the water */ 1811. for(; obj; obj = obj->nobj) { 1812. 1813. (void) snuff_lit(obj); 1814. 1815. if(obj->greased) { 1816. if (force || !rn2(2)) obj->greased = 0; 1817. } else if(Is_container(obj) && !Is_box(obj) && 1818. (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) { 1819. water_damage(obj->cobj,force); 1820. } else if(obj->oclass == SCROLL_CLASS && (force || rn2(12) > Luck) 1821. #ifdef MAIL 1822. && obj->otyp != SCR_MAIL 1823. #endif 1824. ) { 1825. obj->otyp = SCR_BLANK_PAPER; 1826. } else if(obj->oclass == SPBOOK_CLASS && (force || rn2(12) > Luck)) { 1827. if (obj->otyp == SPE_BOOK_OF_THE_DEAD) 1828. pline("Steam rises from %s.", the(xname(obj))); 1829. else obj->otyp = SPE_BLANK_PAPER; 1830. } else if(obj->oclass == POTION_CLASS && (force || rn2(12) > Luck)) { 1831. if (obj->spe == -1) { 1832. obj->otyp = POT_WATER; 1833. obj->blessed = obj->cursed = 0; 1834. obj->spe = 0; 1835. } else obj->spe--; 1836. } else if(is_rustprone(obj) && obj->oeroded < MAX_ERODE && 1837. !(obj->oerodeproof || (obj->blessed && !rnl(4))) && 1838. (force || rn2(12) > Luck)) { 1839. /* all metal stuff and armor except body armor 1840. protected by oilskin cloak */ 1841. if(obj->oclass != ARMOR_CLASS || obj != uarm || 1842. !uarmc || uarmc->otyp != OILSKIN_CLOAK || 1843. (uarmc->cursed && !rn2(3))) 1844. obj->oeroded++; 1845. } 1846. } 1847. } 1848. 1849. /* 1850. * This function is potentially expensive - rolling 1851. * inventory list multiple times. Luckily it's seldom needed. 1852. * Returns TRUE if disrobing made player unencumbered enough to 1853. * crawl out of the current predicament. 1854. */ 1855. static boolean 1856. emergency_disrobe(lostsome) 1857. boolean *lostsome; 1858. { 1859. int invc = inv_cnt(); 1860. 1861. while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) { 1862. register struct obj *obj, *otmp = (struct obj *)0; 1863. register int i = rn2(invc); 1864. 1865. for (obj = invent; obj; obj = obj->nobj) { 1866. /* 1867. * Undroppables are: body armor, boots, gloves, 1868. * amulets, and rings because of the time and effort 1869. * in removing them + loadstone and other cursed stuff 1870. * for obvious reasons. 1871. */ 1872. if (!(obj->otyp == LOADSTONE || 1873. obj == uamul || obj == uleft || obj == uright || 1874. obj == ublindf || obj == uarm || obj == uarmc || 1875. obj == uarmg || obj == uarmf || 1876. #ifdef TOURIST 1877. obj == uarmu || 1878. #endif 1879. (obj->cursed && (obj == uarmh || obj == uarms)) || 1880. welded(obj))) 1881. otmp = obj; 1882. /* reached the mark and found some stuff to drop? */ 1883. if (--i < 0 && otmp) break; 1884. 1885. /* else continue */ 1886. } 1887. 1888. /* nothing to drop and still overweight */ 1889. if (!otmp) return(FALSE); 1890. 1891. if (otmp == uarmh) (void) Helmet_off(); 1892. else if (otmp == uarms) (void) Shield_off(); 1893. else if (otmp == uwep) setuwep((struct obj *)0); 1894. *lostsome = TRUE; 1895. dropx(otmp); 1896. invc--; 1897. } 1898. return(TRUE); 1899. } 1900. 1901. /* 1902. * return(TRUE) == player relocated 1903. */ 1904. boolean 1905. drown() 1906. { 1907. boolean inpool_ok = FALSE, crawl_ok; 1908. int i, x, y; 1909. 1910. /* happily wading in the same contiguous pool */ 1911. if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) && 1912. Magical_breathing) { 1913. /* water effects on objects every now and then */ 1914. if (!rn2(5)) inpool_ok = TRUE; 1915. else return(FALSE); 1916. } 1917. 1918. if (!u.uinwater) { 1919. You("%s into the water!", 1920. Is_waterlevel(&u.uz) ? "plunge" : "fall"); 1921. #ifdef POLYSELF 1922. if(!is_swimmer(uasmon)) 1923. #endif 1924. if (!Is_waterlevel(&u.uz)) 1925. You("sink like %s.", 1926. Hallucination ? "the Titanic" : "a rock"); 1927. } 1928. 1929. water_damage(invent,FALSE); 1930. 1931. #ifdef POLYSELF 1932. if(u.umonnum == PM_GREMLIN && rn2(3)) { 1933. struct monst *mtmp; 1934. if(mtmp = cloneu()) { 1935. mtmp->mhpmax = (u.mhmax /= 2); 1936. You("multiply."); 1937. } 1938. } 1939. 1940. if(is_swimmer(uasmon)) return(FALSE); 1941. #endif 1942. if (inpool_ok) return(FALSE); 1943. #ifdef WALKIES 1944. if ((i = number_leashed()) > 0) { 1945. pline("The leash%s slip%s loose.", 1946. (i > 1) ? "es" : "", 1947. (i > 1) ? "" : "s"); 1948. unleash_all(); 1949. } 1950. #endif 1951. if (Magical_breathing) { 1952. pline("But wait!"); 1953. Your("lungs start acting like gills."); 1954. if (!Is_waterlevel(&u.uz)) 1955. Your("%s the bottom.",Hallucination ? "keel hits" : "feet touch"); 1956. if (Punished) placebc(); 1957. u.uinwater = 1; 1958. under_water(1); 1959. return(FALSE); 1960. } 1961. if((Teleportation || can_teleport(uasmon)) && 1962. (Teleport_control || rn2(3) < Luck+2)) { 1963. You("attempt a teleport spell."); /* utcsri!carroll */ 1964. (void) dotele(); 1965. if(!is_pool(u.ux,u.uy)) 1966. return(TRUE); 1967. } 1968. crawl_ok = FALSE; 1969. /* look around for a place to crawl to */ 1970. for (i = 0; i < 100; i++) { 1971. x = rn1(3,u.ux - 1); 1972. y = rn1(3,u.uy - 1); 1973. if (teleok(x,y,TRUE)) { 1974. crawl_ok = TRUE; 1975. goto crawl; 1976. } 1977. } 1978. /* one more scan */ 1979. for (x = u.ux - 1; x <= u.ux + 1; x++) 1980. for (y = u.uy - 1; y <= u.uy + 1; y++) 1981. if (teleok(x,y,TRUE)) { 1982. crawl_ok = TRUE; 1983. goto crawl; 1984. } 1985. crawl:; 1986. if (crawl_ok) { 1987. boolean lost = FALSE; 1988. /* time to do some strip-tease... */ 1989. boolean succ = Is_waterlevel(&u.uz) ? TRUE : 1990. emergency_disrobe(&lost); 1991. 1992. You("try to crawl out of the water."); 1993. if (lost) 1994. You("dump some of your gear to lose weight..."); 1995. if (succ) { 1996. pline("Pheew! That was close."); 1997. teleds(x,y); 1998. return(TRUE); 1999. } 2000. /* still too much weight */ 2001. pline("But in vain."); 2002. } 2003. u.uinwater = 1; 2004. You("drown."); 2005. killer_format = KILLED_BY_AN; 2006. killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ? 2007. "pool of water" : "moat"; 2008. done(DROWNING); 2009. /* oops, we're still alive. better get out of the water. */ 2010. if (!safe_teleds()) 2011. while (1) { 2012. pline("You're still drowning."); 2013. done(DROWNING); 2014. } 2015. u.uinwater = 0; 2016. You("find yourself back %s.",Is_waterlevel(&u.uz) ? 2017. "in an air bubble" : "on dry land"); 2018. return(TRUE); 2019. } 2020. 2021. void 2022. drain_en(n) 2023. register int n; 2024. { 2025. if (!u.uenmax) return; 2026. You("feel your magical energy drain away!"); 2027. u.uen -= n; 2028. if(u.uen < 0) { 2029. u.uenmax += u.uen; 2030. if(u.uenmax < 0) u.uenmax = 0; 2031. u.uen = 0; 2032. } 2033. flags.botl = 1; 2034. } 2035. 2036. int 2037. dountrap() /* disarm a trapped object */ 2038. { 2039. #ifdef POLYSELF 2040. if(nohands(uasmon)) { 2041. pline("And just how do you expect to do that?"); 2042. return(0); 2043. } 2044. #endif 2045. return untrap(FALSE); 2046. } 2047. 2048. int 2049. untrap(force) 2050. boolean force; 2051. { 2052. register struct obj *otmp; 2053. register boolean confused = (Confusion > 0 || Hallucination > 0); 2054. register int x,y; 2055. int ch; 2056. struct trap *ttmp; 2057. struct monst *mtmp; 2058. boolean trap_skipped = FALSE; 2059. 2060. if(!getdir(NULL)) return(0); 2061. x = u.ux + u.dx; 2062. y = u.uy + u.dy; 2063. 2064. if(!u.dx && !u.dy) { 2065. for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 2066. if(Is_box(otmp)) { 2067. pline("There is %s here.", doname(otmp)); 2068. 2069. switch (ynq("Check for traps?")) { 2070. case 'q': return(0); 2071. case 'n': continue; 2072. } 2073. 2074. if((otmp->otrapped && (force || (!confused 2075. && rn2(MAXULEV + 1 - (int)u.ulevel) < 10))) 2076. || (!force && confused && !rn2(3))) { 2077. You("find a trap on %s!", the(xname(otmp))); 2078. exercise(A_WIS, TRUE); 2079. 2080. switch (ynq("Disarm it?")) { 2081. case 'q': return(1); 2082. case 'n': trap_skipped = TRUE; continue; 2083. } 2084. 2085. if(otmp->otrapped) { 2086. exercise(A_DEX, TRUE); 2087. ch = ACURR(A_DEX) + u.ulevel; 2088. if (pl_character[0] == 'R') ch *= 2; 2089. if(!force && (confused || Fumbling || 2090. rnd(75+level_difficulty()/2) > ch)) { 2091. (void) chest_trap(otmp, FINGER, TRUE); 2092. } else { 2093. You("disarm it!"); 2094. otmp->otrapped = 0; 2095. } 2096. } else pline("That %s was not trapped.", doname(otmp)); 2097. return(1); 2098. } else { 2099. You("find no traps on %s.", the(xname(otmp))); 2100. return(1); 2101. } 2102. } 2103. if ((ttmp = t_at(x,y)) && ttmp->tseen) 2104. You("cannot disable this trap."); 2105. else 2106. You(trap_skipped ? "find no other traps here." 2107. : "know of no traps here."); 2108. return(0); 2109. } 2110. 2111. if ((mtmp = m_at(x,y)) && 2112. mtmp->m_ap_type == M_AP_FURNITURE && 2113. (mtmp->mappearance == S_hcdoor || 2114. mtmp->mappearance == S_vcdoor) && 2115. !Protection_from_shape_changers) { 2116. 2117. stumble_onto_mimic(mtmp); 2118. return(1); 2119. } 2120. 2121. if (!IS_DOOR(levl[x][y].typ)) { 2122. if ((ttmp = t_at(x,y)) && ttmp->tseen) 2123. You("cannot disable that trap."); 2124. else 2125. You("know of no traps there."); 2126. return(0); 2127. } 2128. 2129. switch (levl[x][y].doormask) { 2130. case D_NODOOR: 2131. You("%s no door there.", Blind ? "feel" : "see"); 2132. return(0); 2133. case D_ISOPEN: 2134. pline("This door is safely open."); 2135. return(0); 2136. case D_BROKEN: 2137. pline("This door is broken."); 2138. return(0); 2139. } 2140. 2141. if ((levl[x][y].doormask & D_TRAPPED 2142. && (force || 2143. (!confused && rn2(MAXULEV - (int)u.ulevel + 11) < 10))) 2144. || (!force && confused && !rn2(3))) { 2145. You("find a trap on the door!"); 2146. exercise(A_WIS, TRUE); 2147. if (ynq("Disarm it?") != 'y') return(1); 2148. if (levl[x][y].doormask & D_TRAPPED) { 2149. ch = 15 + 2150. (pl_character[0] == 'R') ? u.ulevel*3 : 2151. u.ulevel; 2152. exercise(A_DEX, TRUE); 2153. if(!force && (confused || Fumbling || 2154. rnd(75+level_difficulty()/2) > ch)) { 2155. You("set it off!"); 2156. b_trapped("door"); 2157. } else 2158. You("disarm it!"); 2159. levl[x][y].doormask &= ~D_TRAPPED; 2160. } else pline("This door was not trapped."); 2161. return(1); 2162. } else { 2163. You("find no traps on the door."); 2164. return(1); 2165. } 2166. } 2167. 2168. /* only called when the player is doing something to the chest directly */ 2169. boolean 2170. chest_trap(obj, bodypart, disarm) 2171. register struct obj *obj; 2172. register int bodypart; 2173. boolean disarm; 2174. { 2175. register struct obj *otmp = obj, *otmp2; 2176. char buf[80]; 2177. const char *msg; 2178. 2179. You(disarm ? "set it off!" : "trigger a trap!"); 2180. display_nhwindow(WIN_MESSAGE, FALSE); 2181. if (Luck > -13 && rn2(13+Luck) > 7) { /* saved by luck */ 2182. /* trap went off, but good luck prevents damage */ 2183. switch (rn2(13)) { 2184. case 12: 2185. case 11: msg = "explosive charge is a dud"; break; 2186. case 10: 2187. case 9: msg = "electric charge is grounded"; break; 2188. case 8: 2189. case 7: msg = "flame fizzles out"; break; 2190. case 6: 2191. case 5: 2192. case 4: msg = "poisoned needle misses"; break; 2193. case 3: 2194. case 2: 2195. case 1: 2196. case 0: msg = "gas cloud blows away"; break; 2197. default: impossible("chest disarm bug"); msg = NULL; break; 2198. } 2199. if (msg) pline("But luckily the %s!", msg); 2200. } else { 2201. switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) { 2202. case 25: 2203. case 24: 2204. case 23: 2205. case 22: 2206. case 21: { 2207. register struct monst *shkp; 2208. long loss = 0L; 2209. boolean costly, insider; 2210. register xchar ox = obj->ox, oy = obj->oy; 2211. 2212. #ifdef GCC_WARN 2213. shkp = (struct monst *) 0; 2214. #endif 2215. /* the obj location need not be that of player */ 2216. costly = (costly_spot(ox, oy) && 2217. (shkp = shop_keeper(*in_rooms(ox, oy, 2218. SHOPBASE))) != (struct monst *)0); 2219. insider = (*u.ushops && inside_shop(u.ux, u.uy) && 2220. *in_rooms(ox, oy, SHOPBASE) == *u.ushops); 2221. 2222. pline("%s explodes!", The(xname(obj))); 2223. Sprintf(buf, "exploding %s", xname(obj)); 2224. 2225. if(costly) 2226. loss += stolen_value(obj, ox, oy, 2227. (boolean)shkp->mpeaceful, TRUE); 2228. delete_contents(obj); 2229. for(otmp = level.objects[u.ux][u.uy]; 2230. otmp; otmp = otmp2) { 2231. otmp2 = otmp->nexthere; 2232. if(costly) 2233. loss += stolen_value(otmp, otmp->ox, 2234. otmp->oy, (boolean)shkp->mpeaceful, 2235. TRUE); 2236. delobj(otmp); 2237. } 2238. exercise(A_STR, FALSE); 2239. losehp(d(6,6), buf, KILLED_BY_AN); 2240. if(costly && loss) { 2241. if(insider) 2242. You("owe %ld zorkmids for objects destroyed.", 2243. loss); 2244. else { 2245. You("caused %ld zorkmids worth of damage!", 2246. loss); 2247. make_angry_shk(shkp, ox, oy); 2248. } 2249. } 2250. wake_nearby(); 2251. return TRUE; 2252. } 2253. case 20: 2254. case 19: 2255. case 18: 2256. case 17: 2257. pline("A cloud of noxious gas billows from %s.", 2258. the(xname(obj))); 2259. poisoned("gas cloud", A_STR, "cloud of poison gas",15); 2260. exercise(A_CON, FALSE); 2261. break; 2262. case 16: 2263. case 15: 2264. case 14: 2265. case 13: 2266. You("feel a needle prick your %s.",body_part(bodypart)); 2267. poisoned("needle", A_CON, "poison needle",10); 2268. exercise(A_CON, FALSE); 2269. break; 2270. case 12: 2271. case 11: 2272. case 10: 2273. case 9: 2274. pline("A tower of flame erupts from %s!", 2275. the(xname(obj))); 2276. if(Fire_resistance) { 2277. shieldeff(u.ux, u.uy); 2278. You("don't seem to be affected."); 2279. } else losehp(d(4, 6), "tower of flame", KILLED_BY_AN); 2280. destroy_item(SCROLL_CLASS, AD_FIRE); 2281. destroy_item(SPBOOK_CLASS, AD_FIRE); 2282. destroy_item(POTION_CLASS, AD_FIRE); 2283. break; 2284. case 8: 2285. case 7: 2286. case 6: 2287. You("are jolted by a surge of electricity!"); 2288. if(Shock_resistance) { 2289. shieldeff(u.ux, u.uy); 2290. You("don't seem to be affected."); 2291. } else losehp(d(4, 4), "electric shock", KILLED_BY_AN); 2292. destroy_item(RING_CLASS, AD_ELEC); 2293. destroy_item(WAND_CLASS, AD_ELEC); 2294. break; 2295. case 5: 2296. case 4: 2297. case 3: 2298. pline("Suddenly you are frozen in place!"); 2299. nomul(-d(5, 6)); 2300. exercise(A_DEX, FALSE); 2301. nomovemsg = "You can move again."; 2302. break; 2303. case 2: 2304. case 1: 2305. case 0: 2306. pline("A cloud of %s gas billows from %s", 2307. hcolor(), the(xname(obj))); 2308. if(!Stunned) 2309. if (Hallucination) 2310. pline("What a groovy feeling!"); 2311. else 2312. You("stagger and your vision blurs..."); 2313. make_stunned(HStun + rn1(7, 16),FALSE); 2314. make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L); 2315. break; 2316. default: impossible("bad chest trap"); 2317. break; 2318. } 2319. bot(); /* to get immediate botl re-display */ 2320. } 2321. otmp->otrapped = 0; /* these traps are one-shot things */ 2322. 2323. return FALSE; 2324. } 2325. 2326. #endif /* OVLB */ 2327. #ifdef OVL0 2328. 2329. struct trap * 2330. t_at(x,y) 2331. register int x, y; 2332. { 2333. register struct trap *trap = ftrap; 2334. while(trap) { 2335. if(trap->tx == x && trap->ty == y) return(trap); 2336. trap = trap->ntrap; 2337. } 2338. return((struct trap *)0); 2339. } 2340. 2341. #endif /* OVL0 */ 2342. #ifdef OVLB 2343. 2344. void 2345. deltrap(trap) 2346. register struct trap *trap; 2347. { 2348. register struct trap *ttmp; 2349. 2350. if(trap == ftrap) 2351. ftrap = ftrap->ntrap; 2352. else { 2353. for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 2354. ttmp->ntrap = trap->ntrap; 2355. } 2356. dealloc_trap(trap); 2357. } 2358. 2359. /* used for doors. can be used for anything else that opens. */ 2360. void 2361. b_trapped(item) 2362. register const char *item; 2363. { 2364. register int lvl = level_difficulty(); 2365. int dmg = rnd(5 + (lvl<5 ? lvl : 2+lvl/2)); 2366. 2367. pline("KABOOM!! %s was booby-trapped!", The(item)); 2368. if (u.ulevel < 4 && lvl < 3 && !rnl(3)) 2369. You("are shaken, but luckily unhurt."); 2370. else losehp(dmg, "explosion", KILLED_BY_AN); 2371. exercise(A_STR, FALSE); 2372. make_stunned(HStun + dmg, TRUE); 2373. } 2374. 2375. /* Monster is hit by trap. */ 2376. /* Note: doesn't work if both obj and d_override are null */ 2377. STATIC_OVL boolean 2378. thitm(tlev, mon, obj, d_override) 2379. register int tlev; 2380. register struct monst *mon; 2381. register struct obj *obj; 2382. int d_override; 2383. { 2384. register int strike; 2385. register boolean trapkilled = FALSE; 2386. 2387. if (d_override) strike = 1; 2388. else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20)); 2389. else strike = (find_mac(mon) + tlev <= rnd(20)); 2390. 2391. /* Actually more accurate than thitu, which doesn't take 2392. * obj->spe into account. 2393. */ 2394. if(!strike) { 2395. if (cansee(mon->mx, mon->my)) 2396. pline("%s is almost hit by %s!", Monnam(mon), 2397. doname(obj)); 2398. } else { 2399. int dam = 1; 2400. 2401. if (obj && cansee(mon->mx, mon->my)) 2402. pline("%s is hit by %s!", Monnam(mon), doname(obj)); 2403. if (d_override) dam = d_override; 2404. else if (obj) { 2405. dam = dmgval(obj, mon->data); 2406. if (dam < 1) dam = 1; 2407. } 2408. if ((mon->mhp -= dam) <= 0) { 2409. int xx = mon->mx; 2410. int yy = mon->my; 2411. 2412. monkilled(mon, "", AD_PHYS); 2413. newsym(xx, yy); 2414. trapkilled = TRUE; 2415. } 2416. } 2417. if (obj && (!strike || d_override)) { 2418. place_object(obj, mon->mx, mon->my); 2419. obj->nobj = fobj; 2420. fobj = obj; 2421. stackobj(fobj); 2422. } else if (obj) dealloc_obj(obj); 2423. 2424. return trapkilled; 2425. } 2426. 2427. boolean 2428. unconscious() 2429. { 2430. return (multi < 0 && (!nomovemsg || 2431. u.usleep || 2432. !strncmp(nomovemsg,"You regain con", 15) || 2433. !strncmp(nomovemsg,"You are consci", 15))); 2434. } 2435. 2436. static char lava_killer[] = "molten lava"; 2437. 2438. boolean 2439. lava_effects() 2440. { 2441. register struct obj *obj, *obj2; 2442. int dmg; 2443. 2444. if (!Fire_resistance) { 2445. if(Wwalking) { 2446. dmg = d(6,6); 2447. pline("The lava here burns you!"); 2448. if(dmg < u.uhp) { 2449. losehp(dmg, lava_killer, KILLED_BY); 2450. goto burn_stuff; 2451. } 2452. } else 2453. You("fall into the lava!"); 2454. 2455. for(obj = invent; obj; obj = obj2) { 2456. obj2 = obj->nobj; 2457. if(is_organic(obj) && !obj->oerodeproof) { 2458. if(obj->owornmask) { 2459. if(obj == uarm) (void) Armor_gone(); 2460. else if(obj == uarmc) (void) Cloak_off(); 2461. else if(obj == uarmh) (void) Helmet_off(); 2462. else if(obj == uarms) (void) Shield_off(); 2463. else if(obj == uarmg) (void) Gloves_off(); 2464. else if(obj == uarmf) (void) Boots_off(); 2465. #ifdef TOURIST 2466. else if(obj == uarmu) setnotworn(obj); 2467. #endif 2468. else if(obj == uleft) Ring_gone(obj); 2469. else if(obj == uright) Ring_gone(obj); 2470. else if(obj == ublindf) Blindf_off(obj); 2471. else if(obj == uwep) uwepgone(); 2472. if(Lifesaved 2473. #ifdef WIZARD 2474. || wizard 2475. #endif 2476. ) Your("%s into flame!", aobjnam(obj, "burst")); 2477. } 2478. useup(obj); 2479. } 2480. } 2481. 2482. /* s/he died... */ 2483. u.uhp = -1; 2484. killer_format = KILLED_BY; 2485. killer = lava_killer; 2486. You("burn to a crisp..."); 2487. done(BURNING); 2488. if (!safe_teleds()) 2489. while (1) { 2490. pline("You're still burning."); 2491. done(BURNING); 2492. } 2493. You("find yourself back on solid ground."); 2494. return(TRUE); 2495. } 2496. 2497. if (!Wwalking) { 2498. u.utrap = rn1(4, 4) + (rn1(4, 12) << 8); 2499. u.utraptype = TT_LAVA; 2500. You("sink into the lava, but it doesn't burn you!"); 2501. } 2502. /* just want to burn boots, not all armor; destroy_item doesn't work on 2503. armor anyway */ 2504. burn_stuff: 2505. if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) { 2506. /* save uarmf value because Boots_off() sets uarmf to NULL */ 2507. obj = uarmf; 2508. Your("%s burst into flame!", xname(obj)); 2509. (void) Boots_off(); 2510. useup(obj); 2511. } 2512. destroy_item(SCROLL_CLASS, AD_FIRE); 2513. destroy_item(SPBOOK_CLASS, AD_FIRE); 2514. destroy_item(POTION_CLASS, AD_FIRE); 2515. return(FALSE); 2516. } 2517. 2518. #endif /* OVLB */ 2519. 2520. /*trap.c*/