Source:NetHack 3.1.0/lock.c

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

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*/