About: Source:NetHack 3.2.0/trap.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to trap.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/trap.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

AttributesValues
rdfs:label
  • Source:NetHack 3.2.0/trap.c
rdfs:comment
  • Below is the full text to trap.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/trap.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to trap.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/trap.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)trap.c 3.2 96/04/08 */ 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. STATIC_DCL void FDECL(dofiretrap, (struct obj *)); 8. STATIC_DCL void NDECL(domagictrap); 9. STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *)); 10. STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp)); 11. STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *)); 12. STATIC_DCL void FDECL(move_into_trap, (struct trap *)); 13. STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P)); 14. STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *)); 15. STATIC_DCL int FDECL(disarm_beartrap, (struct trap *)); 16. STATIC_DCL int FDECL(disarm_landmine, (struct trap *)); 17. STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *)); 18. STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int)); 19. STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int, BOOLEAN_P)); 20. STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *)); 21. STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int)); 22. STATIC_DCL int FDECL(mkroll_launch, 23. (struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long)); 24. STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P)); 25. 26. #ifndef OVLB 27. STATIC_VAR const char *a_your[2]; 28. STATIC_VAR const char *A_Your[2]; 29. STATIC_VAR const char *the_your[2]; 30. STATIC_VAR const char tower_of_flame[]; 31. STATIC_VAR const char *A_gush_of_water_hits; 32. 33. #else 34. 35. STATIC_VAR const char *a_your[2] = { "a", "your" }; 36. STATIC_VAR const char *A_Your[2] = { "A", "Your" }; 37. STATIC_VAR const char *the_your[2] = { "the", "your" }; 38. STATIC_VAR const char tower_of_flame[] = "tower of flame"; 39. STATIC_VAR const char *A_gush_of_water_hits = "A gush of water hits"; 40. 41. #endif /* OVLB */ 42. 43. #ifdef OVLB 44. 45. /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode) */ 46. boolean /* returns TRUE if hit on torso */ 47. burnarmor() 48. { 49. #define burn_dmg(obj,descr) rust_dmg(obj, descr, 0, FALSE) 50. while (1) { 51. switch (rn2(5)) { 52. case 0: 53. if (!burn_dmg(uarmh, "leather helmet")) continue; 54. break; 55. case 1: 56. if (uarmc) 57. (void) burn_dmg(uarmc, "cloak"); 58. else if (uarm) 59. (void) burn_dmg(uarm, xname(uarm)); 60. #ifdef TOURIST 61. else if (uarmu) 62. (void) burn_dmg(uarmu, "shirt"); 63. #endif 64. return TRUE; 65. case 2: 66. if (!burn_dmg(uarms, "wooden shield")) continue; 67. break; 68. case 3: 69. if (!burn_dmg(uarmg, "gloves")) continue; 70. break; 71. case 4: 72. if (!burn_dmg(uarmf, "boots")) continue; 73. break; 74. } 75. break; /* Out of while loop */ 76. } 77. return FALSE; 78. #undef burn_dmg 79. } 80. 81. /* Generic rust-armor function. Returns TRUE if a message was printed; 82. * "print", if set, means to print a message (and thus to return TRUE) even 83. * if the item could not be rusted; otherwise a message is printed and TRUE is 84. * returned only for rustable items. 85. */ 86. boolean 87. rust_dmg(otmp, ostr, type, print) 88. register struct obj *otmp; 89. register const char *ostr; 90. int type; 91. boolean print; 92. { 93. static NEARDATA const char *action[] = { "smoulder", "rust", "rot", "corrode" }; 94. static NEARDATA const char *msg[] = { "burnt", "rusted", "rotten", "corroded" }; 95. boolean vulnerable = FALSE; 96. boolean plural; 97. boolean grprot = FALSE; 98. 99. if (!otmp) return(FALSE); 100. switch(type) { 101. case 0: 102. case 2: vulnerable = is_flammable(otmp); break; 103. case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break; 104. case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break; 105. } 106. 107. if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE)) 108. return FALSE; 109. 110. plural = is_gloves(otmp) || is_boots(otmp); 111. 112. if (!vulnerable) { 113. if (flags.verbose) 114. Your("%s %s not affected.", ostr, plural ? "are" : "is"); 115. } else if (otmp->oeroded < MAX_ERODE) { 116. if (grprot && otmp->greased) { 117. grease_protect(otmp,ostr,plural); 118. } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) { 119. if (flags.verbose) 120. pline("Somehow, your %s %s not affected.", 121. ostr, plural ? "are" : "is"); 122. } else { 123. Your("%s %s%s%s!", ostr, action[type], 124. plural ? "" : "s", 125. otmp->oeroded+1 == MAX_ERODE ? " completely" : 126. otmp->oeroded ? " further" : ""); 127. otmp->oeroded++; 128. } 129. } else { 130. if (flags.verbose) 131. Your("%s %s%s completely %s.", ostr, 132. Blind ? "feel" : "look", 133. plural ? "" : "s", msg[type]); 134. } 135. return(TRUE); 136. } 137. 138. void 139. grease_protect(otmp,ostr,plu) 140. register struct obj *otmp; 141. register const char *ostr; 142. register boolean plu; 143. { 144. static const char txt[] = "protected by the layer of grease!"; 145. 146. if (ostr) 147. Your("%s %s %s",ostr,plu ? "are" : "is",txt); 148. else 149. Your("%s %s",aobjnam(otmp,"are"),txt); 150. if (!rn2(2)) { 151. pline_The("grease dissolves."); 152. otmp->greased = 0; 153. } 154. } 155. 156. struct trap * 157. maketrap(x,y,typ) 158. register int x, y, typ; 159. { 160. register struct trap *ttmp; 161. register struct rm *lev; 162. register boolean oldplace; 163. 164. if ((ttmp = t_at(x,y)) != 0) { 165. if (ttmp->ttyp == MAGIC_PORTAL) return (struct trap *)0; 166. oldplace = TRUE; 167. if (u.utrap && (x == u.ux) && (y == u.uy) && 168. ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) || 169. (u.utraptype == TT_WEB && typ != WEB) || 170. (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT))) 171. u.utrap = 0; 172. } else { 173. oldplace = FALSE; 174. ttmp = newtrap(); 175. ttmp->tx = x; 176. ttmp->ty = y; 177. ttmp->launch.x = -1; /* force error if used before set */ 178. ttmp->launch.y = -1; 179. } 180. ttmp->ttyp = typ; 181. switch(typ) { 182. case STATUE_TRAP: /* create a "living" statue */ 183. (void) mkcorpstat(STATUE, &mons[rndmonnum()], x, y, FALSE); 184. break; 185. case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */ 186. (void) mkroll_launch(ttmp, x, y, BOULDER, 1L); 187. break; 188. case HOLE: 189. case PIT: 190. case SPIKED_PIT: 191. case TRAPDOOR: 192. lev = &levl[x][y]; 193. if (*in_rooms(x, y, SHOPBASE) && 194. ((typ == HOLE || typ == TRAPDOOR) || IS_DOOR(lev->typ))) 195. add_damage(x, y, /* schedule repair */ 196. (IS_DOOR(lev->typ) && !flags.mon_moving) ? 200L : 0L); 197. lev->doormask = 0; /* subsumes altarmask, icedpool... */ 198. if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */ 199. lev->typ = ROOM; 200. 201. /* 202. * some cases which can happen when digging 203. * down while phazing thru solid areas 204. */ 205. else if (lev->typ == STONE || lev->typ == SCORR) 206. lev->typ = CORR; 207. else if (IS_WALL(lev->typ) || lev->typ == SDOOR) 208. lev->typ = level.flags.is_maze_lev ? ROOM : 209. level.flags.is_cavernous_lev ? CORR : DOOR; 210. 211. unearth_objs(x, y); 212. break; 213. } 214. if (ttmp->ttyp == HOLE) ttmp->tseen = 1; /* You can't hide a hole */ 215. else ttmp->tseen = 0; 216. ttmp->once = 0; 217. ttmp->madeby_u = 0; 218. ttmp->dst.dnum = -1; 219. ttmp->dst.dlevel = -1; 220. if (!oldplace) { 221. ttmp->ntrap = ftrap; 222. ftrap = ttmp; 223. } 224. return(ttmp); 225. } 226. 227. void 228. fall_through(td) 229. boolean td; /* td == TRUE : trapdoor or hole */ 230. { 231. d_level dtmp; 232. char msgbuf[BUFSZ]; 233. const char *dont_fall = 0; 234. register int newlevel = dunlev(&u.uz); 235. 236. if(Blind && Levitation) return; 237. 238. do { 239. newlevel++; 240. } while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz)); 241. 242. if(td) { 243. struct trap *t=t_at(u.ux,u.uy); 244. if (t->ttyp == TRAPDOOR) 245. pline("A trap door opens up under you!"); 246. else 247. pline("There's a gaping hole under you!"); 248. } else pline_The("%s opens up under you!", surface(u.ux,u.uy)); 249. 250. if(Levitation || u.ustuck || !Can_fall_thru(&u.uz) 251. || is_flyer(uasmon) || is_clinger(uasmon) 252. || (Inhell && !u.uevent.invoked && 253. newlevel == dunlevs_in_dungeon(&u.uz)) 254. ) { 255. dont_fall = "don't fall in."; 256. } else if (uasmon->msize >= MZ_HUGE) { 257. dont_fall = "don't fit through."; 258. } else if (!next_to_u()) { 259. dont_fall = "are jerked back by your pet!"; 260. } 261. if (dont_fall) { 262. You(dont_fall); 263. /* hero didn't fall through, but any objects here might */ 264. impact_drop((struct obj *)0, u.ux, u.uy, 0); 265. if (!td) { 266. display_nhwindow(WIN_MESSAGE, FALSE); 267. pline_The("opening under you closes up."); 268. } 269. return; 270. } 271. 272. if(*u.ushops) shopdig(1); 273. if (Is_stronghold(&u.uz)) { 274. find_hell(&dtmp); 275. } else { 276. dtmp.dnum = u.uz.dnum; 277. dtmp.dlevel = newlevel; 278. } 279. if (!td) 280. Sprintf(msgbuf, "The hole in the %s above you closes up.", 281. ceiling(u.ux,u.uy)); 282. schedule_goto(&dtmp, FALSE, TRUE, 0, 283. (char *)0, !td ? msgbuf : (char *)0); 284. } 285. 286. /* you've either stepped onto a statue trap's location 287. or you've triggered a statue trap by searching next to it */ 288. void 289. activate_statue_trap(trap, x, y) 290. struct trap *trap; 291. xchar x, y; 292. { 293. struct monst *mtmp; 294. struct obj *otmp = sobj_at(STATUE, x, y); 295. 296. deltrap(trap); 297. if (otmp && (mtmp = makemon(&mons[otmp->corpsenm], x, y)) != 0) { 298. delobj(otmp); 299. /* mimic statue becomes seen mimic; other hiders won't be hidden */ 300. if (mtmp->m_ap_type) seemimic(mtmp); 301. else mtmp->mundetected = FALSE; 302. if (x == u.ux && y == u.uy) 303. pline_The("statue comes to life!"); 304. else 305. You("find %s posing as a statue.", a_monnam(mtmp)); 306. /* avoid hiding under nothing */ 307. if (x == u.ux && y == u.uy && 308. Upolyd && hides_under(uasmon) && !OBJ_AT(x, y)) 309. u.uundetected = 0; 310. } 311. if (Blind) feel_location(x, y); 312. else newsym(x, y); 313. } 314. 315. void 316. dotrap(trap) 317. register struct trap *trap; 318. { 319. register int ttype = trap->ttyp; 320. register struct monst *mtmp; 321. register struct obj *otmp; 322. boolean already_seen = trap->tseen; 323. 324. nomul(0); 325. if(already_seen) { 326. if ((Levitation || is_flyer(uasmon)) && 327. (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE || 328. ttype == BEAR_TRAP)) { 329. You("%s over %s %s.", 330. Levitation ? "float" : "fly", 331. a_your[trap->madeby_u], 332. defsyms[trap_to_defsym(ttype)].explanation); 333. return; 334. } 335. if(!Fumbling && ttype != MAGIC_PORTAL && ttype != ANTI_MAGIC && 336. (!rn2(5) || 337. ((ttype == PIT || ttype == SPIKED_PIT) && is_clinger(uasmon)))) { 338. You("escape %s %s.", 339. (ttype == ARROW_TRAP && !trap->madeby_u) ? "an" : 340. a_your[trap->madeby_u], 341. defsyms[trap_to_defsym(ttype)].explanation); 342. return; 343. } 344. } 345. 346. switch(ttype) { 347. case ARROW_TRAP: 348. seetrap(trap); 349. pline("An arrow shoots out at you!"); 350. otmp = mksobj(ARROW, TRUE, FALSE); 351. otmp->quan = 1L; 352. otmp->owt = weight(otmp); 353. if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) { 354. obfree(otmp, (struct obj *)0); 355. } else { 356. place_object(otmp, u.ux, u.uy); 357. if (!Blind) otmp->dknown = 1; 358. stackobj(otmp); 359. newsym(u.ux, u.uy); 360. } 361. break; 362. case DART_TRAP: 363. seetrap(trap); 364. pline("A little dart shoots out at you!"); 365. otmp = mksobj(DART, TRUE, FALSE); 366. otmp->quan = 1L; 367. otmp->owt = weight(otmp); 368. if (!rn2(6)) otmp->opoisoned = 1; 369. if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { 370. if (otmp->opoisoned) 371. poisoned("dart",A_CON,"poison dart",10); 372. obfree(otmp, (struct obj *)0); 373. } else { 374. place_object(otmp, u.ux, u.uy); 375. if (!Blind) otmp->dknown = 1; 376. stackobj(otmp); 377. newsym(u.ux, u.uy); 378. } 379. break; 380. case ROCKTRAP: 381. { 382. int dmg = d(2,6); /* should be std ROCK dmg? */ 383. 384. seetrap(trap); 385. otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE); 386. otmp->quan = 1L; 387. otmp->owt = weight(otmp); 388. 389. pline("A trap door in the %s opens and a rock falls on your %s!", 390. ceiling(u.ux,u.uy), 391. body_part(HEAD)); 392. 393. if (uarmh) { 394. if(is_metallic(uarmh)) { 395. pline("Fortunately, you are wearing a hard helmet."); 396. dmg = 2; 397. } else if (flags.verbose) { 398. Your("%s does not protect you.", xname(uarmh)); 399. } 400. } 401. 402. if (!Blind) otmp->dknown = 1; 403. stackobj(otmp); 404. newsym(u.ux,u.uy); /* map the rock */ 405. 406. losehp(dmg, "falling rock", KILLED_BY_AN); 407. exercise(A_STR, FALSE); 408. } 409. break; 410. 411. case SQKY_BOARD: /* stepped on a squeaky board */ 412. if (Levitation || is_flyer(uasmon)) { 413. if (!Blind) { 414. seetrap(trap); 415. if (Hallucination) 416. You("notice a crease in the linoleum."); 417. else 418. You("notice a loose board below you."); 419. } 420. } else { 421. seetrap(trap); 422. pline("A board beneath you squeaks loudly."); 423. wake_nearby(); 424. } 425. break; 426. 427. case BEAR_TRAP: 428. if(Levitation || is_flyer(uasmon)) break; 429. seetrap(trap); 430. if(amorphous(uasmon) || is_whirly(uasmon) || 431. unsolid(uasmon)) { 432. pline("%s bear trap closes harmlessly through you.", 433. A_Your[trap->madeby_u]); 434. break; 435. } 436. if(uasmon->msize <= MZ_SMALL) { 437. pline("%s bear trap closes harmlessly over you.", 438. A_Your[trap->madeby_u]); 439. break; 440. } 441. u.utrap = rn1(4, 4); 442. u.utraptype = TT_BEARTRAP; 443. pline("%s bear trap closes on your %s!", 444. A_Your[trap->madeby_u], body_part(FOOT)); 445. if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) 446. You("howl in anger!"); 447. exercise(A_DEX, FALSE); 448. break; 449. 450. case SLP_GAS_TRAP: 451. seetrap(trap); 452. if(Sleep_resistance) { 453. You("are enveloped in a cloud of gas!"); 454. break; 455. } 456. pline("A cloud of gas puts you to sleep!"); 457. flags.soundok = 0; 458. fall_asleep(-rnd(25), TRUE); 459. afternmv = Hear_again; 460. break; 461. 462. case RUST_TRAP: 463. seetrap(trap); 464. if (u.umonnum == PM_IRON_GOLEM) { 465. pline("%s you!", A_gush_of_water_hits); 466. You("are covered with rust!"); 467. rehumanize(); 468. break; 469. } else if (u.umonnum == PM_GREMLIN && rn2(3)) { 470. pline("%s you!", A_gush_of_water_hits); 471. if ((mtmp = cloneu()) != 0) { 472. mtmp->mhpmax = (u.mhmax /= 2); 473. You("multiply."); 474. } 475. break; 476. } 477. 478. /* Unlike monsters, traps cannot aim their rust attacks at 479. * you, so instead of looping through and taking either the 480. * first rustable one or the body, we take whatever we get, 481. * even if it is not rustable. 482. */ 483. switch (rn2(5)) { 484. case 0: 485. pline("%s you on the %s!", A_gush_of_water_hits, 486. body_part(HEAD)); 487. (void) rust_dmg(uarmh, "helmet", 1, TRUE); 488. break; 489. case 1: 490. pline("%s your left %s!", A_gush_of_water_hits, 491. body_part(ARM)); 492. if (rust_dmg(uarms, "shield", 1, TRUE)) break; 493. if (uwep && bimanual(uwep)) 494. goto two_hand; 495. /* Two goto statements in a row--aaarrrgggh! */ 496. glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE); 497. /* Not "metal gauntlets" since it gets called 498. * even if it's leather for the message 499. */ 500. break; 501. case 2: 502. pline("%s your right %s!", A_gush_of_water_hits, 503. body_part(ARM)); 504. two_hand: erode_weapon(FALSE); 505. goto glovecheck; 506. default: 507. pline("%s you!", A_gush_of_water_hits); 508. for (otmp=invent; otmp; otmp = otmp->nobj) 509. (void) snuff_lit(otmp); 510. if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE); 511. else if (uarm) 512. (void) rust_dmg(uarm, "armor", 1, TRUE); 513. #ifdef TOURIST 514. else if (uarmu) 515. (void) rust_dmg(uarmu, "shirt", 1, TRUE); 516. #endif 517. } 518. break; 519. 520. case FIRE_TRAP: 521. seetrap(trap); 522. dofiretrap((struct obj *)0); 523. break; 524. 525. case PIT: 526. case SPIKED_PIT: 527. if (Levitation || is_flyer(uasmon)) break; 528. seetrap(trap); 529. if (is_clinger(uasmon)) { 530. if(trap->tseen) { 531. You("see %s %spit below you.", a_your[trap->madeby_u], 532. ttype == SPIKED_PIT ? "spiked " : ""); 533. } else { 534. pline("%s pit %sopens up under you!", 535. A_Your[trap->madeby_u], 536. ttype == SPIKED_PIT ? "full of spikes " : ""); 537. You("don't fall in!"); 538. } 539. break; 540. } 541. You("fall into %s pit!", a_your[trap->madeby_u]); 542. if (ttype == SPIKED_PIT) 543. You("land on a set of sharp iron spikes!"); 544. if (!passes_walls(uasmon)) 545. u.utrap = rn1(6,2); 546. u.utraptype = TT_PIT; 547. if (ttype == SPIKED_PIT) { 548. losehp(rnd(10),"fell into a pit of iron spikes", 549. NO_KILLER_PREFIX); 550. if (!rn2(6)) 551. poisoned("spikes", A_STR, "fall onto poison spikes", 8); 552. } else 553. losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX); 554. if (Punished && !carried(uball)) { 555. unplacebc(); 556. ballfall(); 557. placebc(); 558. } 559. selftouch("Falling, you"); 560. vision_full_recalc = 1; /* vision limits change */ 561. exercise(A_STR, FALSE); 562. exercise(A_DEX, FALSE); 563. break; 564. case HOLE: 565. case TRAPDOOR: 566. seetrap(trap); 567. if(!Can_fall_thru(&u.uz)) 568. panic("Holes & trapdoors cannot exist on this level."); 569. fall_through(TRUE); 570. break; 571. 572. case TELEP_TRAP: 573. seetrap(trap); 574. tele_trap(trap); 575. break; 576. case LEVEL_TELEP: 577. seetrap(trap); 578. level_tele_trap(trap); 579. break; 580. 581. case WEB: /* Our luckless player has stumbled into a web. */ 582. seetrap(trap); 583. if (amorphous(uasmon) || is_whirly(uasmon) || 584. unsolid(uasmon)) { 585. if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE || 586. u.umonnum == PM_FIRE_ELEMENTAL) { 587. You("%s %s spider web!", 588. (u.umonnum == PM_FIRE_ELEMENTAL) ? "burn" : "dissolve", 589. a_your[trap->madeby_u]); 590. deltrap(trap); 591. newsym(u.ux,u.uy); 592. break; 593. } 594. You("flow through %s spider web.", 595. a_your[trap->madeby_u]); 596. break; 597. } 598. if (uasmon->mlet == S_SPIDER) { 599. pline(trap->madeby_u ? "You take a walk on your web." 600. : "There is a spider web here."); 601. break; 602. } 603. You("%s into %s spider web!", 604. Levitation ? (const char *)"float" : 605. locomotion(uasmon, "stumble"), 606. a_your[trap->madeby_u]); 607. u.utraptype = TT_WEB; 608. 609. /* Time stuck in the web depends on your strength. */ 610. { 611. register int str = ACURR(A_STR); 612. 613. if (str == 3) u.utrap = rn1(6,6); 614. else if (str < 6) u.utrap = rn1(6,4); 615. else if (str < 9) u.utrap = rn1(4,4); 616. else if (str < 12) u.utrap = rn1(4,2); 617. else if (str < 15) u.utrap = rn1(2,2); 618. else if (str < 18) u.utrap = rnd(2); 619. else if (str < 69) u.utrap = 1; 620. else { 621. u.utrap = 0; 622. You("tear through %s web!", a_your[trap->madeby_u]); 623. deltrap(trap); 624. newsym(u.ux,u.uy); /* get rid of trap symbol */ 625. } 626. } 627. break; 628. 629. case STATUE_TRAP: 630. activate_statue_trap(trap, u.ux, u.uy); 631. break; 632. 633. case MAGIC_TRAP: /* A magic trap. */ 634. seetrap(trap); 635. if (!rn2(30)) { 636. deltrap(trap); 637. newsym(u.ux,u.uy); /* update position */ 638. You("are caught in a magical explosion!"); 639. losehp(rnd(10), "magical explosion", KILLED_BY_AN); 640. Your("body absorbs some of the magical energy!"); 641. u.uen = (u.uenmax += 2); 642. } else domagictrap(); 643. break; 644. 645. case ANTI_MAGIC: 646. seetrap(trap); 647. if(Antimagic) { 648. shieldeff(u.ux, u.uy); 649. You_feel("momentarily lethargic."); 650. } else drain_en(rnd(u.ulevel) + 1); 651. break; 652. 653. case POLY_TRAP: 654. seetrap(trap); 655. You("%s onto a polymorph trap!", 656. Levitation ? (const char *)"float" : 657. locomotion(uasmon, "step")); 658. if(Antimagic) { 659. shieldeff(u.ux, u.uy); 660. You_feel("momentarily different."); 661. /* Trap did nothing; don't remove it --KAA */ 662. } else { 663. deltrap(trap); /* delete trap before polymorph */ 664. newsym(u.ux,u.uy); /* get rid of trap symbol */ 665. You_feel("a change coming over you."); 666. polyself(); 667. } 668. break; 669. 670. case LANDMINE: 671. if (Levitation || is_flyer(uasmon)) { 672. if (!already_seen && rn2(3)) break; 673. seetrap(trap); 674. pline("%s %s in a pile of soil below you.", 675. already_seen ? "There is" : "You discover", 676. trap->madeby_u ? "the trigger of your mine" : 677. "a trigger"); 678. if (already_seen && rn2(3)) break; 679. pline("KAABLAMM!!! The air currents set %s%s off!", 680. already_seen ? a_your[trap->madeby_u] : "", 681. already_seen ? " land mine" : "it"); 682. } else { 683. seetrap(trap); 684. pline("KAABLAMM!!! You triggered %s land mine!", 685. a_your[trap->madeby_u]); 686. set_wounded_legs(LEFT_SIDE, rn1(35, 41)); 687. set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); 688. exercise(A_DEX, FALSE); 689. } 690. scatter(u.ux, u.uy, 4, 691. MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS); 692. del_engr_at(u.ux, u.uy); 693. wake_nearto(u.ux, u.uy, 500); 694. trap->ttyp = PIT; /* turn the mine into a pit */ 695. trap->madeby_u = FALSE; /* resulting pit isn't yours */ 696. if (IS_DOOR(levl[u.ux][u.uy].typ)) 697. levl[u.ux][u.uy].doormask = D_BROKEN; 698. newsym(u.ux,u.uy); /* update trap symbol */ 699. losehp(rnd(16), "land mine", KILLED_BY_AN); 700. dotrap(trap); /* fall recursively into the pit... */ 701. break; 702. 703. case ROLLING_BOULDER_TRAP: 704. seetrap(trap); 705. pline("Click! You trigger a rolling boulder trap!"); 706. if(!launch_obj(BOULDER, trap->launch.x, trap->launch.y, 707. trap->launch2.x,trap->launch2.y, ROLL)) { 708. deltrap(trap); 709. newsym(u.ux,u.uy); /* get rid of trap symbol */ 710. pline("Fortunately for you, no boulder was released."); 711. } 712. break; 713. 714. case MAGIC_PORTAL: 715. seetrap(trap); 716. domagicportal(trap); 717. break; 718. 719. default: 720. seetrap(trap); 721. impossible("You hit a trap of type %u", trap->ttyp); 722. } 723. } 724. #endif /* OVLB */ 725. #ifdef OVL3 726. 727. /* 728. * Move obj from (x1,y1) to (x2,y2) 729. * 730. * Return 0 if no object was launched. 731. * 1 if an object was launched and placed somewhere. 732. * 2 if an object was launched, but used up. 733. */ 734. int 735. launch_obj(otyp, x1, y1, x2, y2, style) 736. short otyp; 737. register int x1,y1,x2,y2; 738. int style; 739. { 740. register struct monst *mtmp; 741. register struct obj *otmp; 742. register int dx,dy; 743. struct obj *singleobj; 744. boolean used_up = FALSE; 745. boolean otherside = FALSE; 746. int dist; 747. int tmp; 748. int delaycnt = 0; 749. 750. otmp = sobj_at(otyp, x1, y1); 751. /* Try the other side too, for rolling boulder traps */ 752. if (!otmp && otyp == BOULDER) { 753. otherside = TRUE; 754. otmp = sobj_at(otyp, x2, y2); 755. } 756. if (!otmp) return 0; 757. if (otherside) { /* swap 'em */ 758. int tx, ty; 759. 760. tx = x1; ty = y1; 761. x1 = x2; y1 = y2; 762. x2 = tx; y2 = ty; 763. } 764. 765. if (otmp->quan == 1L) { 766. obj_extract_self(otmp); 767. singleobj = otmp; 768. otmp = (struct obj *) 0; 769. } else { 770. singleobj = splitobj(otmp, otmp->quan - 1L); 771. obj_extract_self(singleobj); 772. } 773. newsym(x1,y1); 774. /* in case you're using a pick-axe to chop the boulder that's being 775. launched (perhaps a monster triggered it), destroy context so that 776. next dig attempt never thinks you're resuming previous effort */ 777. if ((otyp == BOULDER || otyp == STATUE) && 778. singleobj->ox == digging.pos.x && singleobj->oy == digging.pos.y) 779. (void) memset((genericptr_t)&digging, 0, sizeof digging); 780. 781. dist = distmin(x1,y1,x2,y2); 782. bhitpos.x = x1; 783. bhitpos.y = y1; 784. dx = sgn(x2 - x1); 785. dy = sgn(y2 - y1); 786. switch (style) { 787. case ROLL: 788. delaycnt = 2; 789. /* fall through */ 790. default: 791. if (!delaycnt) delaycnt = 1; 792. if (!cansee(bhitpos.x,bhitpos.y)) curs_on_u(); 793. tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); 794. tmp_at(bhitpos.x, bhitpos.y); 795. } 796. while(dist-- > 0 && !used_up) { 797. tmp_at(bhitpos.x, bhitpos.y); 798. tmp = delaycnt; 799. while (tmp-- > 0) delay_output(); 800. bhitpos.x += dx; 801. bhitpos.y += dy; 802. 803. if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { 804. if (otyp == BOULDER && throws_rocks(mtmp->data)) { 805. if (rn2(3)) { 806. pline("%s snatches the boulder.", 807. Monnam(mtmp)); 808. mpickobj(mtmp, singleobj); 809. used_up = TRUE; 810. break; 811. } 812. } 813. if (ohitmon(mtmp,singleobj, 814. (style==ROLL) ? -1 : dist, FALSE)) { 815. used_up = TRUE; 816. break; 817. } 818. } else if (bhitpos.x==u.ux && bhitpos.y==u.uy) { 819. int hitvalu, hitu; 820. if (multi) nomul(0); 821. hitvalu = 9 + singleobj->spe; 822. hitu = thitu(hitvalu, 823. dmgval(singleobj, &youmonst), 824. singleobj, 825. xname(singleobj)); 826. if (hitu) stop_occupation(); 827. } 828. if (style == ROLL) { 829. if (down_gate(bhitpos.x, bhitpos.y) != -1) { 830. if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){ 831. used_up = TRUE; 832. break; 833. } 834. } 835. if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) { 836. used_up = TRUE; 837. break; 838. } 839. } 840. if (otyp == BOULDER && closed_door(bhitpos.x,bhitpos.y)) { 841. if (cansee(bhitpos.x, bhitpos.y)) 842. pline_The("boulder crashes through a door."); 843. levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN; 844. } 845. } 846. tmp_at(DISP_END, 0); 847. if (!used_up) { 848. place_object(singleobj, x2,y2); 849. newsym(x2,y2); 850. return 1; 851. } else 852. return 2; 853. } 854. #endif /* OVL3 */ 855. #ifdef OVLB 856. 857. void 858. seetrap(trap) 859. register struct trap *trap; 860. { 861. if(!trap->tseen) { 862. trap->tseen = 1; 863. newsym(trap->tx, trap->ty); 864. } 865. } 866. 867. #endif /* OVLB */ 868. #ifdef OVL3 869. 870. STATIC_OVL int 871. mkroll_launch(ttmp, x, y, otyp, ocount) 872. struct trap *ttmp; 873. xchar x,y; 874. short otyp; 875. long ocount; 876. { 877. struct obj *otmp; 878. register int tmp; 879. schar dx,dy; 880. int distance; 881. coord cc; 882. coord bcc; 883. int trycount = 0; 884. boolean success = FALSE; 885. int mindist = 4; 886. 887. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) mindist = 2; 888. distance = rn1(5,4); /* 4..8 away */ 889. tmp = rn2(8); /* randomly pick a direction to try first */ 890. while (distance >= mindist) { 891. dx = xdir[tmp]; 892. dy = ydir[tmp]; 893. cc.x = x; cc.y = y; 894. /* Prevent boulder from being placed on water */ 895. if (ttmp->ttyp == ROLLING_BOULDER_TRAP 896. && is_pool(x+distance*dx,y+distance*dy)) 897. success = FALSE; 898. else success = isclearpath(&cc, distance, dx, dy); 899. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 900. boolean success_otherway; 901. bcc.x = x; bcc.y = y; 902. success_otherway = isclearpath(&bcc, distance, 903. -(dx), -(dy)); 904. if (!success_otherway) success = FALSE; 905. } 906. if (success) break; 907. if (++tmp > 7) tmp = 0; 908. if ((++trycount % 8) == 0) --distance; 909. } 910. if (!success) { 911. /* create the trap without any ammo, launch pt at trap location */ 912. cc.x = bcc.x = x; 913. cc.y = bcc.y = y; 914. } else { 915. otmp = mksobj(otyp, TRUE, FALSE); 916. otmp->quan = ocount; 917. otmp->owt = weight(otmp); 918. place_object(otmp, cc.x, cc.y); 919. stackobj(otmp); 920. } 921. ttmp->launch.x = cc.x; 922. ttmp->launch.y = cc.y; 923. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 924. ttmp->launch2.x = bcc.x; 925. ttmp->launch2.y = bcc.y; 926. } else 927. ttmp->launch_otyp = otyp; 928. newsym(ttmp->launch.x, ttmp->launch.y); 929. return 1; 930. } 931. 932. STATIC_OVL boolean 933. isclearpath(cc,distance,dx,dy) 934. coord *cc; 935. int distance; 936. schar dx,dy; 937. { 938. uchar typ; 939. xchar x, y; 940. 941. x = cc->x; 942. y = cc->y; 943. while (distance-- > 0) { 944. x += dx; 945. y += dy; 946. typ = levl[x][y].typ; 947. if (!isok(x,y) || !ZAP_POS(typ) || closed_door(x,y)) 948. return FALSE; 949. } 950. cc->x = x; 951. cc->y = y; 952. return TRUE; 953. } 954. #endif /* OVL3 */ 955. #ifdef OVL1 956. 957. int 958. mintrap(mtmp) 959. register struct monst *mtmp; 960. { 961. register struct trap *trap = t_at(mtmp->mx, mtmp->my); 962. boolean trapkilled = FALSE; 963. struct permonst *mptr = mtmp->data; 964. struct obj *otmp; 965. 966. if(!trap) { 967. mtmp->mtrapped = 0; /* perhaps teleported? */ 968. } else if (mtmp->mtrapped) { /* was in trap */ 969. if(!rn2(40)) { 970. if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 971. ((trap->ttyp == PIT) || 972. (trap->ttyp == SPIKED_PIT))) { 973. if (!rn2(2)) { 974. mtmp->mtrapped = 0; 975. fill_pit(mtmp->mx, mtmp->my); 976. } 977. } else 978. mtmp->mtrapped = 0; 979. } else if (trap->ttyp == BEAR_TRAP && metallivorous(mptr)) { 980. if (canseemon(mtmp)) 981. pline("%s eats a bear trap!", Monnam(mtmp)); 982. deltrap(trap); 983. mtmp->meating = 5; 984. mtmp->mtrapped = 0; 985. } 986. } else { 987. register int tt = trap->ttyp; 988. boolean in_sight, tear_web, see_it; 989. 990. if ((mtmp->mtrapseen & (1 << (tt-1))) != 0 || 991. (tt == HOLE && !mindless(mtmp->data))) { 992. /* it has been in such a trap - perhaps it escapes */ 993. if(rn2(4)) return(0); 994. } else { 995. mtmp->mtrapseen |= (1 << (tt-1)); 996. } 997. /* Monster is aggravated by being trapped by you. 998. Recognizing who made the trap isn't completely 999. unreasonable; everybody has their own style. */ 1000. if (trap->madeby_u && rnl(5)) setmangry(mtmp); 1001. 1002. /* bug? `in_sight' ought to be split to distinguish between 1003. trap_in_sight and can_see_victim to handle invisible monsters */ 1004. in_sight = canseemon(mtmp); 1005. switch (tt) { 1006. case ARROW_TRAP: 1007. otmp = mksobj(ARROW, TRUE, FALSE); 1008. otmp->quan = 1L; 1009. otmp->owt = weight(otmp); 1010. if (in_sight) seetrap(trap); 1011. if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 1012. break; 1013. case DART_TRAP: 1014. otmp = mksobj(DART, TRUE, FALSE); 1015. otmp->quan = 1L; 1016. otmp->owt = weight(otmp); 1017. if (!rn2(6)) otmp->opoisoned = 1; 1018. if (in_sight) seetrap(trap); 1019. if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 1020. break; 1021. case ROCKTRAP: 1022. otmp = mksobj(ROCK, TRUE, FALSE); 1023. otmp->quan = 1L; 1024. otmp->owt = weight(otmp); 1025. if (in_sight) seetrap(trap); 1026. if (is_whirly(mptr) || passes_walls(mptr)) { 1027. if (in_sight) 1028. pline("A rock falls harmlessly through %s.", 1029. mon_nam(mtmp)); 1030. else if (cansee(mtmp->mx, mtmp->my)) 1031. pline("A rock falls to the %s.", 1032. surface(mtmp->mx, mtmp->my)); 1033. place_object(otmp, mtmp->mx, mtmp->my); 1034. stackobj(otmp); 1035. } else if (thitm(0, mtmp, otmp, d(2, 6))) 1036. trapkilled = TRUE; 1037. break; 1038. 1039. case SQKY_BOARD: 1040. if(is_flyer(mptr)) break; 1041. /* stepped on a squeaky board */ 1042. if (in_sight) { 1043. pline("A board beneath %s squeaks loudly.", mon_nam(mtmp)); 1044. seetrap(trap); 1045. } else 1046. You_hear("a distant squeak."); 1047. /* wake up nearby monsters */ 1048. wake_nearto(mtmp->mx, mtmp->my, 40); 1049. break; 1050. 1051. case BEAR_TRAP: 1052. if(mptr->msize > MZ_SMALL && 1053. !amorphous(mptr) && !is_flyer(mptr) && 1054. !is_whirly(mptr) && !unsolid(mptr)) { 1055. mtmp->mtrapped = 1; 1056. if(in_sight) { 1057. pline("%s is caught in %s bear trap!", 1058. Monnam(mtmp), a_your[trap->madeby_u]); 1059. seetrap(trap); 1060. } else { 1061. if((mptr == &mons[PM_OWLBEAR] 1062. || mptr == &mons[PM_BUGBEAR]) 1063. && flags.soundok) 1064. You_hear("the roaring of an angry bear!"); 1065. } 1066. } 1067. break; 1068. 1069. case SLP_GAS_TRAP: 1070. if (!resists_sleep(mtmp) && 1071. !mtmp->msleep && mtmp->mcanmove) { 1072. mtmp->mcanmove = 0; 1073. mtmp->mfrozen = rnd(25); 1074. if (in_sight) { 1075. pline("%s suddenly falls asleep!", 1076. Monnam(mtmp)); 1077. seetrap(trap); 1078. } 1079. } 1080. break; 1081. 1082. case RUST_TRAP: 1083. if (in_sight) { 1084. pline("%s %s!", A_gush_of_water_hits, 1085. mon_nam(mtmp)); 1086. seetrap(trap); 1087. } 1088. if (mptr == &mons[PM_IRON_GOLEM]) { 1089. if (in_sight) 1090. pline("%s falls to pieces!", Monnam(mtmp)); 1091. else if(mtmp->mtame) 1092. pline("May %s rust in peace.", 1093. mon_nam(mtmp)); 1094. mondied(mtmp); 1095. if (mtmp->mhp <= 0) 1096. trapkilled = TRUE; 1097. } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { 1098. struct monst *mtmp2 = clone_mon(mtmp); 1099. 1100. if (mtmp2) { 1101. mtmp2->mhpmax = (mtmp->mhpmax /= 2); 1102. if(in_sight) 1103. pline("%s multiplies.", Monnam(mtmp)); 1104. } 1105. } 1106. if (rn2(2)) 1107. for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 1108. (void) snuff_lit(otmp); 1109. break; 1110. 1111. case FIRE_TRAP: 1112. mfiretrap: 1113. see_it = cansee(mtmp->mx, mtmp->my); 1114. if (in_sight) 1115. pline("A %s erupts from the %s under %s!", 1116. tower_of_flame, 1117. surface(mtmp->mx,mtmp->my), mon_nam(mtmp)); 1118. else if (see_it) /* evidently `mtmp' is invisible */ 1119. You("see a %s erupt from the %s!", 1120. tower_of_flame, surface(mtmp->mx,mtmp->my)); 1121. 1122. if (resists_fire(mtmp)) { 1123. if (in_sight) { 1124. shieldeff(mtmp->mx,mtmp->my); 1125. pline("%s is uninjured.", Monnam(mtmp)); 1126. } 1127. } else { 1128. int num = d(2,4); 1129. 1130. if (thitm(0, mtmp, (struct obj *)0, num)) 1131. trapkilled = TRUE; 1132. else 1133. /* we know mhp is at least `num' below mhpmax, 1134. so no (mhp > mhpmax) check is needed here */ 1135. mtmp->mhpmax -= rn2(num + 1); 1136. } 1137. (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1138. (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1139. (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1140. if (burn_floor_paper(mtmp->mx, mtmp->my, see_it) && 1141. !see_it && distu(mtmp->mx, mtmp->my) <= 3*3) 1142. You("smell smoke."); 1143. if (is_ice(mtmp->mx,mtmp->my)) 1144. melt_ice(mtmp->mx,mtmp->my); 1145. if (see_it) seetrap(trap); 1146. break; 1147. 1148. case PIT: 1149. case SPIKED_PIT: 1150. if ( !is_flyer(mptr) && 1151. (!mtmp->wormno || (count_wsegs(mtmp) < 6)) && 1152. !is_clinger(mptr) ) { 1153. if (!passes_walls(mptr)) 1154. mtmp->mtrapped = 1; 1155. if(in_sight) { 1156. pline("%s falls into %s pit!", 1157. Monnam(mtmp), a_your[trap->madeby_u]); 1158. seetrap(trap); 1159. } 1160. mselftouch(mtmp, "Falling, ", FALSE); 1161. if(mtmp->mhp <= 0 || 1162. thitm(0, mtmp, (struct obj *)0, 1163. rnd((tt==PIT) ? 6 : 10))) 1164. trapkilled = TRUE; 1165. } 1166. break; 1167. case HOLE: 1168. case TRAPDOOR: 1169. if(!Can_fall_thru(&u.uz)) 1170. panic("Holes & trapdoors cannot exist on this level."); 1171. 1172. if (is_flyer(mptr) || mptr == &mons[PM_WUMPUS] || 1173. (mtmp->wormno && count_wsegs(mtmp) > 5) || 1174. mptr->msize >= MZ_HUGE) break; 1175. /* Fall through */ 1176. case LEVEL_TELEP: 1177. case MAGIC_PORTAL: 1178. { 1179. int mlev_res; 1180. mlev_res = mlevel_tele_trap(mtmp, trap, in_sight); 1181. if (mlev_res) return(mlev_res); 1182. } 1183. break; 1184. 1185. case TELEP_TRAP: 1186. mtele_trap(mtmp, trap, in_sight); 1187. break; 1188. 1189. case WEB: 1190. /* Monster in a web. */ 1191. if (mptr->mlet == S_SPIDER) break; 1192. if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)){ 1193. if(acidic(mptr) || 1194. mptr == &mons[PM_GELATINOUS_CUBE] || 1195. mptr == &mons[PM_FIRE_ELEMENTAL]) { 1196. if (in_sight) 1197. pline("%s %s %s spider web!", 1198. Monnam(mtmp), 1199. (mptr == &mons[PM_FIRE_ELEMENTAL]) ? 1200. "burns" : "dissolves", 1201. a_your[trap->madeby_u]); 1202. deltrap(trap); 1203. newsym(mtmp->mx, mtmp->my); 1204. break; 1205. } 1206. if (in_sight) { 1207. pline("%s flows through %s spider web.", 1208. Monnam(mtmp), 1209. a_your[trap->madeby_u]); 1210. seetrap(trap); 1211. } 1212. break; 1213. } 1214. tear_web = FALSE; 1215. switch (monsndx(mptr)) { 1216. case PM_OWLBEAR: /* Eric Backus */ 1217. case PM_BUGBEAR: 1218. if (!in_sight) { 1219. You_hear("the roaring of a confused bear!"); 1220. mtmp->mtrapped = 1; 1221. break; 1222. } 1223. /* fall though */ 1224. default: 1225. if (mptr->mlet == S_GIANT || 1226. (mptr->mlet == S_DRAGON && 1227. extra_nasty(mptr)) || /* excl. babies */ 1228. (mtmp->wormno && count_wsegs(mtmp) > 5)) { 1229. tear_web = TRUE; 1230. } else if (in_sight) { 1231. pline("%s is caught in %s spider web.", 1232. Monnam(mtmp), 1233. a_your[trap->madeby_u]); 1234. seetrap(trap); 1235. } 1236. mtmp->mtrapped = tear_web ? 0 : 1; 1237. break; 1238. /* this list is fairly arbitrary; it deliberately 1239. excludes wumpus & giant/ettin zombies/mummies */ 1240. case PM_TITANOTHERE: 1241. case PM_BALUCHITHERIUM: 1242. case PM_PURPLE_WORM: 1243. case PM_JABBERWOCK: 1244. case PM_IRON_GOLEM: 1245. case PM_BALROG: 1246. case PM_KRAKEN: 1247. tear_web = TRUE; 1248. break; 1249. } 1250. if (tear_web) { 1251. if (in_sight) 1252. pline("%s tears through %s spider web!", 1253. Monnam(mtmp), a_your[trap->madeby_u]); 1254. deltrap(trap); 1255. newsym(mtmp->mx, mtmp->my); 1256. } 1257. break; 1258. 1259. case STATUE_TRAP: 1260. break; 1261. 1262. case MAGIC_TRAP: 1263. /* A magic trap. Monsters usually immune. */ 1264. if (!rn2(21)) goto mfiretrap; 1265. break; 1266. case ANTI_MAGIC: 1267. break; 1268. 1269. case LANDMINE: 1270. if(rn2(3)) 1271. break; /* monsters usually don't set it off */ 1272. if(is_flyer(mptr)) { 1273. boolean already_seen = trap->tseen; 1274. if (in_sight && !already_seen) { 1275. pline("A trigger appears in a pile of soil below %s.", mon_nam(mtmp)); 1276. seetrap(trap); 1277. } 1278. if (rn2(3)) break; 1279. if (in_sight) { 1280. newsym(mtmp->mx, mtmp->my); 1281. pline_The("air currents set %s off!", 1282. already_seen ? "a land mine" : "it"); 1283. } 1284. } else if(in_sight) { 1285. newsym(mtmp->mx, mtmp->my); 1286. pline("KAABLAMM!!! %s triggers %s land mine!", 1287. Monnam(mtmp), a_your[trap->madeby_u]); 1288. } 1289. if (!in_sight) 1290. pline("Kaablamm! You hear an explosion in the distance!"); 1291. scatter(mtmp->mx, mtmp->my, 4, 1292. MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS); 1293. del_engr_at(mtmp->mx, mtmp->my); 1294. if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ)) 1295. levl[mtmp->mx][mtmp->my].doormask = D_BROKEN; 1296. 1297. trap->ttyp = PIT; /* explosion creates a pit */ 1298. trap->madeby_u = FALSE; /* resulting pit isn't yours */ 1299. if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 1300. trapkilled = TRUE; 1301. else { 1302. /* monsters recursively fall into new pit */ 1303. if (mintrap(mtmp) == 2) trapkilled=TRUE; 1304. } 1305. wake_nearto(mtmp->mx, mtmp->my, 500); 1306. if (unconscious()) { 1307. multi = -1; 1308. nomovemsg="The explosion awakens you!"; 1309. } 1310. break; 1311. 1312. case POLY_TRAP: 1313. if (resists_magm(mtmp)) { 1314. shieldeff(mtmp->mx, mtmp->my); 1315. } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1316. (void) newcham(mtmp, (struct permonst *)0); 1317. if (in_sight) seetrap(trap); 1318. } 1319. break; 1320. 1321. case ROLLING_BOULDER_TRAP: 1322. newsym(mtmp->mx,mtmp->my); 1323. if (in_sight) 1324. pline("Click! %s triggers %s.", Monnam(mtmp), 1325. trap->tseen ? 1326. "a rolling boulder trap" : 1327. something); 1328. if (launch_obj(BOULDER, trap->launch.x, trap->launch.y, 1329. trap->launch2.x, trap->launch2.y, ROLL)) { 1330. if (in_sight) trap->tseen = TRUE; 1331. else You_hear(Hallucination ? 1332. "someone bowling." : 1333. "rumbling in the distance."); 1334. if (mtmp->mhp <= 0) trapkilled = TRUE; 1335. } else { 1336. deltrap(trap); 1337. newsym(mtmp->mx,mtmp->my); 1338. } 1339. break; 1340. 1341. default: 1342. impossible("Some monster encountered a strange trap of type %d.", tt); 1343. } 1344. } 1345. if(trapkilled) return 2; 1346. return mtmp->mtrapped; 1347. } 1348. 1349. #endif /* OVL1 */ 1350. #ifdef OVLB 1351. 1352. /* Combine cockatrice checks into single functions to avoid repeating code. */ 1353. void 1354. instapetrify(str) 1355. const char *str; 1356. { 1357. if (resists_ston(&youmonst)) return; 1358. if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 1359. return; 1360. You("turn to stone..."); 1361. killer_format = KILLED_BY; 1362. killer = str; 1363. done(STONING); 1364. } 1365. 1366. void 1367. minstapetrify(mon,byplayer) 1368. struct monst *mon; 1369. boolean byplayer; 1370. { 1371. if (resists_ston(mon)) return; 1372. if (cansee(mon->mx, mon->my)) 1373. pline("%s turns to stone.", Monnam(mon)); 1374. if (poly_when_stoned(mon->data)) { 1375. mon_to_stone(mon); 1376. return; 1377. } 1378. if (byplayer) { 1379. stoned = TRUE; 1380. xkilled(mon,0); 1381. } else monstone(mon); 1382. } 1383. 1384. void 1385. selftouch(arg) 1386. const char *arg; 1387. { 1388. if (uwep && uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE) { 1389. pline("%s touch the cockatrice corpse.", arg); 1390. instapetrify("cockatrice corpse"); 1391. } 1392. } 1393. 1394. void 1395. mselftouch(mon,arg,byplayer) 1396. struct monst *mon; 1397. const char *arg; 1398. boolean byplayer; 1399. { 1400. struct obj *mwep = MON_WEP(mon); 1401. 1402. if (mwep && mwep->otyp == CORPSE && mwep->corpsenm == PM_COCKATRICE) { 1403. if (cansee(mon->mx, mon->my)) { 1404. pline("%s%s touches the cockatrice corpse.", 1405. arg ? arg : "", arg ? mon_nam(mon) : Monnam(mon)); 1406. } 1407. minstapetrify(mon, byplayer); 1408. } 1409. } 1410. 1411. void 1412. float_up() 1413. { 1414. if(u.utrap) { 1415. if(u.utraptype == TT_PIT) { 1416. u.utrap = 0; 1417. You("float up, out of the pit!"); 1418. vision_full_recalc = 1; /* vision limits change */ 1419. fill_pit(u.ux, u.uy); 1420. } else if (u.utraptype == TT_INFLOOR) { 1421. Your("body pulls upward, but your %s are still stuck.", 1422. makeplural(body_part(LEG))); 1423. } else { 1424. You("float up, only your %s is still stuck.", 1425. body_part(LEG)); 1426. } 1427. } 1428. else if(Is_waterlevel(&u.uz)) 1429. pline("It feels as though you'd lost some weight."); 1430. else if(u.uinwater) 1431. spoteffects(); 1432. else if(u.uswallow) 1433. You(is_animal(u.ustuck->data) ? 1434. "float away from the %s." : 1435. "spiral up into %s.", 1436. is_animal(u.ustuck->data) ? 1437. surface(u.ux, u.uy) : 1438. mon_nam(u.ustuck)); 1439. else if (Hallucination) 1440. pline("Up, up, and awaaaay! You're walking on air!"); 1441. else if(Is_airlevel(&u.uz)) 1442. You("gain control over your movements."); 1443. else 1444. You("start to float in the air!"); 1445. } 1446. 1447. void 1448. fill_pit(x, y) 1449. int x, y; 1450. { 1451. struct obj *otmp; 1452. struct trap *t; 1453. 1454. if ((t = t_at(x, y)) && 1455. ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) && 1456. (otmp = sobj_at(BOULDER, x, y))) { 1457. obj_extract_self(otmp); 1458. (void) flooreffects(otmp, x, y, "settle"); 1459. } 1460. } 1461. 1462. int 1463. float_down(override_mask) 1464. long override_mask; /* might cancel timeout */ 1465. { 1466. register struct trap *trap = (struct trap *)0; 1467. d_level current_dungeon_level; 1468. boolean no_msg = FALSE; 1469. 1470. HLevitation &= ~override_mask; 1471. if(Levitation) return(0); /* maybe another ring/potion/boots */ 1472. 1473. if (Punished && !carried(uball) && 1474. (is_pool(uball->ox, uball->oy) || 1475. ((trap = t_at(uball->ox, uball->oy)) && 1476. ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) || 1477. (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) { 1478. u.ux0 = u.ux; 1479. u.uy0 = u.uy; 1480. u.ux = uball->ox; 1481. u.uy = uball->oy; 1482. movobj(uchain, uball->ox, uball->oy); 1483. newsym(u.ux0, u.uy0); 1484. vision_full_recalc = 1; /* in case the hero moved. */ 1485. } 1486. /* check for falling into pool - added by GAN 10/20/86 */ 1487. if(!is_flyer(uasmon)) { 1488. /* kludge alert: 1489. * drown() and lava_effects() print various messages almost 1490. * every time they're called which conflict with the "fall 1491. * into" message below. Thus, we want to avoid printing 1492. * confusing, duplicate or out-of-order messages. 1493. * Use knowledge of the two routines as a hack -- this 1494. * should really handled differently -dlc 1495. */ 1496. if(is_pool(u.ux,u.uy) && !Wwalking && !u.uinwater) 1497. no_msg = drown(); 1498. 1499. if(is_lava(u.ux,u.uy)) { 1500. (void) lava_effects(); 1501. no_msg = TRUE; 1502. } 1503. } 1504. if (!trap) { 1505. if(Is_airlevel(&u.uz)) 1506. You("begin to tumble in place."); 1507. else if (Is_waterlevel(&u.uz) && !no_msg) 1508. You_feel("heavier."); 1509. /* u.uinwater msgs already in spoteffects()/drown() */ 1510. else if (!u.uinwater && !no_msg) { 1511. if (Hallucination) 1512. pline("Bummer! You've %s.", 1513. is_pool(u.ux,u.uy) ? 1514. "splashed down" : "hit the ground"); 1515. else 1516. You("float gently to the %s.", 1517. surface(u.ux, u.uy)); 1518. } 1519. trap = t_at(u.ux,u.uy); 1520. } 1521. 1522. /* can't rely on u.uz0 for detecting trap door-induced level change; 1523. it gets changed to reflect the new level before we can check it */ 1524. assign_level(&current_dungeon_level, &u.uz); 1525. 1526. if(trap) 1527. switch(trap->ttyp) { 1528. case STATUE_TRAP: 1529. break; 1530. case HOLE: 1531. case TRAPDOOR: 1532. if(!Can_fall_thru(&u.uz) || u.ustuck) 1533. break; 1534. /* fall into next case */ 1535. default: 1536. dotrap(trap); 1537. } 1538. 1539. if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow && 1540. /* falling through trap door calls goto_level, 1541. and goto_level does its own pickup() call */ 1542. on_level(&u.uz, &current_dungeon_level)) 1543. pickup(1); 1544. return 1; 1545. } 1546. 1547. STATIC_OVL void 1548. dofiretrap(box) 1549. struct obj *box; /* null for floor trap */ 1550. { 1551. boolean see_it = !Blind; 1552. int num; 1553. 1554. if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) { 1555. pline("A cascade of steamy bubbles erupts from %s!", 1556. the(box ? xname(box) : surface(u.ux,u.uy))); 1557. if (Fire_resistance) You("are uninjured."); 1558. else losehp(rnd(3), "boiling water", KILLED_BY); 1559. return; 1560. } 1561. pline("A %s %s from %s!", tower_of_flame, 1562. box ? "bursts" : "erupts", 1563. the(box ? xname(box) : surface(u.ux,u.uy))); 1564. if (Fire_resistance) { 1565. shieldeff(u.ux, u.uy); 1566. num = rn2(2); 1567. } else { 1568. num = d(2,4); 1569. if (u.uhpmax > u.ulevel) 1570. u.uhpmax -= rn2(min(u.uhpmax,num + 1)), flags.botl = 1; 1571. } 1572. if (!num) 1573. You("are uninjured."); 1574. else 1575. losehp(num, tower_of_flame, KILLED_BY_AN); 1576. 1577. if (burnarmor() || rn2(3)) { 1578. destroy_item(SCROLL_CLASS, AD_FIRE); 1579. destroy_item(SPBOOK_CLASS, AD_FIRE); 1580. destroy_item(POTION_CLASS, AD_FIRE); 1581. } 1582. if (!box && burn_floor_paper(u.ux, u.uy, see_it) && !see_it) 1583. You("smell paper burning."); 1584. if (is_ice(u.ux, u.uy)) 1585. melt_ice(u.ux, u.uy); 1586. } 1587. 1588. STATIC_OVL void 1589. domagictrap() 1590. { 1591. register int fate = rnd(20); 1592. 1593. /* What happened to the poor sucker? */ 1594. 1595. if (fate < 10) { 1596. 1597. /* Most of the time, it creates some monsters. */ 1598. register int cnt = rnd(4); 1599. 1600. /* below checks for blindness added by GAN 10/30/86 */ 1601. if (!Blind) { 1602. You("are momentarily blinded by a flash of light!"); 1603. make_blinded((long)rn1(5,10),FALSE); 1604. } else 1605. You_hear("a deafening roar!"); 1606. while(cnt--) 1607. (void) makemon((struct permonst *) 0, u.ux, u.uy); 1608. } 1609. else 1610. switch (fate) { 1611. 1612. case 10: 1613. case 11: 1614. /* sometimes nothing happens */ 1615. break; 1616. case 12: /* a flash of fire */ 1617. dofiretrap((struct obj *)0); 1618. break; 1619. 1620. /* odd feelings */ 1621. case 13: pline("A shiver runs up and down your %s!", 1622. body_part(SPINE)); 1623. break; 1624. case 14: You_hear(Hallucination ? 1625. "the moon howling at you." : 1626. "distant howling."); 1627. break; 1628. case 15: if (on_level(&u.uz, &qstart_level)) 1629. You_feel("%slike the prodigal son.", 1630. (flags.female || (Upolyd && is_neuter(uasmon))) ? 1631. "oddly " : ""); 1632. else 1633. You("suddenly yearn for %s.", 1634. Hallucination ? "Cleveland" : 1635. (In_quest(&u.uz) || at_dgn_entrance("The Quest")) ? 1636. "your nearby homeland" : 1637. "your distant homeland"); 1638. break; 1639. case 16: Your("pack shakes violently!"); 1640. break; 1641. case 17: You(Hallucination ? 1642. "smell hamburgers." : 1643. "smell charred flesh."); 1644. break; 1645. case 18: You_feel("tired."); 1646. break; 1647. 1648. /* very occasionally something nice happens. */ 1649. 1650. case 19: 1651. /* tame nearby monsters */ 1652. { register int i,j; 1653. register struct monst *mtmp; 1654. 1655. (void) adjattrib(A_CHA,1,FALSE); 1656. for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) { 1657. if(!isok(u.ux+i, u.uy+j)) continue; 1658. mtmp = m_at(u.ux+i, u.uy+j); 1659. if(mtmp) 1660. (void) tamedog(mtmp, (struct obj *)0); 1661. } 1662. break; 1663. } 1664. 1665. case 20: 1666. /* uncurse stuff */ 1667. { register struct obj *obj; 1668. 1669. /* below plines added by GAN 10/30/86 */ 1670. You_feel(Hallucination ? 1671. "in touch with the Universal Oneness." : 1672. "like someone is helping you."); 1673. for(obj = invent; obj ; obj = obj->nobj) 1674. if(obj->owornmask || obj->otyp == LOADSTONE) 1675. uncurse(obj); 1676. if(Punished) unpunish(); 1677. break; 1678. } 1679. default: break; 1680. } 1681. } 1682. 1683. void 1684. water_damage(obj, force, here) 1685. register struct obj *obj; 1686. register boolean force, here; 1687. { 1688. /* Scrolls, spellbooks, potions, weapons and 1689. pieces of armor may get affected by the water */ 1690. for (; obj; obj = (here ? obj->nexthere : obj->nobj)) { 1691. 1692. (void) snuff_lit(obj); 1693. 1694. if(obj->greased) { 1695. if (force || !rn2(2)) obj->greased = 0; 1696. } else if(Is_container(obj) && !Is_box(obj) && 1697. (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) { 1698. water_damage(obj->cobj, force, FALSE); 1699. } else if (!force && (Luck + 5) > rn2(20)) { 1700. /* chance per item of sustaining damage: 1701. * max luck (full moon): 5% 1702. * max luck (elsewhen): 10% 1703. * avg luck (Luck==0): 75% 1704. * awful luck (Luck<-4): 100% 1705. */ 1706. continue; 1707. } else if (obj->oclass == SCROLL_CLASS) { 1708. #ifdef MAIL 1709. if (obj->otyp != SCR_MAIL) 1710. #endif 1711. obj->otyp = SCR_BLANK_PAPER; 1712. obj->spe = 0; 1713. } else if (obj->oclass == SPBOOK_CLASS) { 1714. if (obj->otyp == SPE_BOOK_OF_THE_DEAD) 1715. pline("Steam rises from %s.", the(xname(obj))); 1716. else obj->otyp = SPE_BLANK_PAPER; 1717. } else if (obj->oclass == POTION_CLASS) { 1718. if (obj->odiluted) { 1719. obj->otyp = POT_WATER; 1720. obj->blessed = obj->cursed = 0; 1721. obj->odiluted = 0; 1722. } else if (obj->otyp != POT_WATER || 1723. obj->blessed || obj->cursed) 1724. obj->odiluted++; 1725. } else if (is_rustprone(obj) && obj->oeroded < MAX_ERODE && 1726. !(obj->oerodeproof || (obj->blessed && !rnl(4)))) { 1727. /* all metal stuff and armor except (body armor 1728. protected by oilskin cloak) */ 1729. if(obj->oclass != ARMOR_CLASS || obj != uarm || 1730. !uarmc || uarmc->otyp != OILSKIN_CLOAK || 1731. (uarmc->cursed && !rn2(3))) 1732. obj->oeroded++; 1733. } 1734. } 1735. } 1736. 1737. /* 1738. * This function is potentially expensive - rolling 1739. * inventory list multiple times. Luckily it's seldom needed. 1740. * Returns TRUE if disrobing made player unencumbered enough to 1741. * crawl out of the current predicament. 1742. */ 1743. STATIC_OVL boolean 1744. emergency_disrobe(lostsome) 1745. boolean *lostsome; 1746. { 1747. int invc = inv_cnt(); 1748. 1749. while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) { 1750. register struct obj *obj, *otmp = (struct obj *)0; 1751. register int i = rn2(invc); 1752. 1753. for (obj = invent; obj; obj = obj->nobj) { 1754. /* 1755. * Undroppables are: body armor, boots, gloves, 1756. * amulets, and rings because of the time and effort 1757. * in removing them + loadstone and other cursed stuff 1758. * for obvious reasons. 1759. */ 1760. if (!((obj->otyp == LOADSTONE && obj->cursed) || 1761. obj == uamul || obj == uleft || obj == uright || 1762. obj == ublindf || obj == uarm || obj == uarmc || 1763. obj == uarmg || obj == uarmf || 1764. #ifdef TOURIST 1765. obj == uarmu || 1766. #endif 1767. (obj->cursed && (obj == uarmh || obj == uarms)) || 1768. welded(obj))) 1769. otmp = obj; 1770. /* reached the mark and found some stuff to drop? */ 1771. if (--i < 0 && otmp) break; 1772. 1773. /* else continue */ 1774. } 1775. 1776. /* nothing to drop and still overweight */ 1777. if (!otmp) return(FALSE); 1778. 1779. if (otmp == uarmh) (void) Helmet_off(); 1780. else if (otmp == uarms) (void) Shield_off(); 1781. else if (otmp == uwep) setuwep((struct obj *)0); 1782. *lostsome = TRUE; 1783. dropx(otmp); 1784. invc--; 1785. } 1786. return(TRUE); 1787. } 1788. 1789. /* 1790. * return(TRUE) == player relocated 1791. */ 1792. boolean 1793. drown() 1794. { 1795. boolean inpool_ok = FALSE, crawl_ok; 1796. int i, x, y; 1797. 1798. /* happily wading in the same contiguous pool */ 1799. if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) && 1800. (is_swimmer(uasmon) || Amphibious)) { 1801. /* water effects on objects every now and then */ 1802. if (!rn2(5)) inpool_ok = TRUE; 1803. else return(FALSE); 1804. } 1805. 1806. if (!u.uinwater) { 1807. You("%s into the water%c", 1808. Is_waterlevel(&u.uz) ? "plunge" : "fall", 1809. Amphibious ? '.' : '!'); 1810. if(!is_swimmer(uasmon)) 1811. if (!Is_waterlevel(&u.uz)) 1812. You("sink like %s.", 1813. Hallucination ? "the Titanic" : "a rock"); 1814. } 1815. 1816. water_damage(invent, FALSE, FALSE); 1817. 1818. if(u.umonnum == PM_GREMLIN && rn2(3)) { 1819. struct monst *mtmp; 1820. if ((mtmp = cloneu()) != 0) { 1821. mtmp->mhpmax = (u.mhmax /= 2); 1822. You("multiply."); 1823. } 1824. } 1825. if (inpool_ok) return(FALSE); 1826. 1827. if ((i = number_leashed()) > 0) { 1828. pline_The("leash%s slip%s loose.", 1829. (i > 1) ? "es" : "", 1830. (i > 1) ? "" : "s"); 1831. unleash_all(); 1832. } 1833. 1834. if (Amphibious || is_swimmer(uasmon)) { 1835. if (Amphibious) { 1836. if (flags.verbose) 1837. pline("But you aren't drowning."); 1838. if (!Is_waterlevel(&u.uz)) 1839. if (Hallucination) 1840. Your("keel hits the bottom."); 1841. else 1842. You("touch bottom."); 1843. } 1844. if (Punished) { 1845. unplacebc(); 1846. placebc(); 1847. } 1848. vision_recalc(2); /* unsee old position */ 1849. u.uinwater = 1; 1850. under_water(1); 1851. vision_full_recalc = 1; 1852. return(FALSE); 1853. } 1854. if((Teleportation || can_teleport(uasmon)) && 1855. (Teleport_control || rn2(3) < Luck+2)) { 1856. You("attempt a teleport spell."); /* utcsri!carroll */ 1857. (void) dotele(); 1858. if(!is_pool(u.ux,u.uy)) 1859. return(TRUE); 1860. } 1861. crawl_ok = FALSE; 1862. /* look around for a place to crawl to */ 1863. for (i = 0; i < 100; i++) { 1864. x = rn1(3,u.ux - 1); 1865. y = rn1(3,u.uy - 1); 1866. if (goodpos(x, y, (struct monst *)0, &playermon) 1867. || goodpos(x, y, (struct monst *)0, uasmon)) { 1868. crawl_ok = TRUE; 1869. goto crawl; 1870. } 1871. } 1872. /* one more scan */ 1873. for (x = u.ux - 1; x <= u.ux + 1; x++) 1874. for (y = u.uy - 1; y <= u.uy + 1; y++) 1875. if (goodpos(x, y, (struct monst *)0, &playermon) 1876. || goodpos(x, y, (struct monst *)0, uasmon)) { 1877. crawl_ok = TRUE; 1878. goto crawl; 1879. } 1880. crawl:; 1881. if (crawl_ok) { 1882. boolean lost = FALSE; 1883. /* time to do some strip-tease... */ 1884. boolean succ = Is_waterlevel(&u.uz) ? TRUE : 1885. emergency_disrobe(&lost); 1886. 1887. You("try to crawl out of the water."); 1888. if (lost) 1889. You("dump some of your gear to lose weight..."); 1890. if (succ) { 1891. pline("Pheew! That was close."); 1892. teleds(x,y); 1893. return(TRUE); 1894. } 1895. /* still too much weight */ 1896. pline("But in vain."); 1897. } 1898. u.uinwater = 1; 1899. You("drown."); 1900. killer_format = KILLED_BY_AN; 1901. killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ? 1902. "pool of water" : "moat"; 1903. done(DROWNING); 1904. /* oops, we're still alive. better get out of the water. */ 1905. while (!safe_teleds()) { 1906. pline("You're still drowning."); 1907. done(DROWNING); 1908. } 1909. u.uinwater = 0; 1910. You("find yourself back %s.", Is_waterlevel(&u.uz) ? 1911. "in an air bubble" : "on land"); 1912. return(TRUE); 1913. } 1914. 1915. void 1916. drain_en(n) 1917. register int n; 1918. { 1919. if (!u.uenmax) return; 1920. You_feel("your magical energy drain away!"); 1921. u.uen -= n; 1922. if(u.uen < 0) { 1923. u.uenmax += u.uen; 1924. if(u.uenmax < 0) u.uenmax = 0; 1925. u.uen = 0; 1926. } 1927. flags.botl = 1; 1928. } 1929. 1930. int 1931. dountrap() /* disarm a trap */ 1932. { 1933. if (near_capacity() >= HVY_ENCUMBER) { 1934. pline("You're too strained to do that."); 1935. return 0; 1936. } 1937. if (nohands(uasmon) || !uasmon->mmove) { 1938. pline("And just how do you expect to do that?"); 1939. return 0; 1940. } else if (u.ustuck && sticks(uasmon)) { 1941. pline("You'll have to let go of %s first.", mon_nam(u.ustuck)); 1942. return 0; 1943. } 1944. if (u.ustuck || (welded(uwep) && bimanual(uwep))) { 1945. Your("%s seem to be too busy for that.", 1946. makeplural(body_part(HAND))); 1947. return 0; 1948. } 1949. return untrap(FALSE); 1950. } 1951. #endif /* OVLB */ 1952. #ifdef OVL2 1953. 1954. /* Probability of disabling a trap. Helge Hafting */ 1955. STATIC_OVL int 1956. untrap_prob(ttmp) 1957. struct trap *ttmp; 1958. { 1959. int chance = 3; 1960. 1961. if (Confusion || Hallucination) chance++; 1962. if (Blind) chance++; 1963. if (Stunned) chance += 2; 1964. if (Fumbling) chance *= 2; 1965. /* Your own traps are better known than others. */ 1966. if (ttmp && ttmp->madeby_u) chance--; 1967. if (Role_is('R')) { 1968. if (rn2(2 * MAXULEV) < u.ulevel) chance--; 1969. if (u.uhave.questart && chance > 1) chance--; 1970. } 1971. return rn2(chance); 1972. } 1973. 1974. /* Replace trap with object(s). Helge Hafting */ 1975. STATIC_OVL void 1976. cnv_trap_obj(otyp, cnt, ttmp) 1977. int otyp; 1978. int cnt; 1979. struct trap *ttmp; 1980. { 1981. struct obj *otmp = mksobj(otyp, TRUE, FALSE); 1982. otmp->quan=cnt; 1983. otmp->owt = weight(otmp); 1984. place_object(otmp, ttmp->tx, ttmp->ty); 1985. /* Sell your own traps only... */ 1986. if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); 1987. stackobj(otmp); 1988. newsym(ttmp->tx, ttmp->ty); 1989. deltrap(ttmp); 1990. } 1991. 1992. /* while attempting to disarm an adjacent trap, we've fallen into it */ 1993. STATIC_OVL void 1994. move_into_trap(ttmp) 1995. struct trap *ttmp; 1996. { 1997. int bc; 1998. xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy; 1999. boolean unused; 2000. 2001. /* we know there's no monster in the way, and we're not trapped */ 2002. if (!Punished || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused)) { 2003. u.ux0 = u.ux, u.uy0 = u.uy; 2004. u.ux = x, u.uy = y; 2005. u.umoved = TRUE; 2006. newsym(u.ux0, u.uy0); 2007. vision_recalc(1); 2008. check_leash(u.ux0, u.uy0); 2009. if (Punished) move_bc(0, bc, bx, by, cx, cy); 2010. spoteffects(); /* dotrap() */ 2011. exercise(A_WIS, FALSE); 2012. } 2013. } 2014. 2015. /* 0: doesn't even try 2016. * 1: tries and fails 2017. * 2: succeeds 2018. */ 2019. STATIC_OVL int 2020. try_disarm(ttmp, force_failure) 2021. struct trap *ttmp; 2022. boolean force_failure; 2023. { 2024. struct monst *mtmp = m_at(ttmp->tx,ttmp->ty); 2025. int ttype = ttmp->ttyp; 2026. boolean under_u = (!u.dx && !u.dy); 2027. 2028. /* Test for monster first, monsters are displayed instead of trap. */ 2029. if (mtmp && (!mtmp->mtrapped || ttype != BEAR_TRAP)) { 2030. pline("%s is in the way.", Monnam(mtmp)); 2031. return 0; 2032. } 2033. /* We might be forced to move onto the trap's location. */ 2034. if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) 2035. && !passes_walls(uasmon) && !under_u) { 2036. pline("There is a boulder in your way."); 2037. return 0; 2038. } 2039. /* untrappable traps are located on the ground. */ 2040. if (!can_reach_floor()) { 2041. You("are unable to reach the %s!", 2042. defsyms[trap_to_defsym(ttype)].explanation); 2043. return 0; 2044. } 2045. 2046. /* Will our hero succeed? */ 2047. if (force_failure || untrap_prob(ttmp)) { 2048. if (rnl(5)) { 2049. pline("Whoops..."); 2050. if (mtmp) { /* must be a bear trap */ 2051. if (mtmp->mtame) abuse_dog(mtmp); 2052. if ((mtmp->mhp -= rnd(4)) <= 0) killed(mtmp); 2053. } else if (under_u) { 2054. dotrap(ttmp); 2055. } else { 2056. move_into_trap(ttmp); 2057. } 2058. } else { 2059. pline("%s %s is difficult to disarm.", 2060. ttmp->madeby_u ? "Your" : under_u ? "This" : "That", 2061. defsyms[trap_to_defsym(ttype)].explanation); 2062. } 2063. return 1; 2064. } 2065. return 2; 2066. } 2067. 2068. STATIC_OVL void 2069. reward_untrap(ttmp, mtmp) 2070. struct trap *ttmp; 2071. struct monst *mtmp; 2072. { 2073. if (!ttmp->madeby_u) { 2074. if (rnl(10)<8 && !mtmp->mpeaceful && 2075. mtmp->data->mlet != S_HUMAN) { 2076. mtmp->mpeaceful = 1; 2077. pline("%s is grateful.", Monnam(mtmp)); 2078. } 2079. /* Helping someone out of a trap is a nice thing to do, 2080. * A lawful may be rewarded, but not too often. */ 2081. if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) { 2082. adjalign(1); 2083. You_feel("that you did the right thing."); 2084. } 2085. } 2086. } 2087. 2088. STATIC_OVL int 2089. disarm_beartrap(ttmp) /* Helge Hafting */ 2090. struct trap *ttmp; 2091. { 2092. struct monst *mtmp; 2093. int fails = try_disarm(ttmp, FALSE); 2094. 2095. if (fails < 2) return fails; 2096. 2097. /* ok, disarm it. */ 2098. 2099. /* untrap the monster, if any. 2100. There's no need for a cockatrice test, only the trap is touched */ 2101. if ((mtmp = m_at(ttmp->tx,ttmp->ty)) != 0) { 2102. mtmp->mtrapped = 0; 2103. You("remove %s bear trap from %s.", the_your[ttmp->madeby_u], 2104. mon_nam(mtmp)); 2105. reward_untrap(ttmp, mtmp); 2106. } else You("disarm %s bear trap.", the_your[ttmp->madeby_u]); 2107. cnv_trap_obj(BEARTRAP, 1, ttmp); 2108. return 1; 2109. } 2110. 2111. STATIC_OVL int 2112. disarm_landmine(ttmp) /* Helge Hafting */ 2113. struct trap *ttmp; 2114. { 2115. int fails = try_disarm(ttmp, FALSE); 2116. 2117. if (fails < 2) return fails; 2118. You("disarm %s land mine.", the_your[ttmp->madeby_u]); 2119. cnv_trap_obj(LAND_MINE, 1, ttmp); 2120. return 1; 2121. } 2122. 2123. /* getobj will filter down to cans of grease and known potions of oil */ 2124. static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS, 0 }; 2125. 2126. /* it may not make much sense to use grease on floor boards, but so what? */ 2127. STATIC_OVL int 2128. disarm_squeaky_board(ttmp) 2129. struct trap *ttmp; 2130. { 2131. struct obj *obj; 2132. boolean bad_tool; 2133. int fails; 2134. 2135. obj = getobj(oil, "untrap with"); 2136. if (!obj) return 0; 2137. 2138. bad_tool = (obj->cursed || 2139. ((obj->otyp != POT_OIL || obj->lamplit) && 2140. (obj->otyp != CAN_OF_GREASE || !obj->spe))); 2141. 2142. fails = try_disarm(ttmp, bad_tool); 2143. if (fails < 2) return fails; 2144. 2145. /* successfully used oil or grease to fix squeaky board */ 2146. if (obj->otyp == CAN_OF_GREASE) { 2147. check_unpaid(obj); 2148. obj->spe--; 2149. } else { 2150. useup(obj); /* oil */ 2151. makeknown(POT_OIL); 2152. } 2153. You("repair the squeaky board."); /* no madeby_u */ 2154. deltrap(ttmp); 2155. newsym(u.ux + u.dx, u.uy + u.dy); 2156. more_experienced(1, 5); 2157. return 1; 2158. } 2159. 2160. /* removes traps that shoot arrows, darts, etc. */ 2161. STATIC_OVL int 2162. disarm_shooting_trap(ttmp, otyp) 2163. struct trap *ttmp; 2164. int otyp; 2165. { 2166. int fails = try_disarm(ttmp, FALSE); 2167. 2168. if (fails < 2) return fails; 2169. You("disarm %s trap", the_your[ttmp->madeby_u]); 2170. cnv_trap_obj(otyp, 50-rnl(50), ttmp); 2171. return 1; 2172. } 2173. 2174. /* Is the weight too heavy? 2175. * Formula as in near_capacity() & check_capacity() */ 2176. STATIC_OVL int 2177. try_lift(mtmp, ttmp, wt, stuff) 2178. struct monst *mtmp; 2179. struct trap *ttmp; 2180. int wt; 2181. boolean stuff; 2182. { 2183. int wc = weight_cap(); 2184. 2185. if ((((wt<<1) / wc)+1) >= EXT_ENCUMBER) { 2186. pline("%s is %s for you to lift.", Monnam(mtmp), 2187. stuff ? "carrying too much" : "too heavy"); 2188. if (!ttmp->madeby_u && !mtmp->mpeaceful 2189. && mtmp->data->mlet != S_HUMAN && rnl(10) < 3) { 2190. mtmp->mpeaceful = 1; 2191. pline("%s thinks it was nice of you to try.", Monnam(mtmp)); 2192. } 2193. return 0; 2194. } 2195. return 1; 2196. } 2197. 2198. /* Help trapped monster (out of a (spiked) pit) */ 2199. STATIC_OVL int 2200. help_monster_out(mtmp, ttmp) 2201. struct monst *mtmp; 2202. struct trap *ttmp; 2203. { 2204. int wt; 2205. struct obj *otmp; 2206. 2207. /* 2208. * This works when levitating too -- consistent with the ability 2209. * to hit monsters while levitating. 2210. * 2211. * Should perhaps check that our hero has arms/hands at the 2212. * moment. Helping can also be done by engulfing... 2213. * 2214. * Test the monster first - monsters are displayed before traps. 2215. */ 2216. if (!mtmp->mtrapped) { 2217. pline("%s isn't trapped.", Monnam(mtmp)); 2218. return 0; 2219. } 2220. /* Do you have the necessary capacity to lift anything? */ 2221. if (check_capacity((char *)0)) return 1; 2222. 2223. /* Will our hero succeed? */ 2224. if (untrap_prob(ttmp)) { 2225. You("try to reach out your %s, but %s backs away skeptically.", 2226. makeplural(body_part(ARM)), 2227. mon_nam(mtmp)); 2228. return 1; 2229. } 2230. 2231. 2232. /* is it a cockatrice?... */ 2233. if (mtmp->data == &mons[PM_COCKATRICE] && !uarmg 2234. && !resists_ston(&youmonst)) { 2235. You("grab the trapped cockatrice using your bare %s.", 2236. makeplural(body_part(HAND))); 2237. 2238. if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 2239. display_nhwindow(WIN_MESSAGE, FALSE); 2240. else { 2241. instapetrify("trying to help a cockatrice out of a pit"); 2242. return 1; 2243. } 2244. } 2245. You("reach out your %s and grab %s.", 2246. makeplural(body_part(ARM)), mon_nam(mtmp)); 2247. 2248. /* is the monster too heavy? */ 2249. wt = inv_weight() + mtmp->data->cwt; 2250. if (!try_lift(mtmp, ttmp, wt, FALSE)) return 1; 2251. 2252. /* is the monster with inventory too heavy? */ 2253. for (otmp = mtmp->minvent; otmp; otmp=otmp->nobj) 2254. wt += otmp->owt; 2255. if (!try_lift(mtmp, ttmp, wt, TRUE)) return 1; 2256. 2257. You("pull %s out of the pit.", mon_nam(mtmp)); 2258. mtmp->mtrapped = 0; 2259. reward_untrap(ttmp, mtmp); 2260. return 1; 2261. } 2262. 2263. int 2264. untrap(force) 2265. boolean force; 2266. { 2267. register struct obj *otmp; 2268. register boolean confused = (Confusion > 0 || Hallucination > 0); 2269. register int x,y; 2270. int ch; 2271. struct trap *ttmp; 2272. struct monst *mtmp; 2273. boolean trap_skipped = FALSE; 2274. 2275. if(!getdir((char *)0)) return(0); 2276. x = u.ux + u.dx; 2277. y = u.uy + u.dy; 2278. 2279. if ((ttmp = t_at(x,y)) && ttmp->tseen) { 2280. if (u.utrap) { 2281. You("cannot deal with traps while trapped!"); 2282. return 1; 2283. } 2284. switch(ttmp->ttyp) { 2285. case BEAR_TRAP: 2286. return disarm_beartrap(ttmp); 2287. case LANDMINE: 2288. return disarm_landmine(ttmp); 2289. case SQKY_BOARD: 2290. return disarm_squeaky_board(ttmp); 2291. case DART_TRAP: 2292. return disarm_shooting_trap(ttmp, DART); 2293. case ARROW_TRAP: 2294. return disarm_shooting_trap(ttmp, ARROW); 2295. case PIT: 2296. case SPIKED_PIT: 2297. if (!u.dx && !u.dy) { 2298. You("are already on the edge of the pit."); 2299. return 0; 2300. } 2301. if (!(mtmp = m_at(x,y))) { 2302. pline("Try filling the pit instead."); 2303. return 0; 2304. } 2305. return help_monster_out(mtmp, ttmp); 2306. default: 2307. You("cannot disable %s trap.", (u.dx || u.dy) ? "that" : "this"); 2308. return 0; 2309. } /* end switch */ 2310. } /* end if */ 2311. 2312. if(!u.dx && !u.dy) { 2313. for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 2314. if(Is_box(otmp)) { 2315. pline("There is %s here.", doname(otmp)); 2316. 2317. switch (ynq("Check for traps?")) { 2318. case 'q': return(0); 2319. case 'n': continue; 2320. } 2321. 2322. if((otmp->otrapped && (force || (!confused 2323. && rn2(MAXULEV + 1 - u.ulevel) < 10))) 2324. || (!force && confused && !rn2(3))) { 2325. You("find a trap on %s!", the(xname(otmp))); 2326. exercise(A_WIS, TRUE); 2327. 2328. switch (ynq("Disarm it?")) { 2329. case 'q': return(1); 2330. case 'n': trap_skipped = TRUE; continue; 2331. } 2332. 2333. if(otmp->otrapped) { 2334. exercise(A_DEX, TRUE); 2335. ch = ACURR(A_DEX) + u.ulevel; 2336. if (Role_is('R')) ch *= 2; 2337. if(!force && (confused || Fumbling || 2338. rnd(75+level_difficulty()/2) > ch)) { 2339. (void) chest_trap(otmp, FINGER, TRUE); 2340. } else { 2341. You("disarm it!"); 2342. otmp->otrapped = 0; 2343. } 2344. } else pline("That %s was not trapped.", doname(otmp)); 2345. return(1); 2346. } else { 2347. You("find no traps on %s.", the(xname(otmp))); 2348. return(1); 2349. } 2350. } 2351. 2352. You(trap_skipped ? "find no other traps here." 2353. : "know of no traps here."); 2354. return(0); 2355. } 2356. 2357. if ((mtmp = m_at(x,y)) && 2358. mtmp->m_ap_type == M_AP_FURNITURE && 2359. (mtmp->mappearance == S_hcdoor || 2360. mtmp->mappearance == S_vcdoor) && 2361. !Protection_from_shape_changers) { 2362. 2363. stumble_onto_mimic(mtmp); 2364. return(1); 2365. } 2366. 2367. if (!IS_DOOR(levl[x][y].typ)) { 2368. if ((ttmp = t_at(x,y)) && ttmp->tseen) 2369. You("cannot disable that trap."); 2370. else 2371. You("know of no traps there."); 2372. return(0); 2373. } 2374. 2375. switch (levl[x][y].doormask) { 2376. case D_NODOOR: 2377. You("%s no door there.", Blind ? "feel" : "see"); 2378. return(0); 2379. case D_ISOPEN: 2380. pline("This door is safely open."); 2381. return(0); 2382. case D_BROKEN: 2383. pline("This door is broken."); 2384. return(0); 2385. } 2386. 2387. if ((levl[x][y].doormask & D_TRAPPED 2388. && (force || 2389. (!confused && rn2(MAXULEV - u.ulevel + 11) < 10))) 2390. || (!force && confused && !rn2(3))) { 2391. You("find a trap on the door!"); 2392. exercise(A_WIS, TRUE); 2393. if (ynq("Disarm it?") != 'y') return(1); 2394. if (levl[x][y].doormask & D_TRAPPED) { 2395. ch = 15 + (Role_is('R') ? u.ulevel*3 : u.ulevel); 2396. exercise(A_DEX, TRUE); 2397. if(!force && (confused || Fumbling || 2398. rnd(75+level_difficulty()/2) > ch)) { 2399. You("set it off!"); 2400. b_trapped("door", FINGER); 2401. } else 2402. You("disarm it!"); 2403. levl[x][y].doormask &= ~D_TRAPPED; 2404. } else pline("This door was not trapped."); 2405. return(1); 2406. } else { 2407. You("find no traps on the door."); 2408. return(1); 2409. } 2410. } 2411. #endif /* OVL2 */ 2412. #ifdef OVLB 2413. 2414. /* only called when the player is doing something to the chest directly */ 2415. boolean 2416. chest_trap(obj, bodypart, disarm) 2417. register struct obj *obj; 2418. register int bodypart; 2419. boolean disarm; 2420. { 2421. register struct obj *otmp = obj, *otmp2; 2422. char buf[80]; 2423. const char *msg; 2424. 2425. You(disarm ? "set it off!" : "trigger a trap!"); 2426. display_nhwindow(WIN_MESSAGE, FALSE); 2427. if (Luck > -13 && rn2(13+Luck) > 7) { /* saved by luck */ 2428. /* trap went off, but good luck prevents damage */ 2429. switch (rn2(13)) { 2430. case 12: 2431. case 11: msg = "explosive charge is a dud"; break; 2432. case 10: 2433. case 9: msg = "electric charge is grounded"; break; 2434. case 8: 2435. case 7: msg = "flame fizzles out"; break; 2436. case 6: 2437. case 5: 2438. case 4: msg = "poisoned needle misses"; break; 2439. case 3: 2440. case 2: 2441. case 1: 2442. case 0: msg = "gas cloud blows away"; break; 2443. default: impossible("chest disarm bug"); msg = (char *)0; 2444. break; 2445. } 2446. if (msg) pline("But luckily the %s!", msg); 2447. } else { 2448. switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) { 2449. case 25: 2450. case 24: 2451. case 23: 2452. case 22: 2453. case 21: { 2454. struct monst *shkp = 0; 2455. long loss = 0L; 2456. boolean costly, insider; 2457. register xchar ox = obj->ox, oy = obj->oy; 2458. 2459. /* the obj location need not be that of player */ 2460. costly = (costly_spot(ox, oy) && 2461. (shkp = shop_keeper(*in_rooms(ox, oy, 2462. SHOPBASE))) != (struct monst *)0); 2463. insider = (*u.ushops && inside_shop(u.ux, u.uy) && 2464. *in_rooms(ox, oy, SHOPBASE) == *u.ushops); 2465. 2466. pline("%s explodes!", The(xname(obj))); 2467. Sprintf(buf, "exploding %s", xname(obj)); 2468. 2469. if(costly) 2470. loss += stolen_value(obj, ox, oy, 2471. (boolean)shkp->mpeaceful, TRUE); 2472. delete_contents(obj); 2473. for(otmp = level.objects[u.ux][u.uy]; 2474. otmp; otmp = otmp2) { 2475. otmp2 = otmp->nexthere; 2476. if(costly) 2477. loss += stolen_value(otmp, otmp->ox, 2478. otmp->oy, (boolean)shkp->mpeaceful, 2479. TRUE); 2480. delobj(otmp); 2481. } 2482. wake_nearby(); 2483. losehp(d(6,6), buf, KILLED_BY_AN); 2484. exercise(A_STR, FALSE); 2485. if(costly && loss) { 2486. if(insider) 2487. You("owe %ld zorkmids for objects destroyed.", 2488. loss); 2489. else { 2490. You("caused %ld zorkmids worth of damage!", 2491. loss); 2492. make_angry_shk(shkp, ox, oy); 2493. } 2494. } 2495. return TRUE; 2496. } 2497. case 20: 2498. case 19: 2499. case 18: 2500. case 17: 2501. pline("A cloud of noxious gas billows from %s.", 2502. the(xname(obj))); 2503. poisoned("gas cloud", A_STR, "cloud of poison gas",15); 2504. exercise(A_CON, FALSE); 2505. break; 2506. case 16: 2507. case 15: 2508. case 14: 2509. case 13: 2510. You_feel("a needle prick your %s.",body_part(bodypart)); 2511. poisoned("needle", A_CON, "poisoned needle",10); 2512. exercise(A_CON, FALSE); 2513. break; 2514. case 12: 2515. case 11: 2516. case 10: 2517. case 9: 2518. dofiretrap(obj); 2519. break; 2520. case 8: 2521. case 7: 2522. case 6: { 2523. int dmg; 2524. 2525. You("are jolted by a surge of electricity!"); 2526. if(Shock_resistance) { 2527. shieldeff(u.ux, u.uy); 2528. You("don't seem to be affected."); 2529. dmg = 0; 2530. } else 2531. dmg = d(4, 4); 2532. destroy_item(RING_CLASS, AD_ELEC); 2533. destroy_item(WAND_CLASS, AD_ELEC); 2534. if (dmg) losehp(dmg, "electric shock", KILLED_BY_AN); 2535. break; 2536. } 2537. case 5: 2538. case 4: 2539. case 3: 2540. pline("Suddenly you are frozen in place!"); 2541. nomul(-d(5, 6)); 2542. exercise(A_DEX, FALSE); 2543. nomovemsg = "You can move again."; 2544. break; 2545. case 2: 2546. case 1: 2547. case 0: 2548. pline("A cloud of %s gas billows from %s.", 2549. hcolor((char *)0), 2550. the(xname(obj))); 2551. if(!Stunned) { 2552. if (Hallucination) 2553. pline("What a groovy feeling!"); 2554. else if (Blind) 2555. You("stagger and get dizzy..."); 2556. else 2557. You("stagger and your vision blurs..."); 2558. } 2559. make_stunned(HStun + rn1(7, 16),FALSE); 2560. make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L); 2561. break; 2562. default: impossible("bad chest trap"); 2563. break; 2564. } 2565. bot(); /* to get immediate botl re-display */ 2566. } 2567. otmp->otrapped = 0; /* these traps are one-shot things */ 2568. 2569. return FALSE; 2570. } 2571. 2572. #endif /* OVLB */ 2573. #ifdef OVL0 2574. 2575. struct trap * 2576. t_at(x,y) 2577. register int x, y; 2578. { 2579. register struct trap *trap = ftrap; 2580. while(trap) { 2581. if(trap->tx == x && trap->ty == y) return(trap); 2582. trap = trap->ntrap; 2583. } 2584. return((struct trap *)0); 2585. } 2586. 2587. #endif /* OVL0 */ 2588. #ifdef OVLB 2589. 2590. void 2591. deltrap(trap) 2592. register struct trap *trap; 2593. { 2594. register struct trap *ttmp; 2595. 2596. if(trap == ftrap) 2597. ftrap = ftrap->ntrap; 2598. else { 2599. for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 2600. ttmp->ntrap = trap->ntrap; 2601. } 2602. dealloc_trap(trap); 2603. } 2604. 2605. boolean delfloortrap(ttmp) 2606. register struct trap *ttmp; 2607. { 2608. /* Destroy a trap that emanates from the floor. */ 2609. /* some of these are arbitrary -dlc */ 2610. if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || 2611. (ttmp->ttyp == BEAR_TRAP) || 2612. (ttmp->ttyp == LANDMINE) || 2613. (ttmp->ttyp == FIRE_TRAP) || 2614. (ttmp->ttyp == PIT) || 2615. (ttmp->ttyp == SPIKED_PIT) || 2616. (ttmp->ttyp == HOLE) || 2617. (ttmp->ttyp == TRAPDOOR) || 2618. (ttmp->ttyp == TELEP_TRAP) || 2619. (ttmp->ttyp == LEVEL_TELEP) || 2620. (ttmp->ttyp == WEB) || 2621. (ttmp->ttyp == MAGIC_TRAP) || 2622. (ttmp->ttyp == ANTI_MAGIC))) { 2623. register struct monst *mtmp; 2624. 2625. if (ttmp->tx == u.ux && ttmp->ty == u.uy) { 2626. u.utrap = 0; 2627. u.utraptype = 0; 2628. } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) { 2629. mtmp->mtrapped = 0; 2630. } 2631. deltrap(ttmp); 2632. return TRUE; 2633. } else 2634. return FALSE; 2635. } 2636. 2637. /* used for doors (also tins). can be used for anything else that opens. */ 2638. void 2639. b_trapped(item, bodypart) 2640. register const char *item; 2641. register int bodypart; 2642. { 2643. register int lvl = level_difficulty(); 2644. int dmg = rnd(5 + (lvl < 5 ? lvl : 2+lvl/2)); 2645. 2646. pline("KABOOM!! %s was booby-trapped!", The(item)); 2647. wake_nearby(); 2648. losehp(dmg, "explosion", KILLED_BY_AN); 2649. exercise(A_STR, FALSE); 2650. if (bodypart) exercise(A_CON, FALSE); 2651. make_stunned(HStun + dmg, TRUE); 2652. } 2653. 2654. /* Monster is hit by trap. */ 2655. /* Note: doesn't work if both obj and d_override are null */ 2656. STATIC_OVL boolean 2657. thitm(tlev, mon, obj, d_override) 2658. register int tlev; 2659. register struct monst *mon; 2660. register struct obj *obj; 2661. int d_override; 2662. { 2663. register int strike; 2664. register boolean trapkilled = FALSE; 2665. 2666. if (d_override) strike = 1; 2667. else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20)); 2668. else strike = (find_mac(mon) + tlev <= rnd(20)); 2669. 2670. /* Actually more accurate than thitu, which doesn't take 2671. * obj->spe into account. 2672. */ 2673. if(!strike) { 2674. if (cansee(mon->mx, mon->my)) 2675. pline("%s is almost hit by %s!", Monnam(mon), 2676. doname(obj)); 2677. } else { 2678. int dam = 1; 2679. 2680. if (obj && cansee(mon->mx, mon->my)) 2681. pline("%s is hit by %s!", Monnam(mon), doname(obj)); 2682. if (d_override) dam = d_override; 2683. else if (obj) { 2684. dam = dmgval(obj, mon); 2685. if (dam < 1) dam = 1; 2686. } 2687. if ((mon->mhp -= dam) <= 0) { 2688. int xx = mon->mx; 2689. int yy = mon->my; 2690. 2691. monkilled(mon, "", AD_PHYS); 2692. if (mon->mhp <= 0) { 2693. newsym(xx, yy); 2694. trapkilled = TRUE; 2695. } 2696. } 2697. } 2698. if (obj && (!strike || d_override)) { 2699. place_object(obj, mon->mx, mon->my); 2700. stackobj(obj); 2701. } else if (obj) dealloc_obj(obj); 2702. 2703. return trapkilled; 2704. } 2705. 2706. boolean 2707. unconscious() 2708. { 2709. return((boolean)(multi < 0 && (!nomovemsg || 2710. u.usleep || 2711. !strncmp(nomovemsg,"You regain con", 15) || 2712. !strncmp(nomovemsg,"You are consci", 15)))); 2713. } 2714. 2715. static char lava_killer[] = "molten lava"; 2716. 2717. boolean 2718. lava_effects() 2719. { 2720. register struct obj *obj, *obj2; 2721. int dmg; 2722. 2723. if (likes_lava(uasmon)) return FALSE; 2724. 2725. if (!Fire_resistance) { 2726. if(Wwalking) { 2727. dmg = d(6,6); 2728. pline_The("lava here burns you!"); 2729. if(dmg < u.uhp) { 2730. losehp(dmg, lava_killer, KILLED_BY); 2731. goto burn_stuff; 2732. } 2733. } else 2734. You("fall into the lava!"); 2735. 2736. for(obj = invent; obj; obj = obj2) { 2737. obj2 = obj->nobj; 2738. if(is_organic(obj) && !obj->oerodeproof) { 2739. if(obj->owornmask) { 2740. if(obj == uarm) (void) Armor_gone(); 2741. else if(obj == uarmc) (void) Cloak_off(); 2742. else if(obj == uarmh) (void) Helmet_off(); 2743. else if(obj == uarms) (void) Shield_off(); 2744. else if(obj == uarmg) (void) Gloves_off(); 2745. else if(obj == uarmf) (void) Boots_off(); 2746. #ifdef TOURIST 2747. else if(obj == uarmu) setnotworn(obj); 2748. #endif 2749. else if(obj == uleft) Ring_gone(obj); 2750. else if(obj == uright) Ring_gone(obj); 2751. else if(obj == ublindf) Blindf_off(obj); 2752. else if(obj == uwep) uwepgone(); 2753. if(Lifesaved 2754. #ifdef WIZARD 2755. || wizard 2756. #endif 2757. ) Your("%s into flame!", aobjnam(obj, "burst")); 2758. } 2759. useup(obj); 2760. } 2761. } 2762. 2763. /* s/he died... */ 2764. u.uhp = -1; 2765. killer_format = KILLED_BY; 2766. killer = lava_killer; 2767. You("burn to a crisp..."); 2768. done(BURNING); 2769. while (!safe_teleds()) { 2770. pline("You're still burning."); 2771. done(BURNING); 2772. } 2773. You("find yourself back on solid %s.", surface(u.ux, u.uy)); 2774. return(TRUE); 2775. } 2776. 2777. if (!Wwalking) { 2778. u.utrap = rn1(4, 4) + (rn1(4, 12) << 8); 2779. u.utraptype = TT_LAVA; 2780. You("sink into the lava, but it only burns slightly!"); 2781. if (u.uhp > 1) 2782. losehp(1, lava_killer, KILLED_BY); 2783. } 2784. /* just want to burn boots, not all armor; destroy_item doesn't work on 2785. armor anyway */ 2786. burn_stuff: 2787. if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) { 2788. /* save uarmf value because Boots_off() sets uarmf to null */ 2789. obj = uarmf; 2790. Your("%s burst into flame!", xname(obj)); 2791. (void) Boots_off(); 2792. useup(obj); 2793. } 2794. destroy_item(SCROLL_CLASS, AD_FIRE); 2795. destroy_item(SPBOOK_CLASS, AD_FIRE); 2796. destroy_item(POTION_CLASS, AD_FIRE); 2797. return(FALSE); 2798. } 2799. 2800. #endif /* OVLB */ 2801. 2802. /*trap.c*/
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software