1 /* NetHack 3.6 lock.c $NHDT-Date: 1446955300 2015/11/08 04:01:40 $ $NHDT-Branch: master $:$NHDT-Revision: 1.67 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 STATIC_PTR int NDECL(picklock);
13 STATIC_PTR int NDECL(forcelock);
15 /* at most one of `door' and `box' should be non-null at any given time */
16 STATIC_VAR NEARDATA struct xlock_s {
19 int picktyp, /* key|pick|card for unlock, sharp vs blunt for #force */
23 STATIC_DCL const char *NDECL(lock_action);
24 STATIC_DCL boolean FDECL(obstructed, (int, int, BOOLEAN_P));
25 STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *));
31 if (occupation == picklock) {
45 return (boolean) (occupation == picklock && xlock.door == &levl[x][y]);
48 /* produce an occupation string appropriate for the current activity */
49 STATIC_OVL const char *
52 /* "unlocking"+2 == "locking" */
53 static const char *actions[] = {
55 "unlocking the door", /* [0] */
56 "unlocking the chest", /* [1] */
57 "unlocking the box", /* [2] */
58 "picking the lock" /* [3] */
60 "
\94à
\82Ì
\8c®
\82ð
\82Í
\82¸
\82·",
61 "
\95ó
\94 \82Ì
\8c®
\82ð
\82Í
\82¸
\82·",
62 "
\94 \82Ì
\8c®
\82ð
\82Í
\82¸
\82·",
63 "
\8c®
\82ð
\82Í
\82¸
\82·"
67 /* if the target is currently unlocked, we're trying to lock it now */
68 if (xlock.door && !(xlock.door->doormask & D_LOCKED))
70 return actions[0] + 2; /* "locking the door" */
71 #else /*
\89p
\8cê
\82Í un
\82ð
\8eæ
\82ê
\82Î
\8bt
\82Ì
\88Ó
\96¡
\82É
\82È
\82é
\82ª
\81C
\93ú
\96{
\8cê
\82Í
\82»
\82¤
\82Í
\82¢
\82©
\82È
\82¢
\82Ì
\82Å
\83\8a\83e
\83\89\83\8b\82ð
\8f\91\82 */
72 return "
\94à
\82É
\8c®
\82ð
\82©
\82¯
\82é";
74 else if (xlock.box && !xlock.box->olocked)
76 return xlock.box->otyp == CHEST ? actions[1] + 2 : actions[2] + 2;
78 return xlock.box->otyp == CHEST ? "
\95ó
\94 \82É
\8c®
\82ð
\82©
\82¯
\82é" : "
\94 \82É
\8c®
\82ð
\82©
\82¯
\82é";
80 /* otherwise we're trying to unlock it */
81 else if (xlock.picktyp == LOCK_PICK)
82 return actions[3]; /* "picking the lock" */
83 else if (xlock.picktyp == CREDIT_CARD)
84 return actions[3]; /* same as lock_pick */
86 return actions[0]; /* "unlocking the door" */
88 return xlock.box->otyp == CHEST ? actions[1] : actions[2];
93 /* try to open/close a lock */
98 if ((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) {
99 return ((xlock.usedtime = 0)); /* you or it moved */
102 if (xlock.door != &(levl[u.ux + u.dx][u.uy + u.dy])) {
103 return ((xlock.usedtime = 0)); /* you moved */
105 switch (xlock.door->doormask) {
108 pline("This doorway has no door.");
110 pline("
\8fo
\93ü
\8cû
\82É
\82Í
\94à
\82ª
\82È
\82¢
\81D");
111 return ((xlock.usedtime = 0));
114 You("cannot lock an open door.");
116 pline("
\8aJ
\82¢
\82Ä
\82é
\94à
\82É
\8c®
\82ð
\82©
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
117 return ((xlock.usedtime = 0));
120 pline("This door is broken.");
122 pline("
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
123 return ((xlock.usedtime = 0));
127 if (xlock.usedtime++ >= 50 || nohands(youmonst.data)) {
129 You("give up your attempt at %s.", lock_action());
131 pline("%s
\82Ì
\82ð
\82 \82«
\82ç
\82ß
\82½
\81D", lock_action());
132 exercise(A_DEX, TRUE); /* even if you don't succeed */
133 return ((xlock.usedtime = 0));
136 if (rn2(100) >= xlock.chance)
137 return 1; /* still busy */
140 You("succeed in %s.", lock_action());
142 You("%s
\82Ì
\82É
\90¬
\8c÷
\82µ
\82½
\81D", lock_action());
144 if (xlock.door->doormask & D_TRAPPED) {
146 b_trapped("door", FINGER);
148 b_trapped("
\94à", FINGER);
149 xlock.door->doormask = D_NODOOR;
150 unblock_point(u.ux + u.dx, u.uy + u.dy);
151 if (*in_rooms(u.ux + u.dx, u.uy + u.dy, SHOPBASE))
152 add_damage(u.ux + u.dx, u.uy + u.dy, 0L);
153 newsym(u.ux + u.dx, u.uy + u.dy);
154 } else if (xlock.door->doormask & D_LOCKED)
155 xlock.door->doormask = D_CLOSED;
157 xlock.door->doormask = D_LOCKED;
159 xlock.box->olocked = !xlock.box->olocked;
160 xlock.box->lknown = 1;
161 if (xlock.box->otrapped)
162 (void) chest_trap(xlock.box, FINGER, FALSE);
164 exercise(A_DEX, TRUE);
165 return ((xlock.usedtime = 0));
169 breakchestlock(box, destroyit)
173 if (!destroyit) { /* bill for the box but not for its contents */
174 struct obj *hide_contents = box->cobj;
177 costly_alteration(box, COST_BRKLCK);
178 box->cobj = hide_contents;
182 } else { /* #force has destroyed this box (at <u.ux,u.uy>) */
184 struct monst *shkp = (*u.ushops && costly_spot(u.ux, u.uy))
185 ? shop_keeper(*u.ushops)
187 boolean costly = (boolean) (shkp != 0),
188 peaceful_shk = costly && (boolean) shkp->mpeaceful;
192 pline("In fact, you've totally destroyed %s.", the(xname(box)));
194 pline("
\8eÀ
\8dÛ
\82Ì
\82Æ
\82±
\82ë
\81C%s
\82ð
\8a®
\91S
\82É
\89ó
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", xname(xlock.box));
195 /* Put the contents on ground at the hero's feet. */
196 while ((otmp = box->cobj) != 0) {
197 obj_extract_self(otmp);
198 if (!rn2(3) || otmp->oclass == POTION_CLASS) {
199 chest_shatter_msg(otmp);
202 stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE);
203 if (otmp->quan == 1L) {
204 obfree(otmp, (struct obj *) 0);
209 if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
210 otmp->age = monstermoves - otmp->age; /* actual age */
211 start_corpse_timeout(otmp);
213 place_object(otmp, u.ux, u.uy);
217 loss += stolen_value(box, u.ux, u.uy, peaceful_shk, TRUE);
220 You("owe %ld %s for objects destroyed.", loss, currency(loss));
222 You("
\8aí
\95¨
\94j
\91¹
\82Å%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", loss, currency(loss));
227 /* try to force a locked chest */
231 if ((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy))
232 return ((xlock.usedtime = 0)); /* you or it moved */
234 if (xlock.usedtime++ >= 50 || !uwep || nohands(youmonst.data)) {
236 You("give up your attempt to force the lock.");
238 pline("
\8c®
\82ð
\82±
\82¶
\8aJ
\82¯
\82é
\82Ì
\82ð
\82 \82«
\82ç
\82ß
\82½
\81D");
239 if (xlock.usedtime >= 50) /* you made the effort */
240 exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
241 return ((xlock.usedtime = 0));
244 if (xlock.picktyp) { /* blade */
245 if (rn2(1000 - (int) uwep->spe) > (992 - greatest_erosion(uwep) * 10)
246 && !uwep->cursed && !obj_resists(uwep, 0, 99)) {
247 /* for a +0 weapon, probability that it survives an unsuccessful
248 * attempt to force the lock is (.992)^50 = .67
251 pline("%sour %s broke!", (uwep->quan > 1L) ? "One of y" : "Y",
254 pline("%s
\82Í
\89ó
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",xname(uwep));
258 You("give up your attempt to force the lock.");
260 pline("
\8c®
\82ð
\82±
\82¶
\8aJ
\82¯
\82é
\82Ì
\82ð
\82 \82«
\82ç
\82ß
\82½
\81D");
261 exercise(A_DEX, TRUE);
262 return ((xlock.usedtime = 0));
265 wake_nearby(); /* due to hammering on the container */
267 if (rn2(100) >= xlock.chance)
268 return 1; /* still busy */
271 You("succeed in forcing the lock.");
273 pline("
\8c®
\82ð
\82±
\82¶
\8aJ
\82¯
\82½
\81D");
274 breakchestlock(xlock.box, (boolean) (!xlock.picktyp && !rn2(3)));
276 exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
277 return ((xlock.usedtime = 0));
283 xlock.usedtime = xlock.chance = xlock.picktyp = 0;
288 /* for doapply(); if player gives a direction or resumes an interrupted
289 previous attempt then it costs hero a move even if nothing ultimately
290 happens; when told "can't do that" before being asked for direction
291 or player cancels with ESC while giving direction, it doesn't */
292 #define PICKLOCK_LEARNED_SOMETHING (-1) /* time passes */
293 #define PICKLOCK_DID_NOTHING 0 /* no time passes */
294 #define PICKLOCK_DID_SOMETHING 1
296 /* player is applying a key, lock pick, or credit card */
307 picktyp = pick->otyp;
309 /* check whether we're resuming an interrupted previous attempt */
310 if (xlock.usedtime && picktyp == xlock.picktyp) {
312 static char no_longer[] = "Unfortunately, you can no longer %s %s.";
314 static char no_longer[] = "
\82´
\82ñ
\82Ë
\82ñ
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í%s%s";
316 if (nohands(youmonst.data)) {
318 const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";
320 const char *what = (picktyp == LOCK_PICK) ? "
\8c®
\8aJ
\82¯
\8aí
\8bï" : "
\8c®";
321 if (picktyp == CREDIT_CARD)
325 what = "
\83J
\81[
\83h";
327 pline(no_longer, "hold the", what);
329 pline(no_longer, what, "
\82ð
\82Â
\82©
\82ß
\82È
\82¢");
331 return PICKLOCK_LEARNED_SOMETHING;
332 } else if (u.uswallow || (xlock.box && !can_reach_floor(TRUE))) {
334 pline(no_longer, "reach the", "lock");
336 pline(no_longer, "
\8c®
\82É", "
\93Í
\82©
\82È
\82¢");
338 return PICKLOCK_LEARNED_SOMETHING;
340 const char *action = lock_action();
343 You("resume your attempt at %s.", action);
345 pline("%s
\82Ì
\82ð
\8dÄ
\8aJ
\82µ
\82½
\81D", action);
346 set_occupation(picklock, action, 0);
347 return PICKLOCK_DID_SOMETHING;
351 if (nohands(youmonst.data)) {
353 You_cant("hold %s -- you have no hands!", doname(pick));
355 You("%s
\82ð
\82Â
\82©
\82Þ
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I
\8eè
\82ª
\82È
\82¢
\82ñ
\82¾
\82à
\82Ì
\81I", xname(pick));
356 return PICKLOCK_DID_NOTHING;
357 } else if (u.uswallow) {
358 You_cant("%sunlock %s.", (picktyp == CREDIT_CARD) ? "" : "lock or ",
360 return PICKLOCK_DID_NOTHING;
363 if ((picktyp != LOCK_PICK && picktyp != CREDIT_CARD
364 && picktyp != SKELETON_KEY)) {
365 impossible("picking lock with object %d?", picktyp);
366 return PICKLOCK_DID_NOTHING;
368 ch = 0; /* lint suppression */
371 if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc))
373 if (!get_adjacent_loc((char *) 0, "
\88Ê
\92u
\82ª
\82¨
\82©
\82µ
\82¢
\81I", u.ux, u.uy, &cc))
374 return PICKLOCK_DID_NOTHING;
376 if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */
384 There("isn't any sort of lock up %s.",
385 Levitation ? "here" : "there");
387 pline("%s
\82É
\82Í
\8c®
\82ð
\82©
\82¯
\82é
\82æ
\82¤
\82È
\95¨
\82Í
\82È
\82¢
\81D",
388 Levitation ? "
\82±
\82±" : "
\89º
\95û");
390 return PICKLOCK_LEARNED_SOMETHING;
391 } else if (is_lava(u.ux, u.uy)) {
393 pline("Doing that would probably melt %s.", yname(pick));
395 pline("
\82»
\82ñ
\82È
\82±
\82Æ
\82ð
\82µ
\82½
\82ç%s
\82ª
\97n
\82¯
\82Ä
\82µ
\82Ü
\82¤
\81D", yname(pick));
396 return PICKLOCK_LEARNED_SOMETHING;
397 } else if (is_pool(u.ux, u.uy) && !Underwater) {
399 pline_The("water has no lock.");
401 pline("
\90\85\82É
\8fù
\91O
\82Í
\82È
\82¢
\81D");
402 return PICKLOCK_LEARNED_SOMETHING;
406 c = 'n'; /* in case there are no boxes here */
407 for (otmp = level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
410 if (!can_reach_floor(TRUE)) {
412 You_cant("reach %s from up here.", the(xname(otmp)));
414 You("
\82±
\82±
\82©
\82ç%s
\82É
\93Í
\82©
\82È
\82¢
\81D", the(xname(otmp)));
415 return PICKLOCK_LEARNED_SOMETHING;
422 verb = "
\8fC
\95\9c\82·
\82é";
423 else if (!otmp->olocked)
425 verb = "lock", it = 1;
427 verb = "
\8c®
\82ð
\82©
\82¯
\82é", it = 1;
428 else if (picktyp != LOCK_PICK)
430 verb = "unlock", it = 1;
432 verb = "
\8c®
\82ð
\82Í
\82¸
\82·", it = 1;
437 verb = "
\82±
\82¶
\82 \82¯
\82é";
439 /* "There is <a box> here; <verb> <it|its lock>?" */
441 Sprintf(qsfx, " here; %s %s?", verb, it ? "it" : "its lock");
443 Sprintf(qsfx, "
\82ª
\82 \82é
\81D%s
\81H", verb);
445 (void) safe_qbuf(qbuf, "There is ", qsfx, otmp, doname,
446 ansimpleoname, "a box");
448 (void) safe_qbuf(qbuf, "
\82±
\82±
\82É
\82Í", qsfx, otmp, doname,
449 ansimpleoname, "
\94 ");
461 You_cant("fix its broken lock with %s.", doname(pick));
463 You("
\89ó
\82ê
\82½
\8c®
\82ð%s
\82Å
\8fC
\95\9c\82Å
\82«
\82È
\82¢
\81D", doname(pick));
464 return PICKLOCK_LEARNED_SOMETHING;
465 } else if (picktyp == CREDIT_CARD && !otmp->olocked) {
466 /* credit cards are only good for unlocking */
468 You_cant("do that with %s.",
469 an(simple_typename(picktyp)));
471 pline("%s
\82¶
\82á
\82»
\82ñ
\82È
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
472 simple_typename(picktyp));
474 return PICKLOCK_LEARNED_SOMETHING;
478 ch = ACURR(A_DEX) + 20 * Role_if(PM_ROGUE);
481 ch = 4 * ACURR(A_DEX) + 25 * Role_if(PM_ROGUE);
484 ch = 75 + ACURR(A_DEX);
492 xlock.picktyp = picktyp;
500 There("doesn't seem to be any sort of lock here.");
502 pline("
\82±
\82±
\82É
\82Í
\8c®
\82ð
\82©
\82¯
\82é
\82æ
\82¤
\82È
\95¨
\82Í
\82È
\82¢
\82æ
\82¤
\82¾
\81D");
503 return PICKLOCK_LEARNED_SOMETHING; /* decided against all boxes */
505 } else { /* pick the lock in a door */
508 if (u.utrap && u.utraptype == TT_PIT) {
510 You_cant("reach over the edge of the pit.");
512 pline("
\97\8e\82µ
\8c\8a\82Ì
\92\86\82©
\82ç
\82Å
\82Í
\93Í
\82©
\82È
\82¢
\81D");
513 return PICKLOCK_LEARNED_SOMETHING;
516 door = &levl[cc.x][cc.y];
517 mtmp = m_at(cc.x, cc.y);
518 if (mtmp && canseemon(mtmp) && mtmp->m_ap_type != M_AP_FURNITURE
519 && mtmp->m_ap_type != M_AP_OBJECT) {
520 if (picktyp == CREDIT_CARD
521 && (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]))
523 verbalize("No checks, no credit, no problem.");
525 verbalize("
\82¢
\82Â
\82à
\83j
\83R
\83j
\83R
\8c»
\8bà
\95¥
\82¢
\81D");
528 pline("I don't think %s would appreciate that.",
531 pline("%s
\82ª
\82»
\82Ì
\89¿
\92l
\82ð
\94F
\82ß
\82é
\82Æ
\82Í
\8ev
\82¦
\82È
\82¢
\81D", mon_nam(mtmp));
533 return PICKLOCK_LEARNED_SOMETHING;
534 } else if (mtmp && is_door_mappear(mtmp)) {
535 /* "The door actually was a <mimic>!" */
536 stumble_onto_mimic(mtmp);
537 /* mimic might keep the key (50% chance, 10% for PYEC) */
538 maybe_absorb_item(mtmp, pick, 50, 10);
539 return PICKLOCK_LEARNED_SOMETHING;
541 if (!IS_DOOR(door->typ)) {
542 if (is_drawbridge_wall(cc.x, cc.y) >= 0)
544 You("%s no lock on the drawbridge.", Blind ? "feel" : "see");
546 pline("
\92µ
\82Ë
\8b´
\82É
\82Í
\8c®
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
549 You("%s no door there.", Blind ? "feel" : "see");
551 pline("
\82±
\82±
\82É
\82Í
\94à
\82ª
\82È
\82¢%s
\81D", Blind ? "
\82æ
\82¤
\82¾" : "
\82æ
\82¤
\82É
\8c©
\82¦
\82é");
552 return PICKLOCK_LEARNED_SOMETHING;
554 switch (door->doormask) {
557 pline("This doorway has no door.");
559 pline("
\82±
\82Ì
\8fo
\93ü
\8cû
\82É
\82Í
\94à
\82ª
\82È
\82¢
\81D");
560 return PICKLOCK_LEARNED_SOMETHING;
563 You("cannot lock an open door.");
565 pline("
\8aJ
\82¢
\82Ä
\82é
\94à
\82É
\82Í
\8c®
\82ð
\82©
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
566 return PICKLOCK_LEARNED_SOMETHING;
569 pline("This door is broken.");
571 pline("
\82±
\82Ì
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
572 return PICKLOCK_LEARNED_SOMETHING;
574 /* credit cards are only good for unlocking */
575 if (picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
577 You_cant("lock a door with a credit card.");
579 You("
\83N
\83\8c\83W
\83b
\83g
\83J
\81[
\83h
\82Å
\94à
\82É
\8c®
\82ð
\82©
\82¯
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
580 return PICKLOCK_LEARNED_SOMETHING;
584 Sprintf(qbuf, "%s it?",
585 (door->doormask & D_LOCKED) ? "Unlock" : "Lock");
587 Sprintf(qbuf, "%s
\82Ü
\82·
\82©
\81H",
588 (door->doormask & D_LOCKED) ? "
\82Í
\82¸
\82µ" : "
\82©
\82¯" );
597 ch = 2 * ACURR(A_DEX) + 20 * Role_if(PM_ROGUE);
600 ch = 3 * ACURR(A_DEX) + 30 * Role_if(PM_ROGUE);
603 ch = 70 + ACURR(A_DEX);
614 xlock.picktyp = picktyp;
616 set_occupation(picklock, lock_action(), 0);
617 return PICKLOCK_DID_SOMETHING;
620 /* try to force a chest with your weapon */
624 register struct obj *otmp;
625 register int c, picktyp;
629 You_cant("force anything from inside here.");
632 if (!uwep /* proper type test */
633 || ((uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
634 ? (objects[uwep->otyp].oc_skill < P_DAGGER
635 || objects[uwep->otyp].oc_skill == P_FLAIL
636 || objects[uwep->otyp].oc_skill > P_LANCE)
637 : uwep->oclass != ROCK_CLASS)) {
639 You_cant("force anything %s weapon.",
640 !uwep ? "when not wielding a"
641 : (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))
645 You_cant("%s
\95\90\8aí
\82È
\82µ
\82Å
\8c®
\82ð
\82±
\82¶
\8aJ
\82¯
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
646 !uwep ? "
\91\95\94õ
\82µ
\82Ä
\82¢
\82é"
647 : (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))
653 if (!can_reach_floor(TRUE)) {
654 cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
658 picktyp = is_blade(uwep) && !is_pick(uwep);
659 if (xlock.usedtime && xlock.box && picktyp == xlock.picktyp) {
661 You("resume your attempt to force the lock.");
663 pline("
\8c®
\82ð
\82±
\82¶
\82 \82¯
\82é
\82Ì
\82ð
\8dÄ
\8aJ
\82µ
\82½
\81D");
665 set_occupation(forcelock, "forcing the lock", 0);
667 set_occupation(forcelock, "
\8c®
\82ð
\82±
\82¶
\82 \82¯
\82é", 0);
671 /* A lock is made only for the honest man, the thief will break it. */
672 xlock.box = (struct obj *) 0;
673 for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere)
675 if (otmp->obroken || !otmp->olocked) {
677 There("is %s here, but its lock is already %s.", doname(otmp),
678 otmp->obroken ? "broken" : "unlocked");
680 pline("
\82±
\82±
\82É
\82Í%s
\82ª
\82 \82é
\81C
\82µ
\82©
\82µ
\82»
\82Ì
\8c®
\82Í
\82à
\82¤%s
\81D", doname(otmp),
681 otmp->obroken ? "
\89ó
\82ê
\82Ä
\82¢
\82é" : "
\82Í
\82¸
\82³
\82ê
\82Ä
\82¢
\82é");
687 (void) safe_qbuf(qbuf, "There is ", " here; force its lock?",
688 otmp, doname, ansimpleoname, "a box");
690 (void) safe_qbuf(qbuf, "
\82±
\82±
\82É
\82Í", "
\82ª
\82 \82é
\81C
\8c®
\82ð
\82±
\82¶
\8aJ
\82¯
\82Ü
\82·
\82©
\81H",
691 otmp, doname, ansimpleoname, "
\94 ");
703 You("force %s into a crack and pry.", yname(uwep));
705 You("%s
\82ð
\82·
\82«
\8aÔ
\82É
\8d·
\82µ
\82±
\82ñ
\82Å
\82±
\82¶
\82 \82¯
\82æ
\82¤
\82Æ
\82µ
\82½
\81D",xname(uwep));
708 You("start bashing it with %s.", yname(uwep));
710 pline("%s
\82Å
\89£
\82è
\82Â
\82¯
\82½
\81D", xname(uwep));
712 xlock.chance = objects[uwep->otyp].oc_wldam * 2;
713 xlock.picktyp = picktyp;
720 set_occupation(forcelock, "forcing the lock", 0);
722 set_occupation(forcelock, "
\8c®
\82ð
\82±
\82¶
\82 \82¯
\82é", 0);
725 You("decide not to force the issue.");
727 pline("
\82»
\82ê
\82Í
\96³
\88Ó
\96¡
\82È
\8ds
\88×
\82¾
\81D");
732 stumble_on_door_mimic(x, y)
737 if ((mtmp = m_at(x, y)) && is_door_mappear(mtmp)
738 && !Protection_from_shape_changers) {
739 stumble_onto_mimic(mtmp);
745 /* the 'O' command - try to open a door */
749 return doopen_indir(0, 0);
752 /* try to open a door in direction u.dx/u.dy */
758 register struct rm *door;
762 if (nohands(youmonst.data)) {
764 You_cant("open anything -- you have no hands!");
766 You("
\89½
\82à
\8aJ
\82¯
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I
\8eè
\82ª
\82È
\82¢
\82ñ
\82¾
\82à
\82Ì
\81I");
770 if (u.utrap && u.utraptype == TT_PIT) {
772 You_cant("reach over the edge of the pit.");
774 pline("
\97\8e\82µ
\8c\8a\82Ì
\92\86\82©
\82ç
\93Í
\82©
\82È
\82¢
\81D");
778 if (x > 0 && y > 0) {
781 } else if (!get_adjacent_loc((char *) 0, (char *) 0, u.ux, u.uy, &cc))
784 if ((cc.x == u.ux) && (cc.y == u.uy))
787 if (stumble_on_door_mimic(cc.x, cc.y))
790 /* when choosing a direction is impaired, use a turn
791 regardless of whether a door is successfully targetted */
792 if (Confusion || Stunned)
795 door = &levl[cc.x][cc.y];
796 portcullis = (is_drawbridge_wall(cc.x, cc.y) >= 0);
798 int oldglyph = door->glyph;
799 schar oldlastseentyp = lastseentyp[cc.x][cc.y];
801 feel_location(cc.x, cc.y);
802 if (door->glyph != oldglyph
803 || lastseentyp[cc.x][cc.y] != oldlastseentyp)
804 res = 1; /* learned something */
807 if (portcullis || !IS_DOOR(door->typ)) {
808 /* closed portcullis or spot that opened bridge would span */
809 if (is_db_wall(cc.x, cc.y) || door->typ == DRAWBRIDGE_UP)
811 There("is no obvious way to open the drawbridge.");
813 pline("
\92µ
\82Ë
\8b´
\82ð
\8d~
\82ë
\82·
\96¾
\94\92\82È
\95û
\96@
\82Í
\82È
\82¢
\81D");
814 else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
816 pline_The("drawbridge is already open.");
818 pline_The("
\92µ
\82Ë
\8b´
\82Í
\82à
\82¤
\8aJ
\82¢
\82Ä
\82¢
\82é
\81D");
821 You("%s no door there.", Blind ? "feel" : "see");
823 pline("
\82»
\82±
\82É
\82Í
\94à
\82Í
\82È
\82¢
\82æ
\82¤%s
\81D", Blind ? "
\82¾" : "
\82É
\8c©
\82¦
\82é");
827 if (!(door->doormask & D_CLOSED)) {
830 switch (door->doormask) {
835 mesg = "
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é";
839 mesg = "way has no door";
841 mesg = "
\8fo
\93ü
\8cû
\82É
\82Í
\94à
\82ª
\82È
\82¢";
845 mesg = " is already open";
847 mesg = "
\94à
\82Í
\82à
\82¤
\8aJ
\82¢
\82Ä
\82¢
\82é";
853 mesg = "
\94à
\82É
\82Í
\8c®
\82ª
\8a|
\82©
\82Á
\82Ä
\82¢
\82é";
857 pline("This door%s.", mesg);
859 pline("%s
\81D", mesg);
863 if (verysmall(youmonst.data)) {
865 pline("You're too small to pull the door open.");
867 You("
\94à
\82ð
\89\9f\82·
\82É
\82Í
\8f¬
\82³
\82·
\82¬
\82é
\81D");
871 /* door is known to be CLOSED */
872 if (rnl(20) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
874 pline_The("door opens.");
876 pline("
\94à
\82Í
\8aJ
\82¢
\82½
\81D");
877 if (door->doormask & D_TRAPPED) {
879 b_trapped("door", FINGER);
881 b_trapped("
\94à", FINGER);
882 door->doormask = D_NODOOR;
883 if (*in_rooms(cc.x, cc.y, SHOPBASE))
884 add_damage(cc.x, cc.y, 0L);
886 door->doormask = D_ISOPEN;
887 feel_newsym(cc.x, cc.y); /* the hero knows she opened it */
888 unblock_point(cc.x, cc.y); /* vision: new see through there */
890 exercise(A_STR, TRUE);
892 pline_The("door resists!");
894 pline("
\82È
\82©
\82È
\82©
\8aJ
\82©
\82È
\82¢
\81I");
901 obstructed(x, y, quietly)
905 register struct monst *mtmp = m_at(x, y);
907 if (mtmp && mtmp->m_ap_type != M_AP_FURNITURE) {
908 if (mtmp->m_ap_type == M_AP_OBJECT)
911 if ((mtmp->mx != x) || (mtmp->my != y)) {
914 pline("%s%s blocks the way!",
915 !canspotmon(mtmp) ? Something : s_suffix(Monnam(mtmp)),
916 !canspotmon(mtmp) ? "" : " tail");
918 pline("%s%s
\82ª
\97§
\82¿
\82Ó
\82³
\82ª
\82Á
\82Ä
\82¢
\82é
\81I",
919 !canspotmon(mtmp) ? "
\89½
\82©" : Monnam(mtmp),
920 !canspotmon(mtmp) ? "" : "
\82Ì
\90K
\94ö");
924 pline("%s blocks the way!",
925 !canspotmon(mtmp) ? "Some creature" : Monnam(mtmp));
927 pline("%s
\82ª
\97§
\82¿
\82Ó
\82³
\82ª
\82Á
\82Ä
\82¢
\82é
\81I",
928 !canspotmon(mtmp) ? "
\89½
\8eÒ
\82©" : Monnam(mtmp));
932 if (!canspotmon(mtmp))
940 pline("%s's in the way.", Something);
942 pline("
\89½
\82©
\82ª
\8fo
\93ü
\8cû
\82É
\82 \82é
\81D");
948 /* the 'C' command - try to close a door */
953 register struct rm *door;
957 if (nohands(youmonst.data)) {
959 You_cant("close anything -- you have no hands!");
961 You("
\95Â
\82ß
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I
\8eè
\82ª
\82È
\82¢
\82ñ
\82¾
\82à
\82Ì
\81I");
965 if (u.utrap && u.utraptype == TT_PIT) {
967 You_cant("reach over the edge of the pit.");
969 pline("
\97\8e\82µ
\8c\8a\82Ì
\92\86\82©
\82ç
\93Í
\82©
\82È
\82¢
\81D");
973 if (!getdir((char *) 0))
978 if ((x == u.ux) && (y == u.uy)) {
980 You("are in the way!");
982 pline("
\82 \82È
\82½
\82ª
\8fo
\93ü
\8cû
\82É
\82¢
\82é
\82Ì
\82Å
\95Â
\82Ü
\82ç
\82È
\82¢
\81I");
989 if (stumble_on_door_mimic(x, y))
992 /* when choosing a direction is impaired, use a turn
993 regardless of whether a door is successfully targetted */
994 if (Confusion || Stunned)
998 portcullis = (is_drawbridge_wall(x, y) >= 0);
1000 int oldglyph = door->glyph;
1001 schar oldlastseentyp = lastseentyp[x][y];
1003 feel_location(x, y);
1004 if (door->glyph != oldglyph || lastseentyp[x][y] != oldlastseentyp)
1005 res = 1; /* learned something */
1008 if (portcullis || !IS_DOOR(door->typ)) {
1009 /* is_db_wall: closed portcullis */
1010 if (is_db_wall(x, y) || door->typ == DRAWBRIDGE_UP)
1012 pline_The("drawbridge is already closed.");
1014 pline_The("
\92µ
\82Ë
\8b´
\82Í
\82à
\82¤
\95Â
\82¶
\82Ä
\82¢
\82é
\81D");
1015 else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
1017 There("is no obvious way to close the drawbridge.");
1019 pline("
\92µ
\82Ë
\8b´
\82ð
\95Â
\82ß
\82é
\96¾
\94\92\82È
\95û
\96@
\82Í
\82È
\82¢
\81D");
1023 You("%s no door there.", Blind ? "feel" : "see");
1025 pline("
\82»
\82±
\82É
\94à
\82Í
\82È
\82¢
\82æ
\82¤%s
\81D", Blind ? "
\82¾" : "
\82É
\8c©
\82¦
\82é");
1030 if (door->doormask == D_NODOOR) {
1032 pline("This doorway has no door.");
1034 pline("
\8fo
\93ü
\8cû
\82É
\82Í
\94à
\82ª
\82È
\82¢
\81D");
1036 } else if (obstructed(x, y, FALSE)) {
1038 } else if (door->doormask == D_BROKEN) {
1040 pline("This door is broken.");
1042 pline("
\94à
\82Í
\89ó
\82ê
\82Ä
\82¢
\82é
\81D");
1044 } else if (door->doormask & (D_CLOSED | D_LOCKED)) {
1046 pline("This door is already closed.");
1048 pline("
\94à
\82Í
\82à
\82¤
\95Â
\82¶
\82Ä
\82¢
\82é
\81D");
1052 if (door->doormask == D_ISOPEN) {
1053 if (verysmall(youmonst.data) && !u.usteed) {
1055 pline("You're too small to push the door closed.");
1057 You("
\8f¬
\82³
\82·
\82¬
\82Ä
\94à
\82ð
\95Â
\82ß
\82ç
\82ê
\82È
\82¢
\81D");
1061 || rn2(25) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
1063 pline_The("door closes.");
1065 pline("
\94à
\82Í
\95Â
\82¶
\82½
\81D");
1066 door->doormask = D_CLOSED;
1067 feel_newsym(x, y); /* the hero knows she closed it */
1068 block_point(x, y); /* vision: no longer see there */
1070 exercise(A_STR, TRUE);
1072 pline_The("door resists!");
1074 pline("
\82È
\82©
\82È
\82©
\95Â
\82Ü
\82ç
\82È
\82¢
\81I");
1081 /* box obj was hit with spell or wand effect otmp;
1082 returns true if something happened */
1085 struct obj *obj, *otmp; /* obj *is* a box */
1089 switch (otmp->otyp) {
1091 case SPE_WIZARD_LOCK:
1092 if (!obj->olocked) { /* lock it; fix if broken */
1096 pline("
\83J
\83`
\81I");
1099 if (Role_if(PM_WIZARD))
1104 } /* else already closed and locked */
1108 if (obj->olocked) { /* unlock; couldn't be broken */
1112 pline("
\83R
\83\93\83R
\83\93\81I");
1115 if (Role_if(PM_WIZARD))
1119 } else /* silently fix if broken */
1124 /* maybe start unlocking chest, get interrupted, then zap it;
1125 we must avoid any attempt to resume unlocking it */
1126 if (xlock.box == obj)
1133 /* Door/secret door was hit with spell or wand effect otmp;
1134 returns true if something happened */
1136 doorlock(otmp, x, y)
1140 register struct rm *door = &levl[x][y];
1143 const char *msg = (const char *) 0;
1145 const char *dustcloud = "A cloud of dust";
1147 const char *dustcloud = "
\82Ù
\82±
\82è";
1149 const char *quickly_dissipates = "quickly dissipates";
1151 const char *quickly_dissipates = "
\82 \82Á
\82Æ
\8c¾
\82¤
\82Ü
\82É
\94ò
\82Ñ
\8eU
\82Á
\82½";
1152 boolean mysterywand = (otmp->oclass == WAND_CLASS && !otmp->dknown);
1154 if (door->typ == SDOOR) {
1155 switch (otmp->otyp) {
1159 case SPE_FORCE_BOLT:
1161 door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
1165 pline("A door appears in the wall!");
1167 pline("
\95Ç
\82©
\82ç
\94à
\82ª
\8c»
\82ê
\82½
\81I");
1168 if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK)
1170 break; /* striking: continue door handling below */
1172 case SPE_WIZARD_LOCK:
1178 switch (otmp->otyp) {
1180 case SPE_WIZARD_LOCK:
1181 if (Is_rogue_level(&u.uz)) {
1182 boolean vis = cansee(x, y);
1183 /* Can't have real locking in Rogue, so just hide doorway */
1186 pline("%s springs up in the older, more primitive doorway.",
1188 pline("
\8cÃ
\82
\82³
\82¢
\81C
\8c´
\8en
\93I
\82È
\8fo
\93ü
\8cû
\82É%s
\82ª
\97§
\82¿
\82±
\82ß
\82½
\81D",
1192 You_hear("a swoosh.");
1194 You_hear("
\83V
\83\85\81[
\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1195 if (obstructed(x, y, mysterywand)) {
1198 pline_The("cloud %s.", quickly_dissipates);
1200 pline("
\82Ù
\82±
\82è
\82Í%s
\81D",quickly_dissipates);
1207 pline_The("doorway vanishes!");
1209 pline("
\8fo
\93ü
\8cû
\82Í
\8fÁ
\82¦
\82½
\81I");
1213 if (obstructed(x, y, mysterywand))
1215 /* Don't allow doors to close over traps. This is for pits */
1216 /* & trap doors, but is it ever OK for anything else? */
1218 /* maketrap() clears doormask, so it should be NODOOR */
1220 pline("%s springs up in the doorway, but %s.", dustcloud,
1221 quickly_dissipates);
1223 pline("%s
\82ª
\8fo
\93ü
\8cû
\82É
\97§
\82¿
\82±
\82ß
\82½
\81C
\82µ
\82©
\82µ%s", dustcloud,
1224 quickly_dissipates);
1229 switch (door->doormask & ~D_TRAPPED) {
1232 msg = "The door locks!";
1234 msg = "
\94à
\82É
\8c®
\82ª
\82©
\82©
\82Á
\82½
\81I";
1238 msg = "The door swings shut, and locks!";
1240 msg = "
\94à
\82Í
\90¨
\82¢
\82æ
\82
\95Â
\82Ü
\82è
\81C
\8c®
\82ª
\82©
\82©
\82Á
\82½
\81I";
1244 msg = "The broken door reassembles and locks!";
1246 msg = "
\89ó
\82ê
\82½
\94à
\82ª
\8dÄ
\8d\
\90¬
\82³
\82ê
\81C
\8c®
\82ª
\82©
\82©
\82Á
\82½
\81I";
1251 "A cloud of dust springs up and assembles itself into a door!";
1253 "
\82Ù
\82±
\82è
\82ª
\82½
\82¿
\82±
\82ß
\81C
\8fW
\82Ü
\82Á
\82Ä
\94à
\82É
\82È
\82Á
\82½
\81I";
1260 door->doormask = D_LOCKED | (door->doormask & D_TRAPPED);
1265 if (door->doormask & D_LOCKED) {
1267 msg = "The door unlocks!";
1269 msg = "
\94à
\82Ì
\8c®
\82Í
\82Í
\82¸
\82ê
\82½
\81I";
1270 door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
1275 case SPE_FORCE_BOLT:
1276 if (door->doormask & (D_LOCKED | D_CLOSED)) {
1277 if (door->doormask & D_TRAPPED) {
1279 (void) mb_trapped(m_at(x, y));
1280 else if (flags.verbose) {
1283 pline("KABOOM!! You see a door explode.");
1285 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\94à
\82ª
\94\9a\94
\82µ
\82½
\81D");
1288 You_hear("a distant explosion.");
1290 You_hear("
\89\93\82
\82Ì
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1292 door->doormask = D_NODOOR;
1293 unblock_point(x, y);
1298 door->doormask = D_BROKEN;
1299 if (flags.verbose) {
1302 pline_The("door crashes open!");
1304 pline("
\94à
\82Í
\89ó
\82ê
\8aJ
\82¢
\82½
\81I");
1307 You_hear("a crashing sound.");
1309 You_hear("
\89½
\82©
\82ª
\89ó
\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1311 unblock_point(x, y);
1313 /* force vision recalc before printing more messages */
1314 if (vision_full_recalc)
1321 impossible("magic (%d) attempted on door.", otmp->otyp);
1324 if (msg && cansee(x, y))
1327 /* door was destroyed */
1328 wake_nearto(x, y, loudness);
1329 if (*in_rooms(x, y, SHOPBASE))
1330 add_damage(x, y, 0L);
1333 if (res && picking_at(x, y)) {
1334 /* maybe unseen monster zaps door you're unlocking */
1342 chest_shatter_msg(otmp)
1345 const char *disposition;
1349 if (otmp->oclass == POTION_CLASS) {
1351 You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename()));
1354 You_hear("%s
\82ª
\8a\84\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81I", bottlename());
1356 pline("%s
\82ª
\8a\84\82ê
\82½
\81I", bottlename());
1358 if (!breathless(youmonst.data) || haseyes(youmonst.data))
1359 potionbreathe(otmp);
1362 /* We have functions for distant and singular names, but not one */
1363 /* which does _both_... */
1364 save_Blinded = Blinded;
1366 thing = singular(otmp, xname);
1367 Blinded = save_Blinded;
1368 switch (objects[otmp->otyp].oc_material) {
1371 disposition = "is torn to shreds";
1373 disposition = "
\82Í
\90¡
\92f
\82³
\82ê
\82½";
1377 disposition = "is crushed";
1379 disposition = "
\82ð
\8f°
\82É
\82Ô
\82¿
\82Ü
\82¯
\82½";
1383 disposition = "is pulped";
1385 disposition = "
\82Í
\82Ç
\82ë
\82Ç
\82ë
\82É
\82È
\82Á
\82½";
1389 disposition = "is mashed";
1391 disposition = "
\82Í
\82Ç
\82ë
\82Ç
\82ë
\82É
\82È
\82Á
\82½";
1395 disposition = "shatters";
1397 disposition = "
\82Í
\8a\84\82ê
\82½";
1401 disposition = "splinters to fragments";
1403 disposition = "
\82Í
\82©
\82¯
\82ç
\82É
\82È
\82Á
\82½";
1407 disposition = "is destroyed";
1409 disposition = "
\82Í
\89ó
\82ê
\82½";
1413 pline("%s %s!", An(thing), disposition);
1415 pline("%s%s
\81I", thing, disposition);