Difference between revisions of "Source:SLASH'EM 0.0.7E7F2/lock.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (SLASH'EM 0.0.7E7F2/lock.c moved to Source:SLASH'EM 0.0.7E7F2/lock.c: Robot: moved page) |
(No difference)
|
Latest revision as of 19:11, 7 March 2008
Below is the full text to lock.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/lock.c#line123]], for example.
The latest source code for vanilla NetHack is at 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.4 2000/02/06 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. STATIC_PTR int NDECL(picklock); 8. STATIC_PTR int NDECL(forcelock); 9. STATIC_PTR int NDECL(forcedoor); 10. 11. /* at most one of `door' and `box' should be non-null at any given time */ 12. STATIC_VAR NEARDATA struct xlock_s { 13. struct rm *door; 14. struct obj *box; 15. int picktyp, chance, usedtime; 16. /* ALI - Artifact doors */ 17. int key; /* Key being used (doors only) */ 18. } xlock; 19. 20. #ifdef OVLB 21. 22. STATIC_DCL const char *NDECL(lock_action); 23. STATIC_DCL boolean FDECL(obstructed,(int,int)); 24. STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *)); 25. 26. boolean 27. picking_lock(x, y) 28. int *x, *y; 29. { 30. if (occupation == picklock) { 31. *x = u.ux + u.dx; 32. *y = u.uy + u.dy; 33. return TRUE; 34. } else { 35. *x = *y = 0; 36. return FALSE; 37. } 38. } 39. 40. boolean 41. picking_at(x, y) 42. int x, y; 43. { 44. return (boolean)(occupation == picklock && xlock.door == &levl[x][y]); 45. } 46. 47. /* produce an occupation string appropriate for the current activity */ 48. STATIC_OVL const char * 49. lock_action() 50. { 51. /* "unlocking"+2 == "locking" */ 52. static const char *actions[] = { 53. /* [0] */ "unlocking the door", 54. /* [1] */ "unlocking the chest", 55. /* [2] */ "unlocking the box", 56. /* [3] */ "picking the lock" 57. }; 58. 59. /* if the target is currently unlocked, we're trying to lock it now */ 60. if (xlock.door && !(xlock.door->doormask & D_LOCKED)) 61. return actions[0]+2; /* "locking the door" */ 62. else if (xlock.box && !xlock.box->olocked) 63. return xlock.box->otyp == CHEST ? actions[1]+2 : actions[2]+2; 64. /* otherwise we're trying to unlock it */ 65. else if (xlock.picktyp == LOCK_PICK) 66. return actions[3]; /* "picking the lock" */ 67. #ifdef TOURIST 68. else if (xlock.picktyp == CREDIT_CARD) 69. return actions[3]; /* same as lock_pick */ 70. #endif 71. else if (xlock.door) 72. return actions[0]; /* "unlocking the door" */ 73. else 74. return xlock.box->otyp == CHEST ? actions[1] : actions[2]; 75. } 76. 77. STATIC_PTR 78. int 79. picklock() /* try to open/close a lock */ 80. { 81. 82. if (xlock.box) { 83. if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) { 84. return((xlock.usedtime = 0)); /* you or it moved */ 85. } 86. } else { /* door */ 87. if(xlock.door != &(levl[u.ux+u.dx][u.uy+u.dy])) { 88. return((xlock.usedtime = 0)); /* you moved */ 89. } 90. switch (xlock.door->doormask) { 91. case D_NODOOR: 92. pline("This doorway has no door."); 93. return((xlock.usedtime = 0)); 94. case D_ISOPEN: 95. You("cannot lock an open door."); 96. return((xlock.usedtime = 0)); 97. case D_BROKEN: 98. pline("This door is broken."); 99. return((xlock.usedtime = 0)); 100. } 101. } 102. 103. if (xlock.usedtime++ >= 50 || nohands(youmonst.data)) { 104. You("give up your attempt at %s.", lock_action()); 105. exercise(A_DEX, TRUE); /* even if you don't succeed */ 106. return((xlock.usedtime = 0)); 107. } 108. 109. if(rn2(100) >= xlock.chance) return(1); /* still busy */ 110. 111. You("succeed in %s.", lock_action()); 112. if (xlock.door) { 113. if(xlock.door->doormask & D_TRAPPED) { 114. b_trapped("door", FINGER); 115. xlock.door->doormask = D_NODOOR; 116. unblock_point(u.ux+u.dx, u.uy+u.dy); 117. if (*in_rooms(u.ux+u.dx, u.uy+u.dy, SHOPBASE)) 118. add_damage(u.ux+u.dx, u.uy+u.dy, 0L); 119. newsym(u.ux+u.dx, u.uy+u.dy); 120. } else if(xlock.door->doormask == D_LOCKED) 121. xlock.door->doormask = D_CLOSED; 122. else xlock.door->doormask = D_LOCKED; 123. } else { 124. xlock.box->olocked = !xlock.box->olocked; 125. if(xlock.box->otrapped) 126. (void) chest_trap(xlock.box, FINGER, FALSE); 127. } 128. exercise(A_DEX, TRUE); 129. return((xlock.usedtime = 0)); 130. } 131. 132. STATIC_PTR 133. int 134. forcelock() /* try to force a locked chest */ 135. { 136. 137. register struct obj *otmp; 138. 139. if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) 140. return((xlock.usedtime = 0)); /* you or it moved */ 141. 142. if (xlock.usedtime++ >= 50 || !uwep || nohands(youmonst.data)) { 143. You("give up your attempt to force the lock."); 144. if(xlock.usedtime >= 50) /* you made the effort */ 145. exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE); 146. return((xlock.usedtime = 0)); 147. } 148. 149. if(xlock.picktyp == 1) { /* blade */ 150. 151. if(rn2(1000-(int)uwep->spe) > (992-greatest_erosion(uwep)*10) && 152. !uwep->cursed && !obj_resists(uwep, 0, 99)) { 153. /* for a +0 weapon, probability that it survives an unsuccessful 154. * attempt to force the lock is (.992)^50 = .67 155. */ 156. pline("%sour %s broke!", 157. (uwep->quan > 1L) ? "One of y" : "Y", xname(uwep)); 158. useup(uwep); 159. You("give up your attempt to force the lock."); 160. exercise(A_DEX, TRUE); 161. return((xlock.usedtime = 0)); 162. } 163. } else if(xlock.picktyp == 0) /* blunt */ 164. wake_nearby(); /* due to hammering on the container */ 165. 166. if(rn2(100) >= xlock.chance) return(1); /* still busy */ 167. 168. You("succeed in forcing the lock."); 169. xlock.box->olocked = 0; 170. xlock.box->obroken = 1; 171. if((xlock.picktyp == 0 && !rn2(3)) || (xlock.picktyp == 2 && !rn2(5))) { 172. struct monst *shkp; 173. boolean costly; 174. long loss = 0L; 175. 176. costly = (*u.ushops && costly_spot(u.ux, u.uy)); 177. shkp = costly ? shop_keeper(*u.ushops) : 0; 178. 179. pline("In fact, you've totally destroyed %s.", 180. the(xname(xlock.box))); 181. 182. /* Put the contents on ground at the hero's feet. */ 183. while ((otmp = xlock.box->cobj) != 0) { 184. obj_extract_self(otmp); 185. /* [ALI] Allowing containers to be destroyed is complicated 186. * (because they might contain indestructible objects). 187. * Since this is very unlikely to occur in practice simply 188. * avoid the possibility. 189. */ 190. if (!evades_destruction(otmp) && !Has_contents(otmp) && 191. (!rn2(3) || otmp->oclass == POTION_CLASS)) { 192. chest_shatter_msg(otmp); 193. if (costly) 194. loss += stolen_value(otmp, u.ux, u.uy, 195. (boolean)shkp->mpeaceful, TRUE, 196. TRUE); 197. if (otmp->quan == 1L) { 198. obfree(otmp, (struct obj *) 0); 199. continue; 200. } 201. useup(otmp); 202. } 203. if (xlock.box->otyp == ICE_BOX && otmp->otyp == CORPSE) { 204. otmp->age = monstermoves - otmp->age; /* actual age */ 205. start_corpse_timeout(otmp); 206. } 207. place_object(otmp, u.ux, u.uy); 208. stackobj(otmp); 209. } 210. 211. if (costly) 212. loss += stolen_value(xlock.box, u.ux, u.uy, 213. (boolean)shkp->mpeaceful, TRUE, TRUE); 214. if(loss) You("owe %ld %s for objects destroyed.", loss, currency(loss)); 215. delobj(xlock.box); 216. } 217. exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE); 218. return((xlock.usedtime = 0)); 219. } 220. 221. STATIC_PTR 222. int 223. forcedoor() /* try to break/pry open a door */ 224. { 225. 226. if(xlock.door != &(levl[u.ux+u.dx][u.uy+u.dy])) { 227. return((xlock.usedtime = 0)); /* you moved */ 228. } 229. switch (xlock.door->doormask) { 230. case D_NODOOR: 231. pline("This doorway has no door."); 232. return((xlock.usedtime = 0)); 233. case D_ISOPEN: 234. You("cannot lock an open door."); 235. return((xlock.usedtime = 0)); 236. case D_BROKEN: 237. pline("This door is broken."); 238. return((xlock.usedtime = 0)); 239. } 240. 241. if (xlock.usedtime++ >= 50 || nohands(youmonst.data)) { 242. You("give up your attempt at %s the door.", 243. (xlock.picktyp == 2 ? "melting" : xlock.picktyp == 1 ? 244. "prying open" : "breaking down")); 245. exercise(A_STR, TRUE); /* even if you don't succeed */ 246. return((xlock.usedtime = 0)); 247. } 248. 249. if(rn2(100) > xlock.chance) return(1); /* still busy */ 250. 251. You("succeed in %s the door.", 252. (xlock.picktyp == 2 ? "melting" : xlock.picktyp == 1 ? 253. "prying open" : "breaking down")); 254. 255. if(xlock.door->doormask & D_TRAPPED) { 256. b_trapped("door", 0); 257. xlock.door->doormask = D_NODOOR; 258. } else if (xlock.picktyp == 1) 259. xlock.door->doormask = D_BROKEN; 260. else xlock.door->doormask = D_NODOOR; 261. unblock_point(u.ux+u.dx, u.uy+u.dy); 262. if (*in_rooms(u.ux+u.dx, u.uy+u.dy, SHOPBASE)) 263. add_damage(u.ux+u.dx, u.uy+u.dy, 0L); 264. newsym(u.ux+u.dx, u.uy+u.dy); 265. 266. exercise(A_STR, TRUE); 267. return((xlock.usedtime = 0)); 268. } 269. 270. #endif /* OVLB */ 271. #ifdef OVL0 272. 273. void 274. reset_pick() 275. { 276. xlock.usedtime = xlock.chance = xlock.picktyp = 0; 277. xlock.door = 0; 278. xlock.box = 0; 279. } 280. 281. #endif /* OVL0 */ 282. #ifdef OVLB 283. 284. int 285. pick_lock(pickp) /* pick a lock with a given object */ 286. struct obj **pickp; 287. { 288. int picktyp, c, ch; 289. coord cc; 290. int key; 291. struct rm *door; 292. struct obj *otmp; 293. struct obj *pick = *pickp; 294. char qbuf[QBUFSZ]; 295. 296. picktyp = pick->otyp; 297. 298. /* check whether we're resuming an interrupted previous attempt */ 299. if (xlock.usedtime && picktyp == xlock.picktyp) { 300. static char no_longer[] = "Unfortunately, you can no longer %s %s."; 301. 302. if (nohands(youmonst.data)) { 303. const char *what = (picktyp == LOCK_PICK) ? "pick" : "key"; 304. #ifdef TOURIST 305. if (picktyp == CREDIT_CARD) what = "card"; 306. #endif 307. pline(no_longer, "hold the", what); 308. reset_pick(); 309. return 0; 310. } else if (xlock.box && !can_reach_floor()) { 311. pline(no_longer, "reach the", "lock"); 312. reset_pick(); 313. return 0; 314. } else if (!xlock.door || xlock.key == pick->oartifact) { 315. const char *action = lock_action(); 316. You("resume your attempt at %s.", action); 317. set_occupation(picklock, action, 0); 318. return(1); 319. } 320. } 321. 322. if(nohands(youmonst.data)) { 323. You_cant("hold %s -- you have no hands!", doname(pick)); 324. return(0); 325. } 326. 327. if((picktyp != LOCK_PICK && 328. #ifdef TOURIST 329. picktyp != CREDIT_CARD && 330. #endif 331. picktyp != SKELETON_KEY)) { 332. impossible("picking lock with object %d?", picktyp); 333. return(0); 334. } 335. ch = 0; /* lint suppression */ 336. 337. if(!get_adjacent_loc((char *)0, "Invalid location!", u.ux, u.uy, &cc)) return 0; 338. if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */ 339. const char *verb; 340. boolean it; 341. int count; 342. 343. if (u.dz < 0) { 344. There("isn't any sort of lock up %s.", 345. Levitation ? "here" : "there"); 346. return 0; 347. } else if (is_lava(u.ux, u.uy)) { 348. pline("Doing that would probably melt your %s.", 349. xname(pick)); 350. return 0; 351. } else if (is_pool(u.ux, u.uy) && !Underwater) { 352. pline_The("water has no lock."); 353. return 0; 354. } 355. 356. count = 0; 357. c = 'n'; /* in case there are no boxes here */ 358. for(otmp = level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere) 359. if (Is_box(otmp)) { 360. ++count; 361. if (!can_reach_floor()) { 362. You_cant("reach %s from up here.", the(xname(otmp))); 363. return 0; 364. } 365. it = 0; 366. if (otmp->obroken) verb = "fix"; 367. else if (!otmp->olocked) verb = "lock", it = 1; 368. else if (picktyp != LOCK_PICK) verb = "unlock", it = 1; 369. else verb = "pick"; 370. Sprintf(qbuf, "There is %s here, %s %s?", 371. safe_qbuf("", sizeof("There is here, unlock its lock?"), 372. doname(otmp), an(simple_typename(otmp->otyp)), "a box"), 373. verb, it ? "it" : "its lock"); 374. 375. c = ynq(qbuf); 376. if(c == 'q') return(0); 377. if(c == 'n') continue; 378. 379. if (otmp->obroken) { 380. You_cant("fix its broken lock with %s.", doname(pick)); 381. return 0; 382. } 383. #ifdef TOURIST 384. else if (picktyp == CREDIT_CARD && !otmp->olocked) { 385. /* credit cards are only good for unlocking */ 386. You_cant("do that with %s.", doname(pick)); 387. return 0; 388. } 389. #endif 390. switch(picktyp) { 391. #ifdef TOURIST 392. case CREDIT_CARD: 393. if(!rn2(20) && !pick->blessed && !pick->oartifact) { 394. Your("credit card breaks in half!"); 395. useup(pick); 396. *pickp = (struct obj *)0; 397. return(1); 398. } 399. ch = ACURR(A_DEX) + 20*Role_if(PM_ROGUE); 400. break; 401. #endif 402. case LOCK_PICK: 403. if(!rn2(Role_if(PM_ROGUE) ? 40 : 30) && 404. !pick->blessed && !pick->oartifact) { 405. You("break your pick!"); 406. useup(pick); 407. *pickp = (struct obj *)0; 408. return(1); 409. } 410. ch = 4*ACURR(A_DEX) + 25*Role_if(PM_ROGUE); 411. break; 412. case SKELETON_KEY: 413. if(!rn2(15) && !pick->blessed && !pick->oartifact) { 414. Your("key didn't quite fit the lock and snapped!"); 415. useup(pick); 416. *pickp = (struct obj *)0; 417. return(1); 418. } 419. ch = 75 + ACURR(A_DEX); 420. break; 421. default: ch = 0; 422. } 423. if(otmp->cursed) ch /= 2; 424. 425. xlock.picktyp = picktyp; 426. xlock.box = otmp; 427. xlock.door = 0; 428. break; 429. } 430. if (c != 'y') { 431. if (!count) 432. There("doesn't seem to be any sort of lock here."); 433. return(0); /* decided against all boxes */ 434. } 435. } else { /* pick the lock in a door */ 436. struct monst *mtmp; 437. 438. if (u.utrap && u.utraptype == TT_PIT) { 439. You_cant("reach over the edge of the pit."); 440. return(0); 441. } 442. 443. door = &levl[cc.x][cc.y]; 444. if ((mtmp = m_at(cc.x, cc.y)) && canseemon(mtmp) 445. && mtmp->m_ap_type != M_AP_FURNITURE 446. && mtmp->m_ap_type != M_AP_OBJECT) { 447. #ifdef TOURIST 448. if (picktyp == CREDIT_CARD && 449. (mtmp->isshk || mtmp->data == &mons[PM_ORACLE])) 450. verbalize("No checks, no credit, no problem."); 451. else 452. #endif 453. pline("I don't think %s would appreciate that.", mon_nam(mtmp)); 454. return(0); 455. } 456. if(!IS_DOOR(door->typ)) { 457. if (is_drawbridge_wall(cc.x,cc.y) >= 0) 458. You("%s no lock on the drawbridge.", 459. Blind ? "feel" : "see"); 460. else 461. You("%s no door there.", 462. Blind ? "feel" : "see"); 463. return(0); 464. } 465. switch (door->doormask) { 466. case D_NODOOR: 467. pline("This doorway has no door."); 468. return(0); 469. case D_ISOPEN: 470. You("cannot lock an open door."); 471. return(0); 472. case D_BROKEN: 473. pline("This door is broken."); 474. return(0); 475. default: 476. #ifdef TOURIST 477. /* credit cards are only good for unlocking */ 478. if(picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) { 479. You_cant("lock a door with a credit card."); 480. return(0); 481. } 482. #endif 483. /* ALI - Artifact doors */ 484. key = artifact_door(cc.x, cc.y); 485. 486. Sprintf(qbuf,"%sock it?", 487. (door->doormask & D_LOCKED) ? "Unl" : "L" ); 488. 489. c = yn(qbuf); 490. if(c == 'n') return(0); 491. 492. switch(picktyp) { 493. #ifdef TOURIST 494. case CREDIT_CARD: 495. if(!rn2(Role_if(PM_TOURIST) ? 30 : 20) && 496. !pick->blessed && !pick->oartifact) { 497. You("break your card off in the door!"); 498. useup(pick); 499. *pickp = (struct obj *)0; 500. return(0); 501. } 502. ch = 2*ACURR(A_DEX) + 20*Role_if(PM_ROGUE); 503. break; 504. #endif 505. case LOCK_PICK: 506. if(!rn2(Role_if(PM_ROGUE) ? 40 : 30) && 507. !pick->blessed && !pick->oartifact) { 508. You("break your pick!"); 509. useup(pick); 510. *pickp = (struct obj *)0; 511. return(0); 512. } 513. ch = 3*ACURR(A_DEX) + 30*Role_if(PM_ROGUE); 514. break; 515. case SKELETON_KEY: 516. if(!rn2(15) && !pick->blessed && !pick->oartifact) { 517. Your("key wasn't designed for this door and broke!"); 518. useup(pick); 519. *pickp = (struct obj *)0; 520. return(0); 521. } 522. ch = 70 + ACURR(A_DEX); 523. break; 524. default: ch = 0; 525. } 526. xlock.door = door; 527. xlock.box = 0; 528. 529. /* ALI - Artifact doors */ 530. xlock.key = pick->oartifact; 531. if (key && xlock.key != key) { 532. if (picktyp == SKELETON_KEY) { 533. Your("key doesn't seem to fit."); 534. return(0); 535. } 536. else ch = -1; /* -1 == 0% chance */ 537. } 538. } 539. } 540. flags.move = 0; 541. xlock.chance = ch; 542. xlock.picktyp = picktyp; 543. xlock.usedtime = 0; 544. set_occupation(picklock, lock_action(), 0); 545. return(1); 546. } 547. 548. int 549. doforce() /* try to force a chest with your weapon */ 550. { 551. register struct obj *otmp; 552. register int x, y, c, picktyp; 553. struct rm *door; 554. char qbuf[QBUFSZ]; 555. 556. if (!uwep) { /* Might want to make this so you use your shoulder */ 557. You_cant("force anything without a weapon."); 558. return(0); 559. } 560. 561. if (u.utrap && u.utraptype == TT_WEB) { 562. You("are entangled in a web!"); 563. return(0); 564. #ifdef LIGHTSABERS 565. } else if (uwep && is_lightsaber(uwep)) { 566. if (!uwep->lamplit) { 567. Your("lightsaber is deactivated!"); 568. return(0); 569. } 570. #endif 571. } else if(uwep->otyp == LOCK_PICK || 572. #ifdef TOURIST 573. uwep->otyp == CREDIT_CARD || 574. #endif 575. uwep->otyp == SKELETON_KEY) { 576. return pick_lock(&uwep); 577. /* not a lightsaber or lockpicking device*/ 578. } else if(!uwep || /* proper type test */ 579. (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep) && 580. uwep->oclass != ROCK_CLASS) || 581. (objects[uwep->otyp].oc_skill < P_DAGGER) || 582. (objects[uwep->otyp].oc_skill > P_LANCE) || 583. uwep->otyp == FLAIL || uwep->otyp == AKLYS 584. #ifdef KOPS 585. || uwep->otyp == RUBBER_HOSE 586. #endif 587. ) { 588. You_cant("force anything without a %sweapon.", 589. (uwep) ? "proper " : ""); 590. return(0); 591. } 592. 593. #ifdef LIGHTSABERS 594. if (is_lightsaber(uwep)) 595. picktyp = 2; 596. else 597. #endif 598. picktyp = is_blade(uwep) ? 1 : 0; 599. if(xlock.usedtime && picktyp == xlock.picktyp) { 600. if (xlock.box) { 601. You("resume your attempt to force the lock."); 602. set_occupation(forcelock, "forcing the lock", 0); 603. return(1); 604. } else if (xlock.door) { 605. You("resume your attempt to force the door."); 606. set_occupation(forcedoor, "forcing the door", 0); 607. return(1); 608. } 609. } 610. 611. /* A lock is made only for the honest man, the thief will break it. */ 612. xlock.box = (struct obj *)0; 613. 614. if(!getdir((char *)0)) return(0); 615. 616. x = u.ux + u.dx; 617. y = u.uy + u.dy; 618. if (x == u.ux && y == u.uy && !u.dz) { 619. for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) 620. if(Is_box(otmp)) { 621. if (otmp->obroken || !otmp->olocked) { 622. There("is %s here, but its lock is already %s.", 623. doname(otmp), otmp->obroken ? "broken" : "unlocked"); 624. continue; 625. } 626. Sprintf(qbuf,"There is %s here, force its lock?", 627. safe_qbuf("", sizeof("There is here, force its lock?"), 628. doname(otmp), an(simple_typename(otmp->otyp)), 629. "a box")); 630. 631. c = ynq(qbuf); 632. if(c == 'q') return(0); 633. if(c == 'n') continue; 634. 635. #ifdef LIGHTSABERS 636. if(picktyp == 2) 637. You("begin melting it with your %s.", xname(uwep)); 638. else 639. #endif 640. if(picktyp) 641. You("force your %s into a crack and pry.", xname(uwep)); 642. else 643. You("start bashing it with your %s.", xname(uwep)); 644. xlock.box = otmp; 645. #ifdef LIGHTSABERS 646. if (is_lightsaber(uwep)) 647. xlock.chance = uwep->spe * 2 + 75; 648. else 649. #endif 650. xlock.chance = (uwep->spe + objects[uwep->otyp].oc_wldam) * 2; 651. xlock.picktyp = picktyp; 652. xlock.usedtime = 0; 653. break; 654. } 655. if(xlock.box) { 656. xlock.door = 0; 657. set_occupation(forcelock, "forcing the lock", 0); 658. return(1); 659. } 660. } else { /* break down/open door */ 661. struct monst *mtmp; 662. 663. door = &levl[x][y]; 664. if ((mtmp = m_at(x, y)) && canseemon(mtmp) 665. && mtmp->m_ap_type != M_AP_FURNITURE 666. && mtmp->m_ap_type != M_AP_OBJECT) { 667. 668. if (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]) 669. verbalize("What do you think you are, a Jedi?"); /* Phantom Menace */ 670. else 671. pline("I don't think %s would appreciate that.", mon_nam(mtmp)); 672. return(0); 673. } 674. /* Lightsabers dig through doors and walls via dig.c */ 675. if (is_pick(uwep) || 676. #ifdef LIGHTSABERS 677. is_lightsaber(uwep) || 678. #endif 679. is_axe(uwep)) 680. return use_pick_axe2(uwep); 681. 682. if(!IS_DOOR(door->typ)) { 683. if (is_drawbridge_wall(x,y) >= 0) 684. pline("The drawbridge is too solid to force open."); 685. else 686. You("%s no door there.", 687. Blind ? "feel" : "see"); 688. return(0); 689. } 690. /* ALI - artifact doors */ 691. if (artifact_door(x, y)) { 692. pline("This door is too solid to force open."); 693. return 0; 694. } 695. switch (door->doormask) { 696. case D_NODOOR: 697. pline("This doorway has no door."); 698. return(0); 699. case D_ISOPEN: 700. You("cannot force an open door."); 701. return(0); 702. case D_BROKEN: 703. pline("This door is broken."); 704. return(0); 705. default: 706. c = yn("Break down the door?"); 707. if(c == 'n') return(0); 708. 709. if(picktyp == 1) 710. You("force your %s into a crack and pry.", xname(uwep)); 711. else 712. You("start bashing it with your %s.", xname(uwep)); 713. #ifdef LIGHTSABERS 714. if (is_lightsaber(uwep)) 715. xlock.chance = uwep->spe + 38; 716. else 717. #endif 718. xlock.chance = uwep->spe + objects[uwep->otyp].oc_wldam; 719. xlock.picktyp = picktyp; 720. xlock.usedtime = 0; 721. xlock.door = door; 722. xlock.box = 0; 723. set_occupation(forcedoor, "forcing the door", 0); 724. return(1); 725. } 726. } 727. You("decide not to force the issue."); 728. return(0); 729. } 730. 731. int 732. doopen() /* try to open a door */ 733. { 734. coord cc; 735. register struct rm *door; 736. struct monst *mtmp; 737. 738. if (nohands(youmonst.data)) { 739. You_cant("open anything -- you have no hands!"); 740. return 0; 741. } 742. 743. if (u.utrap && u.utraptype == TT_PIT) { 744. You_cant("reach over the edge of the pit."); 745. return 0; 746. } 747. 748. if(!get_adjacent_loc((char *)0, (char *)0, u.ux, u.uy, &cc)) return(0); 749. 750. if((cc.x == u.ux) && (cc.y == u.uy)) return(0); 751. 752. if ((mtmp = m_at(cc.x,cc.y)) && 753. mtmp->m_ap_type == M_AP_FURNITURE && 754. (mtmp->mappearance == S_hcdoor || 755. mtmp->mappearance == S_vcdoor) && 756. !Protection_from_shape_changers) { 757. 758. stumble_onto_mimic(mtmp); 759. return(1); 760. } 761. 762. door = &levl[cc.x][cc.y]; 763. 764. if(!IS_DOOR(door->typ)) { 765. if (is_db_wall(cc.x,cc.y)) { 766. There("is no obvious way to open the drawbridge."); 767. return(0); 768. } 769. You("%s no door there.", 770. Blind ? "feel" : "see"); 771. return(0); 772. } 773. 774. if (!(door->doormask & D_CLOSED)) { 775. const char *mesg; 776. 777. switch (door->doormask) { 778. case D_BROKEN: mesg = " is broken"; break; 779. case D_NODOOR: mesg = "way has no door"; break; 780. case D_ISOPEN: mesg = " is already open"; break; 781. default: mesg = " is locked"; break; 782. } 783. pline("This door%s.", mesg); 784. if (Blind) feel_location(cc.x,cc.y); 785. return(0); 786. } 787. 788. if(verysmall(youmonst.data)) { 789. pline("You're too small to pull the door open."); 790. return(0); 791. } 792. 793. /* door is known to be CLOSED */ 794. if (rnl(20) < (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3) { 795. pline_The("door opens."); 796. if(door->doormask & D_TRAPPED) { 797. b_trapped("door", FINGER); 798. door->doormask = D_NODOOR; 799. if (*in_rooms(cc.x, cc.y, SHOPBASE)) add_damage(cc.x, cc.y, 0L); 800. } else 801. door->doormask = D_ISOPEN; 802. if (Blind) 803. feel_location(cc.x,cc.y); /* the hero knows she opened it */ 804. else 805. newsym(cc.x,cc.y); 806. unblock_point(cc.x,cc.y); /* vision: new see through there */ 807. } else { 808. exercise(A_STR, TRUE); 809. pline_The("door resists!"); 810. } 811. 812. return(1); 813. } 814. 815. STATIC_OVL 816. boolean 817. obstructed(x,y) 818. register int x, y; 819. { 820. register struct monst *mtmp = m_at(x, y); 821. 822. if(mtmp && mtmp->m_ap_type != M_AP_FURNITURE) { 823. if (mtmp->m_ap_type == M_AP_OBJECT) goto objhere; 824. pline("%s stands in the way!", !canspotmon(mtmp) ? 825. "Some creature" : Monnam(mtmp)); 826. if (!canspotmon(mtmp)) 827. map_invisible(mtmp->mx, mtmp->my); 828. return(TRUE); 829. } 830. if (OBJ_AT(x, y)) { 831. objhere: pline("%s's in the way.", Something); 832. return(TRUE); 833. } 834. return(FALSE); 835. } 836. 837. int 838. doclose() /* try to close a door */ 839. { 840. register int x, y; 841. register struct rm *door; 842. struct monst *mtmp; 843. 844. if (nohands(youmonst.data)) { 845. You_cant("close anything -- you have no hands!"); 846. return 0; 847. } 848. 849. if (u.utrap && u.utraptype == TT_PIT) { 850. You_cant("reach over the edge of the pit."); 851. return 0; 852. } 853. 854. if(!getdir((char *)0)) return(0); 855. 856. x = u.ux + u.dx; 857. y = u.uy + u.dy; 858. if((x == u.ux) && (y == u.uy)) { 859. You("are in the way!"); 860. return(1); 861. } 862. 863. if ((mtmp = m_at(x,y)) && 864. mtmp->m_ap_type == M_AP_FURNITURE && 865. (mtmp->mappearance == S_hcdoor || 866. mtmp->mappearance == S_vcdoor) && 867. !Protection_from_shape_changers) { 868. 869. stumble_onto_mimic(mtmp); 870. return(1); 871. } 872. 873. door = &levl[x][y]; 874. 875. if(!IS_DOOR(door->typ)) { 876. if (door->typ == DRAWBRIDGE_DOWN) 877. There("is no obvious way to close the drawbridge."); 878. else 879. You("%s no door there.", 880. Blind ? "feel" : "see"); 881. return(0); 882. } 883. 884. if(door->doormask == D_NODOOR) { 885. pline("This doorway has no door."); 886. return(0); 887. } 888. 889. if(obstructed(x, y)) return(0); 890. 891. if(door->doormask == D_BROKEN) { 892. pline("This door is broken."); 893. return(0); 894. } 895. 896. if(door->doormask & (D_CLOSED | D_LOCKED)) { 897. pline("This door is already closed."); 898. return(0); 899. } 900. 901. if(door->doormask == D_ISOPEN) { 902. if(verysmall(youmonst.data) 903. #ifdef STEED 904. && !u.usteed 905. #endif 906. ) { 907. pline("You're too small to push the door closed."); 908. return(0); 909. } 910. if ( 911. #ifdef STEED 912. u.usteed || 913. #endif 914. rn2(25) < (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3) { 915. pline_The("door closes."); 916. door->doormask = D_CLOSED; 917. if (Blind) 918. feel_location(x,y); /* the hero knows she closed it */ 919. else 920. newsym(x,y); 921. block_point(x,y); /* vision: no longer see there */ 922. } 923. else { 924. exercise(A_STR, TRUE); 925. pline_The("door resists!"); 926. } 927. } 928. 929. return(1); 930. } 931. 932. boolean /* box obj was hit with spell effect otmp */ 933. boxlock(obj, otmp) /* returns true if something happened */ 934. register struct obj *obj, *otmp; /* obj *is* a box */ 935. { 936. register boolean res = 0; 937. 938. switch(otmp->otyp) { 939. case WAN_LOCKING: 940. case SPE_WIZARD_LOCK: 941. if (!obj->olocked) { /* lock it; fix if broken */ 942. pline("Klunk!"); 943. obj->olocked = 1; 944. obj->obroken = 0; 945. res = 1; 946. } /* else already closed and locked */ 947. break; 948. case WAN_OPENING: 949. case SPE_KNOCK: 950. if (obj->olocked) { /* unlock; couldn't be broken */ 951. pline("Klick!"); 952. obj->olocked = 0; 953. res = 1; 954. } else /* silently fix if broken */ 955. obj->obroken = 0; 956. break; 957. case WAN_POLYMORPH: 958. case SPE_POLYMORPH: 959. /* maybe start unlocking chest, get interrupted, then zap it; 960. we must avoid any attempt to resume unlocking it */ 961. if (xlock.box == obj) 962. reset_pick(); 963. break; 964. } 965. return res; 966. } 967. 968. boolean /* Door/secret door was hit with spell effect otmp */ 969. doorlock(otmp,x,y) /* returns true if something happened */ 970. struct obj *otmp; 971. int x, y; 972. { 973. register struct rm *door = &levl[x][y]; 974. boolean res = TRUE; 975. int loudness = 0; 976. const char *msg = (const char *)0; 977. const char *dustcloud = "A cloud of dust"; 978. const char *quickly_dissipates = "quickly dissipates"; 979. int key = artifact_door(x, y); /* ALI - Artifact doors */ 980. 981. if (door->typ == SDOOR) { 982. switch (otmp->otyp) { 983. case WAN_OPENING: 984. case SPE_KNOCK: 985. case WAN_STRIKING: 986. case SPE_FORCE_BOLT: 987. if (key) /* Artifact doors are revealed only */ 988. cvt_sdoor_to_door(door); 989. else { 990. door->typ = DOOR; 991. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 992. } 993. newsym(x,y); 994. if (cansee(x,y)) pline("A door appears in the wall!"); 995. if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) 996. return TRUE; 997. break; /* striking: continue door handling below */ 998. case WAN_LOCKING: 999. case SPE_WIZARD_LOCK: 1000. default: 1001. return FALSE; 1002. } 1003. } 1004. 1005. switch(otmp->otyp) { 1006. case WAN_LOCKING: 1007. case SPE_WIZARD_LOCK: 1008. #ifdef REINCARNATION 1009. if (Is_rogue_level(&u.uz)) { 1010. boolean vis = cansee(x,y); 1011. /* Can't have real locking in Rogue, so just hide doorway */ 1012. if (vis) pline("%s springs up in the older, more primitive doorway.", 1013. dustcloud); 1014. else 1015. You_hear("a swoosh."); 1016. if (obstructed(x,y)) { 1017. if (vis) pline_The("cloud %s.",quickly_dissipates); 1018. return FALSE; 1019. } 1020. block_point(x, y); 1021. door->typ = SDOOR; 1022. if (vis) pline_The("doorway vanishes!"); 1023. newsym(x,y); 1024. return TRUE; 1025. } 1026. #endif 1027. if (obstructed(x,y)) return FALSE; 1028. /* Don't allow doors to close over traps. This is for pits */ 1029. /* & trap doors, but is it ever OK for anything else? */ 1030. if (t_at(x,y)) { 1031. /* maketrap() clears doormask, so it should be NODOOR */ 1032. pline( 1033. "%s springs up in the doorway, but %s.", 1034. dustcloud, quickly_dissipates); 1035. return FALSE; 1036. } 1037. 1038. switch (door->doormask & ~D_TRAPPED) { 1039. case D_CLOSED: 1040. if (key) 1041. msg = "The door closes!"; 1042. else 1043. msg = "The door locks!"; 1044. break; 1045. case D_ISOPEN: 1046. if (key) 1047. msg = "The door swings shut!"; 1048. else 1049. msg = "The door swings shut, and locks!"; 1050. break; 1051. case D_BROKEN: 1052. if (key) 1053. msg = "The broken door reassembles!"; 1054. else 1055. msg = "The broken door reassembles and locks!"; 1056. break; 1057. case D_NODOOR: 1058. msg = 1059. "A cloud of dust springs up and assembles itself into a door!"; 1060. break; 1061. default: 1062. res = FALSE; 1063. break; 1064. } 1065. block_point(x, y); 1066. if (key) 1067. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 1068. else 1069. door->doormask = D_LOCKED | (door->doormask & D_TRAPPED); 1070. newsym(x,y); 1071. break; 1072. case WAN_OPENING: 1073. case SPE_KNOCK: 1074. if (!key && door->doormask & D_LOCKED) { 1075. msg = "The door unlocks!"; 1076. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 1077. } else res = FALSE; 1078. break; 1079. case WAN_STRIKING: 1080. case SPE_FORCE_BOLT: 1081. if (!key && door->doormask & (D_LOCKED | D_CLOSED)) { 1082. if (door->doormask & D_TRAPPED) { 1083. if (MON_AT(x, y)) 1084. (void) mb_trapped(m_at(x,y)); 1085. else if (flags.verbose) { 1086. if (cansee(x,y)) 1087. pline("KABOOM!! You see a door explode."); 1088. else if (flags.soundok) 1089. You_hear("a distant explosion."); 1090. } 1091. door->doormask = D_NODOOR; 1092. unblock_point(x,y); 1093. newsym(x,y); 1094. loudness = 40; 1095. break; 1096. } 1097. door->doormask = D_BROKEN; 1098. if (flags.verbose) { 1099. if (cansee(x,y)) 1100. pline_The("door crashes open!"); 1101. else if (flags.soundok) 1102. You_hear("a crashing sound."); 1103. } 1104. unblock_point(x,y); 1105. newsym(x,y); 1106. /* force vision recalc before printing more messages */ 1107. if (vision_full_recalc) vision_recalc(0); 1108. loudness = 20; 1109. } else res = FALSE; 1110. break; 1111. default: impossible("magic (%d) attempted on door.", otmp->otyp); 1112. break; 1113. } 1114. if (msg && cansee(x,y)) pline(msg); 1115. if (loudness > 0) { 1116. /* door was destroyed */ 1117. wake_nearto(x, y, loudness); 1118. if (*in_rooms(x, y, SHOPBASE)) add_damage(x, y, 0L); 1119. } 1120. 1121. if (res && picking_at(x, y)) { 1122. /* maybe unseen monster zaps door you're unlocking */ 1123. stop_occupation(); 1124. reset_pick(); 1125. } 1126. return res; 1127. } 1128. 1129. STATIC_OVL void 1130. chest_shatter_msg(otmp) 1131. struct obj *otmp; 1132. { 1133. const char *disposition; 1134. const char *thing; 1135. long save_Blinded; 1136. 1137. if (otmp->oclass == POTION_CLASS) { 1138. You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename())); 1139. if (!breathless(youmonst.data) || haseyes(youmonst.data)) 1140. potionbreathe(otmp); 1141. return; 1142. } 1143. /* We have functions for distant and singular names, but not one */ 1144. /* which does _both_... */ 1145. save_Blinded = Blinded; 1146. Blinded = 1; 1147. thing = singular(otmp, xname); 1148. Blinded = save_Blinded; 1149. switch (objects[otmp->otyp].oc_material) { 1150. case PAPER: disposition = "is torn to shreds"; 1151. break; 1152. case WAX: disposition = "is crushed"; 1153. break; 1154. case VEGGY: disposition = "is pulped"; 1155. break; 1156. case FLESH: disposition = "is mashed"; 1157. break; 1158. case GLASS: disposition = "shatters"; 1159. break; 1160. case WOOD: disposition = "splinters to fragments"; 1161. break; 1162. default: disposition = "is destroyed"; 1163. break; 1164. } 1165. pline("%s %s!", An(thing), disposition); 1166. } 1167. 1168. /* ALI - Kevin Hugo's artifact doors. 1169. * Return the artifact which unlocks the door at (x, y), or 1170. * zero if it is an ordinary door. 1171. * Note: Not all doors are listed in the doors array (eg., doors 1172. * dynamically converted from secret doors). Since only trapped 1173. * and artifact doors are needed this isn't a problem. If we ever 1174. * implement trapped secret doors we will have to extend this. 1175. */ 1176. 1177. int 1178. artifact_door(x, y) 1179. int x, y; 1180. { 1181. int i; 1182. 1183. for(i = 0; i < doorindex; i++) { 1184. if (x == doors[i].x && y == doors[i].y) 1185. return doors[i].arti_key; 1186. } 1187. return 0; 1188. } 1189. 1190. #endif /* OVLB */ 1191. 1192. /*lock.c*/