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. */
7 STATIC_PTR
int picklock(void);
8 STATIC_PTR
int forcelock(void);
9 STATIC_PTR
int forcedoor(void);
11 /* at most one of `door' and `box' should be non-null at any given time */
12 STATIC_VAR NEARDATA
struct xlock_s
{
15 int picktyp
, chance
, usedtime
;
16 /* ALI - Artifact doors */
17 int key
; /* Key being used (doors only) */
22 STATIC_DCL
const char *lock_action(void);
23 STATIC_DCL boolean
obstructed(int,int);
24 STATIC_DCL
void chest_shatter_msg(struct obj
*);
30 if (occupation
== picklock
|| occupation
== forcedoor
) {
44 return (boolean
)(occupation
== picklock
&& xlock
.door
== &levl
[x
][y
]);
47 /* produce an occupation string appropriate for the current activity */
48 STATIC_OVL
const char *
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"
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
|| xlock
.box
->otyp
== NANO_CHEST
|| xlock
.box
->otyp
== CHEST_OF_HOLDING
) ? 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 else if (xlock
.picktyp
== HAIRCLIP
)
68 return actions
[3]; /* "picking the lock" */
69 else if (xlock
.picktyp
== CREDIT_CARD
)
70 return actions
[3]; /* same as lock_pick */
71 else if (xlock
.picktyp
== DATA_CHIP
)
72 return actions
[3]; /* same as lock_pick */
74 return actions
[0]; /* "unlocking the door" */
76 return (xlock
.box
->otyp
== CHEST
|| xlock
.box
->otyp
== NANO_CHEST
|| xlock
.box
->otyp
== CHEST_OF_HOLDING
) ? actions
[1] : actions
[2];
81 picklock() /* try to open/close a lock */
83 register struct obj
*trophy
;
86 if((xlock
.box
->ox
!= u
.ux
) || (xlock
.box
->oy
!= u
.uy
)) {
87 return((xlock
.usedtime
= 0)); /* you or it moved */
90 if(xlock
.door
!= &(levl
[u
.ux
+u
.dx
][u
.uy
+u
.dy
])) {
91 return((xlock
.usedtime
= 0)); /* you moved */
93 switch (xlock
.door
->doormask
) {
95 pline("This doorway has no door.");
96 return((xlock
.usedtime
= 0));
98 You("cannot lock an open door.");
99 return((xlock
.usedtime
= 0));
101 pline("This door is broken.");
102 return((xlock
.usedtime
= 0));
106 if (xlock
.usedtime
++ >= 50 ) {
107 You("give up your attempt at %s.", lock_action());
108 exercise(A_DEX
, TRUE
); /* even if you don't succeed */
109 return((xlock
.usedtime
= 0));
112 if(rn2(100) >= xlock
.chance
) return(1); /* still busy */
113 if(isfriday
&& (rn2(100) >= xlock
.chance
)) return(1); /* still busy */
115 You("succeed in %s.", lock_action());
117 if(xlock
.door
->doormask
& D_TRAPPED
) {
118 b_trapped("door", FINGER
);
119 xlock
.door
->doormask
= D_NODOOR
;
120 unblock_point(u
.ux
+u
.dx
, u
.uy
+u
.dy
);
121 if (*in_rooms(u
.ux
+u
.dx
, u
.uy
+u
.dy
, SHOPBASE
))
122 add_damage(u
.ux
+u
.dx
, u
.uy
+u
.dy
, 0L);
123 newsym(u
.ux
+u
.dx
, u
.uy
+u
.dy
);
124 } else if(xlock
.door
->doormask
== D_LOCKED
) {
125 xlock
.door
->doormask
= D_CLOSED
;
126 u
.cnd_unlockamount
++;
127 } else xlock
.door
->doormask
= D_LOCKED
;
129 /* better handling for special doors in Vlad's: only give the rewards if you actually unlock them --Amy */
130 if (artifact_door(u
.ux
+u
.dx
, u
.uy
+u
.dy
) && !strcmp(dungeons
[u
.uz
.dnum
].dname
, "Vlad's Tower")) {
132 switch (artifact_door(u
.ux
+u
.dx
, u
.uy
+u
.dy
)) {
134 case ART_MASTER_KEY_OF_THIEVERY
:
137 pline("Congratulations, a reward for picking this lock was dropped at your %s!", makeplural(body_part(FOOT
)));
138 trophy
= mksobj(STONE_OF_MAGIC_RESISTANCE
, TRUE
, FALSE
, FALSE
);
144 case ART_NOCTURNAL_KEY
:
147 pline("Congratulations, a reward for picking this lock was dropped at your %s!", makeplural(body_part(FOOT
)));
148 trophy
= mksobj(SPE_PASSWALL
, TRUE
, FALSE
, FALSE
);
154 case ART_KEY_OF_ACCESS
:
157 pline("Congratulations, a reward for picking this lock was dropped at your %s!", makeplural(body_part(FOOT
)));
158 trophy
= mksobj(SPE_GODMODE
, TRUE
, FALSE
, FALSE
);
164 case ART_GAUNTLET_KEY
:
165 if (!u
.keygauntlet
) {
166 u
.keygauntlet
= TRUE
;
167 pline("Congratulations, a reward for picking this lock was dropped at your %s!", makeplural(body_part(FOOT
)));
168 trophy
= mksobj(SCR_WISHING
, TRUE
, FALSE
, FALSE
);
182 xlock
.box
->olocked
= !xlock
.box
->olocked
;
183 if (!xlock
.box
->olocked
) u
.cnd_unlockamount
++;
184 if(xlock
.box
->otrapped
) {
185 if (Role_if(PM_CYBERNINJA
) && rn2(5)) You("also disarm the trap you found on it.");
186 else (void) chest_trap(xlock
.box
, FINGER
, FALSE
);
189 exercise(A_DEX
, TRUE
);
190 return((xlock
.usedtime
= 0));
195 forcelock() /* try to force a locked chest */
198 register struct obj
*otmp
;
200 if((xlock
.box
->ox
!= u
.ux
) || (xlock
.box
->oy
!= u
.uy
))
201 return((xlock
.usedtime
= 0)); /* you or it moved */
203 if (xlock
.usedtime
++ >= 50 || !uwep
) {
204 You("give up your attempt to force the lock.");
205 if(xlock
.usedtime
>= 50) /* you made the effort */
206 exercise((xlock
.picktyp
) ? A_DEX
: A_STR
, TRUE
);
207 return((xlock
.usedtime
= 0));
210 if(xlock
.picktyp
== 1) { /* blade */
212 if(rn2(1000 - (int)uwep
->spe
) > ((isfriday
? 980 : 992) - (greatest_erosionX(uwep
) * 10)) &&
213 !uwep
->cursed
&& !obj_resists(uwep
, 0, 99)) {
214 /* for a +0 weapon, probability that it survives an unsuccessful
215 * attempt to force the lock is (.992)^50 = .67 or on a friday the 13th (.980)^50 = .36
217 pline("%sour %s broke!",
218 (uwep
->quan
> 1L) ? "One of y" : "Y", xname(uwep
));
220 You("give up your attempt to force the lock.");
221 exercise(A_DEX
, TRUE
);
222 return((xlock
.usedtime
= 0));
224 } else if(xlock
.picktyp
== 0) /* blunt */
225 wake_nearby(); /* due to hammering on the container */
227 if(rn2(100) >= xlock
.chance
) return(1); /* still busy */
228 if(isfriday
&& (rn2(100) >= xlock
.chance
)) return(1); /* still busy */
230 You("succeed in forcing the lock.");
232 if (uwep
&& is_lightsaber(uwep
) && (uwep
->lamplit
|| Role_if(PM_SHADOW_JEDI
))) {
233 use_skill(P_WEDI
, 1);
235 if (uwep
&& uwep
->oartifact
== ART_DIGSRU
) {
236 use_skill(P_WEDI
, 1);
239 xlock
.box
->olocked
= 0;
240 xlock
.box
->obroken
= 1;
241 if((xlock
.picktyp
== 0 && !rn2(isfriday
? 2 : 3)) || (xlock
.picktyp
== 2 && !rn2(isfriday
? 3 : 5))) {
246 costly
= (*u
.ushops
&& costly_spot(u
.ux
, u
.uy
));
247 shkp
= costly
? shop_keeper(*u
.ushops
) : 0;
249 pline("In fact, you've totally destroyed %s.",
250 the(xname(xlock
.box
)));
252 /* Put the contents on ground at the hero's feet. */
253 while ((otmp
= xlock
.box
->cobj
) != 0) {
254 obj_extract_self(otmp
);
255 /* [ALI] Allowing containers to be destroyed is complicated
256 * (because they might contain indestructible objects).
257 * Since this is very unlikely to occur in practice simply
258 * avoid the possibility.
260 if (!evades_destruction(otmp
) && !Has_contents(otmp
) &&
261 (!rn2(isfriday
? 2 : 3) || otmp
->oclass
== POTION_CLASS
)) {
262 chest_shatter_msg(otmp
);
264 loss
+= stolen_value(otmp
, u
.ux
, u
.uy
,
265 (boolean
)shkp
->mpeaceful
, TRUE
,
267 if (otmp
->quan
== 1L) {
268 obfree(otmp
, (struct obj
*) 0);
273 if ( (xlock
.box
->otyp
== ICE_BOX
|| xlock
.box
->otyp
== DISPERSION_BOX
|| xlock
.box
->otyp
== ICE_BOX_OF_HOLDING
|| xlock
.box
->otyp
== ICE_BOX_OF_WATERPROOFING
|| xlock
.box
->otyp
== ICE_BOX_OF_DIGESTION
) && otmp
->otyp
== CORPSE
) {
274 otmp
->age
= monstermoves
- otmp
->age
; /* actual age */
275 otmp
->icedobject
= TRUE
;
276 start_corpse_timeout(otmp
);
278 place_object(otmp
, u
.ux
, u
.uy
);
283 loss
+= stolen_value(xlock
.box
, u
.ux
, u
.uy
,
284 (boolean
)shkp
->mpeaceful
, TRUE
, TRUE
);
285 if(loss
) You("owe %ld %s for objects destroyed.", loss
, currency(loss
));
288 exercise((xlock
.picktyp
) ? A_DEX
: A_STR
, TRUE
);
289 return((xlock
.usedtime
= 0));
294 forcedoor() /* try to break/pry open a door */
297 if(xlock
.door
!= &(levl
[u
.ux
+u
.dx
][u
.uy
+u
.dy
])) {
298 return((xlock
.usedtime
= 0)); /* you moved */
300 switch (xlock
.door
->doormask
) {
302 pline("This doorway has no door.");
303 return((xlock
.usedtime
= 0));
305 You("cannot lock an open door.");
306 return((xlock
.usedtime
= 0));
308 pline("This door is broken.");
309 return((xlock
.usedtime
= 0));
312 if (xlock
.usedtime
++ >= 50 ) {
313 You("give up your attempt at %s the door.",
314 (xlock
.picktyp
== 2 ? "melting" : xlock
.picktyp
== 1 ?
315 "prying open" : "breaking down"));
316 exercise(A_STR
, TRUE
); /* even if you don't succeed */
317 return((xlock
.usedtime
= 0));
320 if(rn2(100) > xlock
.chance
) return(1); /* still busy */
321 if(isfriday
&& (rn2(100) > xlock
.chance
)) return(1); /* still busy */
323 You("succeed in %s the door.",
324 (xlock
.picktyp
== 2 ? "melting" : xlock
.picktyp
== 1 ?
325 "prying open" : "breaking down"));
327 if(xlock
.door
->doormask
& D_TRAPPED
) {
328 b_trapped("door", 0);
329 xlock
.door
->doormask
= D_NODOOR
;
330 } else if (xlock
.picktyp
== 1)
331 xlock
.door
->doormask
= D_BROKEN
;
332 else xlock
.door
->doormask
= D_NODOOR
;
333 unblock_point(u
.ux
+u
.dx
, u
.uy
+u
.dy
);
334 if (*in_rooms(u
.ux
+u
.dx
, u
.uy
+u
.dy
, SHOPBASE
)) {
335 add_damage(u
.ux
+u
.dx
, u
.uy
+u
.dy
, 400L);
336 pay_for_damage("break", FALSE
);
338 if (in_town(u
.ux
+u
.dx
, u
.uy
+u
.dy
)) {
340 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
341 if (DEADMONSTER(mtmp
)) continue;
342 if((mtmp
->data
== &mons
[PM_WATCHMAN
] ||
343 mtmp
->data
== &mons
[PM_WATCH_CAPTAIN
]) &&
344 couldsee(mtmp
->mx
, mtmp
->my
) &&
346 if (canspotmon(mtmp
))
347 pline("%s yells:", Amonnam(mtmp
));
349 You_hear("someone yell:");
350 verbalize("Halt, thief! You're under arrest!");
351 (void) angry_guards(FALSE
);
358 feel_location(u
.ux
+u
.dx
, u
.uy
+u
.dy
); /* we know we broke it */
360 newsym(u
.ux
+u
.dx
, u
.uy
+u
.dy
);
362 exercise(A_STR
, TRUE
);
363 return((xlock
.usedtime
= 0));
372 xlock
.usedtime
= xlock
.chance
= xlock
.picktyp
= 0;
381 pick_lock(pickp
) /* pick a lock with a given object */
389 struct obj
*pick
= *pickp
;
391 boolean bypassartilock
= FALSE
;
393 picktyp
= pick
->otyp
;
395 /* check whether we're resuming an interrupted previous attempt */
396 if (xlock
.usedtime
&& picktyp
== xlock
.picktyp
) {
397 static char no_longer
[] = "Unfortunately, you can no longer %s %s.";
399 if (nohands(youmonst
.data
) && !Race_if(PM_TRANSFORMER
)) {
400 const char *what
= (picktyp
== LOCK_PICK
) ? "pick" : (picktyp
== HAIRCLIP
) ? "hairclip" : "key";
401 if (picktyp
== CREDIT_CARD
) what
= "card";
402 if (picktyp
== DATA_CHIP
) what
= "chip";
403 pline(no_longer
, "hold the", what
);
406 } else if (xlock
.box
&& !can_reach_floor()) {
407 pline(no_longer
, "reach the", "lock");
410 } else if (!xlock
.door
|| xlock
.key
== pick
->oartifact
) {
411 const char *action
= lock_action();
412 You("resume your attempt at %s.", action
);
413 set_occupation(picklock
, action
, 0);
414 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) picklock();
419 if(nohands(youmonst
.data
) && !Race_if(PM_TRANSFORMER
)) {
420 You_cant("hold %s -- you have no hands!", doname(pick
));
421 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
422 if (yn("Attempt it anyway?") == 'y') {
423 if (rn2(3) && !polyskillchance()) {
424 playerbleed(rnd(2 + (level_difficulty() * 10)));
425 pline("Great. Now your %s is squirting everywhere.", body_part(BLOOD
));
426 if (!rn2(20)) badeffect();
434 if((picktyp
!= LOCK_PICK
&&
435 picktyp
!= HAIRCLIP
&&
436 picktyp
!= CREDIT_CARD
&&
437 picktyp
!= DATA_CHIP
&&
438 picktyp
!= SECRET_KEY
&&
439 picktyp
!= CONTROVERSY_CODE
&&
440 picktyp
!= SKELETON_KEY
)) {
441 impossible("picking lock with object %d?", picktyp
);
444 ch
= 0; /* lint suppression */
446 if(!get_adjacent_loc((char *)0, "Invalid location!", u
.ux
, u
.uy
, &cc
)) return 0;
447 if (cc
.x
== u
.ux
&& cc
.y
== u
.uy
) { /* pick lock on a container */
453 There("isn't any sort of lock up %s.",
454 Levitation
? "here" : "there");
456 } else if (is_lava(u
.ux
, u
.uy
)) {
457 pline("Doing that would probably melt your %s.",
460 } else if (is_waterypool(u
.ux
, u
.uy
) && !is_crystalwater(u
.ux
, u
.uy
) && !Underwater
) {
461 pline_The("water has no lock.");
466 c
= 'n'; /* in case there are no boxes here */
467 for(otmp
= level
.objects
[cc
.x
][cc
.y
]; otmp
; otmp
= otmp
->nexthere
)
470 if (!can_reach_floor()) {
471 You_cant("reach %s from up here.", the(xname(otmp
)));
475 if (otmp
->obroken
) verb
= "fix";
476 else if (!otmp
->olocked
) verb
= "lock", it
= 1;
477 else if (picktyp
!= LOCK_PICK
&& picktyp
!= HAIRCLIP
) verb
= "unlock", it
= 1;
479 sprintf(qbuf
, "There is %s here, %s %s?",
480 safe_qbuf("", sizeof("There is here, unlock its lock?"),
481 doname(otmp
), an(simple_typename(otmp
->otyp
)), "a box"),
482 verb
, it
? "it" : "its lock");
485 if(c
== 'q') return(0);
486 if(c
== 'n') continue;
488 if (pick
->oartifact
&& !(pick
->oartifact
== ART_UNBRIT_SOV
) && (pick
->obrittle
|| pick
->obrittle2
) ) {
489 Your("key doesn't seem to fit.");
494 You_cant("fix its broken lock with %s.", doname(pick
));
497 else if (picktyp
== CREDIT_CARD
&& !otmp
->olocked
) {
498 /* credit cards are only good for unlocking */
499 You_cant("do that with %s.", doname(pick
));
502 else if (picktyp
== DATA_CHIP
&& !otmp
->olocked
) {
503 You_cant("do that with %s.", doname(pick
));
508 if(!rn2(isfriday
? 10 : 20) && (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
509 Your("credit card breaks in half!");
511 *pickp
= (struct obj
*)0;
514 if(!rn2(isfriday
? 10 : 20) && (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
515 Your("credit card becomes dull and is no longer capable of picking locks!");
516 pick
->obrittle
= pick
->obrittle2
= 3;
519 ch
= ACURR(A_DEX
) + 20*Role_if(PM_ROGUE
) + 40*Role_if(PM_LOCKSMITH
) + 20*Role_if(PM_CYBERNINJA
);
522 if(!rn2(isfriday
? 10 : 20) && (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
523 Your("data chip breaks in half!");
525 *pickp
= (struct obj
*)0;
528 if(!rn2(isfriday
? 10 : 20) && (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
529 Your("data chip becomes dull and is no longer capable of picking locks!");
530 pick
->obrittle
= pick
->obrittle2
= 3;
533 ch
= ACURR(A_DEX
) + 20*Role_if(PM_ROGUE
) + 40*Role_if(PM_LOCKSMITH
) + 20*Role_if(PM_CYBERNINJA
);
537 if(!rn2(isfriday
? 20 : Role_if(PM_LOCKSMITH
) ? 60: (Role_if(PM_ROGUE
) || Role_if(PM_CYBERNINJA
)) ? 40 : 30) &&
538 (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
539 You("break your pick!");
541 *pickp
= (struct obj
*)0;
544 if(!rn2(isfriday
? 20 : Role_if(PM_LOCKSMITH
) ? 60: (Role_if(PM_ROGUE
) || Role_if(PM_CYBERNINJA
)) ? 40 : 30) &&
545 (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
546 if (pick
->oartifact
== ART_DITHERS_WUMA
) {
547 FemaleTrapJette
+= 50000;
548 pline_The("power of feminism compels you.");
550 Your("pick becomes brittle and is no longer capable of picking locks!");
551 pick
->obrittle
= pick
->obrittle2
= 3;
555 ch
= 4*ACURR(A_DEX
) + 25*Role_if(PM_ROGUE
) + 50*Role_if(PM_LOCKSMITH
) + 30*Role_if(PM_CYBERNINJA
);
558 case CONTROVERSY_CODE
:
560 if(!rn2(isfriday
? 7 : 15) && !(pick
->oartifact
== ART_VANULLA_SCORE
) && (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
561 Your("key didn't quite fit the lock and snapped!");
563 *pickp
= (struct obj
*)0;
566 if(!rn2(isfriday
? 7 : 15) && !(pick
->oartifact
== ART_VANULLA_SCORE
) && (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
567 Your("key becomes brittle and is no longer capable of picking locks!");
568 if (pick
->oartifact
== ART_UNBRIT_SOV
) {
569 u
.badfcursed
+= 10000;
570 if (pick
->obrittle
|| pick
->obrittle2
) u
.badfdoomed
+= 10000;
572 pick
->obrittle
= pick
->obrittle2
= 3;
575 ch
= 75 + ACURR(A_DEX
);
579 if(otmp
->cursed
) ch
/= 2;
581 xlock
.picktyp
= picktyp
;
588 There("doesn't seem to be any sort of lock here.");
589 return(0); /* decided against all boxes */
591 } else { /* pick the lock in a door */
594 if (u
.utrap
&& u
.utraptype
== TT_PIT
) {
595 You_cant("reach over the edge of the pit.");
599 door
= &levl
[cc
.x
][cc
.y
];
600 if ((mtmp
= m_at(cc
.x
, cc
.y
)) && canseemon(mtmp
)
601 && mtmp
->m_ap_type
!= M_AP_FURNITURE
602 && mtmp
->m_ap_type
!= M_AP_OBJECT
) {
603 if (picktyp
== CREDIT_CARD
&&
604 (mtmp
->isshk
|| mtmp
->data
== &mons
[PM_ORACLE
]))
605 verbalize("No checks, no credit, no problem.");
607 pline("I don't think %s would appreciate that.", mon_nam(mtmp
));
610 if(!IS_DOOR(door
->typ
)) {
611 if (is_drawbridge_wall(cc
.x
,cc
.y
) >= 0)
612 You("%s no lock on the drawbridge.",
613 Blind
? "feel" : "see");
615 You("%s no door there.",
616 Blind
? "feel" : "see");
619 switch (door
->doormask
) {
621 pline("This doorway has no door.");
624 You("cannot lock an open door.");
627 pline("This door is broken.");
630 /* credit cards are only good for unlocking */
631 if(picktyp
== CREDIT_CARD
&& !(door
->doormask
& D_LOCKED
)) {
632 You_cant("lock a door with a credit card.");
635 if(picktyp
== DATA_CHIP
&& !(door
->doormask
& D_LOCKED
)) {
636 You_cant("lock a door with a data chip.");
639 /* ALI - Artifact doors */
640 key
= artifact_door(cc
.x
, cc
.y
);
642 sprintf(qbuf
,"%sock it?",
643 (door
->doormask
& D_LOCKED
) ? "Unl" : "L" );
646 if(c
== 'n') return(0);
650 if(!rn2(isfriday
? 10 : Role_if(PM_LOCKSMITH
) ? 40 : (Role_if(PM_TOURIST
) || Role_if(PM_CYBERNINJA
)) ? 30 : 20) &&
651 (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
652 You("break your card off in the door!");
654 *pickp
= (struct obj
*)0;
657 if(!rn2(isfriday
? 10 : Role_if(PM_LOCKSMITH
) ? 40 : (Role_if(PM_TOURIST
) || Role_if(PM_CYBERNINJA
)) ? 30 : 20) &&
658 (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
659 Your("credit card becomes dull and is no longer capable of picking locks!");
660 pick
->obrittle
= pick
->obrittle2
= 3;
663 ch
= 2*ACURR(A_DEX
) + 20*Role_if(PM_ROGUE
) + 40*Role_if(PM_LOCKSMITH
) + 20*Role_if(PM_CYBERNINJA
);
666 if(!rn2(isfriday
? 10 : Role_if(PM_LOCKSMITH
) ? 40 : (Role_if(PM_TOURIST
) || Role_if(PM_CYBERNINJA
)) ? 30 : 20) &&
667 (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
668 You("break your chip off in the door!");
670 *pickp
= (struct obj
*)0;
673 if(!rn2(isfriday
? 10 : Role_if(PM_LOCKSMITH
) ? 40 : (Role_if(PM_TOURIST
) || Role_if(PM_CYBERNINJA
)) ? 30 : 20) &&
674 (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
675 Your("data chip becomes dull and is no longer capable of picking locks!");
676 pick
->obrittle
= pick
->obrittle2
= 3;
679 ch
= 2*ACURR(A_DEX
) + 20*Role_if(PM_ROGUE
) + 40*Role_if(PM_LOCKSMITH
) + 20*Role_if(PM_CYBERNINJA
);
683 if(!rn2(isfriday
? 20 : Role_if(PM_LOCKSMITH
) ? 60 : (Role_if(PM_ROGUE
) || Role_if(PM_CYBERNINJA
)) ? 40 : 30) &&
684 (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
685 You("break your pick!");
687 *pickp
= (struct obj
*)0;
690 if(!rn2(isfriday
? 20 : Role_if(PM_LOCKSMITH
) ? 60 : (Role_if(PM_ROGUE
) || Role_if(PM_CYBERNINJA
)) ? 40 : 30) &&
691 (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
692 if (pick
->oartifact
== ART_DITHERS_WUMA
) {
693 FemaleTrapJette
+= 50000;
694 pline_The("power of feminism compels you.");
696 Your("pick becomes brittle and is no longer capable of picking locks!");
697 pick
->obrittle
= pick
->obrittle2
= 3;
701 ch
= 3*ACURR(A_DEX
) + 30*Role_if(PM_ROGUE
) + 60*Role_if(PM_LOCKSMITH
) + 30*Role_if(PM_CYBERNINJA
);
704 case CONTROVERSY_CODE
:
706 if(!rn2(isfriday
? 7 : Role_if(PM_LOCKSMITH
) ? 40 : Role_if(PM_CYBERNINJA
) ? 30 : 15) && !(pick
->oartifact
== ART_VANULLA_SCORE
) && (!pick
->blessed
|| !rn2(3)) && !pick
->oartifact
) {
707 Your("key wasn't designed for this door and broke!");
709 *pickp
= (struct obj
*)0;
712 if(!rn2(isfriday
? 7 : Role_if(PM_LOCKSMITH
) ? 40 : Role_if(PM_CYBERNINJA
) ? 30 : 15) && !(pick
->oartifact
== ART_VANULLA_SCORE
) && (!pick
->blessed
|| !rn2(3)) && pick
->oartifact
) {
713 Your("key becomes brittle and is no longer capable of picking locks!");
714 if (pick
->oartifact
== ART_UNBRIT_SOV
) {
715 u
.badfcursed
+= 10000;
716 if (pick
->obrittle
|| pick
->obrittle2
) u
.badfdoomed
+= 10000;
718 pick
->obrittle
= pick
->obrittle2
= 3;
721 ch
= 70 + ACURR(A_DEX
) + 10*Role_if(PM_LOCKSMITH
) + 5*Role_if(PM_CYBERNINJA
);
728 /* ALI - Artifact doors */
729 xlock
.key
= pick
->oartifact
;
731 /* these variable names... who the hell would expect "key" to be the one that's required and "xlock.key"
732 * to somehow be set to "pick->oartifact", i.e. be the same that you're trying to use??? --Amy */
733 bypassartilock
= FALSE
;
734 if (key
&& key
== ART_GAUNTLET_KEY
&& pick
->oartifact
== ART_GAUNTLET_ABBREVIATION
&& !In_V_tower(&u
.uz
)) {
735 bypassartilock
= TRUE
;
737 if (key
&& key
== ART_KEY_OF_LAW
&& pick
->oartifact
== ART_GETIN_ON_VLADS
) bypassartilock
= TRUE
;
738 if (key
&& key
== ART_KEY_OF_NEUTRALITY
&& pick
->oartifact
== ART_GETIN_ON_VLADS
) bypassartilock
= TRUE
;
739 if (key
&& key
== ART_KEY_OF_CHAOS
&& pick
->oartifact
== ART_GETIN_ON_VLADS
) bypassartilock
= TRUE
;
741 if (key
&& (xlock
.key
!= key
) && !bypassartilock
) {
742 if (picktyp
== SKELETON_KEY
|| picktyp
== CONTROVERSY_CODE
|| picktyp
== SECRET_KEY
) {
743 Your("key doesn't seem to fit.");
746 else ch
= -1; /* -1 == 0% chance */
749 /* artifact keys shouldn't be overpowered --Amy */
751 if (!key
&& pick
->oartifact
&& !(pick
->oartifact
== ART_UNBRIT_SOV
) && (pick
->obrittle
|| pick
->obrittle2
) && !issoviet
) {
752 Your("key doesn't seem to fit.");
756 /* "Artifact key/locking tools work properly again. There is next to no reason for this, especially considering keys/lock picks/etc can break in this game." In Soviet Russia, people will tell you that there's no reason for something, and then proceed to tell you the EXACT reason for the same thing but pretend that it's the reason why the "something" shouldn't be! Can you believe that? To clarify: keys being able to break is the exact reason why I'm not allowing artifact keys to unlock everything, cause otherwise that would render the point of breakable keys completely moot. Once you got your artifact key, it just doesn't matter anymore since you're not going to use normal keys. And what *I* want is that it freaking *MATTERS* if you get lucky finding enough keys. The threat of running out should be present for the entire game, not just until you beat the way-too-easy neutral quest! */
762 xlock
.picktyp
= picktyp
;
764 set_occupation(picklock
, lock_action(), 0);
765 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) picklock();
770 doforce() /* try to force a chest with your weapon */
774 pline("The force command is currently unavailable!");
775 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
779 register struct obj
*otmp
;
780 register int x
, y
, c
, picktyp
;
784 if (!uwep
) { /* Might want to make this so you use your shoulder */
785 You_cant("force anything without a weapon.");
786 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
790 if (u
.utrap
&& u
.utraptype
== TT_WEB
) {
791 You("are entangled in a web!");
792 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
794 } else if (uwep
&& is_lightsaber(uwep
)) {
795 if (!uwep
->lamplit
&& !Role_if(PM_SHADOW_JEDI
)) {
796 Your("lightsaber is deactivated!");
797 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
800 } else if(uwep
->otyp
== LOCK_PICK
||
801 uwep
->otyp
== HAIRCLIP
||
802 uwep
->otyp
== CREDIT_CARD
||
803 uwep
->otyp
== DATA_CHIP
||
804 uwep
->otyp
== SECRET_KEY
||
805 uwep
->otyp
== CONTROVERSY_CODE
||
806 uwep
->otyp
== SKELETON_KEY
) {
807 return pick_lock(&uwep
);
808 /* not a lightsaber or lockpicking device*/
809 } else if(!uwep
|| /* proper type test */
810 (uwep
->oclass
!= WEAPON_CLASS
&& !is_weptool(uwep
) &&
811 uwep
->oclass
!= ROCK_CLASS
&& uwep
->oclass
!= BALL_CLASS
&& uwep
->oclass
!= CHAIN_CLASS
&& uwep
->oclass
!= VENOM_CLASS
) ||
812 (objects
[uwep
->otyp
].oc_skill
< P_DAGGER
) ||
813 (objects
[uwep
->otyp
].oc_skill
> P_LANCE
&& uwep
->otyp
!= STEEL_WHIP
) ||
814 uwep
->otyp
== FLAIL
|| uwep
->otyp
== AKLYS
815 || uwep
->otyp
== RUBBER_HOSE
817 You_cant("force anything without a %sweapon.",
818 (uwep
) ? "proper " : "");
819 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
823 /* so we're trying to force something now, which means you touch your weapon; artifact can blast now --Amy */
824 if (!touch_artifact(uwep
, &youmonst
)) return 0;
826 if (is_lightsaber(uwep
))
829 picktyp
= is_blade(uwep
) ? 1 : 0;
830 if(xlock
.usedtime
&& picktyp
== xlock
.picktyp
) {
832 if (!can_reach_floor()) {
833 pline("Unfortunately, you can no longer reach the lock.");
836 You("resume your attempt to force the lock.");
837 set_occupation(forcelock
, "forcing the lock", 0);
838 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) forcelock();
840 } else if (xlock
.door
) {
841 You("resume your attempt to force the door.");
842 set_occupation(forcedoor
, "forcing the door", 0);
843 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) forcedoor();
848 /* A lock is made only for the honest man, the thief will break it. */
849 xlock
.box
= (struct obj
*)0;
851 if(!getdir((char *)0)) return(0);
855 if (x
== u
.ux
&& y
== u
.uy
) {
857 There("isn't any sort of lock up %s.",
858 Levitation
? "here" : "there");
860 } else if (is_lava(u
.ux
, u
.uy
)) {
861 pline("Doing that would probably melt your %s.",
864 } else if (is_waterypool(u
.ux
, u
.uy
) && !is_crystalwater(u
.ux
, u
.uy
) && !Underwater
) {
865 pline_The("water has no lock.");
869 for(otmp
= level
.objects
[u
.ux
][u
.uy
]; otmp
; otmp
= otmp
->nexthere
)
871 if (!can_reach_floor()) {
872 You_cant("reach %s from up here.", the(xname(otmp
)));
876 if (otmp
->obroken
|| !otmp
->olocked
) {
877 There("is %s here, but its lock is already %s.",
878 doname(otmp
), otmp
->obroken
? "broken" : "unlocked");
881 sprintf(qbuf
,"There is %s here, force its lock?",
882 safe_qbuf("", sizeof("There is here, force its lock?"),
883 doname(otmp
), an(simple_typename(otmp
->otyp
)),
887 if(c
== 'q') return(0);
888 if(c
== 'n') continue;
891 You("begin melting it with your %s.", xname(uwep
));
894 You("force your %s into a crack and pry.", xname(uwep
));
896 You("start bashing it with your %s.", xname(uwep
));
898 if (is_lightsaber(uwep
))
899 xlock
.chance
= uwep
->spe
* 2 + 75;
901 xlock
.chance
= (uwep
->spe
+ objects
[uwep
->otyp
].oc_wldam
) * 2;
902 xlock
.picktyp
= picktyp
;
908 set_occupation(forcelock
, "forcing the lock", 0);
909 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) forcelock();
913 if (picktyp
!= 2) You("cannot find any sort of lock down there.");
915 return use_pick_axe2(uwep
);
919 } else { /* break down/open door */
923 if ((mtmp
= m_at(x
, y
)) && canseemon(mtmp
)
924 && mtmp
->m_ap_type
!= M_AP_FURNITURE
925 && mtmp
->m_ap_type
!= M_AP_OBJECT
) {
927 if (mtmp
->isshk
|| mtmp
->data
== &mons
[PM_ORACLE
])
928 if (Role_if(PM_JEDI
) || Role_if(PM_SHADOW_JEDI
) || Role_if(PM_HEDDERJEDI
))
929 verbalize("Your puny Jedi tricks won't work on me!"); /* Return of the Jedi */
932 verbalize("What do you think you are, a Jedi?"); /* Phantom Menace */
934 if (Role_if(PM_JEDI
) ? (u
.uen
< 5) : Role_if(PM_SHADOW_JEDI
) ? (u
.uen
< 5) : Role_if(PM_HEDDERJEDI
) ? (u
.uen
< 5) : Race_if(PM_BORG
) ? (u
.uen
< 7) : (u
.uen
< 10) ) pline("I don't think %s would appreciate that. Besides, you need %d mana in order to use the force.", mon_nam(mtmp
), Role_if(PM_JEDI
) ? 5 : Role_if(PM_SHADOW_JEDI
) ? 5 : Role_if(PM_HEDDERJEDI
) ? 5 : Race_if(PM_BORG
) ? 7 : 10);
937 if (!UseTheForce
|| rn2(StrongUseTheForce
? 3 : 10)) u
.uen
-= (Role_if(PM_JEDI
) ? 5 : Role_if(PM_SHADOW_JEDI
) ? 5 : Role_if(PM_HEDDERJEDI
) ? 5 : Race_if(PM_BORG
) ? 7 : 10);
941 dmg
= rnd(2) + dbon() + uwep
->spe
;
943 /* having both blades on boosts the damage --Amy */
944 if (uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(3);
946 if (UseTheForce
) dmg
+= 5;
947 if (StrongUseTheForce
) dmg
+= 5;
948 if (tech_inuse(T_USE_THE_FORCE_LUKE
)) dmg
+= techlevX(get_tech_no(T_USE_THE_FORCE_LUKE
));
949 if (uarmg
&& uarmg
->oartifact
== ART_USE_THE_FORCE_LUKE
) dmg
+= 10;
950 if (uwep
&& uwep
->oartifact
== ART_DE_SID
&& uwep
->lamplit
) dmg
+= 5;
951 if (uwep
&& uwep
->oartifact
== ART_DE_SID
&& uwep
->lamplit
&& uwep
->altmode
) dmg
+= 5;
953 if (Role_if(PM_JEDI
) && UseTheForce
) dmg
+= u
.ulevel
;
954 else if (Role_if(PM_HEDDERJEDI
) && UseTheForce
) dmg
+= u
.ulevel
;
955 else if (Role_if(PM_SHADOW_JEDI
) && UseTheForce
) dmg
+= u
.ulevel
;
956 else if (Race_if(PM_BORG
) && UseTheForce
) dmg
+= rnd(u
.ulevel
);
957 if (Role_if(PM_JEDI
) && StrongUseTheForce
) dmg
+= u
.ulevel
;
958 else if (Role_if(PM_HEDDERJEDI
) && StrongUseTheForce
) dmg
+= u
.ulevel
;
959 else if (Role_if(PM_SHADOW_JEDI
) && StrongUseTheForce
) dmg
+= u
.ulevel
;
960 else if (Race_if(PM_BORG
) && StrongUseTheForce
) dmg
+= rnd(u
.ulevel
);
962 if (Role_if(PM_EMERA
) && (mtmp
->data
->msound
== MS_SHOE
|| mtmp
->data
->msound
== MS_PANTS
|| mtmp
->data
->msound
== MS_SOCKS
)) {
963 dmg
+= rnd(2 * u
.ulevel
);
966 if (u
.ulevel
>= 30) dmg
+= rnd(4);
967 else if (u
.ulevel
>= 24) dmg
+= rnd(3);
968 else if (u
.ulevel
>= 16) dmg
+= rnd(2);
969 else if (u
.ulevel
>= 8) dmg
+= 1;
971 if (!PlayerCannotUseSkills
) {
972 switch (P_SKILL(P_WEDI
)) { /* again, bigger boosts if you use both blades --Amy */
975 dmg
+= (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
) ? rnd(2) : 1;
976 if (uwep
&& uwep
->oartifact
== ART_CHRISMISS
) dmg
+= rn2(2);
977 if (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(2);
980 dmg
+= (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
) ? rnd(4) : rnd(2); if (uwep
&& uwep
->oartifact
== ART_CHRISMISS
) dmg
+= rnd(2);
981 if (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(4);
984 dmg
+= (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
) ? rnd(6) : rnd(3); if (uwep
&& uwep
->oartifact
== ART_CHRISMISS
) dmg
+= rnd(3);
985 if (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(6);
988 dmg
+= (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
) ? rnd(8) : rnd(4);
989 if (uwep
&& uwep
->oartifact
== ART_CHRISMISS
) dmg
+= rnd(4);
990 if (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(8);
993 dmg
+= (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
) ? rnd(10) : rnd(5);
994 if (uwep
&& uwep
->oartifact
== ART_CHRISMISS
) dmg
+= rnd(5);
995 if (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(10);
997 case P_SUPREME_MASTER
:
998 dmg
+= (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
) ? rnd(12) : rnd(6);
999 if (uwep
&& uwep
->oartifact
== ART_CHRISMISS
) dmg
+= rnd(6);
1000 if (uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& uwep
->altmode
) dmg
+= rnd(12);
1006 boolean trapkilled
= FALSE
;
1008 pline("You use the force on %s.", mon_nam(mtmp
));
1011 if (Role_if(PM_EMERA
) && (mtmp
->data
->msound
== MS_SHOE
|| mtmp
->data
->msound
== MS_PANTS
|| mtmp
->data
->msound
== MS_SOCKS
)) pline("Your %s furiously rip into %s. You evil bastard.", makeplural(body_part(HAND
)), mon_nam(mtmp
));
1016 if (uwep
&& is_lightsaber(uwep
) && (uwep
->lamplit
|| Role_if(PM_SHADOW_JEDI
)) ) {
1018 mightbooststat(rn2(2) ? A_STR
: A_CON
);
1019 if (u
.uwediturns
>= 2) {
1021 use_skill(P_WEDI
, 1);
1024 if (uwep
&& uwep
->oartifact
== ART_DIGSRU
) {
1026 mightbooststat(rn2(2) ? A_STR
: A_CON
);
1027 if (u
.uwediturns
>= 2) {
1029 use_skill(P_WEDI
, 1);
1037 if (mtmp
->meating
) {
1038 pline("Startled, %s spits out the food it was eating!", mon_nam(mtmp
));
1041 if (mtmp
->mfrozen
) {
1042 pline("Being hit by your force, %s is jolted back to its senses.", mon_nam(mtmp
));
1045 if (mtmp
->msleeping
) {
1046 pline("Being hit by your force, %s suddenly wakes up!", mon_nam(mtmp
));
1047 mtmp
->msleeping
= 0;
1052 monflee(mtmp
, (dmg
? rnd(dmg
) : 1), FALSE
, FALSE
);
1063 if (mtmp
->mhp
> 0 && ( (UseTheForce
&& uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& rn2(2) ) || (StrongUseTheForce
&& uwep
&& is_lightsaber(uwep
) && uwep
->lamplit
&& rn2(2) ) || ( (Role_if(PM_JEDI
) || Role_if(PM_SHADOW_JEDI
) || Role_if(PM_HEDDERJEDI
)) ? (rnd(100) < (u
.ulevel
* 2) ) : (rnd(100) < u
.ulevel
) ) ) &&
1064 mtmp
->mcanmove
&& mtmp
!= u
.ustuck
&& !mtmp
->mtrapped
) {
1065 /* see if the monster has a place to move into */
1066 mdx
= mtmp
->mx
+ u
.dx
;
1067 mdy
= mtmp
->my
+ u
.dy
;
1068 if(goodpos(mdx
, mdy
, mtmp
, 0)) {
1069 pline("%s is pushed back!", Monnam(mtmp
));
1070 if (m_in_out_region(mtmp
, mdx
, mdy
)) {
1071 remove_monster(mtmp
->mx
, mtmp
->my
);
1072 newsym(mtmp
->mx
, mtmp
->my
);
1073 place_monster(mtmp
, mdx
, mdy
);
1074 newsym(mtmp
->mx
, mtmp
->my
);
1076 if (mintrap(mtmp
) == 2) trapkilled
= TRUE
;
1081 (void) passive(mtmp
, TRUE
, mtmp
->mhp
> 0, AT_TUCH
, FALSE
);
1082 if (mtmp
->mhp
<= 0 && !trapkilled
) killed(mtmp
);
1084 if (mtmp
->mhp
> 0 && (mtmp
->data
->msound
== MS_FART_QUIET
|| (!rn2(5) && mtmp
->egotype_farter
) ) ) {
1085 pline("You bash %s's %s butt using %s %s.", mon_nam(mtmp
), mtmp
->female
? "sexy" : "ugly", !rn2(3) ? "both your left and right" : rn2(2) ? "your left" : "your right", body_part(HAND
) );
1086 if (practicantterror
) {
1087 pline("%s thunders: 'Bashing other people's butts is not permitted! 100 zorkmids!'", noroelaname());
1088 fineforpracticant(100, 0, 0);
1091 if (Role_if(PM_BUTT_LOVER
)) {
1092 You_feel("bad for hurting one of your beloved butts!");
1094 if (u
.negativeprotection
> 0 && !rn2(5)) u
.negativeprotection
--;
1096 u
.cnd_forcebuttcount
++;
1097 if (mtmp
->butthurt
< 25 && (!rn2(3) || Role_if(PM_EMERA
)) ) {
1098 int butthurting
= 5;
1099 if (!PlayerCannotUseSkills
) {
1100 switch (P_SKILL(P_WEDI
)) {
1101 case P_BASIC
: butthurting
++; break;
1102 case P_SKILLED
: butthurting
+= 2; break;
1103 case P_EXPERT
: butthurting
+= 3; break;
1104 case P_MASTER
: butthurting
+= 4; break;
1105 case P_GRAND_MASTER
: butthurting
+= 5; break;
1106 case P_SUPREME_MASTER
: butthurting
+= 6; break;
1110 if (uwep
&& uwep
->spe
> 0) butthurting
+= rn2(uwep
->spe
+ 1);
1111 if (UseTheForce
) butthurting
+= 3;
1112 if (StrongUseTheForce
) butthurting
+= 3;
1114 mtmp
->butthurt
+= rnd(butthurting
);
1115 if (mtmp
->butthurt
< 5) pline("%s's %s butt is getting %s red bruises.", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly", mtmp
->female
? "beautiful" : "intense");
1116 else if (mtmp
->butthurt
< 9) pline("%s's %s butt is getting sore from your beating.", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1117 else if (mtmp
->butthurt
< 13) pline("%s's %s butt is hurt badly, and blood is slowly dripping out...", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1118 else if (mtmp
->butthurt
< 17) pline("%s's %s butt is heavily injured and severely bleeding!", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1120 pline("You hurt %s so badly that %s ended up crying, and is begging you to spare %s...", mon_nam(mtmp
), mhe(mtmp
), mhim(mtmp
) );
1121 if (!mtmp
->mfrenzied
) mtmp
->mpeaceful
= 1;
1126 if (mtmp
->mhp
> 0 && (mtmp
->data
->msound
== MS_FART_NORMAL
|| (!rn2(5) && mtmp
->egotype_farter
) ) ) {
1127 pline("You bash %s's %s butt using %s %s.", mon_nam(mtmp
), mtmp
->female
? "sexy" : "ugly", !rn2(3) ? "both your left and right" : rn2(2) ? "your left" : "your right", body_part(HAND
) );
1128 if (practicantterror
) {
1129 pline("%s thunders: 'Bashing other people's butts is not permitted! 100 zorkmids!'", noroelaname());
1130 fineforpracticant(100, 0, 0);
1134 if (FemtrapActiveSueLyn
&& mtmp
->female
&& !mtmp
->mfrenzied
) {
1135 pline("Now %s is really angry, and %s will hurt you badly with %s %snails.", mon_nam(mtmp
), mhe(mtmp
), mhis(mtmp
), mbodypart(mtmp
, FINGER
));
1136 mtmp
->mtame
= FALSE
;
1137 mtmp
->mpeaceful
= FALSE
;
1138 mtmp
->mfrenzied
= TRUE
;
1141 if (Role_if(PM_BUTT_LOVER
)) {
1142 You_feel("bad for hurting one of your beloved butts!");
1144 if (u
.negativeprotection
> 0 && !rn2(5)) u
.negativeprotection
--;
1146 u
.cnd_forcebuttcount
++;
1147 if (mtmp
->butthurt
< 25 && (!rn2(3) || Role_if(PM_EMERA
)) ) {
1148 int butthurting
= 3;
1149 if (!PlayerCannotUseSkills
) {
1150 switch (P_SKILL(P_WEDI
)) {
1151 case P_BASIC
: butthurting
++; break;
1152 case P_SKILLED
: butthurting
+= rnd(2); break;
1153 case P_EXPERT
: butthurting
+= rnd(3); break;
1154 case P_MASTER
: butthurting
+= rnd(4); break;
1155 case P_GRAND_MASTER
: butthurting
+= rnd(5); break;
1156 case P_SUPREME_MASTER
: butthurting
+= rnd(6); break;
1160 if (uwep
&& rn2(2) && uwep
->spe
> 0) butthurting
+= rn2(uwep
->spe
+ 1);
1161 if (UseTheForce
) butthurting
+= 2;
1162 if (StrongUseTheForce
) butthurting
+= 2;
1164 mtmp
->butthurt
+= rnd(butthurting
);
1165 if (mtmp
->butthurt
< 5) pline("%s's %s butt is getting %s red bruises.", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly", mtmp
->female
? "beautiful" : "intense");
1166 else if (mtmp
->butthurt
< 9) pline("%s's %s butt is getting sore from your beating.", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1167 else if (mtmp
->butthurt
< 13) pline("%s's %s butt is hurt badly, and blood is slowly dripping out...", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1168 else if (mtmp
->butthurt
< 17) pline("%s's %s butt is heavily injured and severely bleeding!", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1170 pline("You hurt %s so badly that %s gets unconscious from the pain.", mon_nam(mtmp
), mhe(mtmp
));
1172 mtmp
->mfrozen
= 5 + rnd(15);
1173 mtmp
->mstrategy
&= ~STRAT_WAITFORU
;
1178 if (mtmp
->mhp
> 0 && (mtmp
->data
->msound
== MS_FART_LOUD
|| (!rn2(5) && mtmp
->egotype_farter
) ) ) {
1179 pline("You bash %s's %s butt using %s %s.", mon_nam(mtmp
), mtmp
->female
? "sexy" : "ugly", !rn2(3) ? "both your left and right" : rn2(2) ? "your left" : "your right", body_part(HAND
) );
1180 if (practicantterror
) {
1181 pline("%s thunders: 'Bashing other people's butts is not permitted! 100 zorkmids!'", noroelaname());
1182 fineforpracticant(100, 0, 0);
1185 if (Role_if(PM_BUTT_LOVER
)) {
1186 You_feel("bad for hurting one of your beloved butts!");
1188 if (u
.negativeprotection
> 0 && !rn2(5)) u
.negativeprotection
--;
1190 u
.cnd_forcebuttcount
++;
1191 if (mtmp
->butthurt
< 25 && (!rn2(3) || Role_if(PM_EMERA
)) ) {
1192 int butthurting
= 1;
1193 if (!PlayerCannotUseSkills
&& !rn2(2)) {
1194 switch (P_SKILL(P_WEDI
)) {
1195 case P_BASIC
: butthurting
++; break;
1196 case P_SKILLED
: butthurting
+= rnd(2); break;
1197 case P_EXPERT
: butthurting
+= rnd(3); break;
1198 case P_MASTER
: butthurting
+= rnd(4); break;
1199 case P_GRAND_MASTER
: butthurting
+= rnd(5); break;
1200 case P_SUPREME_MASTER
: butthurting
+= rnd(6); break;
1204 if (uwep
&& !rn2(4) && uwep
->spe
> 0) butthurting
+= rn2(uwep
->spe
+ 1);
1205 if (UseTheForce
) butthurting
+= 1;
1206 if (StrongUseTheForce
) butthurting
+= 1;
1208 mtmp
->butthurt
+= rnd(butthurting
);
1209 if (mtmp
->butthurt
< 5) pline("%s's %s butt is getting %s red bruises.", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly", mtmp
->female
? "beautiful" : "intense");
1210 else if (mtmp
->butthurt
< 9) pline("%s's %s butt is getting sore from your beating.", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1211 else if (mtmp
->butthurt
< 13) pline("%s's %s butt is hurt badly, and blood is slowly dripping out...", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1212 else if (mtmp
->butthurt
< 17) pline("%s's %s butt is heavily injured and severely bleeding!", Monnam(mtmp
), mtmp
->female
? "sexy" : "ugly");
1214 pline("You hurt %s so badly that %s is furious, and realize that you're going to learn a lesson in pain!", mon_nam(mtmp
), mhe(mtmp
));
1215 mtmp
->mpeaceful
= mtmp
->mtame
= 0;
1216 mon_adjust_speed(mtmp
, 2, (struct obj
*)0);
1218 if (!grow_up(mtmp
,(struct monst
*)0)) return 1;
1219 if (!grow_up(mtmp
,(struct monst
*)0)) return 1;
1220 if (!grow_up(mtmp
,(struct monst
*)0)) return 1;
1227 } /* monster forced by player */
1233 if (is_farmland(x
,y
)) {
1235 pline("You have too little energy to force the farmland!");
1239 pline("You fire an ammo at the farmland.");
1240 if (rn2(20)) pline("It doesn't seem to have any effect.");
1242 pline("The farmland disappears.");
1243 u
.cnd_farmlandremoved
++;
1244 levl
[x
][y
].typ
= CORR
;
1246 blockorunblock_point(x
,y
);
1247 more_experienced(25 * (deepest_lev_reached(FALSE
) + 1), 0);
1254 /* Lightsabers dig through doors and walls via dig.c */
1255 if (is_pick(uwep
) || is_antibar(uwep
) ||
1256 is_lightsaber(uwep
) ||
1258 return use_pick_axe2(uwep
);
1260 if(!IS_DOOR(door
->typ
)) {
1261 if (is_drawbridge_wall(x
,y
) >= 0)
1262 pline("The drawbridge is too solid to force open.");
1264 You("%s no door there.",
1265 Blind
? "feel" : "see");
1268 /* ALI - artifact doors */
1269 if (artifact_door(x
, y
)) {
1270 pline("This door is too solid to force open.");
1273 switch (door
->doormask
) {
1275 pline("This doorway has no door.");
1278 You("cannot force an open door.");
1281 pline("This door is broken.");
1284 c
= yn("Break down the door?");
1285 if(c
== 'n') return(0);
1288 You("force your %s into a crack and pry.", xname(uwep
));
1290 You("start bashing it with your %s.", xname(uwep
));
1291 if (is_lightsaber(uwep
))
1292 xlock
.chance
= uwep
->spe
+ 38;
1294 xlock
.chance
= uwep
->spe
+ objects
[uwep
->otyp
].oc_wldam
;
1295 xlock
.picktyp
= picktyp
;
1299 set_occupation(forcedoor
, "forcing the door", 0);
1300 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) forcedoor();
1304 You("decide not to force the issue.");
1309 doopen() /* try to open a door */
1311 return doopen_indir(0, 0);
1315 doopen_indir(x
, y
) /* try to open a door in direction u.dx/u.dy */
1316 int x
, y
; /* if true, prompt for direction */
1319 register struct rm
*door
;
1322 if (nohands(youmonst
.data
) && !Race_if(PM_TRANSFORMER
)) {
1323 You_cant("open anything -- you have no hands!");
1324 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1326 if (yn("Try to open it with another part of your body instead?") == 'y') {
1327 if (rn2(3) && !polyskillchance()) {
1328 make_blinded(Blinded
+ rnd(50),TRUE
);
1329 pline("Off - you just blinded yourself!");
1330 if (!rn2(20)) badeffect();
1331 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1338 if (u
.utrap
&& u
.utraptype
== TT_PIT
) {
1339 You_cant("reach over the edge of the pit.");
1340 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1344 if (x
> 0 && y
> 0) {
1348 else if(!get_adjacent_loc((char *)0, (char *)0, u
.ux
, u
.uy
, &cc
)) return(0);
1350 if((cc
.x
== u
.ux
) && (cc
.y
== u
.uy
)) return(0);
1352 if ((mtmp
= m_at(cc
.x
,cc
.y
)) &&
1353 mtmp
->m_ap_type
== M_AP_FURNITURE
&&
1354 (mtmp
->mappearance
== S_hcdoor
||
1355 mtmp
->mappearance
== S_vcdoor
) &&
1356 !Protection_from_shape_changers
) {
1358 stumble_onto_mimic(mtmp
);
1362 door
= &levl
[cc
.x
][cc
.y
];
1364 if(!IS_DOOR(door
->typ
)) {
1365 if (is_db_wall(cc
.x
,cc
.y
)) {
1366 There("is no obvious way to open the drawbridge.");
1369 You("%s no door there.",
1370 Blind
? "feel" : "see");
1375 if (!(door
->doormask
& D_CLOSED
)) {
1378 if (uwep
&& uwep
->oartifact
== ART_FINAL_DOOR_SOLUTION
&& !artifact_door(cc
.x
, cc
.y
) && (door
->doormask
& D_LOCKED
)) {
1379 door
->doormask
&= ~D_LOCKED
;
1380 door
->doormask
|= D_CLOSED
;
1385 switch (door
->doormask
) {
1386 case D_BROKEN
: mesg
= " is broken"; break;
1387 case D_NODOOR
: mesg
= "way has no door"; break;
1388 case D_ISOPEN
: mesg
= " is already open"; break;
1389 default: mesg
= " is locked"; break;
1391 pline("This door%s.", mesg
);
1392 if (Blind
) feel_location(cc
.x
,cc
.y
);
1396 if(verysmall(youmonst
.data
) && !Race_if(PM_TRANSFORMER
) ) {
1397 pline("You're too small to pull the door open.");
1401 if (uwep
&& uwep
->oartifact
== ART_DUURVOID
&& (door
->doormask
& D_TRAPPED
) && !rn2(5)) {
1402 pline("There seems to be a trap on this door!");
1403 if (yn("Stop handling the door?") == 'y') {
1408 /* door is known to be CLOSED */
1409 if ((rnl(20) < (ACURRSTR
+ACURR(A_DEX
)+ACURR(A_CON
))/3) || (uwep
&& uwep
->oartifact
== ART_DOORBANE
) ) {
1410 pline_The("door opens.");
1411 if(door
->doormask
& D_TRAPPED
) {
1412 b_trapped("door", FINGER
);
1413 door
->doormask
= D_NODOOR
;
1414 if (*in_rooms(cc
.x
, cc
.y
, SHOPBASE
)) add_damage(cc
.x
, cc
.y
, 0L);
1416 door
->doormask
= D_ISOPEN
;
1418 feel_location(cc
.x
,cc
.y
); /* the hero knows she opened it */
1421 unblock_point(cc
.x
,cc
.y
); /* vision: new see through there */
1423 exercise(A_STR
, TRUE
);
1424 pline_The("door resists!");
1435 register struct monst
*mtmp
= m_at(x
, y
);
1437 if(mtmp
&& mtmp
->m_ap_type
!= M_AP_FURNITURE
) {
1438 if (mtmp
->m_ap_type
== M_AP_OBJECT
) goto objhere
;
1439 pline("%s stands in the way!", !canspotmon(mtmp
) ?
1440 "Some creature" : Monnam(mtmp
));
1441 if (!canspotmon(mtmp
) && !(mtmp
->data
->msound
== MS_DEEPSTATE
) && !(mtmp
->egotype_deepstatemember
))
1442 map_invisible(mtmp
->mx
, mtmp
->my
);
1446 objhere
: pline("%s's in the way.", Something
);
1457 register struct monst
*mtmp
= m_at(x
, y
);
1459 if(mtmp
&& mtmp
->m_ap_type
!= M_AP_FURNITURE
) {
1460 if (mtmp
->m_ap_type
== M_AP_OBJECT
) goto objhere
;
1461 if (!canspotmon(mtmp
) && !(mtmp
->data
->msound
== MS_DEEPSTATE
) && !(mtmp
->egotype_deepstatemember
))
1462 map_invisible(mtmp
->mx
, mtmp
->my
);
1466 objhere
: return(TRUE
);
1472 doclose() /* try to close a door */
1475 register struct rm
*door
;
1478 if (nohands(youmonst
.data
) && !Race_if(PM_TRANSFORMER
)) {
1479 You_cant("close anything -- you have no hands!");
1480 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1482 if (yn("Try to close it with another part of your body instead?") == 'y') {
1483 if (rn2(3) && !polyskillchance()) {
1484 make_blinded(Blinded
+ rnd(50),TRUE
);
1485 pline("Something got in your face! You can't see!");
1486 if (!rn2(20)) badeffect();
1487 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1494 if (u
.utrap
&& u
.utraptype
== TT_PIT
) {
1495 You_cant("reach over the edge of the pit.");
1496 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1500 if(!getdir((char *)0)) return(0);
1504 if((x
== u
.ux
) && (y
== u
.uy
)) {
1505 You("are in the way!");
1509 if ((mtmp
= m_at(x
,y
)) &&
1510 mtmp
->m_ap_type
== M_AP_FURNITURE
&&
1511 (mtmp
->mappearance
== S_hcdoor
||
1512 mtmp
->mappearance
== S_vcdoor
) &&
1513 !Protection_from_shape_changers
) {
1515 stumble_onto_mimic(mtmp
);
1521 if(!IS_DOOR(door
->typ
)) {
1522 if (door
->typ
== DRAWBRIDGE_DOWN
)
1523 There("is no obvious way to close the drawbridge.");
1525 You("%s no door there.",
1526 Blind
? "feel" : "see");
1530 if(door
->doormask
== D_NODOOR
) {
1531 pline("This doorway has no door.");
1535 if(obstructed(x
, y
)) return(0);
1537 if(door
->doormask
== D_BROKEN
) {
1538 pline("This door is broken.");
1542 if(door
->doormask
& (D_CLOSED
| D_LOCKED
)) {
1543 pline("This door is already closed.");
1547 if(door
->doormask
== D_ISOPEN
) {
1548 if(verysmall(youmonst
.data
) && !Race_if(PM_TRANSFORMER
)
1550 pline("You're too small to push the door closed.");
1553 if (u
.usteed
|| (rn2(25) < (ACURRSTR
+ACURR(A_DEX
)+ACURR(A_CON
))/3) || (uwep
&& uwep
->oartifact
== ART_DOORBANE
)) {
1554 pline_The("door closes.");
1555 door
->doormask
= D_CLOSED
;
1557 feel_location(x
,y
); /* the hero knows she closed it */
1560 block_point(x
,y
); /* vision: no longer see there */
1563 exercise(A_STR
, TRUE
);
1564 pline_The("door resists!");
1571 boolean
/* box obj was hit with spell effect otmp */
1572 boxlock(obj
, otmp
) /* returns true if something happened */
1573 register struct obj
*obj
, *otmp
; /* obj *is* a box */
1575 register boolean res
= 0;
1577 switch(otmp
->otyp
) {
1579 if (!obj
->olocked
) { /* lock it; fix if broken */
1584 } /* else already closed and locked */
1586 case SPE_WIZARD_LOCK
:
1587 if (Role_if(PM_LOCKSMITH
) ? !rn2(100) : rn2(2)) {
1588 if (!rn2(10)) containerkaboom();
1591 if (!obj
->olocked
) { /* lock it; fix if broken */
1596 } /* else already closed and locked */
1599 if (obj
->olocked
) { /* unlock; couldn't be broken */
1603 } else /* silently fix if broken */
1607 if (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3)) {
1608 if (!rn2(10)) containerkaboom();
1611 if (obj
->olocked
) { /* unlock; couldn't be broken */
1615 } else /* silently fix if broken */
1618 case SPE_LOCK_MANIPULATION
:
1620 if (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3)) {
1621 if (!rn2(10)) containerkaboom();
1626 if (!obj
->olocked
) { /* lock it; fix if broken */
1631 } /* else already closed and locked */
1635 if (obj
->olocked
) { /* unlock; couldn't be broken */
1639 } else /* silently fix if broken */
1649 /* maybe start unlocking chest, get interrupted, then zap it;
1650 we must avoid any attempt to resume unlocking it */
1651 if (xlock
.box
== obj
)
1659 doorlockX(x
,y
,update
)
1664 register struct rm
*door
= &levl
[x
][y
];
1666 int key
= artifact_door(x
, y
); /* ALI - Artifact doors */
1668 if (levl
[x
][y
].typ
!= SDOOR
&& levl
[x
][y
].typ
!= DOOR
) return FALSE
;
1670 /* Amy edit: sigh. The obstructed check was *also* causing savegame errors. Anyway, there's no real reason
1671 * for doors to not close over monsters or objects, so we'll simply allow that to happen. */
1673 /*if (obstructedX(x,y)) return FALSE;*/
1674 /* Don't allow doors to close over traps. This is for pits */
1675 /* & trap doors, but is it ever OK for anything else? */
1676 /*if (t_at(x,y)) {*/
1677 /* maketrap() clears doormask, so it should be NODOOR */
1683 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1685 door
->doormask
= D_LOCKED
| (door
->doormask
& D_TRAPPED
);
1686 if (update
) newsym(x
,y
);
1688 if (update
&& res
&& picking_at(x
, y
)) {
1689 /* maybe unseen monster zaps door you're unlocking */
1696 boolean
/* Door/secret door was hit with spell effect otmp */
1697 doorlock(otmp
,x
,y
) /* returns true if something happened */
1701 register struct rm
*door
= &levl
[x
][y
];
1704 const char *msg
= (const char *)0;
1705 const char *dustcloud
= "A cloud of dust";
1706 const char *quickly_dissipates
= "quickly dissipates";
1707 int key
= artifact_door(x
, y
); /* ALI - Artifact doors */
1709 if (door
->typ
== SDOOR
) {
1710 switch (otmp
->otyp
) {
1714 case WAN_GRAVITY_BEAM
:
1715 case SPE_GRAVITY_BEAM
:
1716 case WAN_DISINTEGRATION
:
1717 case SPE_FORCE_BOLT
:
1718 if (key
) /* Artifact doors are revealed only */
1719 cvt_sdoor_to_door(door
);
1722 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1725 if (cansee(x
,y
)) pline("A door appears in the wall!");
1726 if (otmp
->otyp
== WAN_OPENING
|| otmp
->otyp
== SPE_LOCK_MANIPULATION
)
1728 break; /* striking: continue door handling below */
1730 case SPE_LOCK_MANIPULATION
:
1731 if (rn2(2)) return FALSE
;
1732 if (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3)) {
1733 if (!rn2(10)) containerkaboom();
1737 if (key
) /* Artifact doors are revealed only */
1738 cvt_sdoor_to_door(door
);
1741 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1744 if (cansee(x
,y
)) pline("A door appears in the wall!");
1748 if (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3)) {
1749 if (!rn2(10)) containerkaboom();
1753 if (key
) /* Artifact doors are revealed only */
1754 cvt_sdoor_to_door(door
);
1757 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1760 if (cansee(x
,y
)) pline("A door appears in the wall!");
1763 case SPE_WIZARD_LOCK
:
1769 switch(otmp
->otyp
) {
1771 case SPE_LOCK_MANIPULATION
:
1774 if (!key
&& door
->doormask
& D_LOCKED
) {
1775 msg
= "The door unlocks!";
1776 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1779 } /* else fall through */
1781 case SPE_WIZARD_LOCK
:
1783 if (otmp
->otyp
== SPE_WIZARD_LOCK
&& (Role_if(PM_LOCKSMITH
) ? !rn2(150) : !rn2(3))) {
1784 if (!rn2(10)) containerkaboom();
1787 if (otmp
->otyp
== SPE_LOCK_MANIPULATION
&& (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3))) {
1788 if (!rn2(10)) containerkaboom();
1792 if (door
->doormask
== D_BROKEN
&& otmp
->otyp
== SPE_WIZARD_LOCK
&& (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3))) {
1793 if (!rn2(10)) containerkaboom();
1796 if (door
->doormask
== D_NODOOR
&& otmp
->otyp
== SPE_WIZARD_LOCK
&& (Role_if(PM_LOCKSMITH
) ? !rn2(100) : rn2(2))) {
1797 if (!rn2(10)) containerkaboom();
1802 #ifdef REINCARNATION
1803 if (Is_rogue_level(&u
.uz
)) {
1804 boolean vis
= cansee(x
,y
);
1805 /* Can't have real locking in Rogue, so just hide doorway */
1806 if (vis
) pline("%s springs up in the older, more primitive doorway.",
1809 You_hear("a swoosh.");
1810 if (obstructed(x
,y
)) {
1811 if (vis
) pline_The("cloud %s.",quickly_dissipates
);
1816 if (vis
) pline_The("doorway vanishes!");
1821 if (obstructed(x
,y
)) return FALSE
;
1822 /* Don't allow doors to close over traps. This is for pits */
1823 /* & trap doors, but is it ever OK for anything else? */
1825 /* maketrap() clears doormask, so it should be NODOOR */
1827 "%s springs up in the doorway, but %s.",
1828 dustcloud
, quickly_dissipates
);
1832 switch (door
->doormask
& ~D_TRAPPED
) {
1835 msg
= "The door closes!";
1837 msg
= "The door locks!";
1841 msg
= "The door swings shut!";
1843 msg
= "The door swings shut, and locks!";
1847 msg
= "The broken door reassembles!";
1849 msg
= "The broken door reassembles and locks!";
1853 "A cloud of dust springs up and assembles itself into a door!";
1861 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1863 door
->doormask
= D_LOCKED
| (door
->doormask
& D_TRAPPED
);
1867 if (!key
&& door
->doormask
& D_LOCKED
) {
1868 msg
= "The door unlocks!";
1869 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1873 if (Role_if(PM_LOCKSMITH
) ? !rn2(50) : rn2(3)) {
1874 if (!rn2(10)) containerkaboom();
1877 if (!key
&& door
->doormask
& D_LOCKED
) {
1878 msg
= "The door unlocks!";
1879 door
->doormask
= D_CLOSED
| (door
->doormask
& D_TRAPPED
);
1883 case WAN_GRAVITY_BEAM
:
1884 case WAN_DISINTEGRATION
:
1885 case SPE_FORCE_BOLT
:
1886 case SPE_GRAVITY_BEAM
:
1889 if (!key
&& door
->doormask
& (D_LOCKED
| D_CLOSED
)) {
1890 if (door
->doormask
& D_TRAPPED
) {
1892 (void) mb_trapped(m_at(x
,y
));
1893 else if (flags
.verbose
) {
1895 pline("KABOOM!! You see a door explode.");
1896 else if (flags
.soundok
)
1897 You_hear("a distant explosion.");
1899 door
->doormask
= D_NODOOR
;
1905 door
->doormask
= D_BROKEN
;
1906 if (flags
.verbose
) {
1908 pline_The("door crashes open!");
1909 else if (flags
.soundok
)
1910 You_hear("a crashing sound.");
1914 /* force vision recalc before printing more messages */
1915 if (vision_full_recalc
) vision_recalc(0);
1919 default: impossible("magic (%ld) attempted on door.", otmp
->otyp
);
1922 if (msg
&& cansee(x
,y
)) pline("%s", msg
);
1924 /* door was destroyed */
1925 wake_nearto(x
, y
, loudness
);
1926 if (*in_rooms(x
, y
, SHOPBASE
)) add_damage(x
, y
, 0L);
1929 if (res
&& picking_at(x
, y
)) {
1930 /* maybe unseen monster zaps door you're unlocking */
1938 chest_shatter_msg(otmp
)
1941 const char *disposition
;
1945 if (otmp
->oclass
== POTION_CLASS
) {
1946 You("%s %s shatter!", Blind
? "hear" : "see", an(bottlename()));
1947 if (!breathless(youmonst
.data
) || haseyes(youmonst
.data
))
1948 potionbreathe(otmp
);
1951 /* We have functions for distant and singular names, but not one */
1952 /* which does _both_... */
1953 save_Blinded
= Blinded
;
1955 thing
= singular(otmp
, xname
);
1956 Blinded
= save_Blinded
;
1957 /* Amy grepping target: "materialeffect" */
1958 switch (objects
[otmp
->otyp
].oc_material
) {
1959 case MT_PAPER
: disposition
= "is torn to shreds";
1961 case MT_WAX
: disposition
= "is crushed";
1963 case MT_VEGGY
: disposition
= "is pulped";
1965 case MT_FLESH
: disposition
= "is mashed";
1967 case MT_FILM
: disposition
= "evaporates";
1969 case MT_FOAM
: disposition
= "is mashed";
1971 case MT_TAR
: disposition
= "breaks apart";
1973 case MT_GLASS
: disposition
= "shatters";
1975 case MT_VIVA
: disposition
= "disintegrates";
1977 case MT_SECREE
: disposition
= "decomposes";
1979 case MT_ALKALINE
: disposition
= "decomposes";
1981 case MT_WOOD
: disposition
= "splinters to fragments";
1983 case MT_SHADOWSTUFF
: disposition
= "is swallowed";
1985 default: disposition
= "is destroyed";
1988 pline("%s %s!", An(thing
), disposition
);
1991 /* ALI - Kevin Hugo's artifact doors.
1992 * Return the artifact which unlocks the door at (x, y), or
1993 * zero if it is an ordinary door.
1994 * Note: Not all doors are listed in the doors array (eg., doors
1995 * dynamically converted from secret doors). Since only trapped
1996 * and artifact doors are needed this isn't a problem. If we ever
1997 * implement trapped secret doors we will have to extend this.
2006 for(i
= 0; i
< doorindex
; i
++) {
2007 if (x
== doors
[i
].x
&& y
== doors
[i
].y
)
2008 return doors
[i
].arti_key
;