Wikia

Wikihack

Source:Lock.c

2,032pages on
this wiki
Talk0

Below is the full text to src/lock.c from NetHack 3.4.3. To link to a particular line, write [[lock.c#line123]], for example.

Top of file Edit

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    #include "hack.h"
6.    
7.    STATIC_PTR int NDECL(picklock);
8.    STATIC_PTR int NDECL(forcelock);
9.    
10.   /* at most one of `door' and `box' should be non-null at any given time */
11.   STATIC_VAR NEARDATA struct xlock_s {
12.   	struct rm  *door;
13.   	struct obj *box;
14.   	int picktyp, chance, usedtime;
15.   } xlock;
16.   
17.   #ifdef OVLB
18.   
19.   STATIC_DCL const char *NDECL(lock_action);
20.   STATIC_DCL boolean FDECL(obstructed,(int,int));
21.   STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *));
22.   

picking_lock Edit

23.   boolean
24.   picking_lock(x, y)
25.   	int *x, *y;
26.   {
27.   	if (occupation == picklock) {
28.   	    *x = u.ux + u.dx;
29.   	    *y = u.uy + u.dy;
30.   	    return TRUE;
31.   	} else {
32.   	    *x = *y = 0;
33.   	    return FALSE;
34.   	}
35.   }
36.   

picking_at Edit

37.   boolean
38.   picking_at(x, y)
39.   int x, y;
40.   {
41.   	return (boolean)(occupation == picklock && xlock.door == &levl[x][y]);
42.   }
43.   

lock_action Edit

44.   /* produce an occupation string appropriate for the current activity */
45.   STATIC_OVL const char *
46.   lock_action()
47.   {
48.   	/* "unlocking"+2 == "locking" */
49.   	static const char *actions[] = {
50.   		/* [0] */	"unlocking the door",
51.   		/* [1] */	"unlocking the chest",
52.   		/* [2] */	"unlocking the box",
53.   		/* [3] */	"picking the lock"
54.   	};
55.   
56.   	/* if the target is currently unlocked, we're trying to lock it now */
57.   	if (xlock.door && !(xlock.door->doormask & D_LOCKED))
58.   		return actions[0]+2;	/* "locking the door" */
59.   	else if (xlock.box && !xlock.box->olocked)
60.   		return xlock.box->otyp == CHEST ? actions[1]+2 : actions[2]+2;
61.   	/* otherwise we're trying to unlock it */
62.   	else if (xlock.picktyp == LOCK_PICK)
63.   		return actions[3];	/* "picking the lock" */
64.   #ifdef TOURIST
65.   	else if (xlock.picktyp == CREDIT_CARD)
66.   		return actions[3];	/* same as lock_pick */
67.   #endif
68.   	else if (xlock.door)
69.   		return actions[0];	/* "unlocking the door" */
70.   	else
71.   		return xlock.box->otyp == CHEST ? actions[1] : actions[2];
72.   }
73.   

picklock Edit

74.   STATIC_PTR
75.   int
76.   picklock()	/* try to open/close a lock */
77.   {
78.   
79.   	if (xlock.box) {
80.   	    if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) {
81.   		return((xlock.usedtime = 0));		/* you or it moved */
82.   	    }
83.   	} else {		/* door */
84.   	    if(xlock.door != &(levl[u.ux+u.dx][u.uy+u.dy])) {
85.   		return((xlock.usedtime = 0));		/* you moved */
86.   	    }
87.   	    switch (xlock.door->doormask) {
88.   		case D_NODOOR:
89.   		    pline("This doorway has no door.");
90.   		    return((xlock.usedtime = 0));
91.   		case D_ISOPEN:
92.   		    You("cannot lock an open door.");
93.   		    return((xlock.usedtime = 0));
94.   		case D_BROKEN:
95.   		    pline("This door is broken.");
96.   		    return((xlock.usedtime = 0));
97.   	    }
98.   	}
99.   
100.  	if (xlock.usedtime++ >= 50 || nohands(youmonst.data)) {
101.  	    You("give up your attempt at %s.", lock_action());
102.  	    exercise(A_DEX, TRUE);	/* even if you don't succeed */
103.  	    return((xlock.usedtime = 0));
104.  	}
105.  
106.  	if(rn2(100) >= xlock.chance) return(1);		/* still busy */
107.  
108.  	You("succeed in %s.", lock_action());
109.  	if (xlock.door) {
110.  	    if(xlock.door->doormask & D_TRAPPED) {
111.  		    b_trapped("door", FINGER);
112.  		    xlock.door->doormask = D_NODOOR;
113.  		    unblock_point(u.ux+u.dx, u.uy+u.dy);
114.  		    if (*in_rooms(u.ux+u.dx, u.uy+u.dy, SHOPBASE))
115.  			add_damage(u.ux+u.dx, u.uy+u.dy, 0L);
116.  		    newsym(u.ux+u.dx, u.uy+u.dy);
117.  	    } else if (xlock.door->doormask & D_LOCKED)
118.  		xlock.door->doormask = D_CLOSED;
119.  	    else xlock.door->doormask = D_LOCKED;
120.  	} else {
121.  	    xlock.box->olocked = !xlock.box->olocked;
122.  	    if(xlock.box->otrapped)	
123.  		(void) chest_trap(xlock.box, FINGER, FALSE);
124.  	}
125.  	exercise(A_DEX, TRUE);
126.  	return((xlock.usedtime = 0));
127.  }
128.  

forcelock Edit

129.  STATIC_PTR
130.  int
131.  forcelock()	/* try to force a locked chest */
132.  {
133.  
134.  	register struct obj *otmp;
135.  
136.  	if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy))
137.  		return((xlock.usedtime = 0));		/* you or it moved */
138.  
139.  	if (xlock.usedtime++ >= 50 || !uwep || nohands(youmonst.data)) {
140.  	    You("give up your attempt to force the lock.");
141.  	    if(xlock.usedtime >= 50)		/* you made the effort */
142.  	      exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
143.  	    return((xlock.usedtime = 0));
144.  	}
145.  
146.  	if(xlock.picktyp) {	/* blade */
147.  
148.  	    if(rn2(1000-(int)uwep->spe) > (992-greatest_erosion(uwep)*10) &&
149.  	       !uwep->cursed && !obj_resists(uwep, 0, 99)) {
150.  		/* for a +0 weapon, probability that it survives an unsuccessful
151.  		 * attempt to force the lock is (.992)^50 = .67
152.  		 */
153.  		pline("%sour %s broke!",
154.  		      (uwep->quan > 1L) ? "One of y" : "Y", xname(uwep));
155.  		useup(uwep);
156.  		You("give up your attempt to force the lock.");
157.  		exercise(A_DEX, TRUE);
158.  		return((xlock.usedtime = 0));
159.  	    }
160.  	} else			/* blunt */
161.  	    wake_nearby();	/* due to hammering on the container */
162.  
163.  	if(rn2(100) >= xlock.chance) return(1);		/* still busy */
164.  
165.  	You("succeed in forcing the lock.");
166.  	xlock.box->olocked = 0;
167.  	xlock.box->obroken = 1;
168.  	if(!xlock.picktyp && !rn2(3)) {
169.  	    struct monst *shkp;
170.  	    boolean costly;
171.  	    long loss = 0L;
172.  
173.  	    costly = (*u.ushops && costly_spot(u.ux, u.uy));
174.  	    shkp = costly ? shop_keeper(*u.ushops) : 0;
175.  
176.  	    pline("In fact, you've totally destroyed %s.",
177.  		  the(xname(xlock.box)));
178.  
179.  	    /* Put the contents on ground at the hero's feet. */
180.  	    while ((otmp = xlock.box->cobj) != 0) {
181.  		obj_extract_self(otmp);
182.  		if(!rn2(3) || otmp->oclass == POTION_CLASS) {
183.  		    chest_shatter_msg(otmp);
184.  		    if (costly)
185.  		        loss += stolen_value(otmp, u.ux, u.uy,
186.  					     (boolean)shkp->mpeaceful, TRUE);
187.  		    if (otmp->quan == 1L) {
188.  			obfree(otmp, (struct obj *) 0);
189.  			continue;
190.  		    }
191.  		    useup(otmp);
192.  		}
193.  		if (xlock.box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
194.  		    otmp->age = monstermoves - otmp->age; /* actual age */
195.  		    start_corpse_timeout(otmp);
196.  		}
197.  		place_object(otmp, u.ux, u.uy);
198.  		stackobj(otmp);
199.  	    }
200.  
201.  	    if (costly)
202.  		loss += stolen_value(xlock.box, u.ux, u.uy,
203.  					     (boolean)shkp->mpeaceful, TRUE);
204.  	    if(loss) You("owe %ld %s for objects destroyed.", loss, currency(loss));
205.  	    delobj(xlock.box);
206.  	}
207.  	exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
208.  	return((xlock.usedtime = 0));
209.  }
210.  
211.  #endif /* OVLB */

reset_pick Edit

212.  #ifdef OVL0
213.  
214.  void
215.  reset_pick()
216.  {
217.  	xlock.usedtime = xlock.chance = xlock.picktyp = 0;
218.  	xlock.door = 0;
219.  	xlock.box = 0;
220.  }
221.  
222.  #endif /* OVL0 */

pick_lock Edit

223.  #ifdef OVLB
224.  
225.  int
226.  pick_lock(pick) /* pick a lock with a given object */
227.  	register struct	obj	*pick;
228.  {
229.  	int picktyp, c, ch;
230.  	coord cc;
231.  	struct rm	*door;
232.  	struct obj	*otmp;
233.  	char qbuf[QBUFSZ];
234.  
235.  	picktyp = pick->otyp;
236.  
237.  	/* check whether we're resuming an interrupted previous attempt */
238.  	if (xlock.usedtime && picktyp == xlock.picktyp) {
239.  	    static char no_longer[] = "Unfortunately, you can no longer %s %s.";
240.  
241.  	    if (nohands(youmonst.data)) {
242.  		const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";
243.  #ifdef TOURIST
244.  		if (picktyp == CREDIT_CARD) what = "card";
245.  #endif
246.  		pline(no_longer, "hold the", what);
247.  		reset_pick();
248.  		return 0;
249.  	    } else if (xlock.box && !can_reach_floor()) {
250.  		pline(no_longer, "reach the", "lock");
251.  		reset_pick();
252.  		return 0;
253.  	    } else {
254.  		const char *action = lock_action();
255.  		You("resume your attempt at %s.", action);
256.  		set_occupation(picklock, action, 0);
257.  		return(1);
258.  	    }
259.  	}
260.  
261.  	if(nohands(youmonst.data)) {
262.  		You_cant("hold %s -- you have no hands!", doname(pick));
263.  		return(0);
264.  	}
265.  
266.  	if((picktyp != LOCK_PICK &&
267.  #ifdef TOURIST
268.  	    picktyp != CREDIT_CARD &&
269.  #endif
270.  	    picktyp != SKELETON_KEY)) {
271.  		impossible("picking lock with object %d?", picktyp);
272.  		return(0);
273.  	}
274.  	ch = 0;		/* lint suppression */
275.  
276.  	if(!get_adjacent_loc((char *)0, "Invalid location!", u.ux, u.uy, &cc)) return 0;
277.  	if (cc.x == u.ux && cc.y == u.uy) {	/* pick lock on a container */
278.  	    const char *verb;
279.  	    boolean it;
280.  	    int count;
281.  
282.  	    if (u.dz < 0) {
283.  		There("isn't any sort of lock up %s.",
284.  		      Levitation ? "here" : "there");
285.  		return 0;
286.  	    } else if (is_lava(u.ux, u.uy)) {
287.  		pline("Doing that would probably melt your %s.",
288.  		      xname(pick));
289.  		return 0;
290.  	    } else if (is_pool(u.ux, u.uy) && !Underwater) {
291.  		pline_The("water has no lock.");
292.  		return 0;
293.  	    }
294.  
295.  	    count = 0;
296.  	    c = 'n';			/* in case there are no boxes here */
297.  	    for(otmp = level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
298.  		if (Is_box(otmp)) {
299.  		    ++count;
300.  		    if (!can_reach_floor()) {
301.  			You_cant("reach %s from up here.", the(xname(otmp)));
302.  			return 0;
303.  		    }
304.  		    it = 0;
305.  		    if (otmp->obroken) verb = "fix";
306.  		    else if (!otmp->olocked) verb = "lock", it = 1;
307.  		    else if (picktyp != LOCK_PICK) verb = "unlock", it = 1;
308.  		    else verb = "pick";
309.  		    Sprintf(qbuf, "There is %s here, %s %s?",
310.  		    	    safe_qbuf("", sizeof("There is  here, unlock its lock?"),
311.  			    	doname(otmp), an(simple_typename(otmp->otyp)), "a box"),
312.  			    verb, it ? "it" : "its lock");
313.  
314.  		    c = ynq(qbuf);
315.  		    if(c == 'q') return(0);
316.  		    if(c == 'n') continue;
317.  
318.  		    if (otmp->obroken) {
319.  			You_cant("fix its broken lock with %s.", doname(pick));
320.  			return 0;
321.  		    }
322.  #ifdef TOURIST
323.  		    else if (picktyp == CREDIT_CARD && !otmp->olocked) {
324.  			/* credit cards are only good for unlocking */
325.  			You_cant("do that with %s.", doname(pick));
326.  			return 0;
327.  		    }
328.  #endif
329.  		    switch(picktyp) {
330.  #ifdef TOURIST
331.  			case CREDIT_CARD:
332.  			    ch = ACURR(A_DEX) + 20*Role_if(PM_ROGUE);
333.  			    break;
334.  #endif
335.  			case LOCK_PICK:
336.  			    ch = 4*ACURR(A_DEX) + 25*Role_if(PM_ROGUE);
337.  			    break;
338.  			case SKELETON_KEY:
339.  			    ch = 75 + ACURR(A_DEX);
340.  			    break;
341.  			default:	ch = 0;
342.  		    }
343.  		    if(otmp->cursed) ch /= 2;
344.  
345.  		    xlock.picktyp = picktyp;
346.  		    xlock.box = otmp;
347.  		    xlock.door = 0;
348.  		    break;
349.  		}
350.  	    if (c != 'y') {
351.  		if (!count)
352.  		    There("doesn't seem to be any sort of lock here.");
353.  		return(0);		/* decided against all boxes */
354.  	    }
355.  	} else {			/* pick the lock in a door */
356.  	    struct monst *mtmp;
357.  
358.  	    if (u.utrap && u.utraptype == TT_PIT) {
359.  		You_cant("reach over the edge of the pit.");
360.  		return(0);
361.  	    }
362.  
363.  	    door = &levl[cc.x][cc.y];
364.  	    if ((mtmp = m_at(cc.x, cc.y)) && canseemon(mtmp)
365.  			&& mtmp->m_ap_type != M_AP_FURNITURE
366.  			&& mtmp->m_ap_type != M_AP_OBJECT) {
367.  #ifdef TOURIST
368.  		if (picktyp == CREDIT_CARD &&
369.  		    (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]))
370.  		    verbalize("No checks, no credit, no problem.");
371.  		else
372.  #endif
373.  		    pline("I don't think %s would appreciate that.", mon_nam(mtmp));
374.  		return(0);
375.  	    }
376.  	    if(!IS_DOOR(door->typ)) {
377.  		if (is_drawbridge_wall(cc.x,cc.y) >= 0)
378.  		    You("%s no lock on the drawbridge.",
379.  				Blind ? "feel" : "see");
380.  		else
381.  		    You("%s no door there.",
382.  				Blind ? "feel" : "see");
383.  		return(0);
384.  	    }
385.  	    switch (door->doormask) {
386.  		case D_NODOOR:
387.  		    pline("This doorway has no door.");
388.  		    return(0);
389.  		case D_ISOPEN:
390.  		    You("cannot lock an open door.");
391.  		    return(0);
392.  		case D_BROKEN:
393.  		    pline("This door is broken.");
394.  		    return(0);
395.  		default:
396.  #ifdef TOURIST
397.  		    /* credit cards are only good for unlocking */
398.  		    if(picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
399.  			You_cant("lock a door with a credit card.");
400.  			return(0);
401.  		    }
402.  #endif
403.  
404.  		    Sprintf(qbuf,"%sock it?",
405.  			(door->doormask & D_LOCKED) ? "Unl" : "L" );
406.  
407.  		    c = yn(qbuf);
408.  		    if(c == 'n') return(0);
409.  
410.  		    switch(picktyp) {
411.  #ifdef TOURIST
412.  			case CREDIT_CARD:
413.  			    ch = 2*ACURR(A_DEX) + 20*Role_if(PM_ROGUE);
414.  			    break;
415.  #endif
416.  			case LOCK_PICK:
417.  			    ch = 3*ACURR(A_DEX) + 30*Role_if(PM_ROGUE);
418.  			    break;
419.  			case SKELETON_KEY:
420.  			    ch = 70 + ACURR(A_DEX);
421.  			    break;
422.  			default:    ch = 0;
423.  		    }
424.  		    xlock.door = door;
425.  		    xlock.box = 0;
426.  	    }
427.  	}
428.  	flags.move = 0;
429.  	xlock.chance = ch;
430.  	xlock.picktyp = picktyp;
431.  	xlock.usedtime = 0;
432.  	set_occupation(picklock, lock_action(), 0);
433.  	return(1);
434.  }
435.  

doforce Edit

436.  int
437.  doforce()		/* try to force a chest with your weapon */
438.  {
439.  	register struct obj *otmp;
440.  	register int c, picktyp;
441.  	char qbuf[QBUFSZ];
442.  
443.  	if(!uwep ||	/* proper type test */
444.  	   (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep) &&
445.  	    uwep->oclass != ROCK_CLASS) ||
446.  	   (objects[uwep->otyp].oc_skill < P_DAGGER) ||
447.  	   (objects[uwep->otyp].oc_skill > P_LANCE) ||
448.  	   uwep->otyp == FLAIL || uwep->otyp == AKLYS
449.  #ifdef KOPS
450.  	   || uwep->otyp == RUBBER_HOSE
451.  #endif
452.  	  ) {
453.  	    You_cant("force anything without a %sweapon.",
454.  		  (uwep) ? "proper " : "");
455.  	    return(0);
456.  	}
457.  
458.  	picktyp = is_blade(uwep);
459.  	if(xlock.usedtime && xlock.box && picktyp == xlock.picktyp) {
460.  	    You("resume your attempt to force the lock.");
461.  	    set_occupation(forcelock, "forcing the lock", 0);
462.  	    return(1);
463.  	}
464.  
465.  	/* A lock is made only for the honest man, the thief will break it. */
466.  	xlock.box = (struct obj *)0;
467.  	for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere)
468.  	    if(Is_box(otmp)) {
469.  		if (otmp->obroken || !otmp->olocked) {
470.  		    There("is %s here, but its lock is already %s.",
471.  			  doname(otmp), otmp->obroken ? "broken" : "unlocked");
472.  		    continue;
473.  		}
474.  		Sprintf(qbuf,"There is %s here, force its lock?",
475.  			safe_qbuf("", sizeof("There is  here, force its lock?"),
476.  				doname(otmp), an(simple_typename(otmp->otyp)),
477.  				"a box"));
478.  
479.  		c = ynq(qbuf);
480.  		if(c == 'q') return(0);
481.  		if(c == 'n') continue;
482.  
483.  		if(picktyp)
484.  		    You("force your %s into a crack and pry.", xname(uwep));
485.  		else
486.  		    You("start bashing it with your %s.", xname(uwep));
487.  		xlock.box = otmp;
488.  		xlock.chance = objects[uwep->otyp].oc_wldam * 2;
489.  		xlock.picktyp = picktyp;
490.  		xlock.usedtime = 0;
491.  		break;
492.  	    }
493.  
494.  	if(xlock.box)	set_occupation(forcelock, "forcing the lock", 0);
495.  	else		You("decide not to force the issue.");
496.  	return(1);
497.  }
498.  

doopen Edit

499.  int
500.  doopen()		/* try to open a door */
501.  {
502.  	coord cc;
503.  	register struct rm *door;
504.  	struct monst *mtmp;
505.  
506.  	if (nohands(youmonst.data)) {
507.  	    You_cant("open anything -- you have no hands!");
508.  	    return 0;
509.  	}
510.  
511.  	if (u.utrap && u.utraptype == TT_PIT) {
512.  	    You_cant("reach over the edge of the pit.");
513.  	    return 0;
514.  	}
515.  
516.  	if(!get_adjacent_loc((char *)0, (char *)0, u.ux, u.uy, &cc)) return(0);
517.  
518.  	if((cc.x == u.ux) && (cc.y == u.uy)) return(0);
519.  
520.  	if ((mtmp = m_at(cc.x,cc.y))			&&
521.  		mtmp->m_ap_type == M_AP_FURNITURE	&&
522.  		(mtmp->mappearance == S_hcdoor ||
523.  			mtmp->mappearance == S_vcdoor)	&&
524.  		!Protection_from_shape_changers)	 {
525.  
526.  	    stumble_onto_mimic(mtmp);
527.  	    return(1);
528.  	}
529.  
530.  	door = &levl[cc.x][cc.y];
531.  
532.  	if(!IS_DOOR(door->typ)) {
533.  		if (is_db_wall(cc.x,cc.y)) {
534.  		    There("is no obvious way to open the drawbridge.");
535.  		    return(0);
536.  		}
537.  		You("%s no door there.",
538.  				Blind ? "feel" : "see");
539.  		return(0);
540.  	}
541.  
542.  	if (!(door->doormask & D_CLOSED)) {
543.  	    const char *mesg;
544.  
545.  	    switch (door->doormask) {
546.  	    case D_BROKEN: mesg = " is broken"; break;
547.  	    case D_NODOOR: mesg = "way has no door"; break;
548.  	    case D_ISOPEN: mesg = " is already open"; break;
549.  	    default:	   mesg = " is locked"; break;
550.  	    }
551.  	    pline("This door%s.", mesg);
552.  	    if (Blind) feel_location(cc.x,cc.y);
553.  	    return(0);
554.  	}
555.  
556.  	if(verysmall(youmonst.data)) {
557.  	    pline("You're too small to pull the door open.");
558.  	    return(0);
559.  	}
560.  
561.  	/* door is known to be CLOSED */
562.  	if (rnl(20) < (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3) {
563.  	    pline_The("door opens.");
564.  	    if(door->doormask & D_TRAPPED) {
565.  		b_trapped("door", FINGER);
566.  		door->doormask = D_NODOOR;
567.  		if (*in_rooms(cc.x, cc.y, SHOPBASE)) add_damage(cc.x, cc.y, 0L);
568.  	    } else
569.  		door->doormask = D_ISOPEN;
570.  	    if (Blind)
571.  		feel_location(cc.x,cc.y);	/* the hero knows she opened it  */
572.  	    else
573.  		newsym(cc.x,cc.y);
574.  	    unblock_point(cc.x,cc.y);		/* vision: new see through there */
575.  	} else {
576.  	    exercise(A_STR, TRUE);
577.  	    pline_The("door resists!");
578.  	}
579.  
580.  	return(1);
581.  }
582.  

obstructed Edit

583.  STATIC_OVL
584.  boolean
585.  obstructed(x,y)
586.  register int x, y;
587.  {
588.  	register struct monst *mtmp = m_at(x, y);
589.  
590.  	if(mtmp && mtmp->m_ap_type != M_AP_FURNITURE) {
591.  		if (mtmp->m_ap_type == M_AP_OBJECT) goto objhere;
592.  		pline("%s stands in the way!", !canspotmon(mtmp) ?
593.  			"Some creature" : Monnam(mtmp));
594.  		if (!canspotmon(mtmp))
595.  		    map_invisible(mtmp->mx, mtmp->my);
596.  		return(TRUE);
597.  	}
598.  	if (OBJ_AT(x, y)) {
599.  objhere:	pline("%s's in the way.", Something);
600.  		return(TRUE);
601.  	}
602.  	return(FALSE);
603.  }
604.  

doclose Edit

605.  int
606.  doclose()		/* try to close a door */
607.  {
608.  	register int x, y;
609.  	register struct rm *door;
610.  	struct monst *mtmp;
611.  
612.  	if (nohands(youmonst.data)) {
613.  	    You_cant("close anything -- you have no hands!");
614.  	    return 0;
615.  	}
616.  
617.  	if (u.utrap && u.utraptype == TT_PIT) {
618.  	    You_cant("reach over the edge of the pit.");
619.  	    return 0;
620.  	}
621.  
622.  	if(!getdir((char *)0)) return(0);
623.  
624.  	x = u.ux + u.dx;
625.  	y = u.uy + u.dy;
626.  	if((x == u.ux) && (y == u.uy)) {
627.  		You("are in the way!");
628.  		return(1);
629.  	}
630.  
631.  	if ((mtmp = m_at(x,y))				&&
632.  		mtmp->m_ap_type == M_AP_FURNITURE	&&
633.  		(mtmp->mappearance == S_hcdoor ||
634.  			mtmp->mappearance == S_vcdoor)	&&
635.  		!Protection_from_shape_changers)	 {
636.  
637.  	    stumble_onto_mimic(mtmp);
638.  	    return(1);
639.  	}
640.  
641.  	door = &levl[x][y];
642.  
643.  	if(!IS_DOOR(door->typ)) {
644.  		if (door->typ == DRAWBRIDGE_DOWN)
645.  		    There("is no obvious way to close the drawbridge.");
646.  		else
647.  		    You("%s no door there.",
648.  				Blind ? "feel" : "see");
649.  		return(0);
650.  	}
651.  
652.  	if(door->doormask == D_NODOOR) {
653.  	    pline("This doorway has no door.");
654.  	    return(0);
655.  	}
656.  
657.  	if(obstructed(x, y)) return(0);
658.  
659.  	if(door->doormask == D_BROKEN) {
660.  	    pline("This door is broken.");
661.  	    return(0);
662.  	}
663.  
664.  	if(door->doormask & (D_CLOSED | D_LOCKED)) {
665.  	    pline("This door is already closed.");
666.  	    return(0);
667.  	}
668.  
669.  	if(door->doormask == D_ISOPEN) {
670.  	    if(verysmall(youmonst.data)
671.  #ifdef STEED
672.  		&& !u.usteed
673.  #endif
674.  		) {
675.  		 pline("You're too small to push the door closed.");
676.  		 return(0);
677.  	    }
678.  	    if (
679.  #ifdef STEED
680.  		 u.usteed ||
681.  #endif
682.  		rn2(25) < (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3) {
683.  		pline_The("door closes.");
684.  		door->doormask = D_CLOSED;
685.  		if (Blind)
686.  		    feel_location(x,y);	/* the hero knows she closed it */
687.  		else
688.  		    newsym(x,y);
689.  		block_point(x,y);	/* vision:  no longer see there */
690.  	    }
691.  	    else {
692.  	        exercise(A_STR, TRUE);
693.  	        pline_The("door resists!");
694.  	    }
695.  	}
696.  
697.  	return(1);
698.  }
699.  

boxlock Edit

700.  boolean			/* box obj was hit with spell effect otmp */
701.  boxlock(obj, otmp)	/* returns true if something happened */
702.  register struct obj *obj, *otmp;	/* obj *is* a box */
703.  {
704.  	register boolean res = 0;
705.  
706.  	switch(otmp->otyp) {
707.  	case WAN_LOCKING:
708.  	case SPE_WIZARD_LOCK:
709.  	    if (!obj->olocked) {	/* lock it; fix if broken */
710.  		pline("Klunk!");
711.  		obj->olocked = 1;
712.  		obj->obroken = 0;
713.  		res = 1;
714.  	    } /* else already closed and locked */
715.  	    break;
716.  	case WAN_OPENING:
717.  	case SPE_KNOCK:
718.  	    if (obj->olocked) {		/* unlock; couldn't be broken */
719.  		pline("Klick!");
720.  		obj->olocked = 0;
721.  		res = 1;
722.  	    } else			/* silently fix if broken */
723.  		obj->obroken = 0;
724.  	    break;
725.  	case WAN_POLYMORPH:
726.  	case SPE_POLYMORPH:
727.  	    /* maybe start unlocking chest, get interrupted, then zap it;
728.  	       we must avoid any attempt to resume unlocking it */
729.  	    if (xlock.box == obj)
730.  		reset_pick();
731.  	    break;
732.  	}
733.  	return res;
734.  }
735.  

doorlock Edit

736.  boolean			/* Door/secret door was hit with spell effect otmp */
737.  doorlock(otmp,x,y)	/* returns true if something happened */
738.  struct obj *otmp;
739.  int x, y;
740.  {
741.  	register struct rm *door = &levl[x][y];
742.  	boolean res = TRUE;
743.  	int loudness = 0;
744.  	const char *msg = (const char *)0;
745.  	const char *dustcloud = "A cloud of dust";
746.  	const char *quickly_dissipates = "quickly dissipates";
747.  	
748.  	if (door->typ == SDOOR) {
749.  	    switch (otmp->otyp) {
750.  	    case WAN_OPENING:
751.  	    case SPE_KNOCK:
752.  	    case WAN_STRIKING:
753.  	    case SPE_FORCE_BOLT:
754.  		door->typ = DOOR;
755.  		door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
756.  		newsym(x,y);
757.  		if (cansee(x,y)) pline("A door appears in the wall!");
758.  		if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK)
759.  		    return TRUE;
760.  		break;		/* striking: continue door handling below */
761.  	    case WAN_LOCKING:
762.  	    case SPE_WIZARD_LOCK:
763.  	    default:
764.  		return FALSE;
765.  	    }
766.  	}
767.  
768.  	switch(otmp->otyp) {
769.  	case WAN_LOCKING:
770.  	case SPE_WIZARD_LOCK:
771.  #ifdef REINCARNATION
772.  	    if (Is_rogue_level(&u.uz)) {
773.  	    	boolean vis = cansee(x,y);
774.  		/* Can't have real locking in Rogue, so just hide doorway */
775.  		if (vis) pline("%s springs up in the older, more primitive doorway.",
776.  			dustcloud);
777.  		else
778.  			You_hear("a swoosh.");
779.  		if (obstructed(x,y)) {
780.  			if (vis) pline_The("cloud %s.",quickly_dissipates);
781.  			return FALSE;
782.  		}
783.  		block_point(x, y);
784.  		door->typ = SDOOR;
785.  		if (vis) pline_The("doorway vanishes!");
786.  		newsym(x,y);
787.  		return TRUE;
788.  	    }
789.  #endif
790.  	    if (obstructed(x,y)) return FALSE;
791.  	    /* Don't allow doors to close over traps.  This is for pits */
792.  	    /* & trap doors, but is it ever OK for anything else? */
793.  	    if (t_at(x,y)) {
794.  		/* maketrap() clears doormask, so it should be NODOOR */
795.  		pline(
796.  		"%s springs up in the doorway, but %s.",
797.  		dustcloud, quickly_dissipates);
798.  		return FALSE;
799.  	    }
800.  
801.  	    switch (door->doormask & ~D_TRAPPED) {
802.  	    case D_CLOSED:
803.  		msg = "The door locks!";
804.  		break;
805.  	    case D_ISOPEN:
806.  		msg = "The door swings shut, and locks!";
807.  		break;
808.  	    case D_BROKEN:
809.  		msg = "The broken door reassembles and locks!";
810.  		break;
811.  	    case D_NODOOR:
812.  		msg =
813.  		"A cloud of dust springs up and assembles itself into a door!";
814.  		break;
815.  	    default:
816.  		res = FALSE;
817.  		break;
818.  	    }
819.  	    block_point(x, y);
820.  	    door->doormask = D_LOCKED | (door->doormask & D_TRAPPED);
821.  	    newsym(x,y);
822.  	    break;
823.  	case WAN_OPENING:
824.  	case SPE_KNOCK:
825.  	    if (door->doormask & D_LOCKED) {
826.  		msg = "The door unlocks!";
827.  		door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
828.  	    } else res = FALSE;
829.  	    break;
830.  	case WAN_STRIKING:
831.  	case SPE_FORCE_BOLT:
832.  	    if (door->doormask & (D_LOCKED | D_CLOSED)) {
833.  		if (door->doormask & D_TRAPPED) {
834.  		    if (MON_AT(x, y))
835.  			(void) mb_trapped(m_at(x,y));
836.  		    else if (flags.verbose) {
837.  			if (cansee(x,y))
838.  			    pline("KABOOM!!  You see a door explode.");
839.  			else if (flags.soundok)
840.  			    You_hear("a distant explosion.");
841.  		    }
842.  		    door->doormask = D_NODOOR;
843.  		    unblock_point(x,y);
844.  		    newsym(x,y);
845.  		    loudness = 40;
846.  		    break;
847.  		}
848.  		door->doormask = D_BROKEN;
849.  		if (flags.verbose) {
850.  		    if (cansee(x,y))
851.  			pline_The("door crashes open!");
852.  		    else if (flags.soundok)
853.  			You_hear("a crashing sound.");
854.  		}
855.  		unblock_point(x,y);
856.  		newsym(x,y);
857.  		/* force vision recalc before printing more messages */
858.  		if (vision_full_recalc) vision_recalc(0);
859.  		loudness = 20;
860.  	    } else res = FALSE;
861.  	    break;
862.  	default: impossible("magic (%d) attempted on door.", otmp->otyp);
863.  	    break;
864.  	}
865.  	if (msg && cansee(x,y)) pline(msg);
866.  	if (loudness > 0) {
867.  	    /* door was destroyed */
868.  	    wake_nearto(x, y, loudness);
869.  	    if (*in_rooms(x, y, SHOPBASE)) add_damage(x, y, 0L);
870.  	}
871.  
872.  	if (res && picking_at(x, y)) {
873.  	    /* maybe unseen monster zaps door you're unlocking */
874.  	    stop_occupation();
875.  	    reset_pick();
876.  	}
877.  	return res;
878.  }
879.  

chest_shatter_msg Edit

880.  STATIC_OVL void
881.  chest_shatter_msg(otmp)
882.  struct obj *otmp;
883.  {
884.  	const char *disposition;
885.  	const char *thing;
886.  	long save_Blinded;
887.  
888.  	if (otmp->oclass == POTION_CLASS) {
889.  		You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename()));
890.  		if (!breathless(youmonst.data) || haseyes(youmonst.data))
891.  			potionbreathe(otmp);
892.  		return;
893.  	}
894.  	/* We have functions for distant and singular names, but not one */
895.  	/* which does _both_... */
896.  	save_Blinded = Blinded;
897.  	Blinded = 1;
898.  	thing = singular(otmp, xname);
899.  	Blinded = save_Blinded;
900.  	switch (objects[otmp->otyp].oc_material) {
901.  	case PAPER:	disposition = "is torn to shreds";
902.  		break;
903.  	case WAX:	disposition = "is crushed";
904.  		break;
905.  	case VEGGY:	disposition = "is pulped";
906.  		break;
907.  	case FLESH:	disposition = "is mashed";
908.  		break;
909.  	case GLASS:	disposition = "shatters";
910.  		break;
911.  	case WOOD:	disposition = "splinters to fragments";
912.  		break;
913.  	default:	disposition = "is destroyed";
914.  		break;
915.  	}
916.  	pline("%s %s!", An(thing), disposition);
917.  }
918.  
919.  #endif /* OVLB */
920.  
921.  /*lock.c*/

Around Wikia's network

Random Wiki