Difference between revisions of "Source:NetHack 3.0.0/trap.c"
m (Automated source code upload) |
Ray Chason (talk | contribs) (More operator precedence) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 1,383: | Line 1,383: | ||
<span id="line1378">1378. (pl_character[0] == 'R') ? u.ulevel*3 :</span> | <span id="line1378">1378. (pl_character[0] == 'R') ? u.ulevel*3 :</span> | ||
<span id="line1379">1379. u.ulevel;</span> | <span id="line1379">1379. u.ulevel;</span> | ||
+ | |||
+ | The above statement contains a bug. It is meant to assign 15 + u.ulevel*3 to ch if the player is a [[Rogue]], and 15 + u.ulevel otherwise. In fact, the conditional is always either 15 or 16, both of which are interpreted as true, and the statement assigns u.ulevel*3 to ch regardless of the role. Thus rogues do not in fact have a better chance of disarming a chest trap than other roles. | ||
+ | |||
+ | The logic is changed in [[Source:NetHack 3.1.0/trap.c#line2087|3.1.0]] and rogues from then on have an increased chance of disarming a chest trap. | ||
+ | |||
<span id="line1380">1380. if(confused || Fumbling || rnd(75+dlevel/2) > ch) {</span> | <span id="line1380">1380. if(confused || Fumbling || rnd(75+dlevel/2) > ch) {</span> | ||
<span id="line1381">1381. You("set it off!");</span> | <span id="line1381">1381. You("set it off!");</span> | ||
Line 1,435: | Line 1,440: | ||
<span id="line1430">1430. (pl_character[0] == 'R') ? u.ulevel*3 :</span> | <span id="line1430">1430. (pl_character[0] == 'R') ? u.ulevel*3 :</span> | ||
<span id="line1431">1431. u.ulevel;</span> | <span id="line1431">1431. u.ulevel;</span> | ||
+ | |||
+ | The above statement contains the same bug as line 1377. This one, however, was left unfixed in [[NetHack 3.1.0/trap.c#line2149|3.1.0]]. It is fixed in [[NetHack 3.2.0/trap.c#line2395|3.2.0]]. | ||
+ | |||
<span id="line1432">1432. if(confused || Fumbling || rnd(75+dlevel/2) > ch) {</span> | <span id="line1432">1432. if(confused || Fumbling || rnd(75+dlevel/2) > ch) {</span> | ||
<span id="line1433">1433. You("set it off!");</span> | <span id="line1433">1433. You("set it off!");</span> |
Latest revision as of 01:29, 13 April 2014
Below is the full text to trap.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/trap.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)trap.c 3.0 88/10/22 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "edog.h" 7. #include "trapname.h" 8. 9. void domagictrap(); 10. static boolean thitm(); 11. 12. /* Generic rust-armor function. Returns TRUE if a message was printed; 13. * "print", if set, means to print a message (and thus to return TRUE) even 14. * if the item could not be rusted; otherwise a message is printed and TRUE is 15. * returned only for rustable items. 16. */ 17. boolean 18. rust_dmg(otmp, ostr, type, print) 19. register struct obj *otmp; 20. register char *ostr; 21. int type; 22. boolean print; 23. { 24. static const char *gook[] = { "slag", "rust", "rot", "corrosion" }; 25. static const char *action[] = { "smolder", "rust", "rot", "corrode" }; 26. boolean vulnerable = FALSE; 27. boolean plural; 28. 29. if (!otmp) return(FALSE); 30. switch(type) { 31. case 0: 32. case 2: vulnerable = is_flammable(otmp); break; 33. case 1: vulnerable = is_rustprone(otmp); break; 34. case 3: vulnerable = (otmp->otyp == BRONZE_PLATE_MAIL); break; 35. } 36. 37. if (!print && (!vulnerable || otmp->rustfree || otmp->spe < -2)) 38. return FALSE; 39. 40. plural = is_gloves(otmp) || is_boots(otmp); 41. 42. if (!vulnerable) 43. Your("%s %s not affected!", ostr, plural ? "are" : "is"); 44. else if (otmp->spe >= -2) { 45. if (otmp->rustfree) 46. pline("The %s on your %s vanishes instantly!", 47. gook[type], ostr); 48. else if (otmp->blessed && !rnl(4)) 49. pline("Somehow, your %s %s not affected!", ostr, 50. plural ? "are" : "is"); 51. else { 52. Your("%s %s%s!", ostr, action[type], 53. plural ? "" : "s"); 54. otmp->spe--; 55. adj_abon(otmp, -1); 56. } 57. } else Your("%s look%s quite rusted.", ostr, plural ? "" : "s"); 58. return(TRUE); 59. } 60. 61. struct trap * 62. maketrap(x,y,typ) 63. register int x, y, typ; 64. { 65. register struct trap *ttmp; 66. register struct permonst *ptr; 67. 68. ttmp = newtrap(); 69. ttmp->ttyp = typ; 70. ttmp->tx = x; 71. ttmp->ty = y; 72. switch(typ) { 73. case MONST_TRAP: /* create a monster in "hiding" */ 74. if(rn2(5) && (ptr = mkclass(S_PIERCER))) 75. ttmp->pm = monsndx(ptr); 76. else 77. ttmp->pm = rndmonnum(); 78. break; 79. case STATUE_TRAP: /* create a "living" statue */ 80. ttmp->pm = rndmonnum(); 81. (void) mkstatue(&mons[ttmp->pm], x, y); 82. break; 83. default: 84. ttmp->pm = -1; 85. break; 86. } 87. ttmp->tseen = 0; 88. ttmp->once = 0; 89. ttmp->ntrap = ftrap; 90. ftrap = ttmp; 91. return(ttmp); 92. } 93. 94. int 95. teleok(x, y) 96. register int x, y; 97. { /* might throw him into a POOL 98. * removed by GAN 10/20/86 99. */ 100. #ifdef STUPID 101. boolean tmp1, tmp2, tmp3; 102. # ifdef POLYSELF 103. tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) || 104. passes_walls(uasmon)) && !levl[x][y].mmask; 105. # else 106. tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !levl[x][y].mmask; 107. # endif 108. tmp2 = !sobj_at(BOULDER,x,y) && !t_at(x,y); 109. tmp3 = !(is_pool(x,y) && 110. !(Levitation || Wwalking 111. #ifdef POLYSELF 112. || is_flyer(uasmon) 113. #endif 114. )) && 115. !(IS_DOOR(levl[x][y].typ) && 116. (levl[x][y].doormask & (D_LOCKED | D_CLOSED))); 117. return(tmp1 && tmp2 && tmp3); 118. #else 119. return( isok(x,y) && 120. # ifdef POLYSELF 121. (!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) && 122. # else 123. !IS_ROCK(levl[x][y].typ) && 124. # endif 125. !levl[x][y].mmask && 126. !sobj_at(BOULDER,x,y) && !t_at(x,y) && 127. !(is_pool(x,y) && 128. !(Levitation || Wwalking 129. #ifdef POLYSELF 130. || is_flyer(uasmon) 131. #endif 132. )) && 133. !(IS_DOOR(levl[x][y].typ) && 134. (levl[x][y].doormask & (D_LOCKED | D_CLOSED))) 135. ); 136. #endif 137. /* Note: gold is permitted (because of vaults) */ 138. } 139. 140. static void 141. vtele() { 142. register struct mkroom *croom; 143. 144. for(croom = &rooms[0]; croom->hx >= 0; croom++) 145. if(croom->rtype == VAULT) { 146. register int x, y; 147. 148. x = rn2(2) ? croom->lx : croom->hx; 149. y = rn2(2) ? croom->ly : croom->hy; 150. if(teleok(x,y)) { 151. teleds(x,y); 152. return; 153. } 154. } 155. tele(); 156. } 157. 158. void 159. dotrap(trap) 160. register struct trap *trap; 161. { 162. register int ttype = trap->ttyp; 163. register struct monst *mtmp; 164. register struct obj *otmp; 165. 166. nomul(0); 167. if(trap->tseen && !Fumbling && !(ttype == PIT 168. || ttype == SPIKED_PIT 169. #ifdef SPELLS 170. || ttype == ANTI_MAGIC 171. #endif 172. ) && !rn2(5)) 173. You("escape a%s.", traps[ttype]); 174. else { 175. trap->tseen = 1; 176. if(Invisible && ttype != MONST_TRAP) 177. newsym(trap->tx,trap->ty); 178. switch(ttype) { 179. case SLP_GAS_TRAP: 180. if(Sleep_resistance) { 181. You("are enveloped in a cloud of gas!"); 182. break; 183. } 184. pline("A cloud of gas puts you to sleep!"); 185. flags.soundok = 0; 186. nomul(-rnd(25)); 187. afternmv = Hear_again; 188. break; 189. case BEAR_TRAP: 190. if(Levitation 191. #ifdef POLYSELF 192. || is_flyer(uasmon) 193. #endif 194. ) { 195. You("%s over a bear trap.", 196. Levitation ? "float" : "fly"); 197. break; 198. } 199. u.utrap = 4 + rn2(4); 200. u.utraptype = TT_BEARTRAP; 201. pline("A bear trap closes on your %s!", 202. body_part(FOOT)); 203. #ifdef POLYSELF 204. if(u.umonnum == PM_OWLBEAR) 205. You("howl in anger!"); 206. #endif 207. break; 208. case STATUE_TRAP: 209. for(otmp=fobj; otmp; otmp=otmp->nobj) { 210. if(otmp->otyp == STATUE && otmp->ox == u.ux && 211. otmp->oy == u.uy && otmp->corpsenm == trap->pm) 212. if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) { 213. pline("The statue comes to life!"); 214. delobj(otmp); 215. break; 216. } 217. } 218. deltrap(trap); 219. break; 220. case MONST_TRAP: 221. if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) { 222. switch(mtmp->data->mlet) { 223. case S_PIERCER: 224. pline("%s suddenly drops from the ceiling!", 225. Xmonnam(mtmp)); 226. if(uarmh) 227. pline("Its blow glances off your helmet."); 228. else 229. (void) thitu(3,d(4,6),"falling piercer"); 230. break; 231. default: /* monster surprises you. */ 232. pline("%s attacks you by surprise!", 233. Xmonnam(mtmp)); 234. break; 235. } 236. } 237. deltrap(trap); 238. break; 239. case ARROW_TRAP: 240. pline("An arrow shoots out at you!"); 241. if(!thitu(8,rnd(6),"arrow")){ 242. (void) mksobj_at(ARROW, u.ux, u.uy); 243. fobj->quan = 1; 244. fobj->owt = weight(fobj); 245. } 246. break; 247. case TRAPDOOR: 248. if(is_maze_lev 249. #ifdef STRONGHOLD 250. && (dlevel > stronghold_level) 251. #endif /* STRONGHOLD /**/ 252. ) { 253. pline("A trap door in the ceiling opens and a rock falls on your %s!", 254. body_part(HEAD)); 255. if(uarmh) 256. pline("Fortunately, you are wearing a helmet!"); 257. losehp(uarmh ? 2 : d(2,10),"falling rock"); 258. (void) mksobj_at(ROCK, u.ux, u.uy); 259. fobj->quan = 1; 260. fobj->owt = weight(fobj); 261. stackobj(fobj); 262. if(Invisible) newsym(u.ux, u.uy); 263. } else { 264. register int newlevel = dlevel + 1; 265. while(!rn2(4) && newlevel < 29) newlevel++; 266. pline("A trap door opens up under you!"); 267. if(Levitation || u.ustuck || dlevel == MAXLEVEL 268. #ifdef POLYSELF 269. || is_flyer(uasmon) 270. #endif 271. #ifdef ENDGAME 272. || dlevel == ENDLEVEL 273. #endif 274. ) { 275. You("don't fall in."); 276. break; 277. } 278. #ifdef WALKIES 279. if(!next_to_u()) 280. You("are jerked back by your pet!"); 281. else { 282. #endif 283. unsee(); 284. (void) fflush(stdout); 285. goto_level(newlevel, FALSE); 286. #ifdef WALKIES 287. } 288. #endif 289. } 290. break; 291. case DART_TRAP: 292. pline("A little dart shoots out at you!"); 293. if(thitu(7,rnd(3),"little dart")) { 294. if(!rn2(6)) poisoned("dart",A_CON,"poison dart"); 295. } else { 296. (void) mksobj_at(DART, u.ux, u.uy); 297. fobj->quan = 1; 298. fobj->opoisoned = 1; 299. fobj->owt = weight(fobj); 300. } 301. break; 302. case TELEP_TRAP: 303. if(trap->once) { 304. deltrap(trap); 305. #ifdef ENDGAME 306. if(dlevel == ENDLEVEL) { 307. You("feel a wrenching sensation."); 308. break; 309. } 310. #endif 311. if(Antimagic) { 312. shieldeff(u.ux, u.uy); 313. You("feel a wrenching sensation."); 314. } else { 315. newsym(u.ux, u.uy); 316. vtele(); 317. } 318. } else { 319. #ifdef ENDGAME 320. if(dlevel == ENDLEVEL) { 321. pline("A shiver runs down your spine..."); 322. break; 323. } 324. #endif 325. if(Antimagic) { 326. shieldeff(u.ux, u.uy); 327. You("feel a wrenching sensation."); 328. } else { 329. newsym(u.ux, u.uy); 330. tele(); 331. } 332. } 333. break; 334. case RUST_TRAP: 335. #ifdef POLYSELF 336. #ifdef GOLEMS 337. if (u.umonnum == PM_IRON_GOLEM) { 338. pline("A gush of water hits you!"); 339. You("are covered with rust!"); 340. rehumanize(); 341. break; 342. } 343. #endif /* GOLEMS */ 344. #endif 345. /* Unlike monsters, traps cannot aim their rust attacks at 346. * you, so instead of looping through and taking either the 347. * first rustable one or the body, we take whatever we get, 348. * even if it is not rustable. 349. */ 350. switch (rn2(5)) { 351. case 0: 352. pline("A gush of water hits you on the %s!", 353. body_part(HEAD)); 354. (void) rust_dmg(uarmh, "helmet", 1, TRUE); 355. break; 356. case 1: 357. pline("A gush of water hits your left %s!", 358. body_part(ARM)); 359. if (rust_dmg(uarms, "shield", 1, TRUE)) break; 360. if (uwep && bimanual(uwep)) 361. goto two_hand; 362. /* Two goto statements in a row--aaarrrgggh! */ 363. glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE); 364. /* Not "metal gauntlets" since it gets called 365. * even if it's leather for the message 366. */ 367. break; 368. case 2: 369. pline("A gush of water hits your right %s!", 370. body_part(ARM)); 371. two_hand: corrode_weapon(); 372. goto glovecheck; 373. default: 374. pline("A gush of water hits you!"); 375. if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE); 376. else if (uarm) 377. (void) rust_dmg(uarm, "armor", 1, TRUE); 378. #ifdef SHIRT 379. else if (uarmu) 380. (void) rust_dmg(uarmu, "shirt", 1, TRUE); 381. #endif 382. } 383. break; 384. case PIT: 385. if (Levitation 386. #ifdef POLYSELF 387. || is_flyer(uasmon) || u.umonnum == PM_WUMPUS 388. #endif 389. ) { 390. pline("A pit opens up under you!"); 391. You("don't fall in!"); 392. break; 393. } 394. You("fall into a pit!"); 395. #ifdef POLYSELF 396. if (!passes_walls(uasmon)) 397. #endif 398. u.utrap = rn1(6,2); 399. u.utraptype = TT_PIT; 400. losehp(rnd(6),"fall into a pit"); 401. selftouch("Falling, you"); 402. break; 403. case SPIKED_PIT: 404. if (Levitation 405. #ifdef POLYSELF 406. || is_flyer(uasmon) || u.umonnum == PM_WUMPUS 407. #endif 408. ) { 409. pline("A pit full of spikes opens up under you!"); 410. You("don't fall in!"); 411. break; 412. } 413. You("fall into a pit!"); 414. You("land on a set of sharp iron spikes!"); 415. #ifdef POLYSELF 416. if (!passes_walls(uasmon)) 417. #endif 418. u.utrap = rn1(6,2); 419. u.utraptype = TT_PIT; 420. losehp(rnd(10),"fall onto iron spikes"); 421. if(!rn2(6)) poisoned("spikes",A_STR,"poison spikes"); 422. selftouch("Falling, you"); 423. break; 424. case LEVEL_TELEP: 425. pline("You have %s onto a level teleport trap!", 426. #ifdef POLYSELF 427. is_flyer(uasmon) ? "flown" : 428. (Levitation || nolimbs(uasmon)) ? "moved" : "stepped"); 429. #else 430. Levitation ? "moved" : "stepped"); 431. #endif 432. if(Antimagic) 433. shieldeff(u.ux, u.uy); 434. if(Antimagic 435. #ifdef ENDGAME 436. || dlevel == ENDLEVEL 437. #endif 438. ) { 439. You("feel a wrenching sensation."); 440. break; 441. } 442. if(!Blind) 443. You("are momentarily blinded by a flash of light."); 444. else 445. You("are momentarily disoriented."); 446. deltrap(trap); 447. newsym(u.ux,u.uy); 448. level_tele(); 449. break; 450. #ifdef SPELLS 451. case ANTI_MAGIC: 452. if(Antimagic) { 453. shieldeff(u.ux, u.uy); 454. You("feel momentarily lethargic."); 455. } else drain_en(rnd((int)u.ulevel) + 1); 456. break; 457. #endif 458. #ifdef POLYSELF 459. case POLY_TRAP: 460. if(Antimagic) { 461. shieldeff(u.ux, u.uy); 462. You("feel momentarily different."); 463. /* Trap did nothing; don't remove it --KAA */ 464. } else { 465. You("feel a change coming over you."); 466. polyself(); 467. deltrap(trap); 468. } 469. break; 470. #endif 471. case MGTRP: /* A magic trap. */ 472. if (!rn2(30)) { 473. You("are caught in a magical explosion!"); 474. losehp(rnd(10), "magical explosion"); 475. #ifdef SPELLS 476. Your("body absorbs some of the magical energy!"); 477. u.uen = (u.uenmax += 2); 478. #endif 479. deltrap(trap); 480. if(Invisible) newsym(u.ux,u.uy); 481. } else domagictrap(); 482. break; 483. case SQBRD: /* Stepped on a squeaky board. */ 484. if (Levitation 485. #ifdef POLYSELF 486. || is_flyer(uasmon) 487. #endif 488. ) { 489. if (Hallucination) You("notice a crease in the linoleum."); 490. else You("notice a loose board below you."); 491. } else { 492. pline("A board underfoot gives off a loud squeak!"); 493. wake_nearby(); 494. } 495. break; 496. case WEB: /* Our luckless player has stumbled into a web. */ 497. 498. pline("You've %s into a spider web!", 499. Levitation ? "floated" : 500. #ifdef POLYSELF 501. is_flyer(uasmon) ? "flown" : 502. #endif 503. "stumbled"); 504. u.utraptype = TT_WEB; 505. 506. /* Time stuck in the web depends on your strength. */ 507. 508. if (ACURR(A_STR) == 3) u.utrap = rn1(6,6); 509. else if (ACURR(A_STR) < 6) u.utrap = rn1(6,4); 510. else if (ACURR(A_STR) < 9) u.utrap = rn1(4,4); 511. else if (ACURR(A_STR) < 12) u.utrap = rn1(4,2); 512. else if (ACURR(A_STR) < 15) u.utrap = rn1(2,2); 513. else if (ACURR(A_STR) < 18) u.utrap = rnd(2); 514. else if (ACURR(A_STR) < 69) u.utrap = 1; 515. else { 516. u.utrap = 0; 517. You("tear through the web!"); 518. deltrap(trap); 519. if(Invisible) newsym(u.ux,u.uy); 520. } 521. break; 522. 523. case LANDMINE: { 524. # ifndef LINT 525. register struct monst *mtmp = fmon; 526. # endif /* LINT */ 527. 528. if (Levitation 529. #ifdef POLYSELF 530. || is_flyer(uasmon) 531. #endif 532. ) { 533. You("see a trigger in a pile of soil below you!"); 534. if (rn2(3)) break; 535. pline("KAABLAMM!!! The air currents set it off!"); 536. } else { 537. #ifdef POLYSELF 538. pline("KAABLAMM!!! You %s a land mine!", 539. nolimbs(uasmon) ? "encountered" : "stepped on"); 540. #else 541. pline("KAABLAMM!!! You stepped on a land mine!"); 542. #endif 543. set_wounded_legs(LEFT_SIDE, 40 + rnd(35)); 544. set_wounded_legs(RIGHT_SIDE, 40 + rnd(35)); 545. } 546. losehp(rnd(16), "land mine"); 547. /* wake everything on the level */ 548. while(mtmp) { 549. if(mtmp->msleep) mtmp->msleep = 0; 550. mtmp = mtmp->nmon; 551. } 552. deltrap(t_at(u.ux, u.uy)); /* mines only explode once */ 553. if(Invisible) newsym(u.ux,u.uy); 554. } 555. break; 556. default: 557. impossible("You hit a trap of type %u", trap->ttyp); 558. } 559. } 560. } 561. 562. #ifdef WALKIES 563. static boolean 564. teleport_pet(mtmp) 565. register struct monst *mtmp; 566. { 567. register struct obj *otmp; 568. 569. if(mtmp->mleashed) { 570. otmp = get_mleash(mtmp); 571. if(!otmp) 572. impossible("%s is leashed, without a leash.", Monnam(mtmp)); 573. if(otmp->cursed) { 574. # ifdef SOUNDS 575. yelp(mtmp); 576. # endif 577. return FALSE; 578. } else { 579. Your("leash goes slack."); 580. m_unleash(mtmp); 581. return TRUE; 582. } 583. } 584. return TRUE; 585. } 586. #endif 587. 588. int 589. mintrap(mtmp) 590. register struct monst *mtmp; 591. { 592. register struct trap *trap = t_at(mtmp->mx, mtmp->my); 593. register int newlev, wasintrap = mtmp->mtrapped; 594. register boolean trapkilled = FALSE, tdoor = FALSE; 595. struct obj *otmp; 596. 597. if(!trap) { 598. mtmp->mtrapped = 0; /* perhaps teleported? */ 599. } else if(wasintrap) { 600. if(!rn2(40)) mtmp->mtrapped = 0; 601. } else { 602. register int tt = trap->ttyp; 603. 604. /* A bug fix for dumb messages by ab@unido. 605. */ 606. int in_sight = cansee(mtmp->mx,mtmp->my) 607. && (!mtmp->minvis || See_invisible); 608. 609. if(mtmp->mtrapseen & (1 << tt)) { 610. /* he has been in such a trap - perhaps he escapes */ 611. if(rn2(4)) return(0); 612. } 613. mtmp->mtrapseen |= (1 << tt); 614. switch (tt) { 615. case BEAR_TRAP: 616. if(bigmonst(mtmp->data)) { 617. if(in_sight) 618. pline("%s is caught in a bear trap!", 619. Monnam(mtmp)); 620. else 621. if(mtmp->data == &mons[PM_OWLBEAR] 622. && flags.soundok) 623. You("hear the roaring of an angry bear!"); 624. mtmp->mtrapped = 1; 625. } 626. break; 627. #ifdef POLYSELF 628. case POLY_TRAP: 629. if(!resist(mtmp, WAND_SYM, 0, NOTELL)) 630. (void) newcham(mtmp, (struct permonst *)0); 631. break; 632. #endif 633. case RUST_TRAP: 634. if(in_sight) 635. pline("A gush of water hits %s!", mon_nam(mtmp)); 636. #ifdef GOLEMS 637. if (mtmp->data == &mons[PM_IRON_GOLEM]) { 638. if (in_sight) pline("%s falls to pieces!", 639. Monnam(mtmp)); 640. else if(mtmp->mtame) 641. pline("May %s rust in peace.", 642. mon_nam(mtmp)); 643. mondied(mtmp); 644. trapkilled = TRUE; 645. } 646. #endif /* GOLEMS */ 647. break; 648. case PIT: 649. case SPIKED_PIT: 650. /* there should be a mtmp/data -> floating */ 651. if(!is_flyer(mtmp->data) /* ab */ 652. && mtmp->data != &mons[PM_WUMPUS] /* 3. */) { 653. if (!passes_walls(mtmp->data)) 654. mtmp->mtrapped = 1; 655. if(in_sight) 656. pline("%s falls into a pit!", Monnam(mtmp)); 657. if(thitm(0, mtmp, (struct obj *)0, 658. rnd((tt==PIT) ? 6 : 10))) 659. trapkilled = TRUE; 660. } 661. break; 662. case SLP_GAS_TRAP: 663. if(!resists_sleep(mtmp->data) && 664. !mtmp->msleep && !mtmp->mfroz) { 665. mtmp->msleep = 1; 666. if(in_sight) 667. pline("%s suddenly falls asleep!", 668. Monnam(mtmp)); 669. } 670. break; 671. case TELEP_TRAP: 672. #ifdef WALKIES 673. if(teleport_pet(mtmp)) { 674. #endif 675. rloc(mtmp); 676. if(in_sight && !cansee(mtmp->mx,mtmp->my)) 677. pline("%s suddenly disappears!", 678. Monnam(mtmp)); 679. #ifdef WALKIES 680. } 681. #endif 682. break; 683. case ARROW_TRAP: 684. otmp = mksobj(ARROW, FALSE); 685. otmp->quan = 1; 686. otmp->owt = weight(otmp); 687. if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 688. break; 689. case DART_TRAP: 690. otmp = mksobj(DART, FALSE); 691. otmp->quan = 1; 692. otmp->owt = weight(otmp); 693. if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 694. break; 695. case TRAPDOOR: 696. if(is_maze_lev 697. #ifdef STRONGHOLD 698. && (dlevel > stronghold_level && dlevel < MAXLEVEL) 699. #endif 700. ) { 701. otmp = mksobj(ROCK, FALSE); 702. otmp->quan = 1; 703. otmp->owt = weight(otmp); 704. if(thitm(0, mtmp, otmp, d(2, 10))) 705. trapkilled = TRUE; 706. break; 707. } 708. tdoor = TRUE; 709. /* Fall through */ 710. case LEVEL_TELEP: 711. if(!is_flyer(mtmp->data) 712. #ifdef WORM 713. && !mtmp->wormno 714. /* long worms cannot be allowed to change levels */ 715. #endif 716. ){ 717. #ifdef WALKIES 718. if(teleport_pet(mtmp)) { 719. #endif 720. if(tdoor) 721. fall_down(mtmp, dlevel+1); 722. else { 723. newlev = rnd(3); 724. if(!rn2(2)) newlev = -(newlev); 725. newlev = dlevel + newlev; 726. if(newlev > MAXLEVEL) { 727. if(dlevel != MAXLEVEL) 728. newlev = MAXLEVEL; 729. else newlev = MAXLEVEL - rnd(3); 730. } 731. if(newlev < 1) { 732. if(dlevel != 1) newlev = 1; 733. else newlev = 1 + rnd(3); 734. } 735. fall_down(mtmp, newlev); 736. } 737. if(in_sight) 738. pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp)); 739. return(2); /* no longer on this level */ 740. #ifdef WALKIES 741. } 742. #endif 743. } 744. break; 745. case MONST_TRAP: 746. case STATUE_TRAP: 747. break; 748. case MGTRP: 749. /* A magic trap. Monsters immune. */ 750. break; 751. case SQBRD: { 752. register struct monst *ztmp = fmon; 753. 754. if(is_flyer(mtmp->data)) break; 755. /* Stepped on a squeaky board. */ 756. if (in_sight) 757. pline("%s steps on a squeaky board.", Monnam(mtmp)); 758. else 759. You("hear a distant squeak."); 760. /* Wake up nearby monsters. */ 761. while(ztmp) { 762. if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40) 763. if(ztmp->msleep) ztmp->msleep = 0; 764. ztmp = ztmp->nmon; 765. } 766. break; 767. } 768. case WEB: 769. /* Monster in a web. */ 770. /* in_sight check and confused bear by Eric Backus */ 771. if(mtmp->data->mlet != S_SPIDER) { 772. if(in_sight) 773. pline("%s is caught in a web!", Monnam(mtmp)); 774. else 775. if(mtmp->data == &mons[PM_OWLBEAR]) 776. You("hear the roaring of a confused bear!"); 777. mtmp->mtrapped = 1; 778. } 779. break; 780. #ifdef SPELLS 781. case ANTI_MAGIC: break; 782. #endif 783. case LANDMINE: { 784. register struct monst *mntmp = fmon; 785. 786. if(rn2(3)) 787. break; /* monsters usually don't set it off */ 788. if(in_sight) 789. pline("KAABLAMM!!! %s steps on a land mine!", 790. Monnam(mtmp)); 791. else if (flags.soundok) 792. pline("Kaablamm! You hear an explosion in the distance!"); 793. deltrap(t_at(mtmp->mx, mtmp->my)); 794. if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 795. trapkilled = TRUE; 796. /* wake everything on the level */ 797. while(mntmp) { 798. if(mntmp->msleep) 799. mntmp->msleep = 0; 800. mntmp = mntmp->nmon; 801. } 802. break; 803. } 804. default: 805. impossible("Some monster encountered a strange trap of type %d.",tt); 806. } 807. } 808. if(trapkilled) return 2; 809. else return mtmp->mtrapped; 810. } 811. 812. void 813. selftouch(arg) 814. char *arg; 815. { 816. if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE) 817. #ifdef POLYSELF 818. && !resists_ston(uasmon) 819. #endif 820. ){ 821. pline("%s touch the cockatrice corpse.", arg); 822. You("turn to stone..."); 823. killer = "cockatrice corpse accident"; 824. done("stoned"); 825. } 826. } 827. 828. void 829. float_up() { 830. if(u.utrap) { 831. if(u.utraptype == TT_PIT) { 832. u.utrap = 0; 833. You("float up, out of the pit!"); 834. } else { 835. You("float up, only your %s is still stuck.", 836. body_part(LEG)); 837. } 838. } else 839. if (Hallucination) 840. pline("Oh wow! You're floating in the air!"); 841. else 842. You("start to float in the air!"); 843. } 844. 845. int 846. float_down() { 847. register struct trap *trap; 848. 849. if(Levitation) return(0); /* maybe another ring/potion/boots */ 850. 851. /* check for falling into pool - added by GAN 10/20/86 */ 852. if(is_pool(u.ux,u.uy) && !(Wwalking 853. #ifdef POLYSELF 854. || is_flyer(uasmon) 855. #endif 856. )) 857. drown(); 858. 859. You("float gently to the ground."); 860. if(trap = t_at(u.ux,u.uy)) 861. switch(trap->ttyp) { 862. case MONST_TRAP: 863. case STATUE_TRAP: 864. break; 865. case TRAPDOOR: 866. if(is_maze_lev 867. #ifdef STRONGHOLD 868. && (dlevel >= stronghold_level || dlevel < MAXLEVEL) 869. #endif 870. || u.ustuck) break; 871. /* fall into next case */ 872. default: 873. dotrap(trap); 874. } 875. if(!flags.nopick && (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask)) 876. pickup(1); 877. return 0; 878. } 879. 880. 881. void 882. tele() { 883. coord cc; 884. register int nux,nuy; 885. 886. #ifdef STRONGHOLD 887. /* Disable teleportation in stronghold && Vlad's Tower */ 888. if(dlevel == stronghold_level || 889. # ifdef ENDGAME 890. dlevel == ENDLEVEL || 891. # endif 892. (dlevel >= tower_level && dlevel <= tower_level + 2)) { 893. # ifdef WIZARD 894. if (!wizard) { 895. # endif 896. pline("A mysterious force prevents you from teleporting!"); 897. return; 898. # ifdef WIZARD 899. } 900. # endif 901. } 902. #endif /* STRONGHOLD /**/ 903. if((u.uhave_amulet || dlevel == wiz_level) && !rn2(3)) { 904. You("feel disoriented for a moment."); 905. return; 906. } 907. if(Teleport_control) { 908. if (unconscious()) 909. pline("Being unconscious, you cannot control your teleport."); 910. else { 911. pline("To what position do you want to be teleported?"); 912. getpos(&cc, 1, "the desired position"); /* 1: force valid */ 913. /* possible extensions: introduce a small error if 914. magic power is low; allow transfer to solid rock */ 915. if(teleok(cc.x, cc.y)){ 916. teleds(cc.x, cc.y); 917. return; 918. } 919. pline("Sorry..."); 920. } 921. } 922. do { 923. nux = rnd(COLNO-1); 924. nuy = rn2(ROWNO); 925. } while(!teleok(nux, nuy)); 926. teleds(nux, nuy); 927. } 928. 929. void 930. teleds(nux, nuy) 931. register int nux,nuy; 932. { 933. if(Punished) unplacebc(); 934. unsee(); 935. u.utrap = 0; 936. u.ustuck = 0; 937. u.ux = nux; 938. u.uy = nuy; 939. #ifdef POLYSELF 940. if (hides_under(uasmon)) 941. u.uundetected = (levl[nux][nuy].omask || levl[nux][nuy].gmask); 942. else 943. u.uundetected = 0; 944. if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC; 945. #endif 946. setsee(); 947. if(Punished) placebc(1); 948. if(u.uswallow){ 949. u.uswldtim = u.uswallow = 0; 950. docrt(); 951. } 952. nomul(0); 953. spoteffects(); 954. } 955. 956. int 957. dotele() 958. { 959. struct trap *trap; 960. #ifdef SPELLS 961. boolean castit = FALSE; 962. register int sp_no; 963. #endif 964. 965. trap = t_at(u.ux, u.uy); 966. if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP || trap->once)) 967. trap = 0; 968. 969. if (trap) 970. You("jump onto the teleportation trap..."); 971. else if(!Teleportation || 972. (u.ulevel < (pl_character[0] == 'W' ? 8 : 12) 973. #ifdef POLYSELF 974. && !can_teleport(uasmon) 975. #endif 976. ) 977. ) { 978. #ifdef SPELLS 979. /* Try to use teleport away spell. */ 980. castit = objects[SPE_TELEPORT_AWAY].oc_name_known; 981. if (castit) { 982. for (sp_no = 0; sp_no < MAXSPELL && 983. spl_book[sp_no].sp_id != NO_SPELL && 984. spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++); 985. 986. if (sp_no == MAXSPELL || 987. spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY) 988. castit = FALSE; 989. } 990. #endif 991. #ifdef WIZARD 992. if (!wizard) { 993. #endif 994. #ifdef SPELLS 995. if (!castit) { 996. if (!Teleportation) 997. You("don't know that spell."); 998. else 999. #endif 1000. You("are not able to teleport at will."); 1001. return(0); 1002. #ifdef SPELLS 1003. } 1004. #endif 1005. #ifdef WIZARD 1006. } 1007. #endif 1008. } 1009. 1010. if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) { 1011. You("lack the strength for a teleport spell."); 1012. #ifdef WIZARD 1013. if(!wizard) 1014. #endif 1015. return(1); 1016. } 1017. 1018. #ifdef SPELLS 1019. if (castit) 1020. # ifdef WIZARD 1021. if (!spelleffects(++sp_no, TRUE) && !wizard) return(0); 1022. # else 1023. return spelleffects(++sp_no, TRUE); 1024. # endif 1025. #endif 1026. 1027. #ifdef WALKIES 1028. if(next_to_u()) { 1029. #endif 1030. tele(); 1031. #ifdef WALKIES 1032. (void) next_to_u(); 1033. } else { 1034. You("shudder for a moment."); 1035. return(0); 1036. } 1037. #endif 1038. if (!trap) morehungry(100); 1039. return(1); 1040. } 1041. 1042. void 1043. placebc(attach) 1044. int attach; 1045. { 1046. if(!uchain || !uball){ 1047. impossible("Where are your chain and ball??"); 1048. return; 1049. } 1050. uball->ox = uchain->ox = u.ux; 1051. uball->oy = uchain->oy = u.uy; 1052. levl[u.ux][u.uy].omask = 1; 1053. if(attach){ 1054. uchain->nobj = fobj; 1055. fobj = uchain; 1056. if(!carried(uball)){ 1057. uball->nobj = fobj; 1058. fobj = uball; 1059. } 1060. } 1061. } 1062. 1063. void 1064. unplacebc(){ 1065. if(!carried(uball)){ 1066. freeobj(uball); 1067. unpobj(uball); 1068. } 1069. freeobj(uchain); 1070. unpobj(uchain); 1071. } 1072. 1073. void 1074. level_tele() { 1075. register int newlevel; 1076. #ifdef WALKIES 1077. register boolean pet_by_u = next_to_u(); 1078. #endif 1079. 1080. if(u.uhave_amulet 1081. #ifdef ENDGAME 1082. || dlevel == ENDLEVEL 1083. #endif 1084. ) { 1085. You("feel very disoriented for a moment."); 1086. return; 1087. } 1088. if(Teleport_control 1089. #ifdef WIZARD 1090. || wizard 1091. #endif 1092. ) { 1093. char buf[BUFSZ]; 1094. 1095. do { 1096. pline("To what level do you want to teleport? [type a number] "); 1097. getlin(buf); 1098. } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1]))); 1099. newlevel = atoi(buf); 1100. } else { 1101. newlevel = rn2(5) | !Fire_resistance ? rnd(dlevel + 3) : 1102. #ifdef STRONGHOLD 1103. stronghold_level + 1; 1104. #else 1105. HELLLEVEL; 1106. #endif 1107. if(dlevel == newlevel) 1108. if(is_maze_lev) newlevel--; else newlevel++; 1109. } 1110. if(newlevel < 0) { 1111. #ifdef WALKIES 1112. if(pet_by_u) { 1113. #endif 1114. if(newlevel <= -10) { 1115. You("arrive in heaven."); 1116. pline("\"You are here a bit early, but we'll let you in.\""); 1117. killer = "visit to heaven"; 1118. done("died"); 1119. } else if (newlevel == -9) { 1120. You("feel deliriously happy. "); 1121. pline("(In fact, you're on Cloud 9!) "); 1122. more(); 1123. } else 1124. #ifndef STRONGHOLD 1125. newlevel = 0; 1126. #else 1127. newlevel = 1; 1128. #endif 1129. You("are now high above the clouds..."); 1130. if(Levitation) { 1131. You("float gently down to earth."); 1132. #ifndef STRONGHOLD 1133. done("escaped"); 1134. #endif 1135. } 1136. #ifdef POLYSELF 1137. if(is_flyer(uasmon)) { 1138. You("fly down to earth."); 1139. # ifndef STRONGHOLD 1140. done("escaped"); 1141. # endif 1142. } 1143. #endif 1144. pline("Unfortunately, you don't know how to fly."); 1145. You("plummet a few thousand feet to your death."); 1146. dlevel = 0; 1147. killer = "long fall"; 1148. done("died"); 1149. #ifdef WALKIES 1150. } else { 1151. You("shudder for a moment..."); 1152. return; 1153. } 1154. #endif 1155. } 1156. /* calls done("escaped") if newlevel==0 */ 1157. #ifdef WALKIES 1158. if(!pet_by_u) 1159. You("shudder for a moment..."); 1160. else 1161. #endif 1162. goto_level(newlevel, FALSE); 1163. } 1164. 1165. void 1166. domagictrap() { 1167. register int fate = rnd(20); 1168. 1169. /* What happened to the poor sucker? */ 1170. 1171. if (fate < 10) { 1172. 1173. /* Most of the time, it creates some monsters. */ 1174. register int cnt = rnd(4); 1175. 1176. /* below checks for blindness added by GAN 10/30/86 */ 1177. if (!Blind) { 1178. You("are momentarily blinded by a flash of light!"); 1179. make_blinded((long)rn1(5,10),FALSE); 1180. } else 1181. You("hear a deafening roar!"); 1182. while(cnt--) 1183. (void) makemon((struct permonst *) 0, u.ux, u.uy); 1184. } 1185. else 1186. switch (fate) { 1187. 1188. case 10: 1189. case 11: 1190. /* sometimes nothing happens */ 1191. break; 1192. case 12: 1193. /* a flash of fire */ 1194. { 1195. register int num; 1196. 1197. /* changed to be in conformance with 1198. * SCR_FIRE by GAN 11/02/86 1199. */ 1200. 1201. pline("A tower of flame bursts from the floor!"); 1202. if(Fire_resistance) { 1203. shieldeff(u.ux, u.uy); 1204. You("are uninjured."); 1205. break; 1206. } else { 1207. num = rnd(6); 1208. u.uhpmax -= num; 1209. losehp(num,"a burst of flame"); 1210. break; 1211. } 1212. } 1213. 1214. /* odd feelings */ 1215. case 13: pline("A shiver runs up and down your spine!"); 1216. break; 1217. case 14: You("hear distant howling."); 1218. break; 1219. case 15: You("suddenly yearn for your distant homeland."); 1220. break; 1221. case 16: Your("pack shakes violently!"); 1222. break; 1223. case 17: You("smell charred flesh."); 1224. break; 1225. 1226. /* very occasionally something nice happens. */ 1227. 1228. case 19: 1229. /* tame nearby monsters */ 1230. { register int i,j; 1231. register boolean confused = (Confusion != 0); 1232. register int bd = confused ? 5 : 1; 1233. 1234. /* below pline added by GAN 10/30/86 */ 1235. adjattrib(A_CHA,1,FALSE); 1236. for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 1237. if(levl[u.ux+i][u.uy+j].mmask) 1238. (void) tamedog(m_at(u.ux+i, u.uy+j), (struct obj *)0); 1239. break; 1240. } 1241. 1242. case 20: 1243. /* uncurse stuff */ 1244. { register struct obj *obj; 1245. register boolean confused = (Confusion != 0); 1246. 1247. /* below plines added by GAN 10/30/86 */ 1248. if (confused) 1249. if (Hallucination) 1250. You("feel the power of the Force against you!"); 1251. else 1252. You("feel like you need some help."); 1253. else 1254. if (Hallucination) 1255. You("feel in touch with the Universal Oneness."); 1256. else 1257. You("feel like someone is helping you."); 1258. for(obj = invent; obj ; obj = obj->nobj) 1259. if(obj->owornmask) 1260. if(confused) 1261. curse(obj); 1262. else 1263. obj->cursed = 0; 1264. if(Punished && !confused) 1265. unpunish(); 1266. break; 1267. } 1268. default: break; 1269. } 1270. } 1271. 1272. void 1273. drown() { 1274. register struct obj *obj; 1275. 1276. /* Scrolls and potions get affected by the water */ 1277. for(obj = invent; obj; obj = obj->nobj) { 1278. if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck) 1279. obj->otyp = SCR_BLANK_PAPER; 1280. if(obj->olet == POTION_SYM && rn2(12) > u.uluck) { 1281. if (obj->spe == -1) { 1282. obj->otyp = POT_WATER; 1283. obj->blessed = obj->cursed = 0; 1284. obj->spe = 0; 1285. } else obj->spe--; 1286. } 1287. } 1288. 1289. #ifdef POLYSELF 1290. if(u.usym == S_GREMLIN && rn2(3)) { 1291. struct monst *mtmp; 1292. if(mtmp = cloneu()) { 1293. mtmp->mhpmax = (u.mhmax /= 2); 1294. You("multiply."); 1295. } 1296. } 1297. 1298. if(is_swimmer(uasmon)) return; 1299. #endif 1300. 1301. You("fell into %s!", 1302. levl[u.ux][u.uy].typ == POOL ? "a pool" : "the moat"); 1303. You("can't swim!"); 1304. if( 1305. #ifdef WIZARD 1306. wizard || 1307. #endif 1308. rn2(3) < u.uluck+2) { 1309. You("attempt a teleport spell."); /* utcsri!carroll */ 1310. (void) dotele(); 1311. if(!is_pool(u.ux,u.uy)) return; 1312. } 1313. You("drown."); 1314. killer = levl[u.ux][u.uy].typ == POOL ? "pool of water" : "moat"; 1315. done("drowned"); 1316. } 1317. 1318. #ifdef SPELLS 1319. void 1320. drain_en(n) 1321. register int n; 1322. { 1323. if (!u.uenmax) return; 1324. You("feel your magical energy drain away!"); 1325. u.uen -= n; 1326. if(u.uen < 0) { 1327. u.uenmax += u.uen; 1328. if(u.uenmax < 0) u.uenmax = 0; 1329. u.uen = 0; 1330. } 1331. flags.botl = 1; 1332. } 1333. #endif 1334. 1335. int 1336. dountrap() { /* disarm a trapped object */ 1337. register struct obj *otmp; 1338. register boolean confused = (Confusion > 0); 1339. register int x,y; 1340. int ch; 1341. struct trap *ttmp; 1342. 1343. #ifdef POLYSELF 1344. if(nohands(uasmon)) { 1345. pline("And just how do you expect to do that?"); 1346. return(0); 1347. } 1348. #endif 1349. if(!getdir(TRUE)) return(0); 1350. x = u.ux + u.dx; 1351. y = u.uy + u.dy; 1352. 1353. if(!u.dx && !u.dy) { 1354. if(levl[x][y].omask) 1355. for(otmp = fobj; otmp; otmp = otmp->nobj) 1356. if((otmp->ox == x) && (otmp->oy == y)) 1357. if(Is_box(otmp)) { 1358. pline("There is %s here, check for traps? ", 1359. doname(otmp)); 1360. 1361. switch (ynq()) { 1362. case 'q': return(0); 1363. case 'n': continue; 1364. } 1365. 1366. if((otmp->otrapped && !confused && rn2(44-dlevel*2) < 10) 1367. || confused && !rn2(3)) { 1368. You("find a trap on the %s! Disarm it? ", 1369. xname(otmp)); 1370. 1371. switch (ynq()) { 1372. case 'q': return(1); 1373. case 'n': continue; 1374. } 1375. 1376. if(otmp->otrapped) { 1377. ch = 15 + 1378. (pl_character[0] == 'R') ? u.ulevel*3 : 1379. u.ulevel;
The above statement contains a bug. It is meant to assign 15 + u.ulevel*3 to ch if the player is a Rogue, and 15 + u.ulevel otherwise. In fact, the conditional is always either 15 or 16, both of which are interpreted as true, and the statement assigns u.ulevel*3 to ch regardless of the role. Thus rogues do not in fact have a better chance of disarming a chest trap than other roles.
The logic is changed in 3.1.0 and rogues from then on have an increased chance of disarming a chest trap.
1380. if(confused || Fumbling || rnd(75+dlevel/2) > ch) { 1381. You("set it off!"); 1382. chest_trap(otmp, FINGER); 1383. } else { 1384. You("disarm it!"); 1385. otmp->otrapped = 0; 1386. } 1387. } else pline("That %s was not trapped.", 1388. doname(otmp)); 1389. return(1); 1390. } else { 1391. You("find no traps on the %s.", 1392. xname(otmp)); 1393. return(1); 1394. } 1395. } 1396. if ((ttmp = t_at(x,y)) && ttmp->tseen) 1397. You("cannot disable this trap."); 1398. else 1399. You("know of no traps here."); 1400. return(0); 1401. } 1402. 1403. if (!IS_DOOR(levl[x][y].typ)) { 1404. if ((ttmp = t_at(x,y)) && ttmp->tseen) 1405. You("cannot disable that trap."); 1406. else 1407. You("know of no traps there."); 1408. return(0); 1409. } 1410. 1411. switch (levl[x][y].doormask) { 1412. case D_NODOOR: 1413. You("%s no door there.", Blind ? "feel" : "see"); 1414. return(0); 1415. case D_ISOPEN: 1416. pline("This door is safely open."); 1417. return(0); 1418. case D_BROKEN: 1419. pline("This door is broken."); 1420. return(0); 1421. } 1422. 1423. if ((levl[x][y].doormask & D_TRAPPED && !confused && 1424. rn2(44-dlevel*2) < 10) 1425. || confused && !rn2(3)) { 1426. You("find a trap on the door! Disarm it? "); 1427. if (ynq() != 'y') return(1); 1428. if (levl[x][y].doormask & D_TRAPPED) { 1429. ch = 15 + 1430. (pl_character[0] == 'R') ? u.ulevel*3 : 1431. u.ulevel;
The above statement contains the same bug as line 1377. This one, however, was left unfixed in 3.1.0. It is fixed in 3.2.0.
1432. if(confused || Fumbling || rnd(75+dlevel/2) > ch) { 1433. You("set it off!"); 1434. b_trapped("door"); 1435. } else { 1436. You("disarm it!"); 1437. levl[x][y].doormask &= ~D_TRAPPED; 1438. } 1439. } else pline("This door was not trapped."); 1440. return(1); 1441. } else { 1442. You("find no traps on the door."); 1443. return(1); 1444. } 1445. } 1446. 1447. /* this is only called when the player is doing something to the chest 1448. * -- i.e., the player and the chest are in the same position */ 1449. void 1450. chest_trap(obj, bodypart) 1451. register struct obj *obj; 1452. register int bodypart; 1453. { 1454. register struct obj *otmp,*otmp2; 1455. char buf[80]; 1456. 1457. if(rn2(13+u.uluck) > 7) return; 1458. 1459. otmp = obj; 1460. switch(rn2(13-u.uluck)) { /* which trap? */ 1461. case 23: 1462. case 22: 1463. case 21: 1464. pline("The %s explodes!", xname(obj)); 1465. Sprintf(buf, "exploding %s", xname(obj)); 1466. 1467. delete_contents(obj); 1468. for(otmp = fobj; otmp; otmp = otmp2) { 1469. otmp2 = otmp->nobj; 1470. if((otmp->ox == u.ux) && (otmp->oy == u.uy)) 1471. delobj(otmp); 1472. } 1473. 1474. losehp(d(6,6), buf); 1475. wake_nearby(); 1476. return; 1477. case 20: 1478. case 19: 1479. case 18: 1480. case 17: 1481. pline("A cloud of noxious gas billows from the %s.", 1482. xname(obj)); 1483. poisoned("gas cloud", A_STR, "cloud of poison gas"); 1484. break; 1485. case 16: 1486. case 15: 1487. case 14: 1488. case 13: 1489. pline("A tower of flame erupts from the %s", 1490. xname(obj)); 1491. if(Fire_resistance) { 1492. shieldeff(u.ux, u.uy); 1493. You("don't seem to be affected."); 1494. } else losehp(d(4, 6), "tower of flame"); 1495. destroy_item(SCROLL_SYM, AD_FIRE); 1496. #ifdef SPELLS 1497. destroy_item(SPBOOK_SYM, AD_FIRE); 1498. #endif 1499. destroy_item(POTION_SYM, AD_FIRE); 1500. break; 1501. case 12: 1502. case 10: 1503. case 9: 1504. You("are jolted by a surge of electricity!"); 1505. if(Shock_resistance) { 1506. shieldeff(u.ux, u.uy); 1507. You("don't seem to be affected."); 1508. } else losehp(d(4, 4), "electric shock"); 1509. destroy_item(RING_SYM, AD_ELEC); 1510. destroy_item(WAND_SYM, AD_ELEC); 1511. break; 1512. case 8: 1513. case 7: 1514. case 6: 1515. pline("Suddenly you are frozen in place!"); 1516. nomovemsg = "You can move again."; 1517. multi = -d(5, 6); 1518. break; 1519. case 5: 1520. case 4: 1521. case 3: 1522. pline("A cloud of %s gas billows from the %s", 1523. hcolor(), xname(obj)); 1524. if(!Stunned) 1525. if (Hallucination) 1526. pline("What a groovy feeling!"); 1527. else 1528. You("stagger and your vision blurs..."); 1529. make_stunned(HStun + rn1(7, 16),FALSE); 1530. make_hallucinated(Hallucination + rn1(5, 16),FALSE); 1531. break; 1532. default: 1533. You("feel a needle prick your %s.",body_part(bodypart)); 1534. poisoned("needle", A_CON, "a poisoned needle"); 1535. break; 1536. } 1537. otmp->otrapped = 0; /* these traps are one-shot things */ 1538. } 1539. 1540. void 1541. wake_nearby() { /* Wake up nearby monsters. */ 1542. register struct monst *mtmp; 1543. 1544. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1545. if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) { 1546. if(mtmp->msleep) mtmp->msleep = 0; 1547. if(mtmp->mtame) EDOG(mtmp)->whistletime = moves; 1548. } 1549. } 1550. } 1551. 1552. struct trap * 1553. t_at(x,y) 1554. register int x, y; 1555. { 1556. register struct trap *trap = ftrap; 1557. while(trap) { 1558. if(trap->tx == x && trap->ty == y) return(trap); 1559. trap = trap->ntrap; 1560. } 1561. return((struct trap *)0); 1562. } 1563. 1564. void 1565. deltrap(trap) 1566. register struct trap *trap; 1567. { 1568. register struct trap *ttmp; 1569. 1570. if(trap == ftrap) 1571. ftrap = ftrap->ntrap; 1572. else { 1573. for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 1574. ttmp->ntrap = trap->ntrap; 1575. } 1576. free((genericptr_t) trap); 1577. } 1578. 1579. void 1580. b_trapped(item) /* used for doors. can be used */ 1581. register char *item; /* for anything else that opens */ 1582. { 1583. register int dmg = rn2(15) + rnd((int)u.ulevel); 1584. 1585. pline("KABOOM!! The %s was booby-trapped!", item); 1586. make_stunned(HStun + dmg, TRUE); 1587. losehp(dmg, "explosion"); 1588. } 1589. 1590. /* Monster is hit by trap. */ 1591. /* Note: doesn't work if both obj and d_override are null */ 1592. static boolean 1593. thitm(tlev, mon, obj, d_override) 1594. register int tlev; 1595. register struct monst *mon; 1596. register struct obj *obj; 1597. int d_override; 1598. { 1599. register int strike; 1600. register boolean trapkilled = FALSE; 1601. 1602. if (d_override) strike = 1; 1603. else if (obj) strike = (mon->data->ac + tlev + obj->spe <= rnd(20)); 1604. else strike = (mon->data->ac + tlev <= rnd(20)); 1605. 1606. /* Actually more accurate than thitu, which doesn't take 1607. * obj->spe into account. 1608. */ 1609. if(!strike) { 1610. if (cansee(mon->mx, mon->my)) 1611. pline("%s is almost hit by %s!", Monnam(mon), 1612. doname(obj)); 1613. } else { 1614. int dam = 1; 1615. 1616. if (obj && cansee(mon->mx, mon->my)) 1617. pline("%s is hit by %s!", Monnam(mon), doname(obj)); 1618. if (d_override) dam = d_override; 1619. else if (obj) { 1620. dam = dmgval(obj, mon->data); 1621. if (dam < 1) dam = 1; 1622. } 1623. if ((mon->mhp -= dam) <= 0) { 1624. if (cansee(mon->mx, mon->my)) 1625. pline("%s is killed!", Monnam(mon)); 1626. else if (mon->mtame) 1627. You("have a sad feeling for a moment, then it passes."); 1628. mondied(mon); 1629. trapkilled = TRUE; 1630. } 1631. } 1632. if (obj && (!strike || d_override)) { 1633. obj->ox = mon->mx; 1634. obj->oy = mon->my; 1635. obj->nobj = fobj; 1636. fobj = obj; 1637. stackobj(fobj); 1638. levl[obj->ox][obj->oy].omask = 1; 1639. } else if (obj) free ((genericptr_t)obj); 1640. 1641. return trapkilled; 1642. } 1643. 1644. boolean 1645. unconscious() 1646. { 1647. return (multi < 0 && (!nomovemsg || 1648. !strncmp(nomovemsg,"You wake", 8) || 1649. !strncmp(nomovemsg,"You awake", 9) || 1650. !strncmp(nomovemsg,"You regain con", 15) || 1651. !strncmp(nomovemsg,"You are consci", 15))); 1652. }