PropertyValue
rdfs:label
  • Source:NetHack 3.0.0/lock.c
rdfs:comment
  • Below is the full text to lock.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/lock.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • Below is the full text to lock.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/lock.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)lock.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. 7. static struct { 8. int door_or_box, picktyp; 9. struct rm *door; 10. struct obj *box; 11. int chance, usedtime; 12. } xlock; 13. 14. static 15. int 16. picklock() { /* try to open/close a lock */ 17. 18. if(!xlock.door_or_box) { /* box */ 19. 20. if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) { 21. return((xlock.usedtime = 0)); /* you or it moved */ 22. } 23. } else { /* door */ 24. if(xlock.door != &(levl[u.ux+u.dx][u.uy+u.dy])) { 25. return((xlock.usedtime = 0)); /* you moved */ 26. } 27. switch (xlock.door->doormask) { 28. case D_NODOOR: 29. pline("This doorway has no door."); 30. return((xlock.usedtime = 0)); 31. case D_ISOPEN: 32. pline("Picking the lock of an open door is pointless."); 33. return((xlock.usedtime = 0)); 34. case D_BROKEN: 35. pline("This door is broken."); 36. return((xlock.usedtime = 0)); 37. } 38. } 39. 40. if(xlock.usedtime++ >= 50 41. #ifdef POLYSELF 42. || nohands(uasmon) 43. #endif 44. ) { 45. You("give up your attempt to %s the lock.", 46. (xlock.door_or_box ? !(xlock.door->doormask & D_LOCKED) : 47. !xlock.box->olocked) ? "lock" : 48. ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" )); 49. 50. return((xlock.usedtime = 0)); 51. } 52. 53. if(rn2(100) > xlock.chance) return(1); /* still busy */ 54. 55. if(xlock.door_or_box) { 56. You("succeed in %sing the lock.", 57. !(xlock.door->doormask & D_LOCKED) ? "lock" : 58. ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" )); 59. if(xlock.door->doormask & D_TRAPPED) { 60. b_trapped("door"); 61. xlock.door->doormask = D_NODOOR; 62. } else if(xlock.door->doormask == D_LOCKED) 63. xlock.door->doormask = D_CLOSED; 64. else xlock.door->doormask = D_LOCKED; 65. } else { 66. You("succeed in %sing the lock.", 67. (!xlock.box->olocked) ? "lock" : 68. (xlock.picktyp == LOCK_PICK) ? "pick" : "open" ); 69. xlock.box->olocked = !xlock.box->olocked; 70. if(xlock.box->otrapped) chest_trap(xlock.box, FINGER); 71. } 72. return((xlock.usedtime = 0)); 73. } 74. 75. static 76. int 77. forcelock() { /* try to force a locked chest */ 78. 79. register struct obj *otmp, *otmp2; 80. register struct obj *probj = fcobj; /* initialize to make lint happy */ 81. 82. if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) 83. return((xlock.usedtime = 0)); /* you or it moved */ 84. 85. if(xlock.usedtime++ >= 50 || !uwep 86. #ifdef POLYSELF 87. || nohands(uasmon) 88. #endif 89. ) { 90. You("give up your attempt to force the lock."); 91. 92. return((xlock.usedtime = 0)); 93. } 94. 95. if(xlock.picktyp) { /* blade */ 96. 97. if(rn2(1000-uwep->spe) > 992 && !uwep->cursed) { 98. /* for a +0 weapon, probability that it survives an unsuccessful 99. * attempt to force the lock is (.992)^50 = .67 100. */ 101. pline("%sour %s broke!", 102. (uwep->quan > 1) ? "One of y" : "Y", xname(uwep)); 103. useup(uwep); 104. You("give up your attempt to force the lock."); 105. return((xlock.usedtime = 0)); 106. } 107. } else /* blunt */ 108. wake_nearby(); /* due to hammering on the container */ 109. 110. if(rn2(100) > xlock.chance) return(1); /* still busy */ 111. 112. You("succeed in forcing the lock."); 113. xlock.box->olocked = !xlock.box->olocked; 114. if(!xlock.picktyp && !rn2(3)) { 115. 116. pline("In fact, you've totally destroyed the %s.", 117. xname(xlock.box)); 118. for(otmp = fcobj; otmp; otmp = otmp2) { 119. 120. otmp2 = otmp->nobj; 121. if(otmp->cobj == xlock.box) { 122. 123. /* unlink it from the "contained" list */ 124. if(otmp == fcobj) fcobj = otmp2; 125. else probj->nobj = otmp2; 126. 127. if(!rn2(3) || otmp->olet == POTION_SYM) 128. free((genericptr_t) otmp); 129. else { /* spill it onto the floor */ 130. otmp->nobj = xlock.box->nobj; 131. xlock.box->nobj = otmp; 132. otmp->cobj = (struct obj *)0; 133. otmp->ox = u.ux; 134. otmp->oy = u.uy; 135. levl[u.ux][u.uy].omask = 1; 136. stackobj(otmp); 137. } 138. } else probj = otmp; 139. } 140. delobj(xlock.box); 141. } 142. return((xlock.usedtime = 0)); 143. } 144. 145. int 146. pick_lock(pick) /* pick a lock with a given object */ 147. register struct obj *pick; 148. { 149. register int x, y, picktyp, c, ch; 150. register struct rm *door; 151. register struct obj *otmp; 152. 153. picktyp = pick->otyp; 154. if(xlock.usedtime && picktyp == xlock.picktyp) { 155. 156. You("resume your attempt to %s the lock.", 157. (xlock.door_or_box ? !(xlock.door->doormask & D_LOCKED) : 158. !xlock.box->olocked) ? "lock" : 159. ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" )); 160. 161. set_occupation(picklock, 162. (picktyp == LOCK_PICK) ? "picking the lock" : 163. "opening the lock", 0); 164. return(1); 165. } 166. 167. #ifdef POLYSELF 168. if(nohands(uasmon)) { 169. You("can't hold a %s - you have no hands!"); 170. return(0); 171. } 172. #endif 173. if((picktyp != LOCK_PICK && picktyp != CREDIT_CARD && 174. picktyp != SKELETON_KEY && picktyp != KEY)) { 175. impossible("picking lock with object %d?", picktyp); 176. return(0); 177. } 178. if(!getdir(1)) return(0); 179. 180. x = u.ux + u.dx; 181. y = u.uy + u.dy; 182. if((x == u.ux) && (y == u.uy)) { /* pick the lock on a container */ 183. c = 'n'; /* in case there are no boxes here */ 184. if(levl[x][y].omask) 185. for(otmp = fobj; otmp; otmp = otmp->nobj) 186. if((otmp->ox == x) && (otmp->oy == y)) 187. if(Is_box(otmp)) { 188. pline("There is %s here, %s the lock? ", 189. doname(otmp), (!otmp->olocked) ? "close" : 190. ((picktyp == LOCK_PICK) ? "pick" : "open" )); 191. 192. c = ynq(); 193. if(c == 'q') return(0); 194. if(c == 'n') continue; 195. 196. if(picktyp == KEY && otmp->spe != pick->spe) { 197. pline("The %s won't fit the lock.",xname(pick)); 198. return(1); 199. } 200. switch(picktyp) { 201. case CREDIT_CARD: 202. ch = ACURR(A_DEX)+(20*(pl_character[0] == 'R')); 203. break; 204. case LOCK_PICK: 205. ch = 4*ACURR(A_DEX)+(25*(pl_character[0] == 'R')); 206. break; 207. case SKELETON_KEY: 208. ch = 75 + ACURR(A_DEX); 209. break; 210. case KEY: 211. ch = 1000; 212. break; 213. default: ch = 0; 214. } 215. if(otmp->cursed) ch /= 2; 216. 217. xlock.door_or_box = 0; 218. xlock.picktyp = picktyp; 219. xlock.box = otmp; 220. break; 221. } 222. if(c != 'y') 223. return(0); /* decided against all boxes */ 224. } else { /* pick the lock in a door */ 225. struct monst *mtmp; 226. 227. door = &levl[x][y]; 228. if (door->mmask && canseemon(mtmp = m_at(x,y)) && !mtmp->mimic) { 229. if (picktyp == CREDIT_CARD && 230. #ifdef ORACLE 231. (mtmp->isshk || mtmp->data == &mons[PM_ORACLE])) 232. #else 233. mtmp->isshk) 234. #endif 235. pline("\"No checks, no credit, no problem.\""); 236. else 237. kludge("I don't think %s would appreciate that.", mon_nam(mtmp)); 238. return(0); 239. } 240. if(!IS_DOOR(door->typ)) { 241. #ifdef STRONGHOLD 242. if (is_drawbridge_wall(x,y) >= 0) 243. You("%s no lock on the drawbridge.", 244. Blind ? "feel" : "see"); 245. else 246. #endif 247. You("%s no door there.", 248. Blind ? "feel" : "see"); 249. return(0); 250. } 251. switch (door->doormask) { 252. case D_NODOOR: 253. pline("This doorway has no door."); 254. return(0); 255. case D_ISOPEN: 256. pline("Picking the lock of an open door is pointless."); 257. return(0); 258. case D_BROKEN: 259. pline("This door is broken."); 260. return(0); 261. default: 262. pline("%sock it? ", (door->doormask & D_LOCKED) ? "Unl" : "L" ); 263. 264. c = yn(); 265. if(c == 'n') return(0); 266. 267. switch(picktyp) { 268. case CREDIT_CARD: 269. ch = 2*ACURR(A_DEX)+(20*(pl_character[0] == 'R')); 270. break; 271. case LOCK_PICK: 272. ch = 3*ACURR(A_DEX)+(30*(pl_character[0] == 'R')); 273. break; 274. case SKELETON_KEY: 275. ch = 70 + ACURR(A_DEX); 276. break; 277. case KEY: 278. pline("The %s won't fit the door.", xname(pick)); 279. return(1); 280. default: ch = 0; 281. } 282. xlock.door_or_box = 1; 283. xlock.door = door; 284. } 285. } 286. flags.move = 0; 287. xlock.chance = ch; 288. xlock.picktyp = picktyp; 289. xlock.usedtime = 0; 290. set_occupation(picklock, 291. (picktyp == LOCK_PICK) ? "picking the lock" : 292. "opening the lock", 0); 293. return(1); 294. } 295. 296. int 297. doforce() { /* try to force a chest with your weapon */ 298. 299. register struct obj *otmp; 300. register int c, picktyp; 301. 302. if(!uwep || /* proper type test */ 303. (uwep->olet != WEAPON_SYM && uwep->olet != ROCK_SYM && 304. uwep->otyp != PICK_AXE) || 305. (uwep->otyp < DAGGER) || 306. (uwep->otyp > VOULGE && uwep->olet != ROCK_SYM && 307. uwep->otyp != PICK_AXE) 308. ) { 309. You("can't force anything without a %sweapon.", 310. (uwep) ? "proper " : ""); 311. return(0); 312. } 313. 314. picktyp = (uwep->otyp >= DAGGER && uwep->otyp <= KATANA); 315. if(xlock.usedtime && xlock.box && picktyp == xlock.picktyp) { 316. You("resume your attempt to force the lock."); 317. set_occupation(forcelock, "forcing the lock", 0); 318. return(1); 319. } 320. 321. /* A lock is made only for the honest man, the thief will break it. */ 322. xlock.box = (struct obj *)0; 323. if(levl[u.ux][u.uy].omask) 324. for(otmp = fobj; otmp; otmp = otmp->nobj) 325. if((otmp->ox == u.ux) && (otmp->oy == u.uy)) 326. if(Is_box(otmp)) { 327. if(otmp->olocked) 328. pline("There is %s here, force the lock? ", doname(otmp)); 329. else { 330. pline("There is a %s here, but it's already unlocked.", 331. xname(otmp)); 332. continue; 333. } 334. 335. c = ynq(); 336. if(c == 'q') return(0); 337. if(c == 'n') continue; 338. 339. if(picktyp) 340. You("force your %s into a crack and pry.", xname(uwep)); 341. else 342. You("start bashing it with your %s.", xname(uwep)); 343. xlock.box = otmp; 344. xlock.chance = objects[otmp->otyp].wldam * 2; 345. xlock.picktyp = picktyp; 346. xlock.usedtime = 0; 347. break; 348. } 349. 350. if(xlock.box) set_occupation(forcelock, "forcing the lock", 0); 351. else You("decide not to force the issue."); 352. return(1); 353. } 354. 355. int 356. doopen() { /* try to open a door */ 357. register int x, y; 358. register struct rm *door; 359. 360. if(!getdir(1)) return(0); 361. 362. x = u.ux + u.dx; 363. y = u.uy + u.dy; 364. if((x == u.ux) && (y == u.uy)) return(0); 365. 366. door = &levl[x][y]; 367. 368. if(!IS_DOOR(door->typ)) { 369. #ifdef STRONGHOLD 370. if (is_drawbridge_wall(x,y) >= 0) { 371. pline("There is no obvious way to open the drawbridge."); 372. return(0); 373. } 374. #endif 375. You("%s no door there.", 376. Blind ? "feel" : "see"); 377. return(0); 378. } 379. 380. if(!(door->doormask & D_CLOSED)) { 381. switch(door->doormask) { 382. case D_BROKEN: pline("This door is broken."); break; 383. case D_NODOOR: pline("This doorway has no door."); break; 384. case D_ISOPEN: pline("This door is already open."); break; 385. default: pline("This door is locked."); break; 386. } 387. return(0); 388. } 389. 390. #ifdef POLYSELF 391. if(verysmall(uasmon)) { 392. pline("You're too small to pull the door open."); 393. return(0); 394. } 395. #endif 396. /* door is known to be CLOSED */ 397. if (rnl(20) < (ACURR(A_STR)+ACURR(A_DEX)+ACURR(A_CON))/3) { 398. pline("The door opens."); 399. if(door->doormask & D_TRAPPED) { 400. b_trapped("door"); 401. door->doormask = D_NODOOR; 402. } else 403. door->doormask = D_ISOPEN; 404. } else { 405. pline("The door resists!"); 406. } 407. 408. return(1); 409. } 410. 411. static 412. boolean 413. obstructed(x,y) 414. register int x, y; 415. { 416. if(levl[x][y].mmask) { 417. if (m_at(x,y)->mimic) goto obj; 418. pline("%s stands in the way!", Blind ? 419. "Some creature" : Monnam(m_at(x,y))); 420. return(TRUE); 421. } 422. if (levl[x][y].omask || levl[x][y].gmask) { 423. obj: 424. pline("Something's in the way."); 425. return(TRUE); 426. } 427. return(FALSE); 428. } 429. 430. int 431. doclose() { /* try to close a door */ 432. register int x, y; 433. register struct rm *door; 434. 435. if(!getdir(1)) return(0); 436. 437. x = u.ux + u.dx; 438. y = u.uy + u.dy; 439. if((x == u.ux) && (y == u.uy)) { 440. You("are in the way!"); 441. return(1); 442. } 443. door = &levl[x][y]; 444. 445. if(!IS_DOOR(door->typ)) { 446. #ifdef STRONGHOLD 447. if (door->typ == DRAWBRIDGE_DOWN) 448. pline("There is no obvious way to close the drawbridge."); 449. else 450. #endif 451. You("%s no door there.", 452. Blind ? "feel" : "see"); 453. return(0); 454. } 455. 456. if(door->doormask == D_NODOOR) { 457. pline("This doorway has no door."); 458. return(0); 459. } 460. 461. if(obstructed(x, y)) return(0); 462. 463. if(door->doormask == D_BROKEN) { 464. pline("This door is broken."); 465. return(0); 466. } 467. 468. if(door->doormask & (D_CLOSED | D_LOCKED)) { 469. pline("This door is already closed."); 470. return(0); 471. } 472. 473. if(door->doormask == D_ISOPEN) { 474. #ifdef POLYSELF 475. if(verysmall(uasmon)) { 476. pline("You're too small to push the door closed."); 477. return(0); 478. } 479. #endif 480. if (rn2(25) < (ACURR(A_STR)+ACURR(A_DEX)+ACURR(A_CON))/3) { 481. pline("The door closes."); 482. door->doormask = D_CLOSED; 483. } 484. else pline("The door resists!"); 485. } 486. 487. return(1); 488. } 489. 490. int 491. boxlock(obj, otmp) /* box obj was hit with spell effect otmp */ 492. /* returns 1 if something happened */ 493. register struct obj *obj, *otmp; /* obj *is* a box */ 494. { 495. register boolean res; 496. 497. switch(otmp->otyp) { 498. case WAN_LOCKING: 499. #ifdef SPELLS 500. case SPE_WIZARD_LOCK: 501. #endif 502. if(!obj->olocked) { 503. pline("Klunk!"); 504. obj->olocked = !(obj->olocked); 505. res = 1; 506. } else res = 0; 507. break; 508. case WAN_OPENING: 509. #ifdef SPELLS 510. case SPE_KNOCK: 511. #endif 512. if(obj->olocked) { 513. pline("Klick!"); 514. obj->olocked = !(obj->olocked); 515. res = 1; 516. } else res = 0; 517. break; 518. } 519. return(res); 520. } 521. 522. int 523. doorlock(otmp,x,y) /* door was hit with spell effect otmp */ 524. register struct obj *otmp; 525. int x, y; 526. { 527. register struct rm *door = &levl[x][y]; 528. boolean res = 1; 529. 530. if(obstructed(x,y)) 531. return 0; 532. 533. if(door->typ == SDOOR) { 534. if(otmp->otyp == WAN_OPENING 535. #ifdef SPELLS 536. || otmp->otyp == SPE_KNOCK 537. #endif /* SPELLS /**/ 538. ) { 539. door->typ = DOOR; 540. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 541. if(cansee(x,y)) { 542. pline("A section of the wall opens up!"); 543. newsym(x,y); 544. } 545. return(1); 546. } else 547. return(0); 548. } 549. 550. #ifdef STRONGHOLD 551. /* make sure it isn't an open drawbridge */ 552. if (is_maze_lev && find_drawbridge(&x,&y)) { 553. if(otmp->otyp == WAN_OPENING 554. #ifdef SPELLS 555. || otmp->otyp == SPE_KNOCK 556. #endif /* SPELLS /**/ 557. ) 558. (void) open_drawbridge(x,y); 559. else 560. (void) close_drawbridge(x,y); 561. return 1; 562. } 563. #endif 564. 565. switch(otmp->otyp) { 566. case WAN_LOCKING: 567. #ifdef SPELLS 568. case SPE_WIZARD_LOCK: 569. #endif 570. if (cansee(x,y)) 571. switch (door->doormask & ~D_TRAPPED) { 572. case D_CLOSED: 573. pline("The door locks!"); 574. break; 575. case D_ISOPEN: 576. pline("The door swings shut, and locks!"); 577. break; 578. case D_BROKEN: 579. pline("The broken door reassembles and locks!"); 580. break; 581. case D_NODOOR: 582. pline("A cloud of dust springs up and assembles itself into a door!"); 583. break; 584. default: res = 0; 585. } 586. door->doormask = D_LOCKED | (door->doormask & D_TRAPPED); 587. break; 588. case WAN_OPENING: 589. #ifdef SPELLS 590. case SPE_KNOCK: 591. #endif 592. if(door->doormask & D_LOCKED) { 593. door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); 594. if(cansee(x,y)) pline("The door unlocks!"); 595. } else res = 0; 596. break; 597. default: impossible("magic (%d) attempted on door.", otmp->otyp); 598. } 599. return res; 600. } 601. 602. #ifdef STUPID_CPP /* otherwise these functions are macros in obj.h */ 603. int 604. Is_container(otmp) struct obj * otmp; { 605. return(otmp->otyp >= ICE_BOX && otmp->otyp <= BAG_OF_TRICKS); 606. } 607. 608. int 609. Is_box(otmp) struct obj * otmp; { 610. return(otmp->otyp == LARGE_BOX || otmp->otyp == CHEST); 611. } 612. 613. int 614. Is_mbag(otmp) struct obj * otmp; { 615. return(otmp->otyp == BAG_OF_HOLDING || otmp->otyp == BAG_OF_TRICKS); 616. } 617. 618. int 619. is_sword(otmp) struct obj * otmp; { 620. return(otmp->otyp >= SHORT_SWORD && otmp->otyp <= KATANA); 621. } 622. 623. int 624. bimanual(otmp) struct obj * otmp; { 625. return(otmp->olet == WEAPON_SYM && objects[otmp->otyp].oc_bimanual); 626. } 627. #endif /* STUPID_CPP */