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