About: Source:NetHack 3.4.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.4.0. To link to a particular line, write [[NetHack 3.4.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.4.0/trap.c
rdfs:comment
  • Below is the full text to trap.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4.0. To link to a particular line, write [[NetHack 3.4.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.4 2001/09/06 */ 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. extern const char *destroy_strings[]; 8. 9. STATIC_DCL void FDECL(dofiretrap, (struct obj *)); 10. STATIC_DCL void NDECL(domagictrap); 11. STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *)); 12. STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp)); 13. STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *)); 14. STATIC_DCL void FDECL(move_into_trap, (struct trap *)); 15. STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P)); 16. STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *)); 17. STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *)); 18. STATIC_DCL int FDECL(disarm_landmine, (struct trap *)); 19. STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *)); 20. STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int)); 21. STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int, BOOLEAN_P)); 22. STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *)); 23. STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int)); 24. STATIC_DCL int FDECL(mkroll_launch, 25. (struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long)); 26. STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P)); 27. #ifdef STEED 28. STATIC_OVL int FDECL(steedintrap, (struct trap *, struct obj *)); 29. #endif 30. 31. #ifndef OVLB 32. STATIC_VAR const char *a_your[2]; 33. STATIC_VAR const char *A_Your[2]; 34. STATIC_VAR const char *the_your[2]; 35. STATIC_VAR const char tower_of_flame[]; 36. STATIC_VAR const char *A_gush_of_water_hits; 37. 38. #else 39. 40. STATIC_VAR const char *a_your[2] = { "a", "your" }; 41. STATIC_VAR const char *A_Your[2] = { "A", "Your" }; 42. STATIC_VAR const char *the_your[2] = { "the", "your" }; 43. STATIC_VAR const char tower_of_flame[] = "tower of flame"; 44. STATIC_VAR const char *A_gush_of_water_hits = "A gush of water hits"; 45. 46. #endif /* OVLB */ 47. 48. #ifdef OVLB 49. 50. /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode) */ 51. boolean /* returns TRUE if hit on torso */ 52. burnarmor(victim) 53. struct monst *victim; 54. { 55. struct obj *item; 56. char buf[BUFSZ]; 57. int mat_idx; 58. 59. if (!victim) return 0; 60. #define burn_dmg(obj,descr) rust_dmg(obj, descr, 0, FALSE, victim) 61. while (1) { 62. switch (rn2(5)) { 63. case 0: 64. item = (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH); 65. if (item) { 66. mat_idx = objects[item->otyp].oc_material; 67. Sprintf(buf,"%s helmet", materialnm[mat_idx] ); 68. } 69. if (!burn_dmg(item, item ? buf : "helmet")) continue; 70. break; 71. case 1: 72. item = (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC); 73. if (item) { 74. (void) burn_dmg(item, cloak_simple_name(item)); 75. return TRUE; 76. } 77. item = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM); 78. if (item) { 79. (void) burn_dmg(item, xname(item)); 80. return TRUE; 81. } 82. #ifdef TOURIST 83. item = (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU); 84. if (item) 85. (void) burn_dmg(item, "shirt"); 86. #endif 87. return TRUE; 88. case 2: 89. item = (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS); 90. if (!burn_dmg(item, "wooden shield")) continue; 91. break; 92. case 3: 93. item = (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG); 94. if (!burn_dmg(item, "gloves")) continue; 95. break; 96. case 4: 97. item = (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF); 98. if (!burn_dmg(item, "boots")) continue; 99. break; 100. } 101. break; /* Out of while loop */ 102. } 103. return FALSE; 104. #undef burn_dmg 105. } 106. 107. /* Generic rust-armor function. Returns TRUE if a message was printed; 108. * "print", if set, means to print a message (and thus to return TRUE) even 109. * if the item could not be rusted; otherwise a message is printed and TRUE is 110. * returned only for rustable items. 111. */ 112. boolean 113. rust_dmg(otmp, ostr, type, print, victim) 114. register struct obj *otmp; 115. register const char *ostr; 116. int type; 117. boolean print; 118. struct monst *victim; 119. { 120. static NEARDATA const char *action[] = { "smoulder", "rust", "rot", "corrode" }; 121. static NEARDATA const char *msg[] = { "burnt", "rusted", "rotten", "corroded" }; 122. boolean vulnerable = FALSE; 123. boolean grprot = FALSE; 124. boolean is_primary = TRUE; 125. boolean vismon = (victim != &youmonst) && canseemon(victim); 126. int erosion; 127. 128. if (!otmp) return(FALSE); 129. switch(type) { 130. case 0: vulnerable = is_flammable(otmp); 131. break; 132. case 1: vulnerable = is_rustprone(otmp); 133. grprot = TRUE; 134. break; 135. case 2: vulnerable = is_rottable(otmp); 136. is_primary = FALSE; 137. break; 138. case 3: vulnerable = is_corrodeable(otmp); 139. grprot = TRUE; 140. is_primary = FALSE; 141. break; 142. } 143. erosion = is_primary ? otmp->oeroded : otmp->oeroded2; 144. 145. if (!print && (!vulnerable || otmp->oerodeproof || erosion == MAX_ERODE)) 146. return FALSE; 147. 148. if (!vulnerable) { 149. if (flags.verbose) { 150. if (victim == &youmonst) 151. Your("%s %s not affected.", ostr, vtense(ostr, "are")); 152. else if (vismon) 153. pline("%s's %s %s not affected.", Monnam(victim), ostr, 154. vtense(ostr, "are")); 155. } 156. } else if (erosion < MAX_ERODE) { 157. if (grprot && otmp->greased) { 158. grease_protect(otmp,ostr,victim); 159. } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) { 160. if (flags.verbose) { 161. if (victim == &youmonst) 162. pline("Somehow, your %s %s not affected.", 163. ostr, vtense(ostr, "are")); 164. else if (vismon) 165. pline("Somehow, %s's %s %s not affected.", 166. mon_nam(victim), ostr, vtense(ostr, "are")); 167. } 168. } else { 169. if (victim == &youmonst) 170. Your("%s %s%s!", ostr, 171. vtense(ostr, action[type]), 172. erosion+1 == MAX_ERODE ? " completely" : 173. erosion ? " further" : ""); 174. else if (vismon) 175. pline("%s's %s %s%s!", Monnam(victim), ostr, 176. vtense(ostr, action[type]), 177. erosion+1 == MAX_ERODE ? " completely" : 178. erosion ? " further" : ""); 179. if (is_primary) 180. otmp->oeroded++; 181. else 182. otmp->oeroded2++; 183. update_inventory(); 184. } 185. } else { 186. if (flags.verbose) { 187. if (victim == &youmonst) 188. Your("%s %s completely %s.", ostr, 189. vtense(ostr, Blind ? "feel" : "look"), 190. msg[type]); 191. else if (vismon) 192. pline("%s's %s %s completely %s.", 193. Monnam(victim), ostr, 194. vtense(ostr, "look"), msg[type]); 195. } 196. } 197. return(TRUE); 198. } 199. 200. void 201. grease_protect(otmp,ostr,victim) 202. register struct obj *otmp; 203. register const char *ostr; 204. struct monst *victim; 205. { 206. static const char txt[] = "protected by the layer of grease!"; 207. boolean vismon = victim && (victim != &youmonst) && canseemon(victim); 208. 209. if (ostr) { 210. if (victim == &youmonst) 211. Your("%s %s %s", ostr, vtense(ostr, "are"), txt); 212. else if (vismon) 213. pline("%s's %s %s %s", Monnam(victim), 214. ostr, vtense(ostr, "are"), txt); 215. } else { 216. if (victim == &youmonst) 217. Your("%s %s",aobjnam(otmp,"are"), txt); 218. else if (vismon) 219. pline("%s's %s %s", Monnam(victim), aobjnam(otmp,"are"), txt); 220. } 221. if (!rn2(2)) { 222. otmp->greased = 0; 223. if (carried(otmp)) { 224. pline_The("grease dissolves."); 225. update_inventory(); 226. } 227. } 228. } 229. 230. struct trap * 231. maketrap(x,y,typ) 232. register int x, y, typ; 233. { 234. register struct trap *ttmp; 235. register struct rm *lev; 236. register boolean oldplace; 237. 238. if ((ttmp = t_at(x,y)) != 0) { 239. if (ttmp->ttyp == MAGIC_PORTAL) return (struct trap *)0; 240. oldplace = TRUE; 241. if (u.utrap && (x == u.ux) && (y == u.uy) && 242. ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) || 243. (u.utraptype == TT_WEB && typ != WEB) || 244. (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT))) 245. u.utrap = 0; 246. } else { 247. oldplace = FALSE; 248. ttmp = newtrap(); 249. ttmp->tx = x; 250. ttmp->ty = y; 251. ttmp->launch.x = -1; /* force error if used before set */ 252. ttmp->launch.y = -1; 253. } 254. ttmp->ttyp = typ; 255. switch(typ) { 256. case STATUE_TRAP: /* create a "living" statue */ 257. { struct monst *mtmp; 258. struct obj *otmp, *statue; 259. 260. statue = mkcorpstat(STATUE, (struct monst *)0, 261. &mons[rndmonnum()], x, y, FALSE); 262. mtmp = makemon(&mons[statue->corpsenm], 0, 0, NO_MM_FLAGS); 263. if (!mtmp) break; /* should never happen */ 264. while(mtmp->minvent) { 265. otmp = mtmp->minvent; 266. otmp->owornmask = 0; 267. obj_extract_self(otmp); 268. (void) add_to_container(statue, otmp); 269. } 270. statue->owt = weight(statue); 271. mongone(mtmp); 272. break; 273. } 274. case ROLLING_BOULDER_TRAP: /* boulder will roll towards trigger */ 275. (void) mkroll_launch(ttmp, x, y, BOULDER, 1L); 276. break; 277. case HOLE: 278. case PIT: 279. case SPIKED_PIT: 280. case TRAPDOOR: 281. lev = &levl[x][y]; 282. if (*in_rooms(x, y, SHOPBASE) && 283. ((typ == HOLE || typ == TRAPDOOR) || IS_DOOR(lev->typ))) 284. add_damage(x, y, /* schedule repair */ 285. (IS_DOOR(lev->typ) && !flags.mon_moving) ? 200L : 0L); 286. lev->doormask = 0; /* subsumes altarmask, icedpool... */ 287. if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */ 288. lev->typ = ROOM; 289. 290. /* 291. * some cases which can happen when digging 292. * down while phazing thru solid areas 293. */ 294. else if (lev->typ == STONE || lev->typ == SCORR) 295. lev->typ = CORR; 296. else if (IS_WALL(lev->typ) || lev->typ == SDOOR) 297. lev->typ = level.flags.is_maze_lev ? ROOM : 298. level.flags.is_cavernous_lev ? CORR : DOOR; 299. 300. unearth_objs(x, y); 301. break; 302. } 303. if (ttmp->ttyp == HOLE) ttmp->tseen = 1; /* You can't hide a hole */ 304. else ttmp->tseen = 0; 305. ttmp->once = 0; 306. ttmp->madeby_u = 0; 307. ttmp->dst.dnum = -1; 308. ttmp->dst.dlevel = -1; 309. if (!oldplace) { 310. ttmp->ntrap = ftrap; 311. ftrap = ttmp; 312. } 313. return(ttmp); 314. } 315. 316. void 317. fall_through(td) 318. boolean td; /* td == TRUE : trap door or hole */ 319. { 320. d_level dtmp; 321. char msgbuf[BUFSZ]; 322. const char *dont_fall = 0; 323. register int newlevel = dunlev(&u.uz); 324. 325. /* KMH -- You can't escape the Sokoban level traps */ 326. if(Blind && Levitation && !In_sokoban(&u.uz)) return; 327. 328. do { 329. newlevel++; 330. } while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz)); 331. 332. if(td) { 333. struct trap *t=t_at(u.ux,u.uy); 334. if (!In_sokoban(&u.uz)) { 335. if (t->ttyp == TRAPDOOR) 336. pline("A trap door opens up under you!"); 337. else 338. pline("There's a gaping hole under you!"); 339. } 340. } else pline_The("%s opens up under you!", surface(u.ux,u.uy)); 341. 342. if (In_sokoban(&u.uz) && Can_fall_thru(&u.uz)) 343. ; /* KMH -- You can't escape the Sokoban level traps */ 344. else if(Levitation || u.ustuck || !Can_fall_thru(&u.uz) 345. || Flying || is_clinger(youmonst.data) 346. || (Inhell && !u.uevent.invoked && 347. newlevel == dunlevs_in_dungeon(&u.uz)) 348. ) { 349. dont_fall = "don't fall in."; 350. } else if (youmonst.data->msize >= MZ_HUGE) { 351. dont_fall = "don't fit through."; 352. } else if (!next_to_u()) { 353. dont_fall = "are jerked back by your pet!"; 354. } 355. if (dont_fall) { 356. You(dont_fall); 357. /* hero didn't fall through, but any objects here might */ 358. impact_drop((struct obj *)0, u.ux, u.uy, 0); 359. if (!td) { 360. display_nhwindow(WIN_MESSAGE, FALSE); 361. pline_The("opening under you closes up."); 362. } 363. return; 364. } 365. 366. if(*u.ushops) shopdig(1); 367. if (Is_stronghold(&u.uz)) { 368. find_hell(&dtmp); 369. } else { 370. dtmp.dnum = u.uz.dnum; 371. dtmp.dlevel = newlevel; 372. } 373. if (!td) 374. Sprintf(msgbuf, "The hole in the %s above you closes up.", 375. ceiling(u.ux,u.uy)); 376. schedule_goto(&dtmp, FALSE, TRUE, 0, 377. (char *)0, !td ? msgbuf : (char *)0); 378. } 379. 380. /* 381. * Animate the given statue. May have been via shatter attempt, trap, 382. * or stone to flesh spell. Return a monster if successfully animated. 383. * If the monster is animated, the object is deleted. If fail_reason 384. * is non-null, then fill in the reason for failure (or success). 385. * 386. * The cause of animation is: 387. * 388. * ANIMATE_NORMAL - hero "finds" the monster 389. * ANIMATE_SHATTER - hero tries to destroy the statue 390. * ANIMATE_SPELL - stone to flesh spell hits the statue 391. * 392. * Perhaps x, y is not needed if we can use get_obj_location() to find 393. * the statue's location... ??? 394. */ 395. struct monst * 396. animate_statue(statue, x, y, cause, fail_reason) 397. struct obj *statue; 398. xchar x, y; 399. int cause; 400. int *fail_reason; 401. { 402. struct permonst *mptr; 403. struct monst *mon = 0; 404. struct obj *item; 405. coord cc; 406. 407. if (statue->oxlth && statue->oattached == OATTACHED_MONST) { 408. cc.x = x, cc.y = y; 409. mon = montraits(statue, &cc); 410. if (mon && mon->mtame && !mon->isminion) 411. wary_dog(mon, TRUE); 412. } else { 413. /* 414. * Guard against someone wishing for a statue of a unique monster 415. * (which is allowed in normal play) and then tossing it onto the 416. * [detected or guessed] location of a statue trap. Normally the 417. * uppermost statue is the one which would be activated. 418. */ 419. mptr = &mons[statue->corpsenm]; 420. if (mptr->geno & G_UNIQ) { 421. if (fail_reason) *fail_reason = AS_MON_IS_UNIQUE; 422. return (struct monst *)0; 423. } 424. mon = makemon(mptr, x, y, NO_MINVENT); 425. } 426. 427. if (!mon) { 428. if (fail_reason) *fail_reason = AS_NO_MON; 429. return (struct monst *)0; 430. } 431. 432. /* if statue has been named, give same name to the monster */ 433. if (statue->onamelth) 434. mon = christen_monst(mon, ONAME(statue)); 435. /* transfer any statue contents to monster's inventory */ 436. while ((item = statue->cobj) != 0) { 437. obj_extract_self(item); 438. (void) add_to_minv(mon, item); 439. } 440. m_dowear(mon, TRUE); 441. delobj(statue); 442. /* mimic statue becomes seen mimic; other hiders won't be hidden */ 443. if (mon->m_ap_type) seemimic(mon); 444. else mon->mundetected = FALSE; 445. if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) 446. pline_The("statue comes to life!"); 447. else if (cause == ANIMATE_SHATTER) 448. pline("Instead of shattering, the statue suddenly comes alive!"); 449. else /* cause == ANIMATE_NORMAL */ 450. You("find %s posing as a statue.", a_monnam(mon)); 451. /* avoid hiding under nothing */ 452. if (x == u.ux && y == u.uy && 453. Upolyd && hides_under(youmonst.data) && !OBJ_AT(x, y)) 454. u.uundetected = 0; 455. 456. if (fail_reason) *fail_reason = AS_OK; 457. return mon; 458. } 459. 460. /* 461. * You've either stepped onto a statue trap's location or you've triggered a 462. * statue trap by searching next to it or by trying to break it with a wand 463. * or pick-axe. 464. */ 465. struct monst * 466. activate_statue_trap(trap, x, y, shatter) 467. struct trap *trap; 468. xchar x, y; 469. boolean shatter; 470. { 471. struct monst *mtmp = (struct monst *)0; 472. struct obj *otmp = sobj_at(STATUE, x, y); 473. int fail_reason; 474. 475. /* 476. * Try to animate the first valid statue. Stop the loop when we 477. * actually create something or the failure cause is not because 478. * the mon was unique. 479. */ 480. deltrap(trap); 481. while (otmp) { 482. mtmp = animate_statue(otmp, x, y, 483. shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL, &fail_reason); 484. if (mtmp || fail_reason != AS_MON_IS_UNIQUE) break; 485. 486. while ((otmp = otmp->nexthere) != 0) 487. if (otmp->otyp == STATUE) break; 488. } 489. 490. if (Blind) feel_location(x, y); 491. else newsym(x, y); 492. return mtmp; 493. } 494. 495. void 496. dotrap(trap, trflags) 497. register struct trap *trap; 498. unsigned trflags; 499. { 500. register int ttype = trap->ttyp; 501. register struct obj *otmp; 502. boolean already_seen = trap->tseen; 503. boolean webmsgok = (!(trflags & NOWEBMSG)); 504. 505. nomul(0); 506. 507. /* KMH -- You can't escape the Sokoban level traps */ 508. if (In_sokoban(&u.uz) && 509. (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE || 510. ttype == TRAPDOOR)) { 511. /* The "air currents" message is still appropriate -- even when 512. * the hero isn't flying or levitating -- because it conveys the 513. * reason why the player cannot escape the trap with a dexterity 514. * check, clinging to the ceiling, etc. 515. */ 516. pline("Air currents pull you down into %s %s!", 517. a_your[trap->madeby_u], 518. defsyms[trap_to_defsym(ttype)].explanation); 519. /* then proceed to normal trap effect */ 520. } else if (already_seen) { 521. if ((Levitation || Flying) && 522. (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE || 523. ttype == BEAR_TRAP)) { 524. You("%s over %s %s.", 525. Levitation ? "float" : "fly", 526. a_your[trap->madeby_u], 527. defsyms[trap_to_defsym(ttype)].explanation); 528. return; 529. } 530. if(!Fumbling && ttype != MAGIC_PORTAL && ttype != ANTI_MAGIC && 531. (!rn2(5) || 532. ((ttype == PIT || ttype == SPIKED_PIT) && is_clinger(youmonst.data)))) { 533. You("escape %s %s.", 534. (ttype == ARROW_TRAP && !trap->madeby_u) ? "an" : 535. a_your[trap->madeby_u], 536. defsyms[trap_to_defsym(ttype)].explanation); 537. return; 538. } 539. } 540. 541. switch(ttype) { 542. case ARROW_TRAP: 543. seetrap(trap); 544. pline("An arrow shoots out at you!"); 545. otmp = mksobj(ARROW, TRUE, FALSE); 546. otmp->quan = 1L; 547. otmp->owt = weight(otmp); 548. otmp->opoisoned = 0; 549. #ifdef STEED 550. if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) /* nothing */; 551. else 552. #endif 553. if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) { 554. obfree(otmp, (struct obj *)0); 555. } else { 556. place_object(otmp, u.ux, u.uy); 557. if (!Blind) otmp->dknown = 1; 558. stackobj(otmp); 559. newsym(u.ux, u.uy); 560. } 561. break; 562. case DART_TRAP: 563. seetrap(trap); 564. pline("A little dart shoots out at you!"); 565. otmp = mksobj(DART, TRUE, FALSE); 566. otmp->quan = 1L; 567. otmp->owt = weight(otmp); 568. if (!rn2(6)) otmp->opoisoned = 1; 569. #ifdef STEED 570. if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) /* nothing */; 571. else 572. #endif 573. if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { 574. if (otmp->opoisoned) 575. poisoned("dart",A_CON,"poison dart",10); 576. obfree(otmp, (struct obj *)0); 577. } else { 578. place_object(otmp, u.ux, u.uy); 579. if (!Blind) otmp->dknown = 1; 580. stackobj(otmp); 581. newsym(u.ux, u.uy); 582. } 583. break; 584. case ROCKTRAP: 585. { 586. int dmg = d(2,6); /* should be std ROCK dmg? */ 587. 588. seetrap(trap); 589. otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE); 590. otmp->quan = 1L; 591. otmp->owt = weight(otmp); 592. 593. pline("A trap door in the %s opens and a rock falls on your %s!", 594. ceiling(u.ux,u.uy), 595. body_part(HEAD)); 596. 597. if (uarmh) { 598. if(is_metallic(uarmh)) { 599. pline("Fortunately, you are wearing a hard helmet."); 600. dmg = 2; 601. } else if (flags.verbose) { 602. Your("%s does not protect you.", xname(uarmh)); 603. } 604. } 605. 606. if (!Blind) otmp->dknown = 1; 607. stackobj(otmp); 608. newsym(u.ux,u.uy); /* map the rock */ 609. 610. losehp(dmg, "falling rock", KILLED_BY_AN); 611. exercise(A_STR, FALSE); 612. } 613. break; 614. 615. case SQKY_BOARD: /* stepped on a squeaky board */ 616. if (Levitation || Flying) { 617. if (!Blind) { 618. seetrap(trap); 619. if (Hallucination) 620. You("notice a crease in the linoleum."); 621. else 622. You("notice a loose board below you."); 623. } 624. } else { 625. seetrap(trap); 626. pline("A board beneath you squeaks loudly."); 627. wake_nearby(); 628. } 629. break; 630. 631. case BEAR_TRAP: 632. if(Levitation || Flying) break; 633. seetrap(trap); 634. if(amorphous(youmonst.data) || is_whirly(youmonst.data) || 635. unsolid(youmonst.data)) { 636. pline("%s bear trap closes harmlessly through you.", 637. A_Your[trap->madeby_u]); 638. break; 639. } 640. if( 641. #ifdef STEED 642. !u.usteed && 643. #endif 644. youmonst.data->msize <= MZ_SMALL) { 645. pline("%s bear trap closes harmlessly over you.", 646. A_Your[trap->madeby_u]); 647. break; 648. } 649. u.utrap = rn1(4, 4); 650. u.utraptype = TT_BEARTRAP; 651. #ifdef STEED 652. if (u.usteed) { 653. pline("%s bear trap closes on %s %s!", 654. A_Your[trap->madeby_u], s_suffix(mon_nam(u.usteed)), 655. mbodypart(u.usteed, FOOT)); 656. } else 657. #endif 658. { 659. pline("%s bear trap closes on your %s!", 660. A_Your[trap->madeby_u], body_part(FOOT)); 661. if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) 662. You("howl in anger!"); 663. } 664. exercise(A_DEX, FALSE); 665. break; 666. 667. case SLP_GAS_TRAP: 668. seetrap(trap); 669. if(Sleep_resistance || breathless(youmonst.data)) { 670. You("are enveloped in a cloud of gas!"); 671. break; 672. } 673. pline("A cloud of gas puts you to sleep!"); 674. flags.soundok = 0; 675. fall_asleep(-rnd(25), TRUE); 676. afternmv = Hear_again; 677. #ifdef STEED 678. (void) steedintrap(trap, (struct obj *)0); 679. #endif 680. break; 681. 682. case RUST_TRAP: 683. seetrap(trap); 684. if (u.umonnum == PM_IRON_GOLEM) { 685. pline("%s you!", A_gush_of_water_hits); 686. You("are covered with rust!"); 687. rehumanize(); 688. break; 689. } else if (u.umonnum == PM_GREMLIN && rn2(3)) { 690. pline("%s you!", A_gush_of_water_hits); 691. (void)split_mon(&youmonst, (struct monst *)0); 692. break; 693. } 694. 695. /* Unlike monsters, traps cannot aim their rust attacks at 696. * you, so instead of looping through and taking either the 697. * first rustable one or the body, we take whatever we get, 698. * even if it is not rustable. 699. */ 700. switch (rn2(5)) { 701. case 0: 702. pline("%s you on the %s!", A_gush_of_water_hits, 703. body_part(HEAD)); 704. (void) rust_dmg(uarmh, "helmet", 1, TRUE, &youmonst); 705. break; 706. case 1: 707. pline("%s your left %s!", A_gush_of_water_hits, 708. body_part(ARM)); 709. if (rust_dmg(uarms, "shield", 1, TRUE, &youmonst)) 710. break; 711. if (u.twoweap || (uwep && bimanual(uwep))) 712. erode_obj(u.twoweap ? uswapwep : uwep, FALSE, TRUE); 713. glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst); 714. /* Not "metal gauntlets" since it gets called 715. * even if it's leather for the message 716. */ 717. break; 718. case 2: 719. pline("%s your right %s!", A_gush_of_water_hits, 720. body_part(ARM)); 721. erode_obj(uwep, FALSE, TRUE); 722. goto glovecheck; 723. default: 724. pline("%s you!", A_gush_of_water_hits); 725. for (otmp=invent; otmp; otmp = otmp->nobj) 726. (void) snuff_lit(otmp); 727. if (uarmc) 728. (void) rust_dmg(uarmc, cloak_simple_name(uarmc), 729. 1, TRUE, &youmonst); 730. else if (uarm) 731. (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst); 732. #ifdef TOURIST 733. else if (uarmu) 734. (void) rust_dmg(uarmu, "shirt", 1, TRUE, &youmonst); 735. #endif 736. } 737. update_inventory(); 738. break; 739. 740. case FIRE_TRAP: 741. seetrap(trap); 742. dofiretrap((struct obj *)0); 743. break; 744. 745. case PIT: 746. case SPIKED_PIT: 747. /* KMH -- You can't escape the Sokoban level traps */ 748. if (!In_sokoban(&u.uz) && (Levitation || Flying)) break; 749. seetrap(trap); 750. if (!In_sokoban(&u.uz) && is_clinger(youmonst.data)) { 751. if(trap->tseen) { 752. You("see %s %spit below you.", a_your[trap->madeby_u], 753. ttype == SPIKED_PIT ? "spiked " : ""); 754. } else { 755. pline("%s pit %sopens up under you!", 756. A_Your[trap->madeby_u], 757. ttype == SPIKED_PIT ? "full of spikes " : ""); 758. You("don't fall in!"); 759. } 760. break; 761. } 762. if (!In_sokoban(&u.uz)) { 763. char verbbuf[BUFSZ]; 764. #ifdef STEED 765. if (u.usteed) 766. Sprintf(verbbuf,"lead %s", 767. x_monnam(u.usteed, 768. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 769. "poor", SUPPRESS_SADDLE, FALSE)); 770. else 771. #endif 772. Strcpy(verbbuf,"fall"); 773. You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]); 774. } 775. /* wumpus reference */ 776. if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once && 777. In_quest(&u.uz) && Is_qlocate(&u.uz)) { 778. pline("Fortunately it has a bottom after all..."); 779. trap->once = 1; 780. } else if (u.umonnum == PM_PIT_VIPER || 781. u.umonnum == PM_PIT_FIEND) 782. pline("How pitiful. Isn't that the pits?"); 783. if (ttype == SPIKED_PIT) { 784. char *predicament = "on a set of sharp iron spikes"; 785. #ifdef STEED 786. if (u.usteed) { 787. pline("%s lands %s!", 788. upstart(x_monnam(u.usteed, 789. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 790. "poor", SUPPRESS_SADDLE, FALSE)), predicament); 791. } else 792. #endif 793. You("land %s!", predicament); 794. } 795. if (!Passes_walls) 796. u.utrap = rn1(6,2); 797. u.utraptype = TT_PIT; 798. #ifdef STEED 799. if (!steedintrap(trap, (struct obj *)0)) { 800. #endif 801. if (ttype == SPIKED_PIT) { 802. losehp(rnd(10),"fell into a pit of iron spikes", 803. NO_KILLER_PREFIX); 804. if (!rn2(6)) 805. poisoned("spikes", A_STR, "fall onto poison spikes", 8); 806. } else 807. losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX); 808. if (Punished && !carried(uball)) { 809. unplacebc(); 810. ballfall(); 811. placebc(); 812. } 813. selftouch("Falling, you"); 814. vision_full_recalc = 1; /* vision limits change */ 815. exercise(A_STR, FALSE); 816. exercise(A_DEX, FALSE); 817. #ifdef STEED 818. } 819. #endif 820. break; 821. case HOLE: 822. case TRAPDOOR: 823. seetrap(trap); 824. if (!Can_fall_thru(&u.uz)) { 825. impossible("dotrap: %ss cannot exist on this level.", 826. defsyms[trap_to_defsym(ttype)].explanation); 827. break; /* don't activate it after all */ 828. } 829. fall_through(TRUE); 830. break; 831. 832. case TELEP_TRAP: 833. seetrap(trap); 834. tele_trap(trap); 835. break; 836. case LEVEL_TELEP: 837. seetrap(trap); 838. level_tele_trap(trap); 839. break; 840. 841. case WEB: /* Our luckless player has stumbled into a web. */ 842. seetrap(trap); 843. if (amorphous(youmonst.data) || is_whirly(youmonst.data) || 844. unsolid(youmonst.data)) { 845. if (acidic(youmonst.data) || u.umonnum == PM_GELATINOUS_CUBE || 846. u.umonnum == PM_FIRE_ELEMENTAL) { 847. if (webmsgok) 848. You("%s %s spider web!", 849. (u.umonnum == PM_FIRE_ELEMENTAL) ? "burn" : "dissolve", 850. a_your[trap->madeby_u]); 851. deltrap(trap); 852. newsym(u.ux,u.uy); 853. break; 854. } 855. if (webmsgok) You("flow through %s spider web.", 856. a_your[trap->madeby_u]); 857. break; 858. } 859. if (webmaker(youmonst.data)) { 860. if (webmsgok) 861. pline(trap->madeby_u ? "You take a walk on your web." 862. : "There is a spider web here."); 863. break; 864. } 865. if (webmsgok) { 866. char verbbuf[BUFSZ]; 867. verbbuf[0] = '\0'; 868. #ifdef STEED 869. if (u.usteed) 870. Sprintf(verbbuf,"lead %s", 871. x_monnam(u.usteed, 872. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 873. "poor", SUPPRESS_SADDLE, FALSE)); 874. else 875. #endif 876. 877. Sprintf(verbbuf, "%s", Levitation ? (const char *)"float" : 878. locomotion(youmonst.data, "stumble")); 879. You("%s into %s spider web!", verbbuf, a_your[trap->madeby_u]); 880. } 881. u.utraptype = TT_WEB; 882. 883. /* Time stuck in the web depends on your strength. */ 884. { 885. register int str = ACURR(A_STR); 886. 887. if (str <= 3) u.utrap = rn1(6,6); 888. else if (str < 6) u.utrap = rn1(6,4); 889. else if (str < 9) u.utrap = rn1(4,4); 890. else if (str < 12) u.utrap = rn1(4,2); 891. else if (str < 15) u.utrap = rn1(2,2); 892. else if (str < 18) u.utrap = rnd(2); 893. else if (str < 69) u.utrap = 1; 894. else { 895. u.utrap = 0; 896. if (webmsgok) 897. You("tear through %s web!", a_your[trap->madeby_u]); 898. deltrap(trap); 899. newsym(u.ux,u.uy); /* get rid of trap symbol */ 900. } 901. } 902. break; 903. 904. case STATUE_TRAP: 905. (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); 906. break; 907. 908. case MAGIC_TRAP: /* A magic trap. */ 909. seetrap(trap); 910. if (!rn2(30)) { 911. deltrap(trap); 912. newsym(u.ux,u.uy); /* update position */ 913. You("are caught in a magical explosion!"); 914. losehp(rnd(10), "magical explosion", KILLED_BY_AN); 915. Your("body absorbs some of the magical energy!"); 916. u.uen = (u.uenmax += 2); 917. } else domagictrap(); 918. #ifdef STEED 919. (void) steedintrap(trap, (struct obj *)0); 920. #endif 921. break; 922. 923. case ANTI_MAGIC: 924. seetrap(trap); 925. if(Antimagic) { 926. shieldeff(u.ux, u.uy); 927. You_feel("momentarily lethargic."); 928. } else drain_en(rnd(u.ulevel) + 1); 929. break; 930. 931. case POLY_TRAP: { 932. char verbbuf[BUFSZ]; 933. seetrap(trap); 934. #ifdef STEED 935. if (u.usteed) 936. Sprintf(verbbuf, "lead %s", 937. x_monnam(u.usteed, 938. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 939. (char *)0, SUPPRESS_SADDLE, FALSE)); 940. else 941. #endif 942. Sprintf(verbbuf,"%s", 943. Levitation ? (const char *)"float" : 944. locomotion(youmonst.data, "step")); 945. You("%s onto a polymorph trap!", verbbuf); 946. if(Antimagic || Unchanging) { 947. shieldeff(u.ux, u.uy); 948. You_feel("momentarily different."); 949. /* Trap did nothing; don't remove it --KAA */ 950. } else { 951. #ifdef STEED 952. (void) steedintrap(trap, (struct obj *)0); 953. #endif 954. deltrap(trap); /* delete trap before polymorph */ 955. newsym(u.ux,u.uy); /* get rid of trap symbol */ 956. You_feel("a change coming over you."); 957. polyself(FALSE); 958. } 959. break; 960. } 961. case LANDMINE: 962. if (Levitation || Flying) { 963. if (!already_seen && rn2(3)) break; 964. seetrap(trap); 965. pline("%s %s in a pile of soil below you.", 966. already_seen ? "There is" : "You discover", 967. trap->madeby_u ? "the trigger of your mine" : 968. "a trigger"); 969. if (already_seen && rn2(3)) break; 970. pline("KAABLAMM!!! The air currents set %s%s off!", 971. already_seen ? a_your[trap->madeby_u] : "", 972. already_seen ? " land mine" : "it"); 973. } else { 974. #ifdef STEED 975. /* prevent landmine from killing steed, throwing you to 976. * the ground, and you being affected again by the same 977. * mine because it hasn't been deleted yet 978. */ 979. static boolean recursive_mine = FALSE; 980. 981. if (recursive_mine) break; 982. #endif 983. seetrap(trap); 984. pline("KAABLAMM!!! You triggered %s land mine!", 985. a_your[trap->madeby_u]); 986. #ifdef STEED 987. recursive_mine = TRUE; 988. (void) steedintrap(trap, (struct obj *)0); 989. recursive_mine = FALSE; 990. #endif 991. set_wounded_legs(LEFT_SIDE, rn1(35, 41)); 992. set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); 993. exercise(A_DEX, FALSE); 994. } 995. blow_up_landmine(trap); 996. newsym(u.ux,u.uy); /* update trap symbol */ 997. losehp(rnd(16), "land mine", KILLED_BY_AN); 998. /* fall recursively into the pit... */ 999. if ((trap = t_at(u.ux, u.uy)) != 0) dotrap(trap, 0); 1000. fill_pit(u.ux, u.uy); 1001. break; 1002. 1003. case ROLLING_BOULDER_TRAP: 1004. seetrap(trap); 1005. pline("Click! You trigger a rolling boulder trap!"); 1006. if(!launch_obj(BOULDER, trap->launch.x, trap->launch.y, 1007. trap->launch2.x,trap->launch2.y, ROLL)) { 1008. deltrap(trap); 1009. newsym(u.ux,u.uy); /* get rid of trap symbol */ 1010. pline("Fortunately for you, no boulder was released."); 1011. } 1012. break; 1013. 1014. case MAGIC_PORTAL: 1015. seetrap(trap); 1016. domagicportal(trap); 1017. break; 1018. 1019. default: 1020. seetrap(trap); 1021. impossible("You hit a trap of type %u", trap->ttyp); 1022. } 1023. } 1024. 1025. #ifdef STEED 1026. STATIC_OVL int 1027. steedintrap(trap, otmp) 1028. struct trap *trap; 1029. struct obj *otmp; 1030. { 1031. struct monst *mtmp = u.usteed; 1032. struct permonst *mptr; 1033. int tt; 1034. boolean in_sight; 1035. boolean trapkilled = FALSE; 1036. boolean steedhit = FALSE; 1037. 1038. if (!u.usteed || !trap) return 0; 1039. mptr = mtmp->data; 1040. tt = trap->ttyp; 1041. mtmp->mx = u.ux; 1042. mtmp->my = u.uy; 1043. 1044. in_sight = !Blind; 1045. switch (tt) { 1046. case ARROW_TRAP: 1047. if(!otmp) { 1048. impossible("steed hit by non-existant arrow?"); 1049. return 0; 1050. } 1051. if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 1052. steedhit = TRUE; 1053. break; 1054. case DART_TRAP: 1055. if(!otmp) { 1056. impossible("steed hit by non-existant dart?"); 1057. return 0; 1058. } 1059. if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 1060. steedhit = TRUE; 1061. break; 1062. case SLP_GAS_TRAP: 1063. if (!resists_sleep(mtmp) && !breathless(mptr) && 1064. !mtmp->msleeping && mtmp->mcanmove) { 1065. mtmp->mcanmove = 0; 1066. mtmp->mfrozen = rnd(25); 1067. if (in_sight) { 1068. pline("%s suddenly falls asleep!", 1069. Monnam(mtmp)); 1070. } 1071. } 1072. steedhit = TRUE; 1073. break; 1074. case LANDMINE: 1075. if (thitm(0, mtmp, (struct obj *)0, rnd(16))) 1076. trapkilled = TRUE; 1077. steedhit = TRUE; 1078. break; 1079. case PIT: 1080. case SPIKED_PIT: 1081. if (mtmp->mhp <= 0 || 1082. thitm(0, mtmp, (struct obj *)0, 1083. rnd((tt == PIT) ? 6 : 10))) 1084. trapkilled = TRUE; 1085. steedhit = TRUE; 1086. break; 1087. case POLY_TRAP: 1088. if (!resists_magm(mtmp)) { 1089. if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1090. (void) newcham(mtmp, (struct permonst *)0, FALSE); 1091. if (!can_saddle(mtmp) || !can_ride(mtmp)) { 1092. dismount_steed(DISMOUNT_POLY); 1093. } else { 1094. You("have to adjust yourself in the saddle on %s.", 1095. x_monnam(mtmp, 1096. mtmp->mnamelth ? ARTICLE_NONE : ARTICLE_A, 1097. (char *)0, SUPPRESS_SADDLE, FALSE)); 1098. } 1099. 1100. } 1101. steedhit = TRUE; 1102. break; 1103. default: 1104. return 0; 1105. } 1106. } 1107. if(trapkilled) { 1108. dismount_steed(DISMOUNT_POLY); 1109. return 2; 1110. } 1111. else if(steedhit) return 1; 1112. else return 0; 1113. } 1114. #endif /*STEED*/ 1115. 1116. /* some actions common to both player and monsters for triggered landmine */ 1117. void 1118. blow_up_landmine(trap) 1119. struct trap *trap; 1120. { 1121. scatter(trap->tx, trap->ty, 4, 1122. MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS, 1123. (struct obj *)0); 1124. del_engr_at(trap->tx, trap->ty); 1125. wake_nearto(trap->tx, trap->ty, 400); 1126. if (IS_DOOR(levl[trap->tx][trap->ty].typ)) 1127. levl[trap->tx][trap->ty].doormask = D_BROKEN; 1128. /* TODO: destroy drawbridge if present */ 1129. /* caller may subsequently fill pit, e.g. with a boulder */ 1130. trap->ttyp = PIT; /* explosion creates a pit */ 1131. trap->madeby_u = FALSE; /* resulting pit isn't yours */ 1132. } 1133. 1134. #endif /* OVLB */ 1135. #ifdef OVL3 1136. 1137. /* 1138. * Move obj from (x1,y1) to (x2,y2) 1139. * 1140. * Return 0 if no object was launched. 1141. * 1 if an object was launched and placed somewhere. 1142. * 2 if an object was launched, but used up. 1143. */ 1144. int 1145. launch_obj(otyp, x1, y1, x2, y2, style) 1146. short otyp; 1147. register int x1,y1,x2,y2; 1148. int style; 1149. { 1150. register struct monst *mtmp; 1151. register struct obj *otmp, *otmp2; 1152. register int dx,dy; 1153. struct obj *singleobj; 1154. boolean used_up = FALSE; 1155. boolean otherside = FALSE; 1156. int dist; 1157. int tmp; 1158. int delaycnt = 0; 1159. 1160. otmp = sobj_at(otyp, x1, y1); 1161. /* Try the other side too, for rolling boulder traps */ 1162. if (!otmp && otyp == BOULDER) { 1163. otherside = TRUE; 1164. otmp = sobj_at(otyp, x2, y2); 1165. } 1166. if (!otmp) return 0; 1167. if (otherside) { /* swap 'em */ 1168. int tx, ty; 1169. 1170. tx = x1; ty = y1; 1171. x1 = x2; y1 = y2; 1172. x2 = tx; y2 = ty; 1173. } 1174. 1175. if (otmp->quan == 1L) { 1176. obj_extract_self(otmp); 1177. singleobj = otmp; 1178. otmp = (struct obj *) 0; 1179. } else { 1180. singleobj = splitobj(otmp, 1L); 1181. obj_extract_self(singleobj); 1182. } 1183. newsym(x1,y1); 1184. /* in case you're using a pick-axe to chop the boulder that's being 1185. launched (perhaps a monster triggered it), destroy context so that 1186. next dig attempt never thinks you're resuming previous effort */ 1187. if ((otyp == BOULDER || otyp == STATUE) && 1188. singleobj->ox == digging.pos.x && singleobj->oy == digging.pos.y) 1189. (void) memset((genericptr_t)&digging, 0, sizeof digging); 1190. 1191. dist = distmin(x1,y1,x2,y2); 1192. bhitpos.x = x1; 1193. bhitpos.y = y1; 1194. dx = sgn(x2 - x1); 1195. dy = sgn(y2 - y1); 1196. switch (style) { 1197. case ROLL: 1198. delaycnt = 2; 1199. /* fall through */ 1200. default: 1201. if (!delaycnt) delaycnt = 1; 1202. if (!cansee(bhitpos.x,bhitpos.y)) curs_on_u(); 1203. tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); 1204. tmp_at(bhitpos.x, bhitpos.y); 1205. } 1206. 1207. /* Set the object in motion */ 1208. while(dist-- > 0 && !used_up) { 1209. struct trap *t; 1210. tmp_at(bhitpos.x, bhitpos.y); 1211. tmp = delaycnt; 1212. 1213. /* dstage@u.washington.edu -- Delay only if hero sees it */ 1214. if (cansee(bhitpos.x, bhitpos.y)) 1215. while (tmp-- > 0) delay_output(); 1216. 1217. bhitpos.x += dx; 1218. bhitpos.y += dy; 1219. t = t_at(bhitpos.x, bhitpos.y); 1220. 1221. if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { 1222. if (otyp == BOULDER && throws_rocks(mtmp->data)) { 1223. if (rn2(3)) { 1224. pline("%s snatches the boulder.", 1225. Monnam(mtmp)); 1226. (void) mpickobj(mtmp, singleobj); 1227. used_up = TRUE; 1228. break; 1229. } 1230. } 1231. if (ohitmon(mtmp,singleobj, 1232. (style==ROLL) ? -1 : dist, FALSE)) { 1233. used_up = TRUE; 1234. break; 1235. } 1236. } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) { 1237. if (multi) nomul(0); 1238. if (thitu(9 + singleobj->spe, 1239. dmgval(singleobj, &youmonst), 1240. singleobj, (char *)0)) 1241. stop_occupation(); 1242. } 1243. if (style == ROLL) { 1244. if (down_gate(bhitpos.x, bhitpos.y) != -1) { 1245. if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){ 1246. used_up = TRUE; 1247. break; 1248. } 1249. } 1250. if (t && otyp == BOULDER) { 1251. switch(t->ttyp) { 1252. case LANDMINE: 1253. if (rn2(10) > 2) { 1254. pline( 1255. "KAABLAMM!!!%s", 1256. cansee(bhitpos.x, bhitpos.y) ? 1257. " The rolling boulder triggers a land mine." : ""); 1258. deltrap(t); 1259. del_engr_at(bhitpos.x,bhitpos.y); 1260. place_object(singleobj, bhitpos.x, bhitpos.y); 1261. fracture_rock(singleobj); 1262. scatter(bhitpos.x,bhitpos.y, 4, 1263. MAY_DESTROY|MAY_HIT|MAY_FRACTURE|VIS_EFFECTS, 1264. (struct obj *)0); 1265. if (cansee(bhitpos.x,bhitpos.y)) 1266. newsym(bhitpos.x,bhitpos.y); 1267. used_up = TRUE; 1268. } 1269. break; 1270. case LEVEL_TELEP: 1271. case TELEP_TRAP: 1272. if (cansee(bhitpos.x, bhitpos.y)) 1273. pline("Suddenly the rolling boulder disappears!"); 1274. else 1275. You_hear("a rumbling stop abruptly."); 1276. if (t->ttyp == TELEP_TRAP) 1277. rloco(singleobj); 1278. else { 1279. int newlev = random_teleport_level(); 1280. d_level dest; 1281. 1282. if (newlev == depth(&u.uz) || In_endgame(&u.uz)) 1283. continue; 1284. add_to_migration(singleobj); 1285. get_level(&dest, newlev); 1286. singleobj->ox = dest.dnum; 1287. singleobj->oy = dest.dlevel; 1288. singleobj->owornmask = (long)MIGR_RANDOM; 1289. } 1290. seetrap(t); 1291. used_up = TRUE; 1292. break; 1293. } 1294. if (used_up) break; 1295. } 1296. if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) { 1297. used_up = TRUE; 1298. break; 1299. } 1300. if (otyp == BOULDER && 1301. (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) { 1302. char *bmsg = 1303. " as one boulder sets another in motion"; 1304. You_hear("a loud crash%s!", 1305. cansee(bhitpos.x, bhitpos.y) ? bmsg : ""); 1306. obj_extract_self(otmp2); 1307. place_object(singleobj, bhitpos.x, bhitpos.y); 1308. singleobj = otmp2; 1309. otmp2 = (struct obj *)0; 1310. wake_nearto(bhitpos.x, bhitpos.y, 10*10); 1311. } 1312. } 1313. if (otyp == BOULDER && closed_door(bhitpos.x,bhitpos.y)) { 1314. if (cansee(bhitpos.x, bhitpos.y)) 1315. pline_The("boulder crashes through a door."); 1316. levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN; 1317. if (dist) unblock_point(bhitpos.x, bhitpos.y); 1318. } 1319. } 1320. tmp_at(DISP_END, 0); 1321. if (!used_up) { 1322. place_object(singleobj, x2,y2); 1323. newsym(x2,y2); 1324. return 1; 1325. } else 1326. return 2; 1327. } 1328. #endif /* OVL3 */ 1329. #ifdef OVLB 1330. 1331. void 1332. seetrap(trap) 1333. register struct trap *trap; 1334. { 1335. if(!trap->tseen) { 1336. trap->tseen = 1; 1337. newsym(trap->tx, trap->ty); 1338. } 1339. } 1340. 1341. #endif /* OVLB */ 1342. #ifdef OVL3 1343. 1344. STATIC_OVL int 1345. mkroll_launch(ttmp, x, y, otyp, ocount) 1346. struct trap *ttmp; 1347. xchar x,y; 1348. short otyp; 1349. long ocount; 1350. { 1351. struct obj *otmp; 1352. register int tmp; 1353. schar dx,dy; 1354. int distance; 1355. coord cc; 1356. coord bcc; 1357. int trycount = 0; 1358. boolean success = FALSE; 1359. int mindist = 4; 1360. 1361. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) mindist = 2; 1362. distance = rn1(5,4); /* 4..8 away */ 1363. tmp = rn2(8); /* randomly pick a direction to try first */ 1364. while (distance >= mindist) { 1365. dx = xdir[tmp]; 1366. dy = ydir[tmp]; 1367. cc.x = x; cc.y = y; 1368. /* Prevent boulder from being placed on water */ 1369. if (ttmp->ttyp == ROLLING_BOULDER_TRAP 1370. && is_pool(x+distance*dx,y+distance*dy)) 1371. success = FALSE; 1372. else success = isclearpath(&cc, distance, dx, dy); 1373. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 1374. boolean success_otherway; 1375. bcc.x = x; bcc.y = y; 1376. success_otherway = isclearpath(&bcc, distance, 1377. -(dx), -(dy)); 1378. if (!success_otherway) success = FALSE; 1379. } 1380. if (success) break; 1381. if (++tmp > 7) tmp = 0; 1382. if ((++trycount % 8) == 0) --distance; 1383. } 1384. if (!success) { 1385. /* create the trap without any ammo, launch pt at trap location */ 1386. cc.x = bcc.x = x; 1387. cc.y = bcc.y = y; 1388. } else { 1389. otmp = mksobj(otyp, TRUE, FALSE); 1390. otmp->quan = ocount; 1391. otmp->owt = weight(otmp); 1392. place_object(otmp, cc.x, cc.y); 1393. stackobj(otmp); 1394. } 1395. ttmp->launch.x = cc.x; 1396. ttmp->launch.y = cc.y; 1397. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 1398. ttmp->launch2.x = bcc.x; 1399. ttmp->launch2.y = bcc.y; 1400. } else 1401. ttmp->launch_otyp = otyp; 1402. newsym(ttmp->launch.x, ttmp->launch.y); 1403. return 1; 1404. } 1405. 1406. STATIC_OVL boolean 1407. isclearpath(cc,distance,dx,dy) 1408. coord *cc; 1409. int distance; 1410. schar dx,dy; 1411. { 1412. uchar typ; 1413. xchar x, y; 1414. 1415. x = cc->x; 1416. y = cc->y; 1417. while (distance-- > 0) { 1418. x += dx; 1419. y += dy; 1420. typ = levl[x][y].typ; 1421. if (!isok(x,y) || !ZAP_POS(typ) || closed_door(x,y)) 1422. return FALSE; 1423. } 1424. cc->x = x; 1425. cc->y = y; 1426. return TRUE; 1427. } 1428. #endif /* OVL3 */ 1429. #ifdef OVL1 1430. 1431. int 1432. mintrap(mtmp) 1433. register struct monst *mtmp; 1434. { 1435. register struct trap *trap = t_at(mtmp->mx, mtmp->my); 1436. boolean trapkilled = FALSE; 1437. struct permonst *mptr = mtmp->data; 1438. struct obj *otmp; 1439. 1440. if (!trap) { 1441. mtmp->mtrapped = 0; /* perhaps teleported? */ 1442. } else if (mtmp->mtrapped) { /* is currently in the trap */ 1443. if (!trap->tseen && 1444. cansee(mtmp->mx, mtmp->my) && canseemon(mtmp) && 1445. (trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP || 1446. trap->ttyp == HOLE || trap->ttyp == PIT || 1447. trap->ttyp == WEB)) { 1448. /* If you come upon an obviously trapped monster, then 1449. * you must be able to see the trap it's in too. 1450. */ 1451. seetrap(trap); 1452. } 1453. 1454. if (!rn2(40)) { 1455. if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 1456. (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) { 1457. if (!rn2(2)) { 1458. mtmp->mtrapped = 0; 1459. if (canseemon(mtmp)) 1460. pline("%s pulls free...", Monnam(mtmp)); 1461. fill_pit(mtmp->mx, mtmp->my); 1462. } 1463. } else { 1464. mtmp->mtrapped = 0; 1465. } 1466. } else if (metallivorous(mptr)) { 1467. if (trap->ttyp == BEAR_TRAP) { 1468. if (canseemon(mtmp)) 1469. pline("%s eats a bear trap!", Monnam(mtmp)); 1470. deltrap(trap); 1471. mtmp->meating = 5; 1472. mtmp->mtrapped = 0; 1473. } else if (trap->ttyp == SPIKED_PIT) { 1474. if (canseemon(mtmp)) 1475. pline("%s munches on some spikes!", Monnam(mtmp)); 1476. trap->ttyp = PIT; 1477. mtmp->meating = 5; 1478. } 1479. } 1480. } else { 1481. register int tt = trap->ttyp; 1482. boolean in_sight, tear_web, see_it, 1483. inescapable = ((tt == HOLE || tt == PIT) && 1484. In_sokoban(&u.uz) && !trap->madeby_u); 1485. const char *fallverb; 1486. 1487. if (!inescapable && 1488. ((mtmp->mtrapseen & (1 << (tt-1))) != 0 || 1489. (tt == HOLE && !mindless(mtmp->data)))) { 1490. /* it has been in such a trap - perhaps it escapes */ 1491. if(rn2(4)) return(0); 1492. } else { 1493. mtmp->mtrapseen |= (1 << (tt-1)); 1494. } 1495. /* Monster is aggravated by being trapped by you. 1496. Recognizing who made the trap isn't completely 1497. unreasonable; everybody has their own style. */ 1498. if (trap->madeby_u && rnl(5)) setmangry(mtmp); 1499. 1500. /* bug? `in_sight' ought to be split to distinguish between 1501. trap_in_sight and can_see_victim to handle invisible monsters */ 1502. in_sight = canseemon(mtmp); 1503. switch (tt) { 1504. case ARROW_TRAP: 1505. otmp = mksobj(ARROW, TRUE, FALSE); 1506. otmp->quan = 1L; 1507. otmp->owt = weight(otmp); 1508. otmp->opoisoned = 0; 1509. if (in_sight) seetrap(trap); 1510. if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 1511. break; 1512. case DART_TRAP: 1513. otmp = mksobj(DART, TRUE, FALSE); 1514. otmp->quan = 1L; 1515. otmp->owt = weight(otmp); 1516. if (!rn2(6)) otmp->opoisoned = 1; 1517. if (in_sight) seetrap(trap); 1518. if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 1519. break; 1520. case ROCKTRAP: 1521. otmp = mksobj(ROCK, TRUE, FALSE); 1522. otmp->quan = 1L; 1523. otmp->owt = weight(otmp); 1524. if (in_sight) seetrap(trap); 1525. if (thitm(0, mtmp, otmp, d(2, 6))) 1526. trapkilled = TRUE; 1527. break; 1528. 1529. case SQKY_BOARD: 1530. if(is_flyer(mptr)) break; 1531. /* stepped on a squeaky board */ 1532. if (in_sight) { 1533. pline("A board beneath %s squeaks loudly.", mon_nam(mtmp)); 1534. seetrap(trap); 1535. } else 1536. You_hear("a distant squeak."); 1537. /* wake up nearby monsters */ 1538. wake_nearto(mtmp->mx, mtmp->my, 40); 1539. break; 1540. 1541. case BEAR_TRAP: 1542. if(mptr->msize > MZ_SMALL && 1543. !amorphous(mptr) && !is_flyer(mptr) && 1544. !is_whirly(mptr) && !unsolid(mptr)) { 1545. mtmp->mtrapped = 1; 1546. if(in_sight) { 1547. pline("%s is caught in %s bear trap!", 1548. Monnam(mtmp), a_your[trap->madeby_u]); 1549. seetrap(trap); 1550. } else { 1551. if((mptr == &mons[PM_OWLBEAR] 1552. || mptr == &mons[PM_BUGBEAR]) 1553. && flags.soundok) 1554. You_hear("the roaring of an angry bear!"); 1555. } 1556. } 1557. break; 1558. 1559. case SLP_GAS_TRAP: 1560. if (!resists_sleep(mtmp) && !breathless(mptr) && 1561. !mtmp->msleeping && mtmp->mcanmove) { 1562. mtmp->mcanmove = 0; 1563. mtmp->mfrozen = rnd(25); 1564. if (in_sight) { 1565. pline("%s suddenly falls asleep!", 1566. Monnam(mtmp)); 1567. seetrap(trap); 1568. } 1569. } 1570. break; 1571. 1572. case RUST_TRAP: 1573. { 1574. struct obj *target; 1575. 1576. if (in_sight) 1577. seetrap(trap); 1578. switch (rn2(5)) { 1579. case 0: 1580. if (in_sight) 1581. pline("%s %s on the %s!", A_gush_of_water_hits, 1582. mon_nam(mtmp), mbodypart(mtmp, HEAD)); 1583. target = which_armor(mtmp, W_ARMH); 1584. (void) rust_dmg(target, "helmet", 1, TRUE, mtmp); 1585. break; 1586. case 1: 1587. if (in_sight) 1588. pline("%s %s's left %s!", A_gush_of_water_hits, 1589. mon_nam(mtmp), mbodypart(mtmp, ARM)); 1590. target = which_armor(mtmp, W_ARMS); 1591. if (rust_dmg(target, "shield", 1, TRUE, mtmp)) 1592. break; 1593. target = MON_WEP(mtmp); 1594. if (target && bimanual(target)) 1595. erode_obj(target, FALSE, TRUE); 1596. glovecheck: target = which_armor(mtmp, W_ARMG); 1597. (void) rust_dmg(target, "gauntlets", 1, TRUE, mtmp); 1598. break; 1599. case 2: 1600. if (in_sight) 1601. pline("%s %s's right %s!", A_gush_of_water_hits, 1602. mon_nam(mtmp), mbodypart(mtmp, ARM)); 1603. erode_obj(MON_WEP(mtmp), FALSE, TRUE); 1604. goto glovecheck; 1605. default: 1606. if (in_sight) 1607. pline("%s %s!", A_gush_of_water_hits, 1608. mon_nam(mtmp)); 1609. for (otmp=mtmp->minvent; otmp; otmp = otmp->nobj) 1610. (void) snuff_lit(otmp); 1611. target = which_armor(mtmp, W_ARMC); 1612. if (target) 1613. (void) rust_dmg(target, cloak_simple_name(target), 1614. 1, TRUE, mtmp); 1615. else { 1616. target = which_armor(mtmp, W_ARM); 1617. if (target) 1618. (void) rust_dmg(target, "armor", 1, TRUE, mtmp); 1619. #ifdef TOURIST 1620. else { 1621. target = which_armor(mtmp, W_ARMU); 1622. (void) rust_dmg(target, "shirt", 1, TRUE, mtmp); 1623. } 1624. #endif 1625. } 1626. } 1627. if (mptr == &mons[PM_IRON_GOLEM]) { 1628. if (in_sight) 1629. pline("%s falls to pieces!", Monnam(mtmp)); 1630. else if(mtmp->mtame) 1631. pline("May %s rust in peace.", 1632. mon_nam(mtmp)); 1633. mondied(mtmp); 1634. if (mtmp->mhp <= 0) 1635. trapkilled = TRUE; 1636. } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { 1637. (void)split_mon(mtmp, (struct monst *)0); 1638. } 1639. break; 1640. } 1641. case FIRE_TRAP: 1642. mfiretrap: 1643. see_it = cansee(mtmp->mx, mtmp->my); 1644. if (in_sight) 1645. pline("A %s erupts from the %s under %s!", 1646. tower_of_flame, 1647. surface(mtmp->mx,mtmp->my), mon_nam(mtmp)); 1648. else if (see_it) /* evidently `mtmp' is invisible */ 1649. You("see a %s erupt from the %s!", 1650. tower_of_flame, surface(mtmp->mx,mtmp->my)); 1651. 1652. if (resists_fire(mtmp)) { 1653. if (in_sight) { 1654. shieldeff(mtmp->mx,mtmp->my); 1655. pline("%s is uninjured.", Monnam(mtmp)); 1656. } 1657. } else { 1658. int num = d(2,4); 1659. 1660. if (thitm(0, mtmp, (struct obj *)0, num)) 1661. trapkilled = TRUE; 1662. else 1663. /* we know mhp is at least `num' below mhpmax, 1664. so no (mhp > mhpmax) check is needed here */ 1665. mtmp->mhpmax -= rn2(num + 1); 1666. } 1667. if (burnarmor(mtmp) || rn2(3)) { 1668. (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1669. (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1670. (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1671. } 1672. if (burn_floor_paper(mtmp->mx, mtmp->my, see_it, FALSE) && 1673. !see_it && distu(mtmp->mx, mtmp->my) <= 3*3) 1674. You("smell smoke."); 1675. if (is_ice(mtmp->mx,mtmp->my)) 1676. melt_ice(mtmp->mx,mtmp->my); 1677. if (see_it) seetrap(trap); 1678. break; 1679. 1680. case PIT: 1681. case SPIKED_PIT: 1682. fallverb = "falls"; 1683. if (is_flyer(mptr) || is_floater(mptr) || 1684. (mtmp->wormno && count_wsegs(mtmp) > 5) || 1685. is_clinger(mptr)) { 1686. if (!inescapable) break; /* avoids trap */ 1687. fallverb = "is dragged"; /* sokoban pit */ 1688. } 1689. if (!passes_walls(mptr)) 1690. mtmp->mtrapped = 1; 1691. if (in_sight) { 1692. pline("%s %s into %s pit!", 1693. Monnam(mtmp), fallverb, 1694. a_your[trap->madeby_u]); 1695. if (mptr == &mons[PM_PIT_VIPER] || mptr == &mons[PM_PIT_FIEND]) 1696. pline("How pitiful. Isn't that the pits?"); 1697. seetrap(trap); 1698. } 1699. mselftouch(mtmp, "Falling, ", FALSE); 1700. if (mtmp->mhp <= 0 || 1701. thitm(0, mtmp, (struct obj *)0, 1702. rnd((tt == PIT) ? 6 : 10))) 1703. trapkilled = TRUE; 1704. break; 1705. case HOLE: 1706. case TRAPDOOR: 1707. if (!Can_fall_thru(&u.uz)) { 1708. impossible("mintrap: %ss cannot exist on this level.", 1709. defsyms[trap_to_defsym(tt)].explanation); 1710. break; /* don't activate it after all */ 1711. } 1712. if (is_flyer(mptr) || is_floater(mptr) || 1713. mptr == &mons[PM_WUMPUS] || 1714. (mtmp->wormno && count_wsegs(mtmp) > 5) || 1715. mptr->msize >= MZ_HUGE) { 1716. if (inescapable) { /* sokoban hole */ 1717. if (in_sight) { 1718. pline("%s seems to be yanked down!", 1719. Monnam(mtmp)); 1720. /* suppress message in mlevel_tele_trap() */ 1721. in_sight = FALSE; 1722. seetrap(trap); 1723. } 1724. } else 1725. break; 1726. } 1727. /* Fall through */ 1728. case LEVEL_TELEP: 1729. case MAGIC_PORTAL: 1730. { 1731. int mlev_res; 1732. mlev_res = mlevel_tele_trap(mtmp, trap, 1733. inescapable, in_sight); 1734. if (mlev_res) return(mlev_res); 1735. } 1736. break; 1737. 1738. case TELEP_TRAP: 1739. mtele_trap(mtmp, trap, in_sight); 1740. break; 1741. 1742. case WEB: 1743. /* Monster in a web. */ 1744. if (webmaker(mptr)) break; 1745. if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)){ 1746. if(acidic(mptr) || 1747. mptr == &mons[PM_GELATINOUS_CUBE] || 1748. mptr == &mons[PM_FIRE_ELEMENTAL]) { 1749. if (in_sight) 1750. pline("%s %s %s spider web!", 1751. Monnam(mtmp), 1752. (mptr == &mons[PM_FIRE_ELEMENTAL]) ? 1753. "burns" : "dissolves", 1754. a_your[trap->madeby_u]); 1755. deltrap(trap); 1756. newsym(mtmp->mx, mtmp->my); 1757. break; 1758. } 1759. if (in_sight) { 1760. pline("%s flows through %s spider web.", 1761. Monnam(mtmp), 1762. a_your[trap->madeby_u]); 1763. seetrap(trap); 1764. } 1765. break; 1766. } 1767. tear_web = FALSE; 1768. switch (monsndx(mptr)) { 1769. case PM_OWLBEAR: /* Eric Backus */ 1770. case PM_BUGBEAR: 1771. if (!in_sight) { 1772. You_hear("the roaring of a confused bear!"); 1773. mtmp->mtrapped = 1; 1774. break; 1775. } 1776. /* fall though */ 1777. default: 1778. if (mptr->mlet == S_GIANT || 1779. (mptr->mlet == S_DRAGON && 1780. extra_nasty(mptr)) || /* excl. babies */ 1781. (mtmp->wormno && count_wsegs(mtmp) > 5)) { 1782. tear_web = TRUE; 1783. } else if (in_sight) { 1784. pline("%s is caught in %s spider web.", 1785. Monnam(mtmp), 1786. a_your[trap->madeby_u]); 1787. seetrap(trap); 1788. } 1789. mtmp->mtrapped = tear_web ? 0 : 1; 1790. break; 1791. /* this list is fairly arbitrary; it deliberately 1792. excludes wumpus & giant/ettin zombies/mummies */ 1793. case PM_TITANOTHERE: 1794. case PM_BALUCHITHERIUM: 1795. case PM_PURPLE_WORM: 1796. case PM_JABBERWOCK: 1797. case PM_IRON_GOLEM: 1798. case PM_BALROG: 1799. case PM_KRAKEN: 1800. case PM_MASTODON: 1801. tear_web = TRUE; 1802. break; 1803. } 1804. if (tear_web) { 1805. if (in_sight) 1806. pline("%s tears through %s spider web!", 1807. Monnam(mtmp), a_your[trap->madeby_u]); 1808. deltrap(trap); 1809. newsym(mtmp->mx, mtmp->my); 1810. } 1811. break; 1812. 1813. case STATUE_TRAP: 1814. break; 1815. 1816. case MAGIC_TRAP: 1817. /* A magic trap. Monsters usually immune. */ 1818. if (!rn2(21)) goto mfiretrap; 1819. break; 1820. case ANTI_MAGIC: 1821. break; 1822. 1823. case LANDMINE: 1824. if(rn2(3)) 1825. break; /* monsters usually don't set it off */ 1826. if(is_flyer(mptr)) { 1827. boolean already_seen = trap->tseen; 1828. if (in_sight && !already_seen) { 1829. pline("A trigger appears in a pile of soil below %s.", mon_nam(mtmp)); 1830. seetrap(trap); 1831. } 1832. if (rn2(3)) break; 1833. if (in_sight) { 1834. newsym(mtmp->mx, mtmp->my); 1835. pline_The("air currents set %s off!", 1836. already_seen ? "a land mine" : "it"); 1837. } 1838. } else if(in_sight) { 1839. newsym(mtmp->mx, mtmp->my); 1840. pline("KAABLAMM!!! %s triggers %s land mine!", 1841. Monnam(mtmp), a_your[trap->madeby_u]); 1842. } 1843. if (!in_sight) 1844. pline("Kaablamm! You hear an explosion in the distance!"); 1845. blow_up_landmine(trap); 1846. if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 1847. trapkilled = TRUE; 1848. else { 1849. /* monsters recursively fall into new pit */ 1850. if (mintrap(mtmp) == 2) trapkilled=TRUE; 1851. } 1852. /* a boulder may fill the new pit, crushing monster */ 1853. fill_pit(trap->tx, trap->ty); 1854. if (mtmp->mhp <= 0) trapkilled = TRUE; 1855. if (unconscious()) { 1856. multi = -1; 1857. nomovemsg="The explosion awakens you!"; 1858. } 1859. break; 1860. 1861. case POLY_TRAP: 1862. if (resists_magm(mtmp)) { 1863. shieldeff(mtmp->mx, mtmp->my); 1864. } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1865. (void) newcham(mtmp, (struct permonst *)0, FALSE); 1866. if (in_sight) seetrap(trap); 1867. } 1868. break; 1869. 1870. case ROLLING_BOULDER_TRAP: 1871. if (!is_flyer(mptr)) { 1872. newsym(mtmp->mx,mtmp->my); 1873. if (in_sight) 1874. pline("Click! %s triggers %s.", Monnam(mtmp), 1875. trap->tseen ? 1876. "a rolling boulder trap" : 1877. something); 1878. if (launch_obj(BOULDER, trap->launch.x, trap->launch.y, 1879. trap->launch2.x, trap->launch2.y, ROLL)) { 1880. if (in_sight) trap->tseen = TRUE; 1881. else You_hear(Hallucination ? 1882. "someone bowling." : 1883. "rumbling in the distance."); 1884. if (mtmp->mhp <= 0) trapkilled = TRUE; 1885. } else { 1886. deltrap(trap); 1887. newsym(mtmp->mx,mtmp->my); 1888. } 1889. } 1890. break; 1891. 1892. default: 1893. impossible("Some monster encountered a strange trap of type %d.", tt); 1894. } 1895. } 1896. if(trapkilled) return 2; 1897. return mtmp->mtrapped; 1898. } 1899. 1900. #endif /* OVL1 */ 1901. #ifdef OVLB 1902. 1903. /* Combine cockatrice checks into single functions to avoid repeating code. */ 1904. void 1905. instapetrify(str) 1906. const char *str; 1907. { 1908. if (Stone_resistance) return; 1909. if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 1910. return; 1911. You("turn to stone..."); 1912. killer_format = KILLED_BY; 1913. killer = str; 1914. done(STONING); 1915. } 1916. 1917. void 1918. minstapetrify(mon,byplayer) 1919. struct monst *mon; 1920. boolean byplayer; 1921. { 1922. if (resists_ston(mon)) return; 1923. if (cansee(mon->mx, mon->my)) 1924. pline("%s turns to stone.", Monnam(mon)); 1925. if (poly_when_stoned(mon->data)) { 1926. mon_to_stone(mon); 1927. return; 1928. } 1929. if (byplayer) { 1930. stoned = TRUE; 1931. xkilled(mon,0); 1932. } else monstone(mon); 1933. } 1934. 1935. void 1936. selftouch(arg) 1937. const char *arg; 1938. { 1939. char kbuf[BUFSZ]; 1940. 1941. if(uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm]) 1942. && !Stone_resistance) { 1943. pline("%s touch the %s corpse.", arg, 1944. mons[uwep->corpsenm].mname); 1945. Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname)); 1946. instapetrify(kbuf); 1947. } 1948. /* Or your secondary weapon, if wielded */ 1949. if(u.twoweap && uswapwep && uswapwep->otyp == CORPSE && 1950. touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance){ 1951. pline("%s touch the %s corpse.", arg, 1952. mons[uswapwep->corpsenm].mname); 1953. Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); 1954. instapetrify(kbuf); 1955. } 1956. } 1957. 1958. void 1959. mselftouch(mon,arg,byplayer) 1960. struct monst *mon; 1961. const char *arg; 1962. boolean byplayer; 1963. { 1964. struct obj *mwep = MON_WEP(mon); 1965. 1966. if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])) { 1967. if (cansee(mon->mx, mon->my)) { 1968. pline("%s%s touches the %s corpse.", 1969. arg ? arg : "", arg ? mon_nam(mon) : Monnam(mon), 1970. mons[mwep->corpsenm].mname); 1971. } 1972. minstapetrify(mon, byplayer); 1973. } 1974. } 1975. 1976. void 1977. float_up() 1978. { 1979. if(u.utrap) { 1980. if(u.utraptype == TT_PIT) { 1981. u.utrap = 0; 1982. You("float up, out of the pit!"); 1983. vision_full_recalc = 1; /* vision limits change */ 1984. fill_pit(u.ux, u.uy); 1985. } else if (u.utraptype == TT_INFLOOR) { 1986. Your("body pulls upward, but your %s are still stuck.", 1987. makeplural(body_part(LEG))); 1988. } else { 1989. You("float up, only your %s is still stuck.", 1990. body_part(LEG)); 1991. } 1992. } 1993. else if(Is_waterlevel(&u.uz)) 1994. pline("It feels as though you've lost some weight."); 1995. else if(u.uinwater) 1996. spoteffects(TRUE); 1997. else if(u.uswallow) 1998. You(is_animal(u.ustuck->data) ? 1999. "float away from the %s." : 2000. "spiral up into %s.", 2001. is_animal(u.ustuck->data) ? 2002. surface(u.ux, u.uy) : 2003. mon_nam(u.ustuck)); 2004. else if (Hallucination) 2005. pline("Up, up, and awaaaay! You're walking on air!"); 2006. else if(Is_airlevel(&u.uz)) 2007. You("gain control over your movements."); 2008. else 2009. You("start to float in the air!"); 2010. #ifdef STEED 2011. if (u.usteed && !is_floater(u.usteed->data) && 2012. !is_flyer(u.usteed->data)) { 2013. if (Lev_at_will) 2014. pline("%s magically floats up!", Monnam(u.usteed)); 2015. else { 2016. You("cannot stay on %s.", mon_nam(u.usteed)); 2017. dismount_steed(DISMOUNT_GENERIC); 2018. } 2019. } 2020. #endif 2021. return; 2022. } 2023. 2024. void 2025. fill_pit(x, y) 2026. int x, y; 2027. { 2028. struct obj *otmp; 2029. struct trap *t; 2030. 2031. if ((t = t_at(x, y)) && 2032. ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) && 2033. (otmp = sobj_at(BOULDER, x, y))) { 2034. obj_extract_self(otmp); 2035. (void) flooreffects(otmp, x, y, "settle"); 2036. } 2037. } 2038. 2039. int 2040. float_down(hmask, emask) 2041. long hmask, emask; /* might cancel timeout */ 2042. { 2043. register struct trap *trap = (struct trap *)0; 2044. d_level current_dungeon_level; 2045. boolean no_msg = FALSE; 2046. 2047. HLevitation &= ~hmask; 2048. ELevitation &= ~emask; 2049. if(Levitation) return(0); /* maybe another ring/potion/boots */ 2050. 2051. if (Punished && !carried(uball) && 2052. (is_pool(uball->ox, uball->oy) || 2053. ((trap = t_at(uball->ox, uball->oy)) && 2054. ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) || 2055. (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) { 2056. u.ux0 = u.ux; 2057. u.uy0 = u.uy; 2058. u.ux = uball->ox; 2059. u.uy = uball->oy; 2060. movobj(uchain, uball->ox, uball->oy); 2061. newsym(u.ux0, u.uy0); 2062. vision_full_recalc = 1; /* in case the hero moved. */ 2063. } 2064. /* check for falling into pool - added by GAN 10/20/86 */ 2065. if(!Flying) { 2066. /* kludge alert: 2067. * drown() and lava_effects() print various messages almost 2068. * every time they're called which conflict with the "fall 2069. * into" message below. Thus, we want to avoid printing 2070. * confusing, duplicate or out-of-order messages. 2071. * Use knowledge of the two routines as a hack -- this 2072. * should really be handled differently -dlc 2073. */ 2074. if(is_pool(u.ux,u.uy) && !Wwalking && !Swimming && !u.uinwater) 2075. no_msg = drown(); 2076. 2077. if(is_lava(u.ux,u.uy)) { 2078. (void) lava_effects(); 2079. no_msg = TRUE; 2080. } 2081. } 2082. if (!trap) { 2083. trap = t_at(u.ux,u.uy); 2084. if(Is_airlevel(&u.uz)) 2085. You("begin to tumble in place."); 2086. else if (Is_waterlevel(&u.uz) && !no_msg) 2087. You_feel("heavier."); 2088. /* u.uinwater msgs already in spoteffects()/drown() */ 2089. else if (!u.uinwater && !no_msg) { 2090. #ifdef STEED 2091. if (!(emask & W_SADDLE)) 2092. #endif 2093. { 2094. boolean sokoban_trap = (In_sokoban(&u.uz) && trap); 2095. if (Hallucination) 2096. pline("Bummer! You've %s.", 2097. is_pool(u.ux,u.uy) ? 2098. "splashed down" : sokoban_trap ? "crashed" : 2099. "hit the ground"); 2100. else { 2101. if (!sokoban_trap) 2102. You("float gently to the %s.", 2103. surface(u.ux, u.uy)); 2104. else { 2105. /* Justification elsewhere for Sokoban traps 2106. * is based on air currents. This is 2107. * consistent with that. 2108. * The unexpected additional force of the 2109. * air currents once leviation 2110. * ceases knocks you off your feet. 2111. */ 2112. You("fall over."); 2113. losehp(rnd(2), "dangerous winds", KILLED_BY); 2114. #ifdef STEED 2115. if (u.usteed) dismount_steed(DISMOUNT_FELL); 2116. #endif 2117. selftouch("As you fall, you"); 2118. } 2119. } 2120. } 2121. } 2122. } 2123. 2124. /* can't rely on u.uz0 for detecting trap door-induced level change; 2125. it gets changed to reflect the new level before we can check it */ 2126. assign_level(&current_dungeon_level, &u.uz); 2127. 2128. if(trap) 2129. switch(trap->ttyp) { 2130. case STATUE_TRAP: 2131. break; 2132. case HOLE: 2133. case TRAPDOOR: 2134. if(!Can_fall_thru(&u.uz) || u.ustuck) 2135. break; 2136. /* fall into next case */ 2137. default: 2138. if (!u.utrap) /* not already in the trap */ 2139. dotrap(trap, 0); 2140. } 2141. 2142. if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow && 2143. /* falling through trap door calls goto_level, 2144. and goto_level does its own pickup() call */ 2145. on_level(&u.uz, &current_dungeon_level)) 2146. (void) pickup(1); 2147. return 1; 2148. } 2149. 2150. STATIC_OVL void 2151. dofiretrap(box) 2152. struct obj *box; /* null for floor trap */ 2153. { 2154. boolean see_it = !Blind; 2155. int num; 2156. 2157. /* Bug: for box case, the equivalent of burn_floor_paper() ought 2158. * to be done upon its contents. 2159. */ 2160. 2161. if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) { 2162. pline("A cascade of steamy bubbles erupts from %s!", 2163. the(box ? xname(box) : surface(u.ux,u.uy))); 2164. if (Fire_resistance) You("are uninjured."); 2165. else losehp(rnd(3), "boiling water", KILLED_BY); 2166. return; 2167. } 2168. pline("A %s %s from %s!", tower_of_flame, 2169. box ? "bursts" : "erupts", 2170. the(box ? xname(box) : surface(u.ux,u.uy))); 2171. if (Fire_resistance) { 2172. shieldeff(u.ux, u.uy); 2173. num = rn2(2); 2174. } else { 2175. num = d(2,4); 2176. if (u.uhpmax > u.ulevel) 2177. u.uhpmax -= rn2(min(u.uhpmax,num + 1)), flags.botl = 1; 2178. } 2179. if (!num) 2180. You("are uninjured."); 2181. else 2182. losehp(num, tower_of_flame, KILLED_BY_AN); 2183. burn_away_slime(); 2184. 2185. if (burnarmor(&youmonst) || rn2(3)) { 2186. destroy_item(SCROLL_CLASS, AD_FIRE); 2187. destroy_item(SPBOOK_CLASS, AD_FIRE); 2188. destroy_item(POTION_CLASS, AD_FIRE); 2189. } 2190. if (!box && burn_floor_paper(u.ux, u.uy, see_it, TRUE) && !see_it) 2191. You("smell paper burning."); 2192. if (is_ice(u.ux, u.uy)) 2193. melt_ice(u.ux, u.uy); 2194. } 2195. 2196. STATIC_OVL void 2197. domagictrap() 2198. { 2199. register int fate = rnd(20); 2200. 2201. /* What happened to the poor sucker? */ 2202. 2203. if (fate < 10) { 2204. /* Most of the time, it creates some monsters. */ 2205. register int cnt = rnd(4); 2206. 2207. if (!resists_blnd(&youmonst)) { 2208. You("are momentarily blinded by a flash of light!"); 2209. make_blinded((long)rn1(5,10),FALSE); 2210. if (!Blind) Your(vision_clears); 2211. } else if (!Blind) { 2212. You("see a flash of light!"); 2213. } else 2214. You_hear("a deafening roar!"); 2215. while(cnt--) 2216. (void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS); 2217. } 2218. else 2219. switch (fate) { 2220. 2221. case 10: 2222. case 11: 2223. /* sometimes nothing happens */ 2224. break; 2225. case 12: /* a flash of fire */ 2226. dofiretrap((struct obj *)0); 2227. break; 2228. 2229. /* odd feelings */ 2230. case 13: pline("A shiver runs up and down your %s!", 2231. body_part(SPINE)); 2232. break; 2233. case 14: You_hear(Hallucination ? 2234. "the moon howling at you." : 2235. "distant howling."); 2236. break; 2237. case 15: if (on_level(&u.uz, &qstart_level)) 2238. You_feel("%slike the prodigal son.", 2239. (flags.female || (Upolyd && is_neuter(youmonst.data))) ? 2240. "oddly " : ""); 2241. else 2242. You("suddenly yearn for %s.", 2243. Hallucination ? "Cleveland" : 2244. (In_quest(&u.uz) || at_dgn_entrance("The Quest")) ? 2245. "your nearby homeland" : 2246. "your distant homeland"); 2247. break; 2248. case 16: Your("pack shakes violently!"); 2249. break; 2250. case 17: You(Hallucination ? 2251. "smell hamburgers." : 2252. "smell charred flesh."); 2253. break; 2254. case 18: You_feel("tired."); 2255. break; 2256. 2257. /* very occasionally something nice happens. */ 2258. 2259. case 19: 2260. /* tame nearby monsters */ 2261. { register int i,j; 2262. register struct monst *mtmp; 2263. 2264. (void) adjattrib(A_CHA,1,FALSE); 2265. for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) { 2266. if(!isok(u.ux+i, u.uy+j)) continue; 2267. mtmp = m_at(u.ux+i, u.uy+j); 2268. if(mtmp) 2269. (void) tamedog(mtmp, (struct obj *)0); 2270. } 2271. break; 2272. } 2273. 2274. case 20: 2275. /* uncurse stuff */ 2276. { struct obj pseudo; 2277. long save_conf = HConfusion; 2278. 2279. pseudo = zeroobj; /* neither cursed nor blessed */ 2280. pseudo.otyp = SCR_REMOVE_CURSE; 2281. HConfusion = 0L; 2282. (void) seffects(&pseudo); 2283. HConfusion = save_conf; 2284. break; 2285. } 2286. default: break; 2287. } 2288. } 2289. 2290. /* 2291. * Scrolls, spellbooks, potions, and flammable items 2292. * may get affected by the fire. 2293. * 2294. * Return number of objects destroyed. --ALI 2295. */ 2296. int 2297. fire_damage(chain, force, here, x, y) 2298. struct obj *chain; 2299. boolean force, here; 2300. xchar x, y; 2301. { 2302. int chance; 2303. struct obj *obj, *otmp, *nobj, *ncobj; 2304. int retval = 0; 2305. int in_sight = !Blind && couldsee(x, y); /* Don't care if it's lit */ 2306. int dindx; 2307. 2308. for (obj = chain; obj; obj = nobj) { 2309. nobj = here ? obj->nexthere : obj->nobj; 2310. 2311. /* object might light in a controlled manner */ 2312. if (catch_lit(obj)) 2313. continue; 2314. 2315. if (Is_container(obj)) { 2316. switch (obj->otyp) { 2317. case ICE_BOX: 2318. continue; /* Immune */ 2319. /*NOTREACHED*/ 2320. break; 2321. case CHEST: 2322. chance = 40; 2323. break; 2324. case LARGE_BOX: 2325. chance = 30; 2326. break; 2327. default: 2328. chance = 20; 2329. break; 2330. } 2331. if (!force && (Luck + 5) > rn2(chance)) 2332. continue; 2333. /* Container is burnt up - dump contents out */ 2334. if (in_sight) pline("%s catches fire and burns.", Yname2(obj)); 2335. if (Has_contents(obj)) { 2336. if (in_sight) pline("Its contents fall out."); 2337. for (otmp = obj->cobj; otmp; otmp = ncobj) { 2338. ncobj = otmp->nobj; 2339. obj_extract_self(otmp); 2340. if (!flooreffects(otmp, x, y, "")) 2341. place_object(otmp, x, y); 2342. } 2343. } 2344. delobj(obj); 2345. retval++; 2346. } else if (!force && (Luck + 5) > rn2(20)) { 2347. /* chance per item of sustaining damage: 2348. * max luck (full moon): 5% 2349. * max luck (elsewhen): 10% 2350. * avg luck (Luck==0): 75% 2351. * awful luck (Luck<-4): 100% 2352. */ 2353. continue; 2354. } else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) { 2355. if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL) 2356. continue; 2357. if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 2358. if (in_sight) pline("Smoke rises from %s.", the(xname(obj))); 2359. continue; 2360. } 2361. dindx = (obj->oclass == SCROLL_CLASS) ? 2 : 3; 2362. if (in_sight) 2363. pline("%s %s.", Yname2(obj), (obj->quan > 1) ? 2364. destroy_strings[dindx*3 + 1] : destroy_strings[dindx*3]); 2365. delobj(obj); 2366. retval++; 2367. } else if (obj->oclass == POTION_CLASS) { 2368. dindx = 1; 2369. if (in_sight) 2370. pline("%s %s.", Yname2(obj), (obj->quan > 1) ? 2371. destroy_strings[dindx*3 + 1] : destroy_strings[dindx*3]); 2372. delobj(obj); 2373. retval++; 2374. } else if (is_flammable(obj) && obj->oeroded < MAX_ERODE && 2375. !(obj->oerodeproof || (obj->blessed && !rnl(4)))) { 2376. if (in_sight) { 2377. pline("%s %s%s.", Yname2(obj), otense(obj, "burn"), 2378. obj->oeroded+1 == MAX_ERODE ? " completely" : 2379. obj->oeroded ? " further" : ""); 2380. } 2381. obj->oeroded++; 2382. } 2383. } 2384. 2385. if (retval && !in_sight) 2386. You("smell smoke."); 2387. return retval; 2388. } 2389. 2390. void 2391. water_damage(obj, force, here) 2392. register struct obj *obj; 2393. register boolean force, here; 2394. { 2395. /* Scrolls, spellbooks, potions, weapons and 2396. pieces of armor may get affected by the water */ 2397. for (; obj; obj = (here ? obj->nexthere : obj->nobj)) { 2398. 2399. (void) snuff_lit(obj); 2400. 2401. if(obj->otyp == CAN_OF_GREASE && obj->spe > 0) { 2402. continue; 2403. } else if(obj->greased) { 2404. if (force || !rn2(2)) obj->greased = 0; 2405. } else if(Is_container(obj) && !Is_box(obj) && 2406. (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) { 2407. water_damage(obj->cobj, force, FALSE); 2408. } else if (!force && (Luck + 5) > rn2(20)) { 2409. /* chance per item of sustaining damage: 2410. * max luck (full moon): 5% 2411. * max luck (elsewhen): 10% 2412. * avg luck (Luck==0): 75% 2413. * awful luck (Luck<-4): 100% 2414. */ 2415. continue; 2416. } else if (obj->oclass == SCROLL_CLASS) { 2417. #ifdef MAIL 2418. if (obj->otyp != SCR_MAIL) 2419. #endif 2420. { 2421. obj->otyp = SCR_BLANK_PAPER; 2422. obj->spe = 0; 2423. } 2424. } else if (obj->oclass == SPBOOK_CLASS) { 2425. if (obj->otyp == SPE_BOOK_OF_THE_DEAD) 2426. pline("Steam rises from %s.", the(xname(obj))); 2427. else obj->otyp = SPE_BLANK_PAPER; 2428. } else if (obj->oclass == POTION_CLASS) { 2429. if (obj->odiluted) { 2430. obj->otyp = POT_WATER; 2431. obj->blessed = obj->cursed = 0; 2432. obj->odiluted = 0; 2433. } else if (obj->otyp != POT_WATER) 2434. obj->odiluted++; 2435. } else if (is_rustprone(obj) && obj->oeroded < MAX_ERODE && 2436. !(obj->oerodeproof || (obj->blessed && !rnl(4)))) { 2437. /* all metal stuff and armor except (body armor 2438. protected by oilskin cloak) */ 2439. if(obj->oclass != ARMOR_CLASS || obj != uarm || 2440. !uarmc || uarmc->otyp != OILSKIN_CLOAK || 2441. (uarmc->cursed && !rn2(3))) 2442. obj->oeroded++; 2443. } 2444. } 2445. } 2446. 2447. /* 2448. * This function is potentially expensive - rolling 2449. * inventory list multiple times. Luckily it's seldom needed. 2450. * Returns TRUE if disrobing made player unencumbered enough to 2451. * crawl out of the current predicament. 2452. */ 2453. STATIC_OVL boolean 2454. emergency_disrobe(lostsome) 2455. boolean *lostsome; 2456. { 2457. int invc = inv_cnt(); 2458. 2459. 2460. while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) { 2461. register struct obj *obj, *otmp = (struct obj *)0; 2462. register int i; 2463. 2464. /* Pick a random object */ 2465. if (invc > 0) { 2466. i = rn2(invc); 2467. for (obj = invent; obj; obj = obj->nobj) { 2468. /* 2469. * Undroppables are: body armor, boots, gloves, 2470. * amulets, and rings because of the time and effort 2471. * in removing them + loadstone and other cursed stuff 2472. * for obvious reasons. 2473. */ 2474. if (!((obj->otyp == LOADSTONE && obj->cursed) || 2475. obj == uamul || obj == uleft || obj == uright || 2476. obj == ublindf || obj == uarm || obj == uarmc || 2477. obj == uarmg || obj == uarmf || 2478. #ifdef TOURIST 2479. obj == uarmu || 2480. #endif 2481. (obj->cursed && (obj == uarmh || obj == uarms)) || 2482. welded(obj))) 2483. otmp = obj; 2484. /* reached the mark and found some stuff to drop? */ 2485. if (--i < 0 && otmp) break; 2486. 2487. /* else continue */ 2488. } 2489. } 2490. #ifndef GOLDOBJ 2491. if (!otmp) { 2492. /* Nothing available left to drop; try gold */ 2493. if (u.ugold) { 2494. pline("In desperation, you drop your purse."); 2495. /* Hack: gold is not in the inventory, so make a gold object 2496. * and put it at the head of the inventory list. 2497. */ 2498. obj = mkgoldobj(u.ugold); /* removes from u.ugold */ 2499. u.ugold = obj->quan; /* put the gold back */ 2500. assigninvlet(obj); /* might end up as NOINVSYM */ 2501. obj->nobj = invent; 2502. invent = obj; 2503. *lostsome = TRUE; 2504. dropx(obj); 2505. continue; /* Try again */ 2506. } 2507. /* We can't even drop gold! */ 2508. return (FALSE); 2509. } 2510. #else 2511. if (!otmp) return (FALSE); /* nothing to drop! */ 2512. #endif 2513. if (otmp->owornmask && otmp != uball) remove_worn_item(otmp); 2514. *lostsome = TRUE; 2515. dropx(otmp); 2516. invc--; 2517. } 2518. return(TRUE); 2519. } 2520. 2521. /* 2522. * return(TRUE) == player relocated 2523. */ 2524. boolean 2525. drown() 2526. { 2527. boolean inpool_ok = FALSE, crawl_ok; 2528. int i, x, y; 2529. 2530. /* happily wading in the same contiguous pool */ 2531. if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) && 2532. (Swimming || Amphibious)) { 2533. /* water effects on objects every now and then */ 2534. if (!rn2(5)) inpool_ok = TRUE; 2535. else return(FALSE); 2536. } 2537. 2538. if (!u.uinwater) { 2539. You("%s into the water%c", 2540. Is_waterlevel(&u.uz) ? "plunge" : "fall", 2541. Amphibious || Swimming ? '.' : '!'); 2542. if (!Swimming && !Is_waterlevel(&u.uz)) 2543. You("sink like %s.", 2544. Hallucination ? "the Titanic" : "a rock"); 2545. } 2546. 2547. water_damage(invent, FALSE, FALSE); 2548. 2549. if (u.umonnum == PM_GREMLIN && rn2(3)) 2550. (void)split_mon(&youmonst, (struct monst *)0); 2551. else if (u.umonnum == PM_IRON_GOLEM) { 2552. You("rust!"); 2553. i = d(2,6); 2554. if (u.mhmax > i) u.mhmax -= i; 2555. losehp(i, "rusting away", KILLED_BY); 2556. } 2557. if (inpool_ok) return(FALSE); 2558. 2559. if ((i = number_leashed()) > 0) { 2560. pline_The("leash%s slip%s loose.", 2561. (i > 1) ? "es" : "", 2562. (i > 1) ? "" : "s"); 2563. unleash_all(); 2564. } 2565. 2566. if (Amphibious || Swimming) { 2567. if (Amphibious) { 2568. if (flags.verbose) 2569. pline("But you aren't drowning."); 2570. if (!Is_waterlevel(&u.uz)) { 2571. if (Hallucination) 2572. Your("keel hits the bottom."); 2573. else 2574. You("touch bottom."); 2575. } 2576. } 2577. if (Punished) { 2578. unplacebc(); 2579. placebc(); 2580. } 2581. vision_recalc(2); /* unsee old position */ 2582. u.uinwater = 1; 2583. under_water(1); 2584. vision_full_recalc = 1; 2585. return(FALSE); 2586. } 2587. if((Teleportation || can_teleport(youmonst.data)) && 2588. (Teleport_control || rn2(3) < Luck+2)) { 2589. You("attempt a teleport spell."); /* utcsri!carroll */ 2590. (void) dotele(); 2591. if(!is_pool(u.ux,u.uy)) 2592. return(TRUE); 2593. } 2594. #ifdef STEED 2595. if (u.usteed) { 2596. dismount_steed(DISMOUNT_GENERIC); 2597. if(!is_pool(u.ux,u.uy)) 2598. return(TRUE); 2599. } 2600. #endif 2601. crawl_ok = FALSE; 2602. /* look around for a place to crawl to */ 2603. for (i = 0; i < 100; i++) { 2604. x = rn1(3,u.ux - 1); 2605. y = rn1(3,u.uy - 1); 2606. if (goodpos(x, y, &youmonst)) { 2607. crawl_ok = TRUE; 2608. goto crawl; 2609. } 2610. } 2611. /* one more scan */ 2612. for (x = u.ux - 1; x <= u.ux + 1; x++) 2613. for (y = u.uy - 1; y <= u.uy + 1; y++) 2614. if (goodpos(x, y, &youmonst)) { 2615. crawl_ok = TRUE; 2616. goto crawl; 2617. } 2618. crawl:; 2619. if (crawl_ok) { 2620. boolean lost = FALSE; 2621. /* time to do some strip-tease... */ 2622. boolean succ = Is_waterlevel(&u.uz) ? TRUE : 2623. emergency_disrobe(&lost); 2624. 2625. You("try to crawl out of the water."); 2626. if (lost) 2627. You("dump some of your gear to lose weight..."); 2628. if (succ) { 2629. pline("Pheew! That was close."); 2630. teleds(x,y); 2631. return(TRUE); 2632. } 2633. /* still too much weight */ 2634. pline("But in vain."); 2635. } 2636. u.uinwater = 1; 2637. You("drown."); 2638. killer_format = KILLED_BY_AN; 2639. killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ? 2640. "pool of water" : "moat"; 2641. done(DROWNING); 2642. /* oops, we're still alive. better get out of the water. */ 2643. while (!safe_teleds()) { 2644. pline("You're still drowning."); 2645. done(DROWNING); 2646. } 2647. u.uinwater = 0; 2648. You("find yourself back %s.", Is_waterlevel(&u.uz) ? 2649. "in an air bubble" : "on land"); 2650. return(TRUE); 2651. } 2652. 2653. void 2654. drain_en(n) 2655. register int n; 2656. { 2657. if (!u.uenmax) return; 2658. You_feel("your magical energy drain away!"); 2659. u.uen -= n; 2660. if(u.uen < 0) { 2661. u.uenmax += u.uen; 2662. if(u.uenmax < 0) u.uenmax = 0; 2663. u.uen = 0; 2664. } 2665. flags.botl = 1; 2666. } 2667. 2668. int 2669. dountrap() /* disarm a trap */ 2670. { 2671. if (near_capacity() >= HVY_ENCUMBER) { 2672. pline("You're too strained to do that."); 2673. return 0; 2674. } 2675. if ((nohands(youmonst.data) && !webmaker(youmonst.data)) || !youmonst.data->mmove) { 2676. pline("And just how do you expect to do that?"); 2677. return 0; 2678. } else if (u.ustuck && sticks(youmonst.data)) { 2679. pline("You'll have to let go of %s first.", mon_nam(u.ustuck)); 2680. return 0; 2681. } 2682. if (u.ustuck || (welded(uwep) && bimanual(uwep))) { 2683. Your("%s seem to be too busy for that.", 2684. makeplural(body_part(HAND))); 2685. return 0; 2686. } 2687. return untrap(FALSE); 2688. } 2689. #endif /* OVLB */ 2690. #ifdef OVL2 2691. 2692. /* Probability of disabling a trap. Helge Hafting */ 2693. STATIC_OVL int 2694. untrap_prob(ttmp) 2695. struct trap *ttmp; 2696. { 2697. int chance = 3; 2698. 2699. /* Only spiders know how to deal with webs reliably */ 2700. if (ttmp->ttyp == WEB && !webmaker(youmonst.data)) 2701. chance = 30; 2702. if (Confusion || Hallucination) chance++; 2703. if (Blind) chance++; 2704. if (Stunned) chance += 2; 2705. if (Fumbling) chance *= 2; 2706. /* Your own traps are better known than others. */ 2707. if (ttmp && ttmp->madeby_u) chance--; 2708. if (Role_if(PM_ROGUE)) { 2709. if (rn2(2 * MAXULEV) < u.ulevel) chance--; 2710. if (u.uhave.questart && chance > 1) chance--; 2711. } else if (Role_if(PM_RANGER) && chance > 1) chance--; 2712. return rn2(chance); 2713. } 2714. 2715. /* Replace trap with object(s). Helge Hafting */ 2716. STATIC_OVL void 2717. cnv_trap_obj(otyp, cnt, ttmp) 2718. int otyp; 2719. int cnt; 2720. struct trap *ttmp; 2721. { 2722. struct obj *otmp = mksobj(otyp, TRUE, FALSE); 2723. otmp->quan=cnt; 2724. otmp->owt = weight(otmp); 2725. /* Only dart traps are capable of being poisonous */ 2726. if (otyp != DART) 2727. otmp->opoisoned = 0; 2728. place_object(otmp, ttmp->tx, ttmp->ty); 2729. /* Sell your own traps only... */ 2730. if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); 2731. stackobj(otmp); 2732. newsym(ttmp->tx, ttmp->ty); 2733. deltrap(ttmp); 2734. } 2735. 2736. /* while attempting to disarm an adjacent trap, we've fallen into it */ 2737. STATIC_OVL void 2738. move_into_trap(ttmp) 2739. struct trap *ttmp; 2740. { 2741. int bc; 2742. xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy; 2743. boolean unused; 2744. 2745. /* we know there's no monster in the way, and we're not trapped */ 2746. if (!Punished || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused)) { 2747. u.ux0 = u.ux, u.uy0 = u.uy; 2748. u.ux = x, u.uy = y; 2749. u.umoved = TRUE; 2750. newsym(u.ux0, u.uy0); 2751. vision_recalc(1); 2752. check_leash(u.ux0, u.uy0); 2753. if (Punished) move_bc(0, bc, bx, by, cx, cy); 2754. spoteffects(TRUE); /* dotrap() */ 2755. exercise(A_WIS, FALSE); 2756. } 2757. } 2758. 2759. /* 0: doesn't even try 2760. * 1: tries and fails 2761. * 2: succeeds 2762. */ 2763. STATIC_OVL int 2764. try_disarm(ttmp, force_failure) 2765. struct trap *ttmp; 2766. boolean force_failure; 2767. { 2768. struct monst *mtmp = m_at(ttmp->tx,ttmp->ty); 2769. int ttype = ttmp->ttyp; 2770. boolean under_u = (!u.dx && !u.dy); 2771. boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB); 2772. 2773. /* Test for monster first, monsters are displayed instead of trap. */ 2774. if (mtmp && (!mtmp->mtrapped || !holdingtrap)) { 2775. pline("%s is in the way.", Monnam(mtmp)); 2776. return 0; 2777. } 2778. /* We might be forced to move onto the trap's location. */ 2779. if (sobj_at(BOULDER, ttmp->tx, ttmp->ty) 2780. && !Passes_walls && !under_u) { 2781. There("is a boulder in your way."); 2782. return 0; 2783. } 2784. /* duplicate tight-space checks from test_move */ 2785. if (u.dx && u.dy && 2786. bad_rock(youmonst.data,u.ux,ttmp->ty) && 2787. bad_rock(youmonst.data,ttmp->tx,u.uy)) { 2788. if ((invent && (inv_weight() + weight_cap() > 600)) || 2789. bigmonst(youmonst.data)) { 2790. /* don't allow untrap if they can't get thru to it */ 2791. You("are unable to reach the %s!", 2792. defsyms[trap_to_defsym(ttype)].explanation); 2793. return 0; 2794. } 2795. } 2796. /* untrappable traps are located on the ground. */ 2797. if (!can_reach_floor()) { 2798. #ifdef STEED 2799. if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) 2800. You("aren't skilled enough to reach from %s.", 2801. mon_nam(u.usteed)); 2802. else 2803. #endif 2804. You("are unable to reach the %s!", 2805. defsyms[trap_to_defsym(ttype)].explanation); 2806. return 0; 2807. } 2808. 2809. /* Will our hero succeed? */ 2810. if (force_failure || untrap_prob(ttmp)) { 2811. if (rnl(5)) { 2812. pline("Whoops..."); 2813. if (mtmp) { /* must be a trap that holds monsters */ 2814. if (ttype == BEAR_TRAP) { 2815. if (mtmp->mtame) abuse_dog(mtmp); 2816. if ((mtmp->mhp -= rnd(4)) <= 0) killed(mtmp); 2817. } else if (ttype == WEB) { 2818. if (!webmaker(youmonst.data)) { 2819. struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB); 2820. if (ttmp2) { 2821. pline_The("webbing sticks to you. You're caught too!"); 2822. dotrap(ttmp2, NOWEBMSG); 2823. } 2824. } else 2825. pline("%s remains entangled.", Monnam(mtmp)); 2826. } 2827. } else if (under_u) { 2828. dotrap(ttmp, 0); 2829. } else { 2830. move_into_trap(ttmp); 2831. } 2832. } else { 2833. pline("%s %s is difficult to %s.", 2834. ttmp->madeby_u ? "Your" : under_u ? "This" : "That", 2835. defsyms[trap_to_defsym(ttype)].explanation, 2836. (ttype == WEB) ? "remove" : "disarm"); 2837. } 2838. return 1; 2839. } 2840. return 2; 2841. } 2842. 2843. STATIC_OVL void 2844. reward_untrap(ttmp, mtmp) 2845. struct trap *ttmp; 2846. struct monst *mtmp; 2847. { 2848. if (!ttmp->madeby_u) { 2849. if (rnl(10) < 8 && !mtmp->mpeaceful && 2850. !mindless(mtmp->data) && 2851. mtmp->data->mlet != S_HUMAN) { 2852. mtmp->mpeaceful = 1; 2853. set_malign(mtmp); /* reset alignment */ 2854. pline("%s is grateful.", Monnam(mtmp)); 2855. } 2856. /* Helping someone out of a trap is a nice thing to do, 2857. * A lawful may be rewarded, but not too often. */ 2858. if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) { 2859. adjalign(1); 2860. You_feel("that you did the right thing."); 2861. } 2862. } 2863. } 2864. 2865. STATIC_OVL int 2866. disarm_holdingtrap(ttmp) /* Helge Hafting */ 2867. struct trap *ttmp; 2868. { 2869. struct monst *mtmp; 2870. int fails = try_disarm(ttmp, FALSE); 2871. 2872. if (fails < 2) return fails; 2873. 2874. /* ok, disarm it. */ 2875. 2876. /* untrap the monster, if any. 2877. There's no need for a cockatrice test, only the trap is touched */ 2878. if ((mtmp = m_at(ttmp->tx,ttmp->ty)) != 0) { 2879. mtmp->mtrapped = 0; 2880. You("remove %s %s from %s.", the_your[ttmp->madeby_u], 2881. (ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing", 2882. mon_nam(mtmp)); 2883. reward_untrap(ttmp, mtmp); 2884. } else { 2885. if (ttmp->ttyp == BEAR_TRAP) { 2886. You("disarm %s bear trap.", the_your[ttmp->madeby_u]); 2887. cnv_trap_obj(BEARTRAP, 1, ttmp); 2888. } else /* if (ttmp->ttyp == WEB) */ { 2889. You("succeed in removing %s web.", the_your[ttmp->madeby_u]); 2890. deltrap(ttmp); 2891. } 2892. } 2893. newsym(u.ux + u.dx, u.uy + u.dy); 2894. return 1; 2895. } 2896. 2897. STATIC_OVL int 2898. disarm_landmine(ttmp) /* Helge Hafting */ 2899. struct trap *ttmp; 2900. { 2901. int fails = try_disarm(ttmp, FALSE); 2902. 2903. if (fails < 2) return fails; 2904. You("disarm %s land mine.", the_your[ttmp->madeby_u]); 2905. cnv_trap_obj(LAND_MINE, 1, ttmp); 2906. return 1; 2907. } 2908. 2909. /* getobj will filter down to cans of grease and known potions of oil */ 2910. static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS, 0 }; 2911. 2912. /* it may not make much sense to use grease on floor boards, but so what? */ 2913. STATIC_OVL int 2914. disarm_squeaky_board(ttmp) 2915. struct trap *ttmp; 2916. { 2917. struct obj *obj; 2918. boolean bad_tool; 2919. int fails; 2920. 2921. obj = getobj(oil, "untrap with"); 2922. if (!obj) return 0; 2923. 2924. bad_tool = (obj->cursed || 2925. ((obj->otyp != POT_OIL || obj->lamplit) && 2926. (obj->otyp != CAN_OF_GREASE || !obj->spe))); 2927. 2928. fails = try_disarm(ttmp, bad_tool); 2929. if (fails < 2) return fails; 2930. 2931. /* successfully used oil or grease to fix squeaky board */ 2932. if (obj->otyp == CAN_OF_GREASE) { 2933. check_unpaid(obj); 2934. obj->spe--; 2935. } else { 2936. useup(obj); /* oil */ 2937. makeknown(POT_OIL); 2938. } 2939. You("repair the squeaky board."); /* no madeby_u */ 2940. deltrap(ttmp); 2941. newsym(u.ux + u.dx, u.uy + u.dy); 2942. more_experienced(1, 5); 2943. newexplevel(); 2944. return 1; 2945. } 2946. 2947. /* removes traps that shoot arrows, darts, etc. */ 2948. STATIC_OVL int 2949. disarm_shooting_trap(ttmp, otyp) 2950. struct trap *ttmp; 2951. int otyp; 2952. { 2953. int fails = try_disarm(ttmp, FALSE); 2954. 2955. if (fails < 2) return fails; 2956. You("disarm %s trap.", the_your[ttmp->madeby_u]); 2957. cnv_trap_obj(otyp, 50-rnl(50), ttmp); 2958. return 1; 2959. } 2960. 2961. /* Is the weight too heavy? 2962. * Formula as in near_capacity() & check_capacity() */ 2963. STATIC_OVL int 2964. try_lift(mtmp, ttmp, wt, stuff) 2965. struct monst *mtmp; 2966. struct trap *ttmp; 2967. int wt; 2968. boolean stuff; 2969. { 2970. int wc = weight_cap(); 2971. 2972. if (((wt * 2) / wc) >= HVY_ENCUMBER) { 2973. pline("%s is %s for you to lift.", Monnam(mtmp), 2974. stuff ? "carrying too much" : "too heavy"); 2975. if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove && 2976. !mindless(mtmp->data) && 2977. mtmp->data->mlet != S_HUMAN && rnl(10) < 3) { 2978. mtmp->mpeaceful = 1; 2979. set_malign(mtmp); /* reset alignment */ 2980. pline("%s thinks it was nice of you to try.", Monnam(mtmp)); 2981. } 2982. return 0; 2983. } 2984. return 1; 2985. } 2986. 2987. /* Help trapped monster (out of a (spiked) pit) */ 2988. STATIC_OVL int 2989. help_monster_out(mtmp, ttmp) 2990. struct monst *mtmp; 2991. struct trap *ttmp; 2992. { 2993. int wt; 2994. struct obj *otmp; 2995. boolean uprob; 2996. 2997. /* 2998. * This works when levitating too -- consistent with the ability 2999. * to hit monsters while levitating. 3000. * 3001. * Should perhaps check that our hero has arms/hands at the 3002. * moment. Helping can also be done by engulfing... 3003. * 3004. * Test the monster first - monsters are displayed before traps. 3005. */ 3006. if (!mtmp->mtrapped) { 3007. pline("%s isn't trapped.", Monnam(mtmp)); 3008. return 0; 3009. } 3010. /* Do you have the necessary capacity to lift anything? */ 3011. if (check_capacity((char *)0)) return 1; 3012. 3013. /* Will our hero succeed? */ 3014. if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) { 3015. You("try to reach out your %s, but %s backs away skeptically.", 3016. makeplural(body_part(ARM)), 3017. mon_nam(mtmp)); 3018. return 1; 3019. } 3020. 3021. 3022. /* is it a cockatrice?... */ 3023. if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) { 3024. You("grab the trapped %s using your bare %s.", 3025. mtmp->data->mname, makeplural(body_part(HAND))); 3026. 3027. if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 3028. display_nhwindow(WIN_MESSAGE, FALSE); 3029. else { 3030. char kbuf[BUFSZ]; 3031. 3032. Sprintf(kbuf, "trying to help %s out of a pit", 3033. an(mtmp->data->mname)); 3034. instapetrify(kbuf); 3035. return 1; 3036. } 3037. } 3038. /* need to do cockatrice check first if sleeping or paralyzed */ 3039. if (uprob) { 3040. You("try to grab %s, but cannot get a firm grasp.", 3041. mon_nam(mtmp)); 3042. if (mtmp->msleeping) { 3043. mtmp->msleeping = 0; 3044. pline("%s awakens.", Monnam(mtmp)); 3045. } 3046. return 1; 3047. } 3048. 3049. You("reach out your %s and grab %s.", 3050. makeplural(body_part(ARM)), mon_nam(mtmp)); 3051. 3052. if (mtmp->msleeping) { 3053. mtmp->msleeping = 0; 3054. pline("%s awakens.", Monnam(mtmp)); 3055. } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) { 3056. /* After such manhandling, perhaps the effect wears off */ 3057. mtmp->mcanmove = 1; 3058. mtmp->mfrozen = 0; 3059. pline("%s stirs.", Monnam(mtmp)); 3060. } 3061. 3062. /* is the monster too heavy? */ 3063. wt = inv_weight() + mtmp->data->cwt; 3064. if (!try_lift(mtmp, ttmp, wt, FALSE)) return 1; 3065. 3066. /* is the monster with inventory too heavy? */ 3067. for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 3068. wt += otmp->owt; 3069. if (!try_lift(mtmp, ttmp, wt, TRUE)) return 1; 3070. 3071. You("pull %s out of the pit.", mon_nam(mtmp)); 3072. mtmp->mtrapped = 0; 3073. fill_pit(mtmp->mx, mtmp->my); 3074. reward_untrap(ttmp, mtmp); 3075. return 1; 3076. } 3077. 3078. int 3079. untrap(force) 3080. boolean force; 3081. { 3082. register struct obj *otmp; 3083. register boolean confused = (Confusion > 0 || Hallucination > 0); 3084. register int x,y; 3085. int ch; 3086. struct trap *ttmp; 3087. struct monst *mtmp; 3088. boolean trap_skipped = FALSE; 3089. 3090. if(!getdir((char *)0)) return(0); 3091. x = u.ux + u.dx; 3092. y = u.uy + u.dy; 3093. 3094. if ((ttmp = t_at(x,y)) && ttmp->tseen) { 3095. if (u.utrap) { 3096. You("cannot deal with traps while trapped!"); 3097. return 1; 3098. } 3099. switch(ttmp->ttyp) { 3100. case BEAR_TRAP: 3101. case WEB: 3102. return disarm_holdingtrap(ttmp); 3103. case LANDMINE: 3104. return disarm_landmine(ttmp); 3105. case SQKY_BOARD: 3106. return disarm_squeaky_board(ttmp); 3107. case DART_TRAP: 3108. return disarm_shooting_trap(ttmp, DART); 3109. case ARROW_TRAP: 3110. return disarm_shooting_trap(ttmp, ARROW); 3111. case PIT: 3112. case SPIKED_PIT: 3113. if (!u.dx && !u.dy) { 3114. You("are already on the edge of the pit."); 3115. return 0; 3116. } 3117. if (!(mtmp = m_at(x,y))) { 3118. pline("Try filling the pit instead."); 3119. return 0; 3120. } 3121. return help_monster_out(mtmp, ttmp); 3122. default: 3123. You("cannot disable %s trap.", (u.dx || u.dy) ? "that" : "this"); 3124. return 0; 3125. } /* end switch */ 3126. } /* end if */ 3127. 3128. if(!u.dx && !u.dy) { 3129. for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 3130. if(Is_box(otmp)) { 3131. There("is %s here.", doname(otmp)); 3132. 3133. switch (ynq("Check for traps?")) { 3134. case 'q': return(0); 3135. case 'n': continue; 3136. } 3137. 3138. if((otmp->otrapped && (force || (!confused 3139. && rn2(MAXULEV + 1 - u.ulevel) < 10))) 3140. || (!force && confused && !rn2(3))) { 3141. You("find a trap on %s!", the(xname(otmp))); 3142. exercise(A_WIS, TRUE); 3143. 3144. switch (ynq("Disarm it?")) { 3145. case 'q': return(1); 3146. case 'n': trap_skipped = TRUE; continue; 3147. } 3148. 3149. if(otmp->otrapped) { 3150. exercise(A_DEX, TRUE); 3151. ch = ACURR(A_DEX) + u.ulevel; 3152. if (Role_if(PM_ROGUE)) ch *= 2; 3153. if(!force && (confused || Fumbling || 3154. rnd(75+level_difficulty()/2) > ch)) { 3155. (void) chest_trap(otmp, FINGER, TRUE); 3156. } else { 3157. You("disarm it!"); 3158. otmp->otrapped = 0; 3159. } 3160. } else pline("That %s was not trapped.", xname(otmp)); 3161. return(1); 3162. } else { 3163. You("find no traps on %s.", the(xname(otmp))); 3164. return(1); 3165. } 3166. } 3167. 3168. You(trap_skipped ? "find no other traps here." 3169. : "know of no traps here."); 3170. return(0); 3171. } 3172. 3173. if ((mtmp = m_at(x,y)) && 3174. mtmp->m_ap_type == M_AP_FURNITURE && 3175. (mtmp->mappearance == S_hcdoor || 3176. mtmp->mappearance == S_vcdoor) && 3177. !Protection_from_shape_changers) { 3178. 3179. stumble_onto_mimic(mtmp); 3180. return(1); 3181. } 3182. 3183. if (!IS_DOOR(levl[x][y].typ)) { 3184. if ((ttmp = t_at(x,y)) && ttmp->tseen) 3185. You("cannot disable that trap."); 3186. else 3187. You("know of no traps there."); 3188. return(0); 3189. } 3190. 3191. switch (levl[x][y].doormask) { 3192. case D_NODOOR: 3193. You("%s no door there.", Blind ? "feel" : "see"); 3194. return(0); 3195. case D_ISOPEN: 3196. pline("This door is safely open."); 3197. return(0); 3198. case D_BROKEN: 3199. pline("This door is broken."); 3200. return(0); 3201. } 3202. 3203. if ((levl[x][y].doormask & D_TRAPPED 3204. && (force || 3205. (!confused && rn2(MAXULEV - u.ulevel + 11) < 10))) 3206. || (!force && confused && !rn2(3))) { 3207. You("find a trap on the door!"); 3208. exercise(A_WIS, TRUE); 3209. if (ynq("Disarm it?") != 'y') return(1); 3210. if (levl[x][y].doormask & D_TRAPPED) { 3211. ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel*3 : u.ulevel); 3212. exercise(A_DEX, TRUE); 3213. if(!force && (confused || Fumbling || 3214. rnd(75+level_difficulty()/2) > ch)) { 3215. You("set it off!"); 3216. b_trapped("door", FINGER); 3217. levl[x][y].doormask = D_NODOOR; 3218. unblock_point(x, y); 3219. newsym(x, y); 3220. /* (probably ought to charge for this damage...) */ 3221. if (*in_rooms(x, y, SHOPBASE)) add_damage(x, y, 0L); 3222. } else { 3223. You("disarm it!"); 3224. levl[x][y].doormask &= ~D_TRAPPED; 3225. } 3226. } else pline("This door was not trapped."); 3227. return(1); 3228. } else { 3229. You("find no traps on the door."); 3230. return(1); 3231. } 3232. } 3233. #endif /* OVL2 */ 3234. #ifdef OVLB 3235. 3236. /* only called when the player is doing something to the chest directly */ 3237. boolean 3238. chest_trap(obj, bodypart, disarm) 3239. register struct obj *obj; 3240. register int bodypart; 3241. boolean disarm; 3242. { 3243. register struct obj *otmp = obj, *otmp2; 3244. char buf[80]; 3245. const char *msg; 3246. coord cc; 3247. 3248. if (get_obj_location(obj, &cc.x, &cc.y, 0)) /* might be carried */ 3249. obj->ox = cc.x, obj->oy = cc.y; 3250. 3251. otmp->otrapped = 0; /* trap is one-shot; clear flag first in case 3252. chest kills you and ends up in bones file */ 3253. You(disarm ? "set it off!" : "trigger a trap!"); 3254. display_nhwindow(WIN_MESSAGE, FALSE); 3255. if (Luck > -13 && rn2(13+Luck) > 7) { /* saved by luck */ 3256. /* trap went off, but good luck prevents damage */ 3257. switch (rn2(13)) { 3258. case 12: 3259. case 11: msg = "explosive charge is a dud"; break; 3260. case 10: 3261. case 9: msg = "electric charge is grounded"; break; 3262. case 8: 3263. case 7: msg = "flame fizzles out"; break; 3264. case 6: 3265. case 5: 3266. case 4: msg = "poisoned needle misses"; break; 3267. case 3: 3268. case 2: 3269. case 1: 3270. case 0: msg = "gas cloud blows away"; break; 3271. default: impossible("chest disarm bug"); msg = (char *)0; 3272. break; 3273. } 3274. if (msg) pline("But luckily the %s!", msg); 3275. } else { 3276. switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) { 3277. case 25: 3278. case 24: 3279. case 23: 3280. case 22: 3281. case 21: { 3282. struct monst *shkp = 0; 3283. long loss = 0L; 3284. boolean costly, insider; 3285. register xchar ox = obj->ox, oy = obj->oy; 3286. 3287. /* the obj location need not be that of player */ 3288. costly = (costly_spot(ox, oy) && 3289. (shkp = shop_keeper(*in_rooms(ox, oy, 3290. SHOPBASE))) != (struct monst *)0); 3291. insider = (*u.ushops && inside_shop(u.ux, u.uy) && 3292. *in_rooms(ox, oy, SHOPBASE) == *u.ushops); 3293. 3294. pline("%s!", Tobjnam(obj, "explode")); 3295. Sprintf(buf, "exploding %s", xname(obj)); 3296. 3297. if(costly) 3298. loss += stolen_value(obj, ox, oy, 3299. (boolean)shkp->mpeaceful, TRUE); 3300. delete_contents(obj); 3301. for(otmp = level.objects[u.ux][u.uy]; 3302. otmp; otmp = otmp2) { 3303. otmp2 = otmp->nexthere; 3304. if(costly) 3305. loss += stolen_value(otmp, otmp->ox, 3306. otmp->oy, (boolean)shkp->mpeaceful, 3307. TRUE); 3308. delobj(otmp); 3309. } 3310. wake_nearby(); 3311. losehp(d(6,6), buf, KILLED_BY_AN); 3312. exercise(A_STR, FALSE); 3313. if(costly && loss) { 3314. if(insider) 3315. You("owe %ld %s for objects destroyed.", 3316. loss, currency(loss)); 3317. else { 3318. You("caused %ld %s worth of damage!", 3319. loss, currency(loss)); 3320. make_angry_shk(shkp, ox, oy); 3321. } 3322. } 3323. return TRUE; 3324. } 3325. case 20: 3326. case 19: 3327. case 18: 3328. case 17: 3329. pline("A cloud of noxious gas billows from %s.", 3330. the(xname(obj))); 3331. poisoned("gas cloud", A_STR, "cloud of poison gas",15); 3332. exercise(A_CON, FALSE); 3333. break; 3334. case 16: 3335. case 15: 3336. case 14: 3337. case 13: 3338. You_feel("a needle prick your %s.",body_part(bodypart)); 3339. poisoned("needle", A_CON, "poisoned needle",10); 3340. exercise(A_CON, FALSE); 3341. break; 3342. case 12: 3343. case 11: 3344. case 10: 3345. case 9: 3346. dofiretrap(obj); 3347. break; 3348. case 8: 3349. case 7: 3350. case 6: { 3351. int dmg; 3352. 3353. You("are jolted by a surge of electricity!"); 3354. if(Shock_resistance) { 3355. shieldeff(u.ux, u.uy); 3356. You("don't seem to be affected."); 3357. dmg = 0; 3358. } else 3359. dmg = d(4, 4); 3360. destroy_item(RING_CLASS, AD_ELEC); 3361. destroy_item(WAND_CLASS, AD_ELEC); 3362. if (dmg) losehp(dmg, "electric shock", KILLED_BY_AN); 3363. break; 3364. } 3365. case 5: 3366. case 4: 3367. case 3: 3368. if (!Free_action) { 3369. pline("Suddenly you are frozen in place!"); 3370. nomul(-d(5, 6)); 3371. exercise(A_DEX, FALSE); 3372. nomovemsg = You_can_move_again; 3373. } else You("momentarily stiffen."); 3374. break; 3375. case 2: 3376. case 1: 3377. case 0: 3378. pline("A cloud of %s gas billows from %s.", 3379. hcolor((char *)0), 3380. the(xname(obj))); 3381. if(!Stunned) { 3382. if (Hallucination) 3383. pline("What a groovy feeling!"); 3384. else if (Blind) 3385. You("%s and get dizzy...", 3386. stagger(youmonst.data, "stagger")); 3387. else 3388. You("%s and your vision blurs...", 3389. stagger(youmonst.data, "stagger")); 3390. } 3391. make_stunned(HStun + rn1(7, 16),FALSE); 3392. make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L); 3393. break; 3394. default: impossible("bad chest trap"); 3395. break; 3396. } 3397. bot(); /* to get immediate botl re-display */ 3398. } 3399. 3400. return FALSE; 3401. } 3402. 3403. #endif /* OVLB */ 3404. #ifdef OVL0 3405. 3406. struct trap * 3407. t_at(x,y) 3408. register int x, y; 3409. { 3410. register struct trap *trap = ftrap; 3411. while(trap) { 3412. if(trap->tx == x && trap->ty == y) return(trap); 3413. trap = trap->ntrap; 3414. } 3415. return((struct trap *)0); 3416. } 3417. 3418. #endif /* OVL0 */ 3419. #ifdef OVLB 3420. 3421. void 3422. deltrap(trap) 3423. register struct trap *trap; 3424. { 3425. register struct trap *ttmp; 3426. 3427. if(trap == ftrap) 3428. ftrap = ftrap->ntrap; 3429. else { 3430. for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 3431. ttmp->ntrap = trap->ntrap; 3432. } 3433. dealloc_trap(trap); 3434. } 3435. 3436. boolean delfloortrap(ttmp) 3437. register struct trap *ttmp; 3438. { 3439. /* Destroy a trap that emanates from the floor. */ 3440. /* some of these are arbitrary -dlc */ 3441. if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || 3442. (ttmp->ttyp == BEAR_TRAP) || 3443. (ttmp->ttyp == LANDMINE) || 3444. (ttmp->ttyp == FIRE_TRAP) || 3445. (ttmp->ttyp == PIT) || 3446. (ttmp->ttyp == SPIKED_PIT) || 3447. (ttmp->ttyp == HOLE) || 3448. (ttmp->ttyp == TRAPDOOR) || 3449. (ttmp->ttyp == TELEP_TRAP) || 3450. (ttmp->ttyp == LEVEL_TELEP) || 3451. (ttmp->ttyp == WEB) || 3452. (ttmp->ttyp == MAGIC_TRAP) || 3453. (ttmp->ttyp == ANTI_MAGIC))) { 3454. register struct monst *mtmp; 3455. 3456. if (ttmp->tx == u.ux && ttmp->ty == u.uy) { 3457. u.utrap = 0; 3458. u.utraptype = 0; 3459. } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) { 3460. mtmp->mtrapped = 0; 3461. } 3462. deltrap(ttmp); 3463. return TRUE; 3464. } else 3465. return FALSE; 3466. } 3467. 3468. /* used for doors (also tins). can be used for anything else that opens. */ 3469. void 3470. b_trapped(item, bodypart) 3471. register const char *item; 3472. register int bodypart; 3473. { 3474. register int lvl = level_difficulty(); 3475. int dmg = rnd(5 + (lvl < 5 ? lvl : 2+lvl/2)); 3476. 3477. pline("KABOOM!! %s was booby-trapped!", The(item)); 3478. wake_nearby(); 3479. losehp(dmg, "explosion", KILLED_BY_AN); 3480. exercise(A_STR, FALSE); 3481. if (bodypart) exercise(A_CON, FALSE); 3482. make_stunned(HStun + dmg, TRUE); 3483. } 3484. 3485. /* Monster is hit by trap. */ 3486. /* Note: doesn't work if both obj and d_override are null */ 3487. STATIC_OVL boolean 3488. thitm(tlev, mon, obj, d_override) 3489. register int tlev; 3490. register struct monst *mon; 3491. register struct obj *obj; 3492. int d_override; 3493. { 3494. register int strike; 3495. register boolean trapkilled = FALSE; 3496. 3497. if (d_override) strike = 1; 3498. else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20)); 3499. else strike = (find_mac(mon) + tlev <= rnd(20)); 3500. 3501. /* Actually more accurate than thitu, which doesn't take 3502. * obj->spe into account. 3503. */ 3504. if(!strike) { 3505. if (obj && cansee(mon->mx, mon->my)) 3506. pline("%s is almost hit by %s!", Monnam(mon), doname(obj)); 3507. } else { 3508. int dam = 1; 3509. 3510. if (obj && cansee(mon->mx, mon->my)) 3511. pline("%s is hit by %s!", Monnam(mon), doname(obj)); 3512. if (d_override) dam = d_override; 3513. else if (obj) { 3514. dam = dmgval(obj, mon); 3515. if (dam < 1) dam = 1; 3516. } 3517. if ((mon->mhp -= dam) <= 0) { 3518. int xx = mon->mx; 3519. int yy = mon->my; 3520. 3521. monkilled(mon, "", AD_PHYS); 3522. if (mon->mhp <= 0) { 3523. newsym(xx, yy); 3524. trapkilled = TRUE; 3525. } 3526. } 3527. } 3528. if (obj && (!strike || d_override)) { 3529. place_object(obj, mon->mx, mon->my); 3530. stackobj(obj); 3531. } else if (obj) dealloc_obj(obj); 3532. 3533. return trapkilled; 3534. } 3535. 3536. boolean 3537. unconscious() 3538. { 3539. return((boolean)(multi < 0 && (!nomovemsg || 3540. u.usleep || 3541. !strncmp(nomovemsg,"You regain con", 14) || 3542. !strncmp(nomovemsg,"You are consci", 14)))); 3543. } 3544. 3545. static char lava_killer[] = "molten lava"; 3546. 3547. boolean 3548. lava_effects() 3549. { 3550. register struct obj *obj, *obj2; 3551. int dmg; 3552. boolean usurvive; 3553. 3554. burn_away_slime(); 3555. if (likes_lava(youmonst.data)) return FALSE; 3556. 3557. if (!Fire_resistance) { 3558. if(Wwalking) { 3559. dmg = d(6,6); 3560. pline_The("lava here burns you!"); 3561. if(dmg < u.uhp) { 3562. losehp(dmg, lava_killer, KILLED_BY); 3563. goto burn_stuff; 3564. } 3565. } else 3566. You("fall into the lava!"); 3567. 3568. usurvive = Lifesaved || discover; 3569. #ifdef WIZARD 3570. if (wizard) usurvive = TRUE; 3571. #endif 3572. for(obj = invent; obj; obj = obj2) { 3573. obj2 = obj->nobj; 3574. if(is_organic(obj) && !obj->oerodeproof) { 3575. if(obj->owornmask) { 3576. if (usurvive) 3577. Your("%s into flame!", aobjnam(obj, "burst")); 3578. 3579. if(obj == uarm) (void) Armor_gone(); 3580. else if(obj == uarmc) (void) Cloak_off(); 3581. else if(obj == uarmh) (void) Helmet_off(); 3582. else if(obj == uarms) (void) Shield_off(); 3583. else if(obj == uarmg) (void) Gloves_off(); 3584. else if(obj == uarmf) (void) Boots_off(); 3585. #ifdef TOURIST 3586. else if(obj == uarmu) setnotworn(obj); 3587. #endif 3588. else if(obj == uleft) Ring_gone(obj); 3589. else if(obj == uright) Ring_gone(obj); 3590. else if(obj == ublindf) Blindf_off(obj); 3591. else if(obj == uamul) Amulet_off(); 3592. else if(obj == uwep) uwepgone(); 3593. else if (obj == uquiver) uqwepgone(); 3594. else if (obj == uswapwep) uswapwepgone(); 3595. } 3596. useupall(obj); 3597. } 3598. } 3599. 3600. /* s/he died... */ 3601. u.uhp = -1; 3602. killer_format = KILLED_BY; 3603. killer = lava_killer; 3604. You("burn to a crisp..."); 3605. done(BURNING); 3606. while (!safe_teleds()) { 3607. pline("You're still burning."); 3608. done(BURNING); 3609. } 3610. You("find yourself back on solid %s.", surface(u.ux, u.uy)); 3611. return(TRUE); 3612. } 3613. 3614. if (!Wwalking) { 3615. u.utrap = rn1(4, 4) + (rn1(4, 12) << 8); 3616. u.utraptype = TT_LAVA; 3617. You("sink into the lava, but it only burns slightly!"); 3618. if (u.uhp > 1) 3619. losehp(1, lava_killer, KILLED_BY); 3620. } 3621. /* just want to burn boots, not all armor; destroy_item doesn't work on 3622. armor anyway */ 3623. burn_stuff: 3624. if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) { 3625. /* save uarmf value because Boots_off() sets uarmf to null */ 3626. obj = uarmf; 3627. Your("%s bursts into flame!", xname(obj)); 3628. (void) Boots_off(); 3629. useup(obj); 3630. } 3631. destroy_item(SCROLL_CLASS, AD_FIRE); 3632. destroy_item(SPBOOK_CLASS, AD_FIRE); 3633. destroy_item(POTION_CLASS, AD_FIRE); 3634. return(FALSE); 3635. } 3636. 3637. #endif /* OVLB */ 3638. 3639. /*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