Source:NetHack 3.1.0/lock.c
Jump to navigation
Jump to search
Below is the full text to lock.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/lock.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: @(#)lock.c 3.1 92/09/02 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. #define CONTAINER_BITS 0 /* box options not [yet?] implemented */ 8. 9. STATIC_PTR int NDECL(picklock); 10. STATIC_PTR int NDECL(forcelock); 11. 12. STATIC_VAR struct xlock_s { 13. int door_or_box, picktyp; 14. struct rm *door; 15. struct obj *box; 16. int chance, usedtime; 17. } NEARDATA xlock; 18. 19. #ifdef OVLB 20. 21. static boolean FDECL(obstructed,(int,int)); 22. static void FDECL(chest_shatter_msg, (struct obj *)); 23. 24. boolean 25. picking_at(x, y) 26. int x, y; 27. { 28. return((occupation == picklock) && 29. xlock.door_or_box && (xlock.door == &levl[x][y])); 30. } 31. 32. STATIC_PTR 33. int 34. picklock() /* try to open/close a lock */ 35. { 36. 37. if(!xlock.door_or_box) { /* box */ 38. 39. if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) { 40. return((xlock.usedtime = 0)); /* you or it moved */ 41. } 42. } else { /* door */ 43. if(xlock.door != &(levl[u.ux+u.dx][u.uy+u.dy])) { 44. return((xlock.usedtime = 0)); /* you moved */ 45. } 46. switch (xlock.door->doormask) { 47. case D_NODOOR: 48. pline("This doorway has no door."); 49. return((xlock.usedtime = 0)); 50. case D_ISOPEN: 51. pline("Picking the lock of an open door is pointless."); 52. return((xlock.usedtime = 0)); 53. case D_BROKEN: 54. pline("This door is broken."); 55. return((xlock.usedtime = 0)); 56. } 57. } 58. 59. if(xlock.usedtime++ >= 50 60. #ifdef POLYSELF 61. || nohands(uasmon) 62. #endif 63. ) { 64. You("give up your attempt to %s the lock.", 65. (xlock.door_or_box ? !(xlock.door->doormask & D_LOCKED) : 66. !xlock.box->olocked) ? "lock" : 67. ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" )); 68. 69. exercise(A_DEX, TRUE); /* even if you don't succeed */ 70. return((xlock.usedtime = 0)); 71. } 72. 73. if(rn2(100) > xlock.chance) return(1); /* still busy */ 74. 75. if(xlock.door_or_box) { 76. You("succeed in %sing the lock.", 77. !(xlock.door->doormask & D_LOCKED) ? "lock" : 78. ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" )); 79. if(xlock.door->doormask & D_TRAPPED) { 80. b_trapped("door"); 81. xlock.door->doormask = D_NODOOR; 82. unblock_point(u.ux+u.dx, u.uy+u.dy); 83. newsym(u.ux+u.dx, u.uy+u.dy); 84. } else if(xlock.door->doormask == D_LOCKED) 85. xlock.door->doormask = D_CLOSED; 86. else xlock.door->doormask = D_LOCKED; 87. } else { 88. You("succeed in %sing the lock.", 89. (!xlock.box->olocked) ? "lock" : 90. (xlock.picktyp == LOCK_PICK) ? "pick" : "open" ); 91. xlock.box->olocked = !xlock.box->olocked; 92. if(xlock.box->otrapped) 93. (void) chest_trap(xlock.box, FINGER, FALSE); 94. } 95. exercise(A_DEX, TRUE); 96. return((xlock.usedtime = 0)); 97. } 98. 99. STATIC_PTR 100. int 101. forcelock() /* try to force a locked chest */ 102. { 103. 104. register struct obj *otmp, *otmp2; 105. 106. if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) 107. return((xlock.usedtime = 0)); /* you or it moved */ 108. 109. if(xlock.usedtime++ >= 50 || !uwep 110. #ifdef POLYSELF 111. || nohands(uasmon) 112. #endif 113. ) { 114. You("give up your attempt to force the lock."); 115. if(xlock.usedtime >= 50) /* you made the effort */ 116. exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE); 117. return((xlock.usedtime = 0)); 118. } 119. 120. if(xlock.picktyp) { /* blade */ 121. 122. if(rn2(1000-(int)uwep->spe) > (992-(int)uwep->oeroded*10) && 123. !uwep->cursed) { 124. /* for a +0 weapon, probability that it survives an unsuccessful 125. * attempt to force the lock is (.992)^50 = .67 126. */ 127. pline("%sour %s broke!", 128. (uwep->quan > 1L) ? "One of y" : "Y", xname(uwep)); 129. useup(uwep); 130. You("give up your attempt to force the lock."); 131. exercise(A_DEX, TRUE); 132. return((xlock.usedtime = 0)); 133. } 134. } else /* blunt */ 135. wake_nearby(); /* due to hammering on the container */ 136. 137. if(rn2(100) > xlock.chance) return(1); /* still busy */ 138. 139. You("succeed in forcing the lock."); 140. xlock.box->olocked = 0; 141. xlock.box->obroken = 1; 142. if(!xlock.picktyp && !rn2(3)) { 143. register struct monst *shkp; 144. long loss = 0L; 145. 146. #ifdef GCC_WARN 147. shkp = (struct monst *) 0; 148. #endif 149. 150. if(*u.ushops) shkp = shop_keeper(*u.ushops); 151. 152. pline("In fact, you've totally destroyed %s.", 153. the(xname(xlock.box))); 154. 155. /* Put the contents on ground at the hero's feet. */ 156. for (otmp = xlock.box->cobj; otmp; otmp = otmp2) { 157. otmp2 = otmp->nobj; 158. if(!rn2(3) || otmp->oclass == POTION_CLASS) { 159. chest_shatter_msg(otmp); 160. if(*u.ushops && costly_spot(u.ux, u.uy)) 161. loss += stolen_value(otmp, u.ux, u.uy, 162. (boolean)shkp->mpeaceful, TRUE); 163. if (otmp->quan == 1L) { 164. obfree(otmp, (struct obj *) 0); 165. continue; 166. } 167. useup(otmp); 168. } 169. place_object(otmp,u.ux,u.uy); 170. otmp->nobj = fobj; 171. fobj = otmp; 172. stackobj(otmp); 173. } 174. xlock.box->cobj = (struct obj *) 0; /* no contents */ 175. if(*u.ushops && costly_spot(u.ux, u.uy)) 176. loss += stolen_value(otmp, u.ux, u.uy, 177. (boolean)shkp->mpeaceful, TRUE); 178. if(loss) You("owe %ld zorkmids for objects destroyed.", loss); 179. delobj(xlock.box); 180. } 181. exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE); 182. return((xlock.usedtime = 0)); 183. } 184. 185. #endif /* OVLB */ 186. #ifdef OVL0 187. 188. void 189. reset_pick() { xlock.usedtime = 0; } 190. 191. #endif /* OVL0 */ 192. #ifdef OVLB 193. 194. int 195. pick_lock(pick) /* pick a lock with a given object */ 196. register struct obj *pick; 197. { 198. register int x, y, picktyp, c, ch; 199. register struct rm *door; 200. register struct obj *otmp; 201. char qbuf[QBUFSZ]; 202. 203. #ifdef GCC_WARN 204. ch = 0; /* GCC myopia */ 205. #endif 206. picktyp = pick->otyp; 207. if(xlock.usedtime && picktyp == xlock.picktyp) { 208. 209. You("resume your attempt to %s the lock.", 210. (xlock.door_or_box ? !(xlock.door->doormask & D_LOCKED) : 211. !xlock.box->olocked) ? "lock" : 212. ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" )); 213. 214. set_occupation(picklock, 215. (picktyp == LOCK_PICK) ? "picking the lock" : 216. "opening the lock", 0); 217. return(1); 218. } 219. 220. #ifdef POLYSELF 221. if(nohands(uasmon)) { 222. You("can't hold a %s - you have no hands!", xname(pick)); 223. return(0); 224. } 225. #endif 226. if((picktyp != LOCK_PICK && 227. #ifdef TOURIST 228. picktyp != CREDIT_CARD && 229. #endif 230. picktyp != SKELETON_KEY)) { 231. impossible("picking lock with object %d?", picktyp); 232. return(0); 233. } 234. if(!getdir(NULL)) return(0); 235. 236. x = u.ux + u.dx; 237. y = u.uy + u.dy; 238. if((x == u.ux) && (y == u.uy)) { /* pick the lock on a container */ 239. c = 'n'; /* in case there are no boxes here */ 240. for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 241. if (Is_box(otmp)) { 242. const char *verb; 243. boolean it = 0; 244. #if CONTAINER_BITS 245. if (!otmp->oclosed) { /* it's open */ 246. pline("There is %s here.", doname(otmp)); 247. continue; 248. } 249. if (!otmp->lknown) verb = "work"; 250. else 251. #endif 252. if (otmp->obroken) verb = "fix"; 253. else if (!otmp->olocked) verb = "lock", it = 1; 254. else if (picktyp != LOCK_PICK) verb = "unlock", it = 1; 255. else verb = "pick"; 256. Sprintf(qbuf, "There is %s here, %s %s?", 257. doname(otmp), verb, it ? "it" : "its lock"); 258. 259. c = ynq(qbuf); 260. if(c == 'q') return(0); 261. if(c == 'n') continue; 262. 263. #if CONTAINER_BITS 264. otmp->lknown = 1; 265. #endif 266. if (otmp->obroken) { 267. You("can't fix its broken lock with %s.", doname(pick)); 268. return 0; 269. } 270. #ifdef TOURIST 271. else if (picktyp == CREDIT_CARD && !otmp->olocked) { 272. /* credit cards are only good for unlocking */ 273. You("can't do that with %s.", doname(pick)); 274. return 0; 275. } 276. #endif 277. switch(picktyp) { 278. #ifdef TOURIST 279. case CREDIT_CARD: 280. ch = ACURR(A_DEX)+(20*(pl_character[0] == 'R')); 281. break; 282. #endif 283. case LOCK_PICK: 284. ch = 4*ACURR(A_DEX)+(25*(pl_character[0] == 'R')); 285. break; 286. case SKELETON_KEY: 287. ch = 75 + ACURR(A_DEX); 288. break; 289. default: ch = 0; 290. } 291. if(otmp->cursed) ch /= 2; 292. 293. xlock.door_or_box = 0; 294. xlock.picktyp = picktyp; 295. xlock.box = otmp; 296. break; 297. } 298. if(c != 'y') 299. return(0); /* decided against all boxes */ 300. } else { /* pick the lock in a door */ 301. struct monst *mtmp; 302. 303. door = &levl[x][y]; 304. if ((mtmp = m_at(x, y)) && canseemon(mtmp) 305. && mtmp->m_ap_type != M_AP_FURNITURE 306. && mtmp->m_ap_type != M_AP_OBJECT) { 307. #ifdef TOURIST 308. if (picktyp == CREDIT_CARD && 309. (mtmp->isshk || mtmp->data == &mons[PM_ORACLE])) 310. verbalize("No checks, no credit, no problem."); 311. else 312. #endif 313. pline("I don't think %s would appreciate that.", mon_nam(mtmp)); 314. return(0); 315. } 316. if(!IS_DOOR(door->typ)) { 317. if (is_drawbridge_wall(x,y) >= 0) 318. You("%s no lock on the drawbridge.", 319. Blind ? "feel" : "see"); 320. else 321. You("%s no door there.", 322. Blind ? "feel" : "see"); 323. return(0); 324. } 325. switch (door->doormask) { 326. case D_NODOOR: 327. pline("This doorway has no door."); 328. return(0); 329. case D_ISOPEN: 330. pline("Picking the lock of an open door is pointless."); 331. return(0); 332. case D_BROKEN: 333. pline("This door is broken."); 334. return(0); 335. default: 336. #ifdef TOURIST 337. /* credit cards are only good for unlocking */ 338. if(picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) { 339. You("can't lock a door with a credit card."); 340. return(0); 341. } 342. #endif 343. 344. Sprintf(qbuf,"%sock it?", 345. (door->doormask & D_LOCKED) ? "Unl" : "L" ); 346. 347. c = yn(qbuf); 348. if(c == 'n') return(0); 349. 350. switch(picktyp) { 351. #ifdef TOURIST 352. case CREDIT_CARD: 353. ch = 2*ACURR(A_DEX)+(20*(pl_character[0] == 'R')); 354. break; 355. #endif 356. case LOCK_PICK: 357. ch = 3*ACURR(A_DEX)+(30*(pl_character[0] == 'R')); 358. break; 359. case SKELETON_KEY: 360. ch = 70 + ACURR(A_DEX); 361. break; 362. default: ch = 0; 363. } 364. xlock.door_or_box = 1; 365. xlock.door = door; 366. } 367. } 368. flags.move = 0; 369. xlock.chance = ch; 370. xlock.picktyp = picktyp; 371. xlock.usedtime = 0; 372. set_occupation(picklock, 373. (picktyp == LOCK_PICK) ? "picking the lock" : 374. "opening the lock", 0); 375. return(1); 376. } 377. 378. int 379. doforce() /* try to force a chest with your weapon */ 380. { 381. register struct obj *otmp; 382. register int c, picktyp; 383. char qbuf[QBUFSZ]; 384. 385. if(!uwep || /* proper type test */ 386. (uwep->oclass != WEAPON_CLASS && uwep->oclass != ROCK_CLASS && 387. uwep->otyp != PICK_AXE) || 388. (uwep->otyp < BOOMERANG) || 389. (uwep->otyp > AKLYS && uwep->oclass != ROCK_CLASS && 390. uwep->otyp != PICK_AXE) 391. #ifdef KOPS 392. || uwep->otyp == RUBBER_HOSE 393. #endif 394. ) { 395. You("can't force anything without a %sweapon.", 396. (uwep) ? "proper " : ""); 397. return(0); 398. } 399. 400. picktyp = is_blade(uwep); 401. if(xlock.usedtime && xlock.box && picktyp == xlock.picktyp) { 402. You("resume your attempt to force the lock."); 403. set_occupation(forcelock, "forcing the lock", 0); 404. return(1); 405. } 406. 407. /* A lock is made only for the honest man, the thief will break it. */ 408. xlock.box = (struct obj *)0; 409. for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) 410. if(Is_box(otmp)) { 411. #if CONTAINER_BITS 412. if (!otmp->oclosed) { /* it's open */ 413. pline("There is %s here.", doname(otmp)); 414. continue; 415. } 416. if (otmp->obroken || (otmp->lknown && !otmp->olocked)) { 417. #else 418. if (otmp->obroken || !otmp->olocked) { 419. #endif 420. pline("There is %s here, but its lock is already %s.", 421. doname(otmp), otmp->obroken ? "broken" : "unlocked"); 422. continue; 423. } 424. Sprintf(qbuf,"There is %s here, force its lock?", doname(otmp)); 425. 426. c = ynq(qbuf); 427. if(c == 'q') return(0); 428. if(c == 'n') continue; 429. 430. #if CONTAINER_BITS 431. if (!otmp->olocked) { /* lock-status wasn't known */ 432. pline("Well what'd'ya know? It's already unlocked."); 433. otmp->lknown = 1; 434. return 0; 435. } 436. #endif 437. if(picktyp) 438. You("force your %s into a crack and pry.", xname(uwep)); 439. else 440. You("start bashing it with your %s.", xname(uwep)); 441. xlock.box = otmp; 442. xlock.chance = objects[otmp->otyp].oc_wldam * 2; 443. xlock.picktyp = picktyp; 444. xlock.usedtime = 0; 445. break; 446. } 447. 448. if(xlock.box) set_occupation(forcelock, "forcing the lock", 0); 449. else You("decide not to force the issue."); 450. return(1); 451. } 452. 453. int 454. doopen() /* try to open a door */ 455. { 456. register int x, y; 457. register struct rm *door; 458. struct monst *mtmp; 459. 460. if (u.utrap && u.utraptype == TT_PIT) { 461. You("can't reach over the edge of the pit."); 462. return 0; 463. } 464. 465. if(!getdir(NULL)) return(0); 466. 467. x = u.ux + u.dx; 468. y = u.uy + u.dy; 469. if((x == u.ux) && (y == u.uy)) return(0); 470. 471. if ((mtmp = m_at(x,y)) && 472. mtmp->m_ap_type == M_AP_FURNITURE && 473. (mtmp->mappearance == S_hcdoor || 474. mtmp->mappearance == S_vcdoor) && 475. !Protection_from_shape_changers) { 476. 477. stumble_onto_mimic(mtmp); 478. return(1); 479. } 480. 481. door = &levl[x][y]; 482. 483. if(!IS_DOOR(door->typ)) { 484. if (is_db_wall(x,y)) { 485. pline("There is no obvious way to open the drawbridge."); 486. return(0); 487. } 488. You("%s no door there.", 489. Blind ? "feel" : "see"); 490. return(0); 491. } 492. 493. if(!(door->doormask & D_CLOSED)) { 494. switch(door->doormask) { 495. case D_BROKEN: pline("This door is broken."); break; 496. case D_NODOOR: pline("This doorway has no door."); break; 497. case D_ISOPEN: pline("This door is already open."); break; 498. default: pline("This door is locked."); break; 499. } 500. return(0); 501. } 502. 503. #ifdef POLYSELF 504. if(verysmall(uasmon)) { 505. pline("You're too small to pull the door open."); 506. return(0); 507. } 508. #endif 509. /* door is known to be CLOSED */ 510. if (rnl(20) < (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3) { 511. pline("The door opens."); 512. if(door->doormask & D_TRAPPED) { 513. b_trapped("door"); 514. door->doormask = D_NODOOR; 515. } else 516. door->doormask = D_ISOPEN; 517. if (Blind) 518. feel_location(x,y); /* the hero knows she opened it */ 519. else 520. newsym(x,y); 521. unblock_point(x,y); /* vision: new see through there */ 522. } else { 523. exercise(A_STR, TRUE); 524. pline("The door resists!"); 525. } 526. 527. return(1); 528. } 529. 530. static 531. boolean 532. obstructed(x,y) 533. register int x, y; 534. { 535. register struct monst *mtmp = m_at(x, y); 536. 537. if(mtmp && mtmp->m_ap_type != M_AP_FURNITURE) { 538. if (mtmp->m_ap_type == M_AP_OBJECT) goto objhere; 539. pline("%s stands in the way!", Blind ? 540. "Some creature" : Monnam(mtmp)); 541. return(TRUE); 542. } 543. if (OBJ_AT(x, y)) { 544. objhere: pline("Something's in the way."); 545. return(TRUE); 546. } 547. return(FALSE); 548. } 549. 550. int 551. doclose() /* try to close a door */ 552. { 553. register int x, y; 554. register struct rm *door; 555. struct monst *mtmp; 556. 557. if (u.utrap && u.utraptype == TT_PIT) { 558. You("can't reach over the edge of the pit."); 559. return 0; 560. } 561. 562. if(!getdir(NULL)) return(0); 563. 564. x = u.ux + u.dx; 565. y = u.uy + u.dy; 566. if((x == u.ux) && (y == u.uy)) { 567. You("are in the way!"); 568. return(1); 569. } 570. 571. if ((mtmp = m_at(x,y)) && 572. mtmp->m_ap_type == M_AP_FURNITURE && 573. (mtmp->mappearance == S_hcdoor || 574. mtmp->mappearance == S_vcdoor) && 575. !Protection_from_shape_changers) { 576. 577. stumble_onto_mimic(mtmp); 578. return(1); 579. } 580. 581. door = &levl[x][y]; 582. 583. if(!IS_DOOR(door->typ)) { 584. if (door->typ == DRAWBRIDGE_DOWN) 585. pline("There is no obvious way to close the drawbridge."); 586. else 587. You("%s no door there.", 588. Blind ? "feel" : "see"); 589. return(0); 590. } 591. 592. if(door->doormask == D_NODOOR) { 593. pline("This doorway has no door."); 594. return(0); 595. } 596. 597. if(obstructed(x, y)) return(0); 598. 599. if(door->doormask == D_BROKEN) { 600. pline("This door is broken."); 601. return(0); 602. } 603. 604. if(door->doormask & (D_CLOSED | D_LOCKED)) { 605. pline("This door is already closed."); 606. return(0); 607. } 608. 609. if(door->doormask == D_ISOPEN) { 610. #ifdef POLYSELF 611. if(verysmall(uasmon)) { 612. pline("You're too small to push the door closed."); 613. return(0); 614. } 615. #endif 616. if (rn2(25) < (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3) { 617. pline("The door closes."); 618. door->doormask = D_CLOSED; 619. if (Blind) 620. feel_location(x,y); /* the hero knows she closed it */ 621. else 622. newsym(x,y); 623. block_point(x,y); /* vision: no longer see there */ 624. } 625. else { 626. exercise(A_STR, TRUE); 627. pline("The door resists!"); 628. } 629. } 630. 631. return(1); 632. } 633. 634. boolean /* box obj was hit with spell effect otmp */ 635. boxlock(obj, otmp) /* returns true if something happened */ 636. register struct obj *obj, *otmp; /* obj *is* a box */ 637. { 638. register boolean res = 0; 639. 640. switch(otmp->otyp) { 641. case WAN_LOCKING: 642. case SPE_WIZARD_LOCK: 643. if (!obj->olocked) { /* lock it; fix if broken */ 644. pline("Klunk!"); 645. #if CONTAINER_BITS 646. obj->lknown = 0; 647. obj->oclosed = 1; 648. #endif 649. obj->olocked = 1; 650. obj->obroken = 0; 651. res = 1; 652. } /* else already closed and locked */ 653. break; 654. case WAN_OPENING: 655. case SPE_KNOCK: 656. if (obj->olocked) { /* unlock; couldn't be broken */ 657. pline("Klick!"); 658. #if CONTAINER_BITS 659. obj->lknown = 0; 660. #endif 661. obj->olocked = 0; 662. res = 1; 663. } else /* silently fix if broken */ 664. obj->obroken = 0; 665. #if CONTAINER_BITS 666. obj->oclosed = 0; /* now open, unconditionally */ 667. #endif 668. break; 669. } 670. return res; 671. } 672. 673. boolean /* Door/secret door was hit with spell effect otmp */ 674. doorlock(otmp,x,y) /* returns true if something happened */ 675. register struct obj *otmp; 676. int x, y; 677. { 678. register struct rm *door = &levl[x][y]; 679. boolean res = 1; 680. const char *msg = NULL; 681. 682. if (door->typ == SDOOR) { 683. if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) { 684. door->typ = DOOR; 685. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 686. if (cansee(x,y)) pline("A section of the wall opens up!"); 687. newsym(x,y); 688. return(1); 689. } else 690. return(0); 691. } 692. 693. switch(otmp->otyp) { 694. case WAN_LOCKING: 695. case SPE_WIZARD_LOCK: 696. if (obstructed(x,y)) return 0; 697. switch (door->doormask & ~D_TRAPPED) { 698. case D_CLOSED: 699. msg = "The door locks!"; 700. break; 701. case D_ISOPEN: 702. msg = "The door swings shut, and locks!"; 703. break; 704. case D_BROKEN: 705. msg = "The broken door reassembles and locks!"; 706. break; 707. case D_NODOOR: 708. msg = 709. "A cloud of dust springs up and assembles itself into a door!"; 710. break; 711. default: 712. res = 0; 713. break; 714. } 715. block_point(x, y); 716. door->doormask = D_LOCKED | (door->doormask & D_TRAPPED); 717. newsym(x,y); 718. break; 719. case WAN_OPENING: 720. case SPE_KNOCK: 721. if (door->doormask & D_LOCKED) { 722. msg = "The door unlocks!"; 723. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 724. } else res = 0; 725. break; 726. case WAN_STRIKING: 727. case SPE_FORCE_BOLT: 728. if (door->doormask & (D_LOCKED | D_CLOSED)) { 729. if (door->doormask & D_TRAPPED) { 730. if (MON_AT(x, y)) 731. (void) mb_trapped(m_at(x,y)); 732. else if (flags.verbose) { 733. if (cansee(x,y)) 734. pline("KABOOM!! You see a door explode."); 735. else if (flags.soundok) 736. You("hear a distant explosion."); 737. } 738. door->doormask = D_NODOOR; 739. unblock_point(x,y); 740. newsym(x,y); 741. break; 742. } 743. door->doormask = D_BROKEN; 744. if (flags.verbose) { 745. if (cansee(x,y)) 746. pline("The door crashes open!"); 747. else if (flags.soundok) 748. You("hear a crashing sound."); 749. } 750. unblock_point(x,y); 751. newsym(x,y); 752. } else res = 0; 753. break; 754. default: impossible("magic (%d) attempted on door.", otmp->otyp); 755. break; 756. } 757. if (msg && cansee(x,y)) pline(msg); 758. return res; 759. } 760. 761. static void 762. chest_shatter_msg(otmp) 763. struct obj *otmp; 764. { 765. const char *disposition, *article = (otmp->quan > 1L) ? "A" : "The"; 766. char *thing; 767. long save_Blinded; 768. 769. if (otmp->oclass == POTION_CLASS) { 770. You("%s a flask shatter!", Blind ? "hear" : "see"); 771. potionbreathe(otmp); 772. return; 773. } 774. /* We have functions for distant and singular names, but not one */ 775. /* which does _both_... */ 776. save_Blinded = Blinded; 777. Blinded = 1; 778. thing = singular(otmp, xname); 779. Blinded = save_Blinded; 780. switch (objects[otmp->otyp].oc_material) { 781. case PAPER: disposition = "is torn to shreds"; 782. break; 783. case WAX: disposition = "is crushed"; 784. break; 785. case VEGGY: disposition = "is pulped"; 786. break; 787. case FLESH: disposition = "is mashed"; 788. break; 789. case GLASS: disposition = "shatters"; 790. break; 791. case WOOD: disposition = "splinters to fragments"; 792. break; 793. default: disposition = "is destroyed"; 794. break; 795. } 796. pline("%s %s %s!", article, thing, disposition); 797. } 798. 799. #endif /* OVLB */ 800. 801. /*lock.c*/