OSDN Git Service

update year to 2020
[jnethack/source.git] / src / lock.c
1 /* NetHack 3.6  lock.c  $NHDT-Date: 1548978605 2019/01/31 23:50:05 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 /* at most one of `door' and `box' should be non-null at any given time */
14 STATIC_VAR NEARDATA struct xlock_s {
15     struct rm *door;
16     struct obj *box;
17     int picktyp, /* key|pick|card for unlock, sharp vs blunt for #force */
18         chance, usedtime;
19     boolean magic_key;
20 } xlock;
21
22 /* occupation callbacks */
23 STATIC_PTR int NDECL(picklock);
24 STATIC_PTR int NDECL(forcelock);
25
26 STATIC_DCL const char *NDECL(lock_action);
27 STATIC_DCL boolean FDECL(obstructed, (int, int, BOOLEAN_P));
28 STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *));
29
30 boolean
31 picking_lock(x, y)
32 int *x, *y;
33 {
34     if (occupation == picklock) {
35         *x = u.ux + u.dx;
36         *y = u.uy + u.dy;
37         return TRUE;
38     } else {
39         *x = *y = 0;
40         return FALSE;
41     }
42 }
43
44 boolean
45 picking_at(x, y)
46 int x, y;
47 {
48     return (boolean) (occupation == picklock && xlock.door == &levl[x][y]);
49 }
50
51 /* produce an occupation string appropriate for the current activity */
52 STATIC_OVL const char *
53 lock_action()
54 {
55     /* "unlocking"+2 == "locking" */
56     static const char *actions[] = {
57 #if 0 /*JP:T*/
58         "unlocking the door",   /* [0] */
59         "unlocking the chest",  /* [1] */
60         "unlocking the box",    /* [2] */
61         "picking the lock"      /* [3] */
62 #else 
63         "\94à\82Ì\8c®\82ð\82Í\82¸\82·", 
64         "\95ó\94 \82Ì\8c®\82ð\82Í\82¸\82·",
65         "\94 \82Ì\8c®\82ð\82Í\82¸\82·",
66         "\8c®\82ð\82Í\82¸\82·"
67 #endif
68     };
69
70     /* if the target is currently unlocked, we're trying to lock it now */
71     if (xlock.door && !(xlock.door->doormask & D_LOCKED))
72 #if 0 /*JP*/
73         return actions[0] + 2; /* "locking the door" */
74 #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­ */
75         return "\94à\82É\8c®\82ð\82©\82¯\82é";
76 #endif
77     else if (xlock.box && !xlock.box->olocked)
78 #if 0 /*JP*/
79         return xlock.box->otyp == CHEST ? actions[1] + 2 : actions[2] + 2;
80 #else
81         return xlock.box->otyp == CHEST ? "\95ó\94 \82É\8c®\82ð\82©\82¯\82é" : "\94 \82É\8c®\82ð\82©\82¯\82é";
82 #endif
83     /* otherwise we're trying to unlock it */
84     else if (xlock.picktyp == LOCK_PICK)
85         return actions[3]; /* "picking the lock" */
86     else if (xlock.picktyp == CREDIT_CARD)
87         return actions[3]; /* same as lock_pick */
88     else if (xlock.door)
89         return actions[0]; /* "unlocking the door" */
90     else if (xlock.box)
91         return xlock.box->otyp == CHEST ? actions[1] : actions[2];
92     else
93         return actions[3];
94 }
95
96 /* try to open/close a lock */
97 STATIC_PTR int
98 picklock(VOID_ARGS)
99 {
100     if (xlock.box) {
101         if (xlock.box->where != OBJ_FLOOR
102             || xlock.box->ox != u.ux || xlock.box->oy != u.uy) {
103             return ((xlock.usedtime = 0)); /* you or it moved */
104         }
105     } else { /* door */
106         if (xlock.door != &(levl[u.ux + u.dx][u.uy + u.dy])) {
107             return ((xlock.usedtime = 0)); /* you moved */
108         }
109         switch (xlock.door->doormask) {
110         case D_NODOOR:
111 /*JP
112             pline("This doorway has no door.");
113 */
114             pline("\8fo\93ü\8cû\82É\82Í\94à\82ª\82È\82¢\81D");
115             return ((xlock.usedtime = 0));
116         case D_ISOPEN:
117 /*JP
118             You("cannot lock an open door.");
119 */
120             pline("\8aJ\82¢\82Ä\82é\94à\82É\8c®\82ð\82©\82¯\82ç\82ê\82È\82¢\81D");
121             return ((xlock.usedtime = 0));
122         case D_BROKEN:
123 /*JP
124             pline("This door is broken.");
125 */
126             pline("\94à\82Í\89ó\82ê\82Ä\82¢\82é\81D");
127             return ((xlock.usedtime = 0));
128         }
129     }
130
131     if (xlock.usedtime++ >= 50 || nohands(youmonst.data)) {
132 /*JP
133         You("give up your attempt at %s.", lock_action());
134 */
135         pline("%s\82Ì\82ð\82 \82«\82ç\82ß\82½\81D", lock_action());
136         exercise(A_DEX, TRUE); /* even if you don't succeed */
137         return ((xlock.usedtime = 0));
138     }
139
140     if (rn2(100) >= xlock.chance)
141         return 1; /* still busy */
142
143     /* using the Master Key of Thievery finds traps if its bless/curse
144        state is adequate (non-cursed for rogues, blessed for others;
145        checked when setting up 'xlock') */
146     if ((!xlock.door ? (int) xlock.box->otrapped
147                      : (xlock.door->doormask & D_TRAPPED) != 0)
148         && xlock.magic_key) {
149         xlock.chance += 20; /* less effort needed next time */
150         /* unfortunately we don't have a 'tknown' flag to record
151            "known to be trapped" so declining to disarm and then
152            retrying lock manipulation will find it all over again */
153 /*JP
154         if (yn("You find a trap!  Do you want to try to disarm it?") == 'y') {
155 */
156         if (yn("ã©\82ð\8c©\82Â\82¯\82½\81I\8aO\82µ\82Ü\82·\82©\81H") == 'y') {
157             const char *what;
158             boolean alreadyunlocked;
159
160             /* disarming while using magic key always succeeds */
161             if (xlock.door) {
162                 xlock.door->doormask &= ~D_TRAPPED;
163 /*JP
164                 what = "door";
165 */
166                 what = "\94à";
167                 alreadyunlocked = !(xlock.door->doormask & D_LOCKED);
168             } else {
169                 xlock.box->otrapped = 0;
170 /*JP
171                 what = (xlock.box->otyp == CHEST) ? "chest" : "box";
172 */
173                 what = (xlock.box->otyp == CHEST) ? "\95ó\94 " : "\94 ";
174                 alreadyunlocked = !xlock.box->olocked;
175             }
176 #if 0 /*JP:T*/
177             You("succeed in disarming the trap.  The %s is still %slocked.",
178                 what, alreadyunlocked ? "un" : "");
179 #else
180             You("ã©\82ð\8aO\82µ\82½\81D%s\82Í\8c®\82ª%s\82Ü\82Ü\82¾\81D",
181                 what, alreadyunlocked ? "\8aJ\82¢\82½" : "\82©\82©\82Á\82½");
182 #endif
183             exercise(A_WIS, TRUE);
184         } else {
185 /*JP
186             You("stop %s.", lock_action());
187 */
188             You("%s\82Ì\82ð\82â\82ß\82½\81D", lock_action());
189             exercise(A_WIS, FALSE);
190         }
191         return ((xlock.usedtime = 0));
192     }
193
194 /*JP
195     You("succeed in %s.", lock_action());
196 */
197     You("%s\82Ì\82É\90¬\8c÷\82µ\82½\81D", lock_action());
198     if (xlock.door) {
199         if (xlock.door->doormask & D_TRAPPED) {
200 /*JP
201             b_trapped("door", FINGER);
202 */
203             b_trapped("\94à", FINGER);
204             xlock.door->doormask = D_NODOOR;
205             unblock_point(u.ux + u.dx, u.uy + u.dy);
206             if (*in_rooms(u.ux + u.dx, u.uy + u.dy, SHOPBASE))
207                 add_damage(u.ux + u.dx, u.uy + u.dy, SHOP_DOOR_COST);
208             newsym(u.ux + u.dx, u.uy + u.dy);
209         } else if (xlock.door->doormask & D_LOCKED)
210             xlock.door->doormask = D_CLOSED;
211         else
212             xlock.door->doormask = D_LOCKED;
213     } else {
214         xlock.box->olocked = !xlock.box->olocked;
215         xlock.box->lknown = 1;
216         if (xlock.box->otrapped)
217             (void) chest_trap(xlock.box, FINGER, FALSE);
218     }
219     exercise(A_DEX, TRUE);
220     return ((xlock.usedtime = 0));
221 }
222
223 void
224 breakchestlock(box, destroyit)
225 struct obj *box;
226 boolean destroyit;
227 {
228     if (!destroyit) { /* bill for the box but not for its contents */
229         struct obj *hide_contents = box->cobj;
230
231         box->cobj = 0;
232         costly_alteration(box, COST_BRKLCK);
233         box->cobj = hide_contents;
234         box->olocked = 0;
235         box->obroken = 1;
236         box->lknown = 1;
237     } else { /* #force has destroyed this box (at <u.ux,u.uy>) */
238         struct obj *otmp;
239         struct monst *shkp = (*u.ushops && costly_spot(u.ux, u.uy))
240                                  ? shop_keeper(*u.ushops)
241                                  : 0;
242         boolean costly = (boolean) (shkp != 0),
243                 peaceful_shk = costly && (boolean) shkp->mpeaceful;
244         long loss = 0L;
245
246 /*JP
247         pline("In fact, you've totally destroyed %s.", the(xname(box)));
248 */
249         pline("\8eÀ\8dÛ\82Ì\82Æ\82±\82ë\81C%s\82ð\8a®\91S\82É\89ó\82µ\82Ä\82µ\82Ü\82Á\82½\81D", xname(xlock.box));
250         /* Put the contents on ground at the hero's feet. */
251         while ((otmp = box->cobj) != 0) {
252             obj_extract_self(otmp);
253             if (!rn2(3) || otmp->oclass == POTION_CLASS) {
254                 chest_shatter_msg(otmp);
255                 if (costly)
256                     loss += stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE);
257                 if (otmp->quan == 1L) {
258                     obfree(otmp, (struct obj *) 0);
259                     continue;
260                 }
261                 /* this works because we're sure to have at least 1 left;
262                    otherwise it would fail since otmp is not in inventory */
263                 useup(otmp);
264             }
265             if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
266                 otmp->age = monstermoves - otmp->age; /* actual age */
267                 start_corpse_timeout(otmp);
268             }
269             place_object(otmp, u.ux, u.uy);
270             stackobj(otmp);
271         }
272         if (costly)
273             loss += stolen_value(box, u.ux, u.uy, peaceful_shk, TRUE);
274         if (loss)
275 /*JP
276             You("owe %ld %s for objects destroyed.", loss, currency(loss));
277 */
278             You("\8aí\95¨\94j\91¹\82Å%ld%s\82Ì\8eØ\82è\82ð\82Â\82­\82Á\82½\81D", loss, currency(loss));
279         delobj(box);
280     }
281 }
282
283 /* try to force a locked chest */
284 STATIC_PTR int
285 forcelock(VOID_ARGS)
286 {
287     if ((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy))
288         return ((xlock.usedtime = 0)); /* you or it moved */
289
290     if (xlock.usedtime++ >= 50 || !uwep || nohands(youmonst.data)) {
291 /*JP
292         You("give up your attempt to force the lock.");
293 */
294         pline("\8c®\82ð\82±\82\8aJ\82¯\82é\82Ì\82ð\82 \82«\82ç\82ß\82½\81D");
295         if (xlock.usedtime >= 50) /* you made the effort */
296             exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
297         return ((xlock.usedtime = 0));
298     }
299
300     if (xlock.picktyp) { /* blade */
301         if (rn2(1000 - (int) uwep->spe) > (992 - greatest_erosion(uwep) * 10)
302             && !uwep->cursed && !obj_resists(uwep, 0, 99)) {
303             /* for a +0 weapon, probability that it survives an unsuccessful
304              * attempt to force the lock is (.992)^50 = .67
305              */
306 #if 0 /*JP:T*/
307             pline("%sour %s broke!", (uwep->quan > 1L) ? "One of y" : "Y",
308                   xname(uwep));
309 #else
310             pline("%s\82Í\89ó\82ê\82Ä\82µ\82Ü\82Á\82½\81I",xname(uwep));
311 #endif
312             useup(uwep);
313 /*JP
314             You("give up your attempt to force the lock.");
315 */
316             pline("\8c®\82ð\82±\82\8aJ\82¯\82é\82Ì\82ð\82 \82«\82ç\82ß\82½\81D");
317             exercise(A_DEX, TRUE);
318             return ((xlock.usedtime = 0));
319         }
320     } else             /* blunt */
321         wake_nearby(); /* due to hammering on the container */
322
323     if (rn2(100) >= xlock.chance)
324         return 1; /* still busy */
325
326 /*JP
327     You("succeed in forcing the lock.");
328 */
329     pline("\8c®\82ð\82±\82\8aJ\82¯\82½\81D");
330     exercise(xlock.picktyp ? A_DEX : A_STR, TRUE);
331     /* breakchestlock() might destroy xlock.box; if so, xlock context will
332        be cleared (delobj -> obfree -> maybe_reset_pick); but it might not,
333        so explicitly clear that manually */
334     breakchestlock(xlock.box, (boolean) (!xlock.picktyp && !rn2(3)));
335     reset_pick(); /* lock-picking context is no longer valid */
336
337     return 0;
338 }
339
340 void
341 reset_pick()
342 {
343     xlock.usedtime = xlock.chance = xlock.picktyp = 0;
344     xlock.magic_key = FALSE;
345     xlock.door = (struct rm *) 0;
346     xlock.box = (struct obj *) 0;
347 }
348
349 /* level change or object deletion; context may no longer be valid */
350 void
351 maybe_reset_pick(container)
352 struct obj *container; /* passed from obfree() */
353 {
354     /*
355      * If a specific container, only clear context if it is for that
356      * particular container (which is being deleted).  Other stuff on
357      * the current dungeon level remains valid.
358      * However if 'container' is Null, clear context if not carrying
359      * xlock.box (which might be Null if context is for a door).
360      * Used for changing levels, where a floor container or a door is
361      * being left behind and won't be valid on the new level but a
362      * carried container will still be.  There might not be any context,
363      * in which case redundantly clearing it is harmless.
364      */
365     if (container ? (container == xlock.box)
366                   : (!xlock.box || !carried(xlock.box)))
367         reset_pick();
368 }
369
370 /* for doapply(); if player gives a direction or resumes an interrupted
371    previous attempt then it costs hero a move even if nothing ultimately
372    happens; when told "can't do that" before being asked for direction
373    or player cancels with ESC while giving direction, it doesn't */
374 #define PICKLOCK_LEARNED_SOMETHING (-1) /* time passes */
375 #define PICKLOCK_DID_NOTHING 0          /* no time passes */
376 #define PICKLOCK_DID_SOMETHING 1
377
378 /* player is applying a key, lock pick, or credit card */
379 int
380 pick_lock(pick)
381 struct obj *pick;
382 {
383     int picktyp, c, ch;
384     coord cc;
385     struct rm *door;
386     struct obj *otmp;
387     char qbuf[QBUFSZ];
388
389     picktyp = pick->otyp;
390
391     /* check whether we're resuming an interrupted previous attempt */
392     if (xlock.usedtime && picktyp == xlock.picktyp) {
393 /*JP
394         static char no_longer[] = "Unfortunately, you can no longer %s %s.";
395 */
396         static char no_longer[] = "\82´\82ñ\82Ë\82ñ\82È\82ª\82ç\81C\82 \82È\82½\82Í%s%s";
397
398         if (nohands(youmonst.data)) {
399 /*JP
400             const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";
401 */
402             const char *what = (picktyp == LOCK_PICK) ? "\8c®\8aJ\82¯\8aí\8bï" : "\8c®";
403
404             if (picktyp == CREDIT_CARD)
405 /*JP
406                 what = "card";
407 */
408                 what = "\83J\81[\83h";
409 /*JP
410             pline(no_longer, "hold the", what);
411 */
412             pline(no_longer, what, "\82ð\82Â\82©\82ß\82È\82¢");
413             reset_pick();
414             return PICKLOCK_LEARNED_SOMETHING;
415         } else if (u.uswallow || (xlock.box && !can_reach_floor(TRUE))) {
416 /*JP
417             pline(no_longer, "reach the", "lock");
418 */
419             pline(no_longer, "\8c®\82É", "\93Í\82©\82È\82¢");
420             reset_pick();
421             return PICKLOCK_LEARNED_SOMETHING;
422         } else {
423             const char *action = lock_action();
424
425 /*JP
426             You("resume your attempt at %s.", action);
427 */
428             pline("%s\82Ì\82ð\8dÄ\8aJ\82µ\82½\81D", action);
429             xlock.magic_key = is_magic_key(&youmonst, pick);
430             set_occupation(picklock, action, 0);
431             return PICKLOCK_DID_SOMETHING;
432         }
433     }
434
435     if (nohands(youmonst.data)) {
436 /*JP
437         You_cant("hold %s -- you have no hands!", doname(pick));
438 */
439         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));
440         return PICKLOCK_DID_NOTHING;
441     } else if (u.uswallow) {
442 #if 0 /*JP:T*/
443         You_cant("%sunlock %s.", (picktyp == CREDIT_CARD) ? "" : "lock or ",
444                  mon_nam(u.ustuck));
445 #else
446         You_cant("%s\82ð%s\82È\82¢\81D", mon_nam(u.ustuck),
447                  (picktyp == CREDIT_CARD) ? "\8aJ\82¯\82ç\82ê" : "\8aJ\82¯\95Â\82ß\82Å\82«");
448 #endif
449         return PICKLOCK_DID_NOTHING;
450     }
451
452     if (picktyp != LOCK_PICK
453         && picktyp != CREDIT_CARD
454         && picktyp != SKELETON_KEY) {
455         impossible("picking lock with object %d?", picktyp);
456         return PICKLOCK_DID_NOTHING;
457     }
458     ch = 0; /* lint suppression */
459
460 /*JP
461     if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc))
462 */
463     if (!get_adjacent_loc((char *) 0, "\88Ê\92u\82ª\82¨\82©\82µ\82¢\81I", u.ux, u.uy, &cc))
464         return PICKLOCK_DID_NOTHING;
465
466     if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */
467         const char *verb;
468         char qsfx[QBUFSZ];
469 #if 0 /*JP*/
470         boolean it;
471 #endif
472         int count;
473
474         if (u.dz < 0) {
475 #if 0 /*JP:T*/
476             There("isn't any sort of lock up %s.",
477                   Levitation ? "here" : "there");
478 #else
479             pline("%s\82É\82Í\8c®\82ð\82©\82¯\82é\82æ\82¤\82È\95¨\82Í\82È\82¢\81D",
480                   Levitation ? "\82±\82±" : "\89º\95û");
481 #endif
482             return PICKLOCK_LEARNED_SOMETHING;
483         } else if (is_lava(u.ux, u.uy)) {
484 /*JP
485             pline("Doing that would probably melt %s.", yname(pick));
486 */
487             pline("\82»\82ñ\82È\82±\82Æ\82ð\82µ\82½\82ç%s\82ª\97n\82¯\82Ä\82µ\82Ü\82¤\81D", yname(pick));
488             return PICKLOCK_LEARNED_SOMETHING;
489         } else if (is_pool(u.ux, u.uy) && !Underwater) {
490 /*JP
491             pline_The("%s has no lock.", hliquid("water"));
492 */
493             pline_The("%s\82É\8fù\91O\82Í\82È\82¢\81D", hliquid("\90\85"));
494             return PICKLOCK_LEARNED_SOMETHING;
495         }
496
497         count = 0;
498         c = 'n'; /* in case there are no boxes here */
499         for (otmp = level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
500             if (Is_box(otmp)) {
501                 ++count;
502                 if (!can_reach_floor(TRUE)) {
503 /*JP
504                     You_cant("reach %s from up here.", the(xname(otmp)));
505 */
506                     You("\82±\82±\82©\82ç%s\82É\93Í\82©\82È\82¢\81D", the(xname(otmp)));
507                     return PICKLOCK_LEARNED_SOMETHING;
508                 }
509 #if 0 /*JP*/
510                 it = 0;
511 #endif
512                 if (otmp->obroken)
513 /*JP
514                     verb = "fix";
515 */
516                     verb = "\8fC\95\9c\82·\82é";
517                 else if (!otmp->olocked)
518 /*JP
519                     verb = "lock", it = 1;
520 */
521                     verb = "\8c®\82ð\82©\82¯\82é";
522                 else if (picktyp != LOCK_PICK)
523 /*JP
524                     verb = "unlock", it = 1;
525 */
526                     verb = "\8c®\82ð\82Í\82¸\82·";
527                 else
528 /*JP
529                     verb = "pick";
530 */
531                     verb = "\82±\82\82 \82¯\82é";
532
533                 /* "There is <a box> here; <verb> <it|its lock>?" */
534 /*JP
535                 Sprintf(qsfx, " here; %s %s?", verb, it ? "it" : "its lock");
536 */
537                 Sprintf(qsfx, "\82ª\82 \82é\81D%s\81H", verb);
538 #if 0 /*JP:T*/
539                 (void) safe_qbuf(qbuf, "There is ", qsfx, otmp, doname,
540                                  ansimpleoname, "a box");
541 #else
542                 (void) safe_qbuf(qbuf, "\82±\82±\82É\82Í", qsfx, otmp, doname,
543                                  ansimpleoname, "\94 ");
544 #endif
545                 otmp->lknown = 1;
546
547                 c = ynq(qbuf);
548                 if (c == 'q')
549                     return 0;
550                 if (c == 'n')
551                     continue;
552
553                 if (otmp->obroken) {
554 /*JP
555                     You_cant("fix its broken lock with %s.", doname(pick));
556 */
557                     You("\89ó\82ê\82½\8c®\82ð%s\82Å\8fC\95\9c\82Å\82«\82È\82¢\81D", doname(pick));
558                     return PICKLOCK_LEARNED_SOMETHING;
559                 } else if (picktyp == CREDIT_CARD && !otmp->olocked) {
560                     /* credit cards are only good for unlocking */
561 #if 0 /*JP:T*/
562                     You_cant("do that with %s.",
563                              an(simple_typename(picktyp)));
564 #else
565                     pline("%s\82\82á\82»\82ñ\82È\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
566                           simple_typename(picktyp));
567 #endif
568                     return PICKLOCK_LEARNED_SOMETHING;
569                 }
570                 switch (picktyp) {
571                 case CREDIT_CARD:
572                     ch = ACURR(A_DEX) + 20 * Role_if(PM_ROGUE);
573                     break;
574                 case LOCK_PICK:
575                     ch = 4 * ACURR(A_DEX) + 25 * Role_if(PM_ROGUE);
576                     break;
577                 case SKELETON_KEY:
578                     ch = 75 + ACURR(A_DEX);
579                     break;
580                 default:
581                     ch = 0;
582                 }
583                 if (otmp->cursed)
584                     ch /= 2;
585
586                 xlock.box = otmp;
587                 xlock.door = 0;
588                 break;
589             }
590         if (c != 'y') {
591             if (!count)
592 /*JP
593                 There("doesn't seem to be any sort of lock here.");
594 */
595                 pline("\82±\82±\82É\82Í\8c®\82ð\82©\82¯\82é\82æ\82¤\82È\95¨\82Í\82È\82¢\82æ\82¤\82¾\81D");
596             return PICKLOCK_LEARNED_SOMETHING; /* decided against all boxes */
597         }
598     } else { /* pick the lock in a door */
599         struct monst *mtmp;
600
601         if (u.utrap && u.utraptype == TT_PIT) {
602 /*JP
603             You_cant("reach over the edge of the pit.");
604 */
605             pline("\97\8e\82µ\8c\8a\82Ì\92\86\82©\82ç\82Å\82Í\93Í\82©\82È\82¢\81D");
606             return PICKLOCK_LEARNED_SOMETHING;
607         }
608
609         door = &levl[cc.x][cc.y];
610         mtmp = m_at(cc.x, cc.y);
611         if (mtmp && canseemon(mtmp) && M_AP_TYPE(mtmp) != M_AP_FURNITURE
612             && M_AP_TYPE(mtmp) != M_AP_OBJECT) {
613             if (picktyp == CREDIT_CARD
614                 && (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]))
615 /*JP
616                 verbalize("No checks, no credit, no problem.");
617 */
618                 verbalize("\82¢\82Â\82à\83j\83R\83j\83R\8c»\8bà\95¥\82¢\81D");
619             else
620 #if 0 /*JP:T*/
621                 pline("I don't think %s would appreciate that.",
622                       mon_nam(mtmp));
623 #else
624                 pline("%s\82ª\82»\82Ì\89¿\92l\82ð\94F\82ß\82é\82Æ\82Í\8ev\82¦\82È\82¢\81D", mon_nam(mtmp));
625 #endif
626             return PICKLOCK_LEARNED_SOMETHING;
627         } else if (mtmp && is_door_mappear(mtmp)) {
628             /* "The door actually was a <mimic>!" */
629             stumble_onto_mimic(mtmp);
630             /* mimic might keep the key (50% chance, 10% for PYEC or MKoT) */
631             maybe_absorb_item(mtmp, pick, 50, 10);
632             return PICKLOCK_LEARNED_SOMETHING;
633         }
634         if (!IS_DOOR(door->typ)) {
635             if (is_drawbridge_wall(cc.x, cc.y) >= 0)
636 /*JP
637                 You("%s no lock on the drawbridge.", Blind ? "feel" : "see");
638 */
639                 pline("\92µ\82Ë\8b´\82É\82Í\8c®\82ª\82È\82¢%s\81D", Blind ? "\82æ\82¤\82¾" : "\82æ\82¤\82É\8c©\82¦\82é");
640             else
641 /*JP
642                 You("%s no door there.", Blind ? "feel" : "see");
643 */
644                 pline("\82±\82±\82É\82Í\94à\82ª\82È\82¢%s\81D", Blind ? "\82æ\82¤\82¾" : "\82æ\82¤\82É\8c©\82¦\82é");
645             return PICKLOCK_LEARNED_SOMETHING;
646         }
647         switch (door->doormask) {
648         case D_NODOOR:
649 /*JP
650             pline("This doorway has no door.");
651 */
652             pline("\82±\82Ì\8fo\93ü\8cû\82É\82Í\94à\82ª\82È\82¢\81D");
653             return PICKLOCK_LEARNED_SOMETHING;
654         case D_ISOPEN:
655 /*JP
656             You("cannot lock an open door.");
657 */
658             pline("\8aJ\82¢\82Ä\82é\94à\82É\82Í\8c®\82ð\82©\82¯\82ç\82ê\82È\82¢\81D");
659             return PICKLOCK_LEARNED_SOMETHING;
660         case D_BROKEN:
661 /*JP
662             pline("This door is broken.");
663 */
664             pline("\82±\82Ì\94à\82Í\89ó\82ê\82Ä\82¢\82é\81D");
665             return PICKLOCK_LEARNED_SOMETHING;
666         default:
667             /* credit cards are only good for unlocking */
668             if (picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
669 /*JP
670                 You_cant("lock a door with a credit card.");
671 */
672                 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");
673                 return PICKLOCK_LEARNED_SOMETHING;
674             }
675
676 #if 0 /*JP:T*/
677             Sprintf(qbuf, "%s it?",
678                     (door->doormask & D_LOCKED) ? "Unlock" : "Lock");
679 #else
680             Sprintf(qbuf, "%s\82Ü\82·\82©\81H",
681                     (door->doormask & D_LOCKED) ? "\82Í\82¸\82µ" : "\82©\82¯" );
682 #endif
683
684             c = yn(qbuf);
685             if (c == 'n')
686                 return 0;
687
688             switch (picktyp) {
689             case CREDIT_CARD:
690                 ch = 2 * ACURR(A_DEX) + 20 * Role_if(PM_ROGUE);
691                 break;
692             case LOCK_PICK:
693                 ch = 3 * ACURR(A_DEX) + 30 * Role_if(PM_ROGUE);
694                 break;
695             case SKELETON_KEY:
696                 ch = 70 + ACURR(A_DEX);
697                 break;
698             default:
699                 ch = 0;
700             }
701             xlock.door = door;
702             xlock.box = 0;
703         }
704     }
705     context.move = 0;
706     xlock.chance = ch;
707     xlock.picktyp = picktyp;
708     xlock.magic_key = is_magic_key(&youmonst, pick);
709     xlock.usedtime = 0;
710     set_occupation(picklock, lock_action(), 0);
711     return PICKLOCK_DID_SOMETHING;
712 }
713
714 /* try to force a chest with your weapon */
715 int
716 doforce()
717 {
718     register struct obj *otmp;
719     register int c, picktyp;
720     char qbuf[QBUFSZ];
721
722     if (u.uswallow) {
723 /*JP
724         You_cant("force anything from inside here.");
725 */
726         You_cant("\93à\91¤\82©\82ç\82±\82\8aJ\82¯\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
727         return 0;
728     }
729     if (!uwep /* proper type test */
730         || ((uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
731                ? (objects[uwep->otyp].oc_skill < P_DAGGER
732                   || objects[uwep->otyp].oc_skill == P_FLAIL
733                   || objects[uwep->otyp].oc_skill > P_LANCE)
734                : uwep->oclass != ROCK_CLASS)) {
735 #if 0 /*JP:T*/
736         You_cant("force anything %s weapon.",
737                  !uwep ? "when not wielding a"
738                        : (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))
739                              ? "without a proper"
740                              : "with that");
741 #else
742         You_cant("%s\95\90\8aí\82È\82µ\82Å\8c®\82ð\82±\82\8aJ\82¯\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
743                  !uwep ? "\91\95\94õ\82µ\82Ä\82¢\82é"
744                        : (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))
745                              ? "\93K\90Ø\82È"
746                              : "");
747 #endif
748         return 0;
749     }
750     if (!can_reach_floor(TRUE)) {
751         cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
752         return 0;
753     }
754
755     picktyp = is_blade(uwep) && !is_pick(uwep);
756     if (xlock.usedtime && xlock.box && picktyp == xlock.picktyp) {
757 /*JP
758         You("resume your attempt to force the lock.");
759 */
760         pline("\8c®\82ð\82±\82\82 \82¯\82é\82Ì\82ð\8dÄ\8aJ\82µ\82½\81D");
761 /*JP
762         set_occupation(forcelock, "forcing the lock", 0);
763 */
764         set_occupation(forcelock, "\8c®\82ð\82±\82\82 \82¯\82é", 0);
765         return 1;
766     }
767
768     /* A lock is made only for the honest man, the thief will break it. */
769     xlock.box = (struct obj *) 0;
770     for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere)
771         if (Is_box(otmp)) {
772             if (otmp->obroken || !otmp->olocked) {
773                 /* force doname() to omit known "broken" or "unlocked"
774                    prefix so that the message isn't worded redundantly;
775                    since we're about to set lknown, there's no need to
776                    remember and then reset its current value */
777                 otmp->lknown = 0;
778 #if 0 /*JP:T*/
779                 There("is %s here, but its lock is already %s.",
780                       doname(otmp), otmp->obroken ? "broken" : "unlocked");
781 #else
782                 pline("\82±\82±\82É\82Í%s\82ª\82 \82é\81D\82µ\82©\82µ\82»\82Ì\8c®\82Í\82à\82¤%s\81D",
783                       doname(otmp),
784                       otmp->obroken ? "\89ó\82ê\82Ä\82¢\82é" : "\82Í\82¸\82³\82ê\82Ä\82¢\82é");
785 #endif
786                 otmp->lknown = 1;
787                 continue;
788             }
789 #if 0 /*JP:T*/
790             (void) safe_qbuf(qbuf, "There is ", " here; force its lock?",
791                              otmp, doname, ansimpleoname, "a box");
792 #else
793             (void) safe_qbuf(qbuf, "\82±\82±\82É\82Í", "\82ª\82 \82é\81D\8c®\82ð\82±\82\8aJ\82¯\82Ü\82·\82©\81H",
794                              otmp, doname, ansimpleoname, "\94 ");
795 #endif
796             otmp->lknown = 1;
797
798             c = ynq(qbuf);
799             if (c == 'q')
800                 return 0;
801             if (c == 'n')
802                 continue;
803
804             if (picktyp)
805 /*JP
806                 You("force %s into a crack and pry.", yname(uwep));
807 */
808                 You("%s\82ð\82·\82«\8aÔ\82É\8d·\82µ\82±\82ñ\82Å\82±\82\82 \82¯\82æ\82¤\82Æ\82µ\82½\81D",xname(uwep));
809             else
810 /*JP
811                 You("start bashing it with %s.", yname(uwep));
812 */
813                 pline("%s\82Å\89£\82è\82Â\82¯\82½\81D", xname(uwep));
814             xlock.box = otmp;
815             xlock.chance = objects[uwep->otyp].oc_wldam * 2;
816             xlock.picktyp = picktyp;
817             xlock.magic_key = FALSE;
818             xlock.usedtime = 0;
819             break;
820         }
821
822     if (xlock.box)
823 /*JP
824         set_occupation(forcelock, "forcing the lock", 0);
825 */
826         set_occupation(forcelock, "\8c®\82ð\82±\82\82 \82¯\82é", 0);
827     else
828 /*JP
829         You("decide not to force the issue.");
830 */
831         pline("\82»\82ê\82Í\96³\88Ó\96¡\82È\8ds\88×\82¾\81D");
832     return 1;
833 }
834
835 boolean
836 stumble_on_door_mimic(x, y)
837 int x, y;
838 {
839     struct monst *mtmp;
840
841     if ((mtmp = m_at(x, y)) && is_door_mappear(mtmp)
842         && !Protection_from_shape_changers) {
843         stumble_onto_mimic(mtmp);
844         return TRUE;
845     }
846     return FALSE;
847 }
848
849 /* the 'O' command - try to open a door */
850 int
851 doopen()
852 {
853     return doopen_indir(0, 0);
854 }
855
856 /* try to open a door in direction u.dx/u.dy */
857 int
858 doopen_indir(x, y)
859 int x, y;
860 {
861     coord cc;
862     register struct rm *door;
863     boolean portcullis;
864     int res = 0;
865
866     if (nohands(youmonst.data)) {
867 /*JP
868         You_cant("open anything -- you have no hands!");
869 */
870         You("\89½\82à\8aJ\82¯\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\81I\8eè\82ª\82È\82¢\82ñ\82¾\82à\82Ì\81I");
871         return 0;
872     }
873
874     if (u.utrap && u.utraptype == TT_PIT) {
875 /*JP
876         You_cant("reach over the edge of the pit.");
877 */
878         pline("\97\8e\82µ\8c\8a\82Ì\92\86\82©\82ç\93Í\82©\82È\82¢\81D");
879         return 0;
880     }
881
882     if (x > 0 && y > 0) {
883         cc.x = x;
884         cc.y = y;
885     } else if (!get_adjacent_loc((char *) 0, (char *) 0, u.ux, u.uy, &cc))
886         return 0;
887
888     /* open at yourself/up/down */
889     if ((cc.x == u.ux) && (cc.y == u.uy))
890         return doloot();
891
892     if (stumble_on_door_mimic(cc.x, cc.y))
893         return 1;
894
895     /* when choosing a direction is impaired, use a turn
896        regardless of whether a door is successfully targetted */
897     if (Confusion || Stunned)
898         res = 1;
899
900     door = &levl[cc.x][cc.y];
901     portcullis = (is_drawbridge_wall(cc.x, cc.y) >= 0);
902     if (Blind) {
903         int oldglyph = door->glyph;
904         schar oldlastseentyp = lastseentyp[cc.x][cc.y];
905
906         feel_location(cc.x, cc.y);
907         if (door->glyph != oldglyph
908             || lastseentyp[cc.x][cc.y] != oldlastseentyp)
909             res = 1; /* learned something */
910     }
911
912     if (portcullis || !IS_DOOR(door->typ)) {
913         /* closed portcullis or spot that opened bridge would span */
914         if (is_db_wall(cc.x, cc.y) || door->typ == DRAWBRIDGE_UP)
915 /*JP
916             There("is no obvious way to open the drawbridge.");
917 */
918             pline("\92µ\82Ë\8b´\82ð\8d~\82ë\82·\96¾\94\92\82È\95û\96@\82Í\82È\82¢\81D");
919         else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
920 /*JP
921             pline_The("drawbridge is already open.");
922 */
923             pline_The("\92µ\82Ë\8b´\82Í\82à\82¤\8aJ\82¢\82Ä\82¢\82é\81D");
924         else if (container_at(cc.x, cc.y, TRUE))
925 #if 0 /*JP:T*/
926             pline("%s like something lootable over there.",
927                   Blind ? "Feels" : "Seems");
928 #else
929             pline("\82±\82±\82É\82Í\89½\82©\93ü\82ê\95¨\82ª\82 \82é\82æ\82¤\82¾\81D");
930 #endif
931         else
932 /*JP
933             You("%s no door there.", Blind ? "feel" : "see");
934 */
935             pline("\82»\82±\82É\82Í\94à\82Í\82È\82¢\82æ\82¤%s\81D", Blind ? "\82¾" : "\82É\8c©\82¦\82é");
936         return res;
937     }
938
939     if (!(door->doormask & D_CLOSED)) {
940         const char *mesg;
941
942         switch (door->doormask) {
943         case D_BROKEN:
944 /*JP
945             mesg = " is broken";
946 */
947             mesg = "\94à\82Í\89ó\82ê\82Ä\82¢\82é";
948             break;
949         case D_NODOOR:
950 /*JP
951             mesg = "way has no door";
952 */
953             mesg = "\8fo\93ü\8cû\82É\82Í\94à\82ª\82È\82¢";
954             break;
955         case D_ISOPEN:
956 /*JP
957             mesg = " is already open";
958 */
959             mesg = "\94à\82Í\82à\82¤\8aJ\82¢\82Ä\82¢\82é";
960             break;
961         default:
962 /*JP
963             mesg = " is locked";
964 */
965             mesg = "\94à\82É\82Í\8c®\82ª\8a|\82©\82Á\82Ä\82¢\82é";
966             break;
967         }
968 /*JP
969         pline("This door%s.", mesg);
970 */
971         pline("%s\81D", mesg);
972         return res;
973     }
974
975     if (verysmall(youmonst.data)) {
976 /*JP
977         pline("You're too small to pull the door open.");
978 */
979         You("\94à\82ð\89\9f\82·\82É\82Í\8f¬\82³\82·\82¬\82é\81D");
980         return res;
981     }
982
983     /* door is known to be CLOSED */
984     if (rnl(20) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
985 /*JP
986         pline_The("door opens.");
987 */
988         pline("\94à\82Í\8aJ\82¢\82½\81D");
989         if (door->doormask & D_TRAPPED) {
990 /*JP
991             b_trapped("door", FINGER);
992 */
993             b_trapped("\94à", FINGER);
994             door->doormask = D_NODOOR;
995             if (*in_rooms(cc.x, cc.y, SHOPBASE))
996                 add_damage(cc.x, cc.y, SHOP_DOOR_COST);
997         } else
998             door->doormask = D_ISOPEN;
999         feel_newsym(cc.x, cc.y); /* the hero knows she opened it */
1000         unblock_point(cc.x, cc.y); /* vision: new see through there */
1001     } else {
1002         exercise(A_STR, TRUE);
1003 /*JP
1004         pline_The("door resists!");
1005 */
1006         pline("\82È\82©\82È\82©\8aJ\82©\82È\82¢\81I");
1007     }
1008
1009     return 1;
1010 }
1011
1012 STATIC_OVL boolean
1013 obstructed(x, y, quietly)
1014 register int x, y;
1015 boolean quietly;
1016 {
1017     register struct monst *mtmp = m_at(x, y);
1018
1019     if (mtmp && M_AP_TYPE(mtmp) != M_AP_FURNITURE) {
1020         if (M_AP_TYPE(mtmp) == M_AP_OBJECT)
1021             goto objhere;
1022         if (!quietly) {
1023             if ((mtmp->mx != x) || (mtmp->my != y)) {
1024                 /* worm tail */
1025 #if 0 /*JP:T*/
1026                 pline("%s%s blocks the way!",
1027                       !canspotmon(mtmp) ? Something : s_suffix(Monnam(mtmp)),
1028                       !canspotmon(mtmp) ? "" : " tail");
1029 #else
1030                 pline("%s%s\82ª\97§\82¿\82Ó\82³\82ª\82Á\82Ä\82¢\82é\81I",
1031                       !canspotmon(mtmp) ? "\89½\82©" : Monnam(mtmp),
1032                       !canspotmon(mtmp) ? "" : "\82Ì\90K\94ö");
1033 #endif
1034             } else {
1035 #if 0 /*JP:T*/
1036                 pline("%s blocks the way!",
1037                       !canspotmon(mtmp) ? "Some creature" : Monnam(mtmp));
1038 #else
1039                 pline("%s\82ª\97§\82¿\82Ó\82³\82ª\82Á\82Ä\82¢\82é\81I",
1040                       !canspotmon(mtmp) ? "\89½\8eÒ\82©" : Monnam(mtmp));
1041 #endif
1042             }
1043         }
1044         if (!canspotmon(mtmp))
1045             map_invisible(x, y);
1046         return TRUE;
1047     }
1048     if (OBJ_AT(x, y)) {
1049  objhere:
1050         if (!quietly)
1051 /*JP
1052             pline("%s's in the way.", Something);
1053 */
1054             pline("\89½\82©\82ª\8fo\93ü\8cû\82É\82 \82é\81D");
1055         return TRUE;
1056     }
1057     return FALSE;
1058 }
1059
1060 /* the 'C' command - try to close a door */
1061 int
1062 doclose()
1063 {
1064     register int x, y;
1065     register struct rm *door;
1066     boolean portcullis;
1067     int res = 0;
1068
1069     if (nohands(youmonst.data)) {
1070 /*JP
1071         You_cant("close anything -- you have no hands!");
1072 */
1073         You("\95Â\82ß\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\81I\8eè\82ª\82È\82¢\82ñ\82¾\82à\82Ì\81I");
1074         return 0;
1075     }
1076
1077     if (u.utrap && u.utraptype == TT_PIT) {
1078 /*JP
1079         You_cant("reach over the edge of the pit.");
1080 */
1081         pline("\97\8e\82µ\8c\8a\82Ì\92\86\82©\82ç\93Í\82©\82È\82¢\81D");
1082         return 0;
1083     }
1084
1085     if (!getdir((char *) 0))
1086         return 0;
1087
1088     x = u.ux + u.dx;
1089     y = u.uy + u.dy;
1090     if ((x == u.ux) && (y == u.uy)) {
1091 /*JP
1092         You("are in the way!");
1093 */
1094         pline("\82 \82È\82½\82ª\8fo\93ü\8cû\82É\82¢\82é\82Ì\82Å\95Â\82Ü\82ç\82È\82¢\81I");
1095         return 1;
1096     }
1097
1098     if (!isok(x, y))
1099         goto nodoor;
1100
1101     if (stumble_on_door_mimic(x, y))
1102         return 1;
1103
1104     /* when choosing a direction is impaired, use a turn
1105        regardless of whether a door is successfully targetted */
1106     if (Confusion || Stunned)
1107         res = 1;
1108
1109     door = &levl[x][y];
1110     portcullis = (is_drawbridge_wall(x, y) >= 0);
1111     if (Blind) {
1112         int oldglyph = door->glyph;
1113         schar oldlastseentyp = lastseentyp[x][y];
1114
1115         feel_location(x, y);
1116         if (door->glyph != oldglyph || lastseentyp[x][y] != oldlastseentyp)
1117             res = 1; /* learned something */
1118     }
1119
1120     if (portcullis || !IS_DOOR(door->typ)) {
1121         /* is_db_wall: closed portcullis */
1122         if (is_db_wall(x, y) || door->typ == DRAWBRIDGE_UP)
1123 /*JP
1124             pline_The("drawbridge is already closed.");
1125 */
1126             pline_The("\92µ\82Ë\8b´\82Í\82à\82¤\95Â\82\82Ä\82¢\82é\81D");
1127         else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
1128 /*JP
1129             There("is no obvious way to close the drawbridge.");
1130 */
1131             pline("\92µ\82Ë\8b´\82ð\95Â\82ß\82é\96¾\94\92\82È\95û\96@\82Í\82È\82¢\81D");
1132         else {
1133  nodoor:
1134 /*JP
1135             You("%s no door there.", Blind ? "feel" : "see");
1136 */
1137             pline("\82»\82±\82É\94à\82Í\82È\82¢\82æ\82¤%s\81D", Blind ? "\82¾" : "\82É\8c©\82¦\82é");
1138         }
1139         return res;
1140     }
1141
1142     if (door->doormask == D_NODOOR) {
1143 /*JP
1144         pline("This doorway has no door.");
1145 */
1146         pline("\8fo\93ü\8cû\82É\82Í\94à\82ª\82È\82¢\81D");
1147         return res;
1148     } else if (obstructed(x, y, FALSE)) {
1149         return res;
1150     } else if (door->doormask == D_BROKEN) {
1151 /*JP
1152         pline("This door is broken.");
1153 */
1154         pline("\94à\82Í\89ó\82ê\82Ä\82¢\82é\81D");
1155         return res;
1156     } else if (door->doormask & (D_CLOSED | D_LOCKED)) {
1157 /*JP
1158         pline("This door is already closed.");
1159 */
1160         pline("\94à\82Í\82à\82¤\95Â\82\82Ä\82¢\82é\81D");
1161         return res;
1162     }
1163
1164     if (door->doormask == D_ISOPEN) {
1165         if (verysmall(youmonst.data) && !u.usteed) {
1166 /*JP
1167             pline("You're too small to push the door closed.");
1168 */
1169             You("\8f¬\82³\82·\82¬\82Ä\94à\82ð\95Â\82ß\82ç\82ê\82È\82¢\81D");
1170             return res;
1171         }
1172         if (u.usteed
1173             || rn2(25) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
1174 /*JP
1175             pline_The("door closes.");
1176 */
1177             pline("\94à\82Í\95Â\82\82½\81D");
1178             door->doormask = D_CLOSED;
1179             feel_newsym(x, y); /* the hero knows she closed it */
1180             block_point(x, y); /* vision:  no longer see there */
1181         } else {
1182             exercise(A_STR, TRUE);
1183 /*JP
1184             pline_The("door resists!");
1185 */
1186             pline("\82È\82©\82È\82©\95Â\82Ü\82ç\82È\82¢\81I");
1187         }
1188     }
1189
1190     return 1;
1191 }
1192
1193 /* box obj was hit with spell or wand effect otmp;
1194    returns true if something happened */
1195 boolean
1196 boxlock(obj, otmp)
1197 struct obj *obj, *otmp; /* obj *is* a box */
1198 {
1199     boolean res = 0;
1200
1201     switch (otmp->otyp) {
1202     case WAN_LOCKING:
1203     case SPE_WIZARD_LOCK:
1204         if (!obj->olocked) { /* lock it; fix if broken */
1205 /*JP
1206             pline("Klunk!");
1207 */
1208             pline("\83J\83`\81I");
1209             obj->olocked = 1;
1210             obj->obroken = 0;
1211             if (Role_if(PM_WIZARD))
1212                 obj->lknown = 1;
1213             else
1214                 obj->lknown = 0;
1215             res = 1;
1216         } /* else already closed and locked */
1217         break;
1218     case WAN_OPENING:
1219     case SPE_KNOCK:
1220         if (obj->olocked) { /* unlock; couldn't be broken */
1221 /*JP
1222             pline("Klick!");
1223 */
1224             pline("\83R\83\93\83R\83\93\81I");
1225             obj->olocked = 0;
1226             res = 1;
1227             if (Role_if(PM_WIZARD))
1228                 obj->lknown = 1;
1229             else
1230                 obj->lknown = 0;
1231         } else /* silently fix if broken */
1232             obj->obroken = 0;
1233         break;
1234     case WAN_POLYMORPH:
1235     case SPE_POLYMORPH:
1236         /* maybe start unlocking chest, get interrupted, then zap it;
1237            we must avoid any attempt to resume unlocking it */
1238         if (xlock.box == obj)
1239             reset_pick();
1240         break;
1241     }
1242     return res;
1243 }
1244
1245 /* Door/secret door was hit with spell or wand effect otmp;
1246    returns true if something happened */
1247 boolean
1248 doorlock(otmp, x, y)
1249 struct obj *otmp;
1250 int x, y;
1251 {
1252     register struct rm *door = &levl[x][y];
1253     boolean res = TRUE;
1254     int loudness = 0;
1255     const char *msg = (const char *) 0;
1256 /*JP
1257     const char *dustcloud = "A cloud of dust";
1258 */
1259     const char *dustcloud = "\82Ù\82±\82è";
1260 /*JP
1261     const char *quickly_dissipates = "quickly dissipates";
1262 */
1263     const char *quickly_dissipates = "\82 \82Á\82Æ\8c¾\82¤\82Ü\82É\94ò\82Ñ\8eU\82Á\82½";
1264     boolean mysterywand = (otmp->oclass == WAND_CLASS && !otmp->dknown);
1265
1266     if (door->typ == SDOOR) {
1267         switch (otmp->otyp) {
1268         case WAN_OPENING:
1269         case SPE_KNOCK:
1270         case WAN_STRIKING:
1271         case SPE_FORCE_BOLT:
1272             door->typ = DOOR;
1273             door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
1274             newsym(x, y);
1275             if (cansee(x, y))
1276 /*JP
1277                 pline("A door appears in the wall!");
1278 */
1279                 pline("\95Ç\82©\82ç\94à\82ª\8c»\82ê\82½\81I");
1280             if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK)
1281                 return TRUE;
1282             break; /* striking: continue door handling below */
1283         case WAN_LOCKING:
1284         case SPE_WIZARD_LOCK:
1285         default:
1286             return FALSE;
1287         }
1288     }
1289
1290     switch (otmp->otyp) {
1291     case WAN_LOCKING:
1292     case SPE_WIZARD_LOCK:
1293         if (Is_rogue_level(&u.uz)) {
1294             boolean vis = cansee(x, y);
1295             /* Can't have real locking in Rogue, so just hide doorway */
1296             if (vis)
1297 /*JP
1298                 pline("%s springs up in the older, more primitive doorway.",
1299 */
1300                 pline("\8cÃ\82­\82³\82¢\81C\8c´\8en\93I\82È\8fo\93ü\8cû\82É%s\82ª\97§\82¿\82±\82ß\82½\81D",
1301                       dustcloud);
1302             else
1303 /*JP
1304                 You_hear("a swoosh.");
1305 */
1306                 You_hear("\83V\83\85\81[\83b\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
1307             if (obstructed(x, y, mysterywand)) {
1308                 if (vis)
1309 /*JP
1310                     pline_The("cloud %s.", quickly_dissipates);
1311 */
1312                     pline("\82Ù\82±\82è\82Í%s\81D",quickly_dissipates);
1313                 return FALSE;
1314             }
1315             block_point(x, y);
1316             door->typ = SDOOR, door->doormask = D_NODOOR;
1317             if (vis)
1318 /*JP
1319                 pline_The("doorway vanishes!");
1320 */
1321                 pline("\8fo\93ü\8cû\82Í\8fÁ\82¦\82½\81I");
1322             newsym(x, y);
1323             return TRUE;
1324         }
1325         if (obstructed(x, y, mysterywand))
1326             return FALSE;
1327         /* Don't allow doors to close over traps.  This is for pits */
1328         /* & trap doors, but is it ever OK for anything else? */
1329         if (t_at(x, y)) {
1330             /* maketrap() clears doormask, so it should be NODOOR */
1331 #if 0 /*JP:T*/
1332             pline("%s springs up in the doorway, but %s.", dustcloud,
1333                   quickly_dissipates);
1334 #else
1335             pline("%s\82ª\8fo\93ü\8cû\82É\97§\82¿\82±\82ß\82½\81C\82µ\82©\82µ%s", dustcloud,
1336                   quickly_dissipates);
1337 #endif
1338             return FALSE;
1339         }
1340
1341         switch (door->doormask & ~D_TRAPPED) {
1342         case D_CLOSED:
1343 /*JP
1344             msg = "The door locks!";
1345 */
1346             msg = "\94à\82É\8c®\82ª\82©\82©\82Á\82½\81I";
1347             break;
1348         case D_ISOPEN:
1349 /*JP
1350             msg = "The door swings shut, and locks!";
1351 */
1352             msg = "\94à\82Í\90¨\82¢\82æ\82­\95Â\82Ü\82è\81C\8c®\82ª\82©\82©\82Á\82½\81I";
1353             break;
1354         case D_BROKEN:
1355 /*JP
1356             msg = "The broken door reassembles and locks!";
1357 */
1358             msg = "\89ó\82ê\82½\94à\82ª\8dÄ\8d\\90¬\82³\82ê\81C\8c®\82ª\82©\82©\82Á\82½\81I";
1359             break;
1360         case D_NODOOR:
1361             msg =
1362 /*JP
1363                "A cloud of dust springs up and assembles itself into a door!";
1364 */
1365                "\82Ù\82±\82è\82ª\82½\82¿\82±\82ß\81C\8fW\82Ü\82Á\82Ä\94à\82É\82È\82Á\82½\81I";
1366             break;
1367         default:
1368             res = FALSE;
1369             break;
1370         }
1371         block_point(x, y);
1372         door->doormask = D_LOCKED | (door->doormask & D_TRAPPED);
1373         newsym(x, y);
1374         break;
1375     case WAN_OPENING:
1376     case SPE_KNOCK:
1377         if (door->doormask & D_LOCKED) {
1378 /*JP
1379             msg = "The door unlocks!";
1380 */
1381             msg = "\94à\82Ì\8c®\82Í\82Í\82¸\82ê\82½\81I";
1382             door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
1383         } else
1384             res = FALSE;
1385         break;
1386     case WAN_STRIKING:
1387     case SPE_FORCE_BOLT:
1388         if (door->doormask & (D_LOCKED | D_CLOSED)) {
1389             if (door->doormask & D_TRAPPED) {
1390                 if (MON_AT(x, y))
1391                     (void) mb_trapped(m_at(x, y));
1392                 else if (flags.verbose) {
1393                     if (cansee(x, y))
1394 /*JP
1395                         pline("KABOOM!!  You see a door explode.");
1396 */
1397                         pline("\82¿\82ã\82Ç\81[\82ñ\81I\94à\82ª\94\9a\94­\82µ\82½\81D");
1398                     else
1399 /*JP
1400                         You_hear("a distant explosion.");
1401 */
1402                         You_hear("\89\93\82­\82Ì\94\9a\94­\89¹\82ð\95·\82¢\82½\81D");
1403                 }
1404                 door->doormask = D_NODOOR;
1405                 unblock_point(x, y);
1406                 newsym(x, y);
1407                 loudness = 40;
1408                 break;
1409             }
1410             door->doormask = D_BROKEN;
1411             if (flags.verbose) {
1412                 if (cansee(x, y))
1413 /*JP
1414                     pline_The("door crashes open!");
1415 */
1416                     pline("\94à\82Í\89ó\82ê\8aJ\82¢\82½\81I");
1417                 else
1418 /*JP
1419                     You_hear("a crashing sound.");
1420 */
1421                     You_hear("\89½\82©\82ª\89ó\82ê\82é\89¹\82ð\95·\82¢\82½\81D");
1422             }
1423             unblock_point(x, y);
1424             newsym(x, y);
1425             /* force vision recalc before printing more messages */
1426             if (vision_full_recalc)
1427                 vision_recalc(0);
1428             loudness = 20;
1429         } else
1430             res = FALSE;
1431         break;
1432     default:
1433         impossible("magic (%d) attempted on door.", otmp->otyp);
1434         break;
1435     }
1436     if (msg && cansee(x, y))
1437         pline1(msg);
1438     if (loudness > 0) {
1439         /* door was destroyed */
1440         wake_nearto(x, y, loudness);
1441         if (*in_rooms(x, y, SHOPBASE))
1442             add_damage(x, y, 0L);
1443     }
1444
1445     if (res && picking_at(x, y)) {
1446         /* maybe unseen monster zaps door you're unlocking */
1447         stop_occupation();
1448         reset_pick();
1449     }
1450     return res;
1451 }
1452
1453 STATIC_OVL void
1454 chest_shatter_msg(otmp)
1455 struct obj *otmp;
1456 {
1457     const char *disposition;
1458     const char *thing;
1459     long save_Blinded;
1460
1461     if (otmp->oclass == POTION_CLASS) {
1462 #if 0 /*JP:T*/
1463         You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename()));
1464 #else
1465         if (Blind)
1466             You_hear("%s\82ª\8a\84\82ê\82é\89¹\82ð\95·\82¢\82½\81I", bottlename());
1467         else
1468             pline("%s\82ª\8a\84\82ê\82½\81I", bottlename());
1469 #endif
1470         if (!breathless(youmonst.data) || haseyes(youmonst.data))
1471             potionbreathe(otmp);
1472         return;
1473     }
1474     /* We have functions for distant and singular names, but not one */
1475     /* which does _both_... */
1476     save_Blinded = Blinded;
1477     Blinded = 1;
1478     thing = singular(otmp, xname);
1479     Blinded = save_Blinded;
1480     switch (objects[otmp->otyp].oc_material) {
1481     case PAPER:
1482 /*JP
1483         disposition = "is torn to shreds";
1484 */
1485         disposition = "\82Í\90¡\92f\82³\82ê\82½";
1486         break;
1487     case WAX:
1488 /*JP
1489         disposition = "is crushed";
1490 */
1491         disposition = "\82ð\8f°\82É\82Ô\82¿\82Ü\82¯\82½";
1492         break;
1493     case VEGGY:
1494 /*JP
1495         disposition = "is pulped";
1496 */
1497         disposition = "\82Í\82Ç\82ë\82Ç\82ë\82É\82È\82Á\82½";
1498         break;
1499     case FLESH:
1500 /*JP
1501         disposition = "is mashed";
1502 */
1503         disposition = "\82Í\82Ç\82ë\82Ç\82ë\82É\82È\82Á\82½";
1504         break;
1505     case GLASS:
1506 /*JP
1507         disposition = "shatters";
1508 */
1509         disposition = "\82Í\8a\84\82ê\82½";
1510         break;
1511     case WOOD:
1512 /*JP
1513         disposition = "splinters to fragments";
1514 */
1515         disposition = "\82Í\82©\82¯\82ç\82É\82È\82Á\82½";
1516         break;
1517     default:
1518 /*JP
1519         disposition = "is destroyed";
1520 */
1521         disposition = "\82Í\89ó\82ê\82½";
1522         break;
1523     }
1524 /*JP
1525     pline("%s %s!", An(thing), disposition);
1526 */
1527     pline("%s%s\81I", thing, disposition);
1528 }
1529
1530 /*lock.c*/