Wikia

Wikihack

Source:SLASH'EM 0.0.7E7F2/lock.c

2,032pages on
this wiki
Talk0

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

Around Wikia's network

Random Wiki