OSDN Git Service

16b4eb212125cf9a9e4a4454e8161d6bb41b3560
[jnethack/source.git] / src / engrave.c
1 /* NetHack 3.6  engrave.c       $NHDT-Date: 1445388915 2015/10/21 00:55:15 $  $NHDT-Branch: master $:$NHDT-Revision: 1.59 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
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. */
9
10 #include "hack.h"
11 #include "lev.h"
12
13 STATIC_VAR NEARDATA struct engr *head_engr;
14
15 char *
16 random_engraving(outbuf)
17 char *outbuf;
18 {
19     const char *rumor;
20
21     /* a random engraving may come from the "rumors" file,
22        or from the "engrave" file (formerly in an array here) */
23     if (!rn2(4) || !(rumor = getrumor(0, outbuf, TRUE)) || !*rumor)
24         (void) get_rnd_text(ENGRAVEFILE, outbuf);
25
26     wipeout_text(outbuf, (int) (strlen(outbuf) / 4), 0);
27     return outbuf;
28 }
29
30 /* Partial rubouts for engraving characters. -3. */
31 static const struct {
32     char wipefrom;
33     const char *wipeto;
34 } rubouts[] = { { 'A', "^" },
35                 { 'B', "Pb[" },
36                 { 'C', "(" },
37                 { 'D', "|)[" },
38                 { 'E', "|FL[_" },
39                 { 'F', "|-" },
40                 { 'G', "C(" },
41                 { 'H', "|-" },
42                 { 'I', "|" },
43                 { 'K', "|<" },
44                 { 'L', "|_" },
45                 { 'M', "|" },
46                 { 'N', "|\\" },
47                 { 'O', "C(" },
48                 { 'P', "F" },
49                 { 'Q', "C(" },
50                 { 'R', "PF" },
51                 { 'T', "|" },
52                 { 'U', "J" },
53                 { 'V', "/\\" },
54                 { 'W', "V/\\" },
55                 { 'Z', "/" },
56                 { 'b', "|" },
57                 { 'd', "c|" },
58                 { 'e', "c" },
59                 { 'g', "c" },
60                 { 'h', "n" },
61                 { 'j', "i" },
62                 { 'k', "|" },
63                 { 'l', "|" },
64                 { 'm', "nr" },
65                 { 'n', "r" },
66                 { 'o', "c" },
67                 { 'q', "c" },
68                 { 'w', "v" },
69                 { 'y', "v" },
70                 { ':', "." },
71                 { ';', ",:" },
72                 { ',', "." },
73                 { '=', "-" },
74                 { '+', "-|" },
75                 { '*', "+" },
76                 { '@', "0" },
77                 { '0', "C(" },
78                 { '1', "|" },
79                 { '6', "o" },
80                 { '7', "/" },
81                 { '8', "3o" } };
82
83 /* degrade some of the characters in a string */
84 void
85 wipeout_text(engr, cnt, seed)
86 char *engr;
87 int cnt;
88 unsigned seed; /* for semi-controlled randomization */
89 {
90 #if 0 /*JP*/
91     char *s;
92 #else
93     unsigned char *s;
94 #endif
95     int i, j, nxt, use_rubout, lth = (int) strlen(engr);
96
97     if (lth && cnt > 0) {
98         while (cnt--) {
99             /* pick next character */
100             if (!seed) {
101                 /* random */
102                 nxt = rn2(lth);
103                 use_rubout = rn2(4);
104             } else {
105                 /* predictable; caller can reproduce the same sequence by
106                    supplying the same arguments later, or a pseudo-random
107                    sequence by varying any of them */
108                 nxt = seed % lth;
109                 seed *= 31, seed %= (BUFSZ - 1);
110                 use_rubout = seed & 3;
111             }
112 #if 0 /*JP*/
113             s = &engr[nxt];
114 #else /*JP: \93ú\96{\8cê\82Ì\8fê\8d\87\82Íjrubout()\82ð\8eg\82Á\82Ä\8fÁ\82·*/
115             if (!seed)
116                 j = rn2(2);
117             else {
118                 seed *= 31,  seed %= (BUFSZ-1);
119                 j = seed % 2;
120             }
121
122             if(jrubout(engr, nxt, use_rubout, j)){
123                 continue;
124             }
125
126             s = (unsigned char *)&engr[nxt];
127 #endif
128             if (*s == ' ')
129                 continue;
130
131             /* rub out unreadable & small punctuation marks */
132             if (index("?.,'`-|_", *s)) {
133                 *s = ' ';
134                 continue;
135             }
136
137             if (!use_rubout)
138                 i = SIZE(rubouts);
139             else
140                 for (i = 0; i < SIZE(rubouts); i++)
141                     if (*s == rubouts[i].wipefrom) {
142                         /*
143                          * Pick one of the substitutes at random.
144                          */
145                         if (!seed)
146                             j = rn2(strlen(rubouts[i].wipeto));
147                         else {
148                             seed *= 31, seed %= (BUFSZ - 1);
149                             j = seed % (strlen(rubouts[i].wipeto));
150                         }
151                         *s = rubouts[i].wipeto[j];
152                         break;
153                     }
154
155             /* didn't pick rubout; use '?' for unreadable character */
156             if (i == SIZE(rubouts))
157                 *s = '?';
158         }
159     }
160
161     /* trim trailing spaces */
162     while (lth && engr[lth - 1] == ' ')
163         engr[--lth] = '\0';
164 }
165
166 /* check whether hero can reach something at ground level */
167 boolean
168 can_reach_floor(check_pit)
169 boolean check_pit;
170 {
171     struct trap *t;
172
173     if (u.uswallow)
174         return FALSE;
175     /* Restricted/unskilled riders can't reach the floor */
176     if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
177         return FALSE;
178     if (check_pit && !Flying
179         && (t = t_at(u.ux, u.uy)) != 0 && uteetering_at_seen_pit(t))
180         return FALSE;
181
182     return (boolean) ((!Levitation || Is_airlevel(&u.uz)
183                        || Is_waterlevel(&u.uz))
184                       && (!u.uundetected || !is_hider(youmonst.data)
185                           || u.umonnum == PM_TRAPPER));
186 }
187
188 /* give a message after caller has determined that hero can't reach */
189 void
190 cant_reach_floor(x, y, up, check_pit)
191 int x, y;
192 boolean up, check_pit;
193 {
194 #if 0 /*JP*/
195     You("can't reach the %s.",
196         up ? ceiling(x, y)
197            : (check_pit && can_reach_floor(FALSE))
198                ? "bottom of the pit"
199                : surface(x, y));
200 #else
201     You("%s\82É\93Í\82©\82È\82¢\81D",
202         up ? ceiling(x, y)
203            : (check_pit && can_reach_floor(FALSE))
204                ? "\97\8e\82µ\8c\8a\82Ì\92ê"
205                : surface(x, y));
206 #endif
207 }
208
209 const char *
210 surface(x, y)
211 register int x, y;
212 {
213     register struct rm *lev = &levl[x][y];
214
215     if (x == u.ux && y == u.uy && u.uswallow && is_animal(u.ustuck->data))
216 /*JP
217         return "maw";
218 */
219         return "\88Ý\91Ü";
220     else if (IS_AIR(lev->typ) && Is_airlevel(&u.uz))
221 /*JP
222         return "air";
223 */
224         return "\8bó\92\86";
225     else if (is_pool(x, y))
226 /*JP
227         return (Underwater && !Is_waterlevel(&u.uz)) ? "bottom" : "water";
228 */
229         return (Underwater && !Is_waterlevel(&u.uz)) ? "\90\85\82Ì\92ê" : "\90\85\92\86";
230     else if (is_ice(x, y))
231 /*JP
232         return "ice";
233 */
234         return "\95X";
235     else if (is_lava(x, y))
236 /*JP
237         return "lava";
238 */
239         return "\97n\8aâ";
240     else if (lev->typ == DRAWBRIDGE_DOWN)
241 /*JP
242         return "bridge";
243 */
244         return "\8b´";
245     else if (IS_ALTAR(levl[x][y].typ))
246 /*JP
247         return "altar";
248 */
249         return "\8dÕ\92d";
250     else if (IS_GRAVE(levl[x][y].typ))
251 /*JP
252         return "headstone";
253 */
254         return "\95æ\90Î";
255     else if (IS_FOUNTAIN(levl[x][y].typ))
256 /*JP
257         return "fountain";
258 */
259         return "\90ò";
260     else if ((IS_ROOM(lev->typ) && !Is_earthlevel(&u.uz))
261              || IS_WALL(lev->typ) || IS_DOOR(lev->typ) || lev->typ == SDOOR)
262 /*JP
263         return "floor";
264 */
265         return "\8f°";
266     else
267 /*JP
268         return "ground";
269 */
270         return "\92n\96Ê";
271 }
272
273 const char *
274 ceiling(x, y)
275 register int x, y;
276 {
277     register struct rm *lev = &levl[x][y];
278     const char *what;
279
280     /* other room types will no longer exist when we're interested --
281      * see check_special_room()
282      */
283     if (*in_rooms(x, y, VAULT))
284 /*JP
285         what = "vault's ceiling";
286 */
287         what = "\91q\8cÉ\82Ì\93V\88ä";
288     else if (*in_rooms(x, y, TEMPLE))
289 /*JP
290         what = "temple's ceiling";
291 */
292         what = "\8e\9b\89@\82Ì\93V\88ä";
293     else if (*in_rooms(x, y, SHOPBASE))
294 /*JP
295         what = "shop's ceiling";
296 */
297         what = "\93X\82Ì\93V\88ä";
298     else if (Is_waterlevel(&u.uz))
299         /* water plane has no surface; its air bubbles aren't below sky */
300 /*JP
301         what = "water above";
302 */
303         what = "\90\85\82Ì\8fã\95û";
304     else if (IS_AIR(lev->typ))
305 /*JP
306         what = "sky";
307 */
308         what = "\8bó";
309     else if (Underwater)
310 /*JP
311         what = "water's surface";
312 */
313         what = "\90\85\96Ê";
314     else if ((IS_ROOM(lev->typ) && !Is_earthlevel(&u.uz))
315              || IS_WALL(lev->typ) || IS_DOOR(lev->typ) || lev->typ == SDOOR)
316 /*JP
317         what = "ceiling";
318 */
319         what = "\93V\88ä";
320     else
321 /*JP
322         what = "rock cavern";
323 */
324         what = "\93´\8cA\82Ì\93V\88ä";
325
326     return what;
327 }
328
329 struct engr *
330 engr_at(x, y)
331 xchar x, y;
332 {
333     register struct engr *ep = head_engr;
334
335     while (ep) {
336         if (x == ep->engr_x && y == ep->engr_y)
337             return ep;
338         ep = ep->nxt_engr;
339     }
340     return (struct engr *) 0;
341 }
342
343 /* Decide whether a particular string is engraved at a specified
344  * location; a case-insensitive substring match is used.
345  * Ignore headstones, in case the player names herself "Elbereth".
346  *
347  * If strict checking is requested, the word is only considered to be
348  * present if it is intact and is the first word in the engraving.
349  * ("Elbereth burrito" matches; "o Elbereth" does not.)
350  */
351 int
352 sengr_at(s, x, y, strict)
353 const char *s;
354 xchar x, y;
355 boolean strict;
356 {
357     register struct engr *ep = engr_at(x, y);
358
359     if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= moves) {
360         return strict ? (strncmpi(ep->engr_txt, s, strlen(s)) == 0)
361                       : (strstri(ep->engr_txt, s) != 0);
362     }
363     return FALSE;
364 }
365
366 void
367 u_wipe_engr(cnt)
368 int cnt;
369 {
370     if (can_reach_floor(TRUE))
371         wipe_engr_at(u.ux, u.uy, cnt, FALSE);
372 }
373
374 void
375 wipe_engr_at(x, y, cnt, magical)
376 xchar x, y, cnt, magical;
377 {
378     register struct engr *ep = engr_at(x, y);
379
380     /* Headstones are indelible */
381     if (ep && ep->engr_type != HEADSTONE) {
382         debugpline1("asked to erode %d characters", cnt);
383         if (ep->engr_type != BURN || is_ice(x, y) || (magical && !rn2(2))) {
384             if (ep->engr_type != DUST && ep->engr_type != ENGR_BLOOD) {
385                 cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1;
386                 debugpline1("actually eroding %d characters", cnt);
387             }
388             wipeout_text(ep->engr_txt, (int) cnt, 0);
389             while (ep->engr_txt[0] == ' ')
390                 ep->engr_txt++;
391             if (!ep->engr_txt[0])
392                 del_engr(ep);
393         }
394     }
395 }
396
397 void
398 read_engr_at(x, y)
399 int x, y;
400 {
401     register struct engr *ep = engr_at(x, y);
402     int sensed = 0;
403     char buf[BUFSZ];
404
405     /* Sensing an engraving does not require sight,
406      * nor does it necessarily imply comprehension (literacy).
407      */
408     if (ep && ep->engr_txt[0]) {
409         switch (ep->engr_type) {
410         case DUST:
411             if (!Blind) {
412                 sensed = 1;
413 #if 0 /*JP*/
414                 pline("%s is written here in the %s.", Something,
415                       is_ice(x, y) ? "frost" : "dust");
416 #else
417                 pline("\89½\82©\82Ì\95\8e\9a\82ª%s\82É\8f\91\82¢\82Ä\82 \82é\81D",
418                       is_ice(x, y) ? "\91\9a" : "\82Ù\82±\82è");
419 #endif
420             }
421             break;
422         case ENGRAVE:
423         case HEADSTONE:
424             if (!Blind || can_reach_floor(TRUE)) {
425                 sensed = 1;
426 /*JP
427                 pline("%s is engraved here on the %s.", Something,
428 */
429                 pline("\89½\82©\82Ì\95\8e\9a\82ª%s\82É\8d\8f\82Ü\82ê\82Ä\82¢\82é\81D",
430                       surface(x, y));
431             }
432             break;
433         case BURN:
434             if (!Blind || can_reach_floor(TRUE)) {
435                 sensed = 1;
436 #if 0 /*JP*/
437                 pline("Some text has been %s into the %s here.",
438                       is_ice(x, y) ? "melted" : "burned", surface(x, y));
439 #else
440                 pline("\89½\82©\82Ì\95\8e\9a\82ª%s%s\82¢\82é\81D",
441                       surface(x,y),
442                       is_ice(x,y) ? "\82É\8d\8f\82Ü\82ê\82Ä" : "\82É\8fÄ\82«\95t\82¯\82ç\82ê\82Ä");
443 #endif
444             }
445             break;
446         case MARK:
447             if (!Blind) {
448                 sensed = 1;
449 /*JP
450                 pline("There's some graffiti on the %s here.", surface(x, y));
451 */
452                 pline("%s\82É\97\8e\8f\91\82ª\82 \82é\81D", surface(x,y));
453             }
454             break;
455         case ENGR_BLOOD:
456             /* "It's a message!  Scrawled in blood!"
457              * "What's it say?"
458              * "It says... `See you next Wednesday.'" -- Thriller
459              */
460             if (!Blind) {
461                 sensed = 1;
462 /*JP
463                 You_see("a message scrawled in blood here.");
464 */
465                 You("\8c\8c\95\8e\9a\82ª\82È\82®\82è\8f\91\82«\82³\82ê\82Ä\82¢\82é\82Ì\82ð\8c©\82Â\82¯\82½\81D");
466             }
467             break;
468         default:
469             impossible("%s is written in a very strange way.", Something);
470             sensed = 1;
471         }
472         if (sensed) {
473             char *et;
474 /*JP
475             unsigned maxelen = BUFSZ - sizeof("You feel the words: \"\". ");
476 */
477             unsigned maxelen = BUFSZ - sizeof("\82 \82È\82½\82Í\8e\9f\82Ì\82æ\82¤\82É\8a´\82\82½\81F\81u\81v");
478             if (strlen(ep->engr_txt) > maxelen) {
479                 (void) strncpy(buf, ep->engr_txt, (int) maxelen);
480                 buf[maxelen] = '\0';
481                 et = buf;
482             } else
483                 et = ep->engr_txt;
484 /*JP
485             You("%s: \"%s\".", (Blind) ? "feel the words" : "read", et);
486 */
487             You("%s\81F\81u%s\81v", (Blind) ? "\8e\9f\82Ì\82æ\82¤\82É\8a´\82\82½" : "\93Ç\82ñ\82¾",  et);
488             if (context.run > 1)
489                 nomul(0);
490         }
491     }
492 }
493
494 void
495 make_engr_at(x, y, s, e_time, e_type)
496 int x, y;
497 const char *s;
498 long e_time;
499 xchar e_type;
500 {
501     struct engr *ep;
502
503     if ((ep = engr_at(x, y)) != 0)
504         del_engr(ep);
505     ep = newengr(strlen(s) + 1);
506     ep->nxt_engr = head_engr;
507     head_engr = ep;
508     ep->engr_x = x;
509     ep->engr_y = y;
510     ep->engr_txt = (char *) (ep + 1);
511     Strcpy(ep->engr_txt, s);
512     /* engraving Elbereth shows wisdom */
513     if (!in_mklev && !strcmp(s, "Elbereth"))
514         exercise(A_WIS, TRUE);
515     ep->engr_time = e_time;
516     ep->engr_type = e_type > 0 ? e_type : rnd(N_ENGRAVE - 1);
517     ep->engr_lth = strlen(s) + 1;
518 }
519
520 /* delete any engraving at location <x,y> */
521 void
522 del_engr_at(x, y)
523 int x, y;
524 {
525     register struct engr *ep = engr_at(x, y);
526
527     if (ep)
528         del_engr(ep);
529 }
530
531 /*
532  *      freehand - returns true if player has a free hand
533  */
534 int
535 freehand()
536 {
537     return (!uwep || !welded(uwep)
538             || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
539 }
540
541 static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
542                                           TOOL_CLASS,  WEAPON_CLASS,
543                                           WAND_CLASS,  GEM_CLASS,
544                                           RING_CLASS,  0 };
545
546 /* Mohs' Hardness Scale:
547  *  1 - Talc             6 - Orthoclase
548  *  2 - Gypsum           7 - Quartz
549  *  3 - Calcite          8 - Topaz
550  *  4 - Fluorite         9 - Corundum
551  *  5 - Apatite         10 - Diamond
552  *
553  * Since granite is an igneous rock hardness ~ 7, anything >= 8 should
554  * probably be able to scratch the rock.
555  * Devaluation of less hard gems is not easily possible because obj struct
556  * does not contain individual oc_cost currently. 7/91
557  *
558  * steel     -  5-8.5   (usu. weapon)
559  * diamond    - 10                      * jade       -  5-6      (nephrite)
560  * ruby       -  9      (corundum)      * turquoise  -  5-6
561  * sapphire   -  9      (corundum)      * opal       -  5-6
562  * topaz      -  8                      * glass      - ~5.5
563  * emerald    -  7.5-8  (beryl)         * dilithium  -  4-5??
564  * aquamarine -  7.5-8  (beryl)         * iron       -  4-5
565  * garnet     -  7.25   (var. 6.5-8)    * fluorite   -  4
566  * agate      -  7      (quartz)        * brass      -  3-4
567  * amethyst   -  7      (quartz)        * gold       -  2.5-3
568  * jasper     -  7      (quartz)        * silver     -  2.5-3
569  * onyx       -  7      (quartz)        * copper     -  2.5-3
570  * moonstone  -  6      (orthoclase)    * amber      -  2-2.5
571  */
572
573 /* return 1 if action took 1 (or more) moves, 0 if error or aborted */
574 int
575 doengrave()
576 {
577     boolean dengr = FALSE;    /* TRUE if we wipe out the current engraving */
578     boolean doblind = FALSE;  /* TRUE if engraving blinds the player */
579     boolean doknown = FALSE;  /* TRUE if we identify the stylus */
580     boolean eow = FALSE;      /* TRUE if we are overwriting oep */
581     boolean jello = FALSE;    /* TRUE if we are engraving in slime */
582     boolean ptext = TRUE;     /* TRUE if we must prompt for engrave text */
583     boolean teleengr = FALSE; /* TRUE if we move the old engraving */
584     boolean zapwand = FALSE;  /* TRUE if we remove a wand charge */
585     xchar type = DUST;        /* Type of engraving made */
586     char buf[BUFSZ];          /* Buffer for final/poly engraving text */
587     char ebuf[BUFSZ];         /* Buffer for initial engraving text */
588     char fbuf[BUFSZ];         /* Buffer for "your fingers" */
589     char qbuf[QBUFSZ];        /* Buffer for query text */
590     char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
591     const char *everb;          /* Present tense of engraving type */
592     const char *eloc; /* Where the engraving is (ie dust/floor/...) */
593     char *sp;         /* Place holder for space count of engr text */
594     int len;          /* # of nonspace chars of new engraving text */
595     int maxelen;      /* Max allowable length of engraving text */
596     struct engr *oep = engr_at(u.ux, u.uy);
597     /* The current engraving */
598     struct obj *otmp; /* Object selected with which to engrave */
599     char *writer;
600
601     multi = 0;              /* moves consumed */
602     nomovemsg = (char *) 0; /* occupation end message */
603
604     buf[0] = (char) 0;
605     ebuf[0] = (char) 0;
606     post_engr_text[0] = (char) 0;
607     maxelen = BUFSZ - 1;
608     if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
609         type = ENGR_BLOOD;
610
611     /* Can the adventurer engrave at all? */
612
613     if (u.uswallow) {
614         if (is_animal(u.ustuck->data)) {
615 /*JP
616             pline("What would you write?  \"Jonah was here\"?");
617 */
618             pline("\89½\82ð\8f\91\82­\82ñ\82¾\82¢\81H\81u\83\88\83i\82Í\82±\82±\82É\82¢\82é\81v\81H");
619             return 0;
620         } else if (is_whirly(u.ustuck->data)) {
621             cant_reach_floor(u.ux, u.uy, FALSE, FALSE);
622             return 0;
623         } else
624             jello = TRUE;
625     } else if (is_lava(u.ux, u.uy)) {
626 /*JP
627         You_cant("write on the %s!", surface(u.ux, u.uy));
628 */
629         You("%s\82É\93Í\82©\82È\82¢\81D", surface(u.ux,u.uy));
630         return 0;
631     } else if (is_pool(u.ux, u.uy) || IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
632 /*JP
633         You_cant("write on the %s!", surface(u.ux, u.uy));
634 */
635         You("%s\82É\82Í\8f\91\82¯\82È\82¢\81I", surface(u.ux, u.uy));
636         return 0;
637     }
638     if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) /* in bubble */) {
639 /*JP
640         You_cant("write in thin air!");
641 */
642         You("\8bó\92\86\82É\82Í\8f\91\82¯\82È\82¢\81I");
643         return 0;
644     } else if (!accessible(u.ux, u.uy)) {
645         /* stone, tree, wall, secret corridor, pool, lava, bars */
646 /*JP
647         You_cant("write here.");
648 */
649         You_cant("\82±\82±\82É\82Í\8f\91\82¯\82È\82¢\81D");
650         return 0;
651     }
652     if (cantwield(youmonst.data)) {
653 /*JP
654         You_cant("even hold anything!");
655 */
656         You("\89½\82©\82ð\8e\9d\82Â\82±\82Æ\82·\82ç\82Å\82«\82È\82¢\81I");
657         return 0;
658     }
659     if (check_capacity((char *) 0))
660         return 0;
661
662     /* One may write with finger, or weapon, or wand, or..., or...
663      * Edited by GAN 10/20/86 so as not to change weapon wielded.
664      */
665
666     otmp = getobj(styluses, "write with");
667     if (!otmp) /* otmp == zeroobj if fingers */
668         return 0;
669
670     if (otmp == &zeroobj) {
671 /*JP
672         Strcat(strcpy(fbuf, "your "), makeplural(body_part(FINGER)));
673 */
674         Strcat(strcpy(fbuf, "\82 \82È\82½\82Ì"), makeplural(body_part(FINGER)));
675         writer = fbuf;
676     } else
677         writer = yname(otmp);
678
679     /* There's no reason you should be able to write with a wand
680      * while both your hands are tied up.
681      */
682     if (!freehand() && otmp != uwep && !otmp->owornmask) {
683 /*JP
684         You("have no free %s to write with!", body_part(HAND));
685 */
686         pline("%s\82Ì\8e©\97R\82ª\8cø\82©\82È\82¢\82Ì\82Å\8f\91\82¯\82È\82¢\81I", body_part(HAND));
687         return 0;
688     }
689
690     if (jello) {
691 /*JP
692         You("tickle %s with %s.", mon_nam(u.ustuck), writer);
693 */
694                 You("%s\82Å%s\82ð\82­\82·\82®\82Á\82½\81D", writer, mon_nam(u.ustuck));
695 /*JP
696         Your("message dissolves...");
697 */
698                 Your("\83\81\83b\83Z\81[\83W\82Í\8fÁ\82¦\82½\81D\81D\81D");
699         return 0;
700     }
701     if (otmp->oclass != WAND_CLASS && !can_reach_floor(TRUE)) {
702         cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
703         return 0;
704     }
705     if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
706 /*JP
707         You("make a motion towards the altar with %s.", writer);
708 */
709         You("%s\82ð\8eg\82Á\82Ä\8dÕ\92d\82É\8f\91\82±\82¤\82Æ\82µ\82½\81D", writer);
710         altar_wrath(u.ux, u.uy);
711         return 0;
712     }
713     if (IS_GRAVE(levl[u.ux][u.uy].typ)) {
714         if (otmp == &zeroobj) { /* using only finger */
715 /*JP
716             You("would only make a small smudge on the %s.",
717 */
718             You("\82Í%s\82É\8f¬\82³\82È\82µ\82Ý\82ð\82Â\82¯\82é\82±\82Æ\82µ\82©\82Å\82«\82È\82©\82Á\82½\81D",
719                 surface(u.ux, u.uy));
720             return 0;
721         } else if (!levl[u.ux][u.uy].disturbed) {
722 /*JP
723             You("disturb the undead!");
724 */
725             You("\95s\8e\80\82Ì\8eÒ\82Ì\96°\82è\82ð\96W\82°\82½\81I");
726             levl[u.ux][u.uy].disturbed = 1;
727             (void) makemon(&mons[PM_GHOUL], u.ux, u.uy, NO_MM_FLAGS);
728             exercise(A_WIS, FALSE);
729             return 1;
730         }
731     }
732
733     /* SPFX for items */
734
735     switch (otmp->oclass) {
736     default:
737     case AMULET_CLASS:
738     case CHAIN_CLASS:
739     case POTION_CLASS:
740     case COIN_CLASS:
741         break;
742     case RING_CLASS:
743         /* "diamond" rings and others should work */
744     case GEM_CLASS:
745         /* diamonds & other hard gems should work */
746         if (objects[otmp->otyp].oc_tough) {
747             type = ENGRAVE;
748             break;
749         }
750         break;
751     case ARMOR_CLASS:
752         if (is_boots(otmp)) {
753             type = DUST;
754             break;
755         }
756         /*FALLTHRU*/
757     /* Objects too large to engrave with */
758     case BALL_CLASS:
759     case ROCK_CLASS:
760 /*JP
761         You_cant("engrave with such a large object!");
762 */
763         pline("\82»\82ñ\82È\91å\82«\82È\82à\82Ì\82ð\8eg\82Á\82Ä\95\8e\9a\82ð\8d\8f\82ß\82È\82¢\81I");
764         ptext = FALSE;
765         break;
766     /* Objects too silly to engrave with */
767     case FOOD_CLASS:
768     case SCROLL_CLASS:
769     case SPBOOK_CLASS:
770 #if 0 /*JP*/
771         pline("%s would get %s.", Yname2(otmp),
772               is_ice(u.ux, u.uy) ? "all frosty" : "too dirty");
773 #else
774         Your("%s\82Í%s\82È\82Á\82½\81D", xname(otmp),
775              is_ice(u.ux,u.uy) ? "\91\9a\82¾\82ç\82¯\82É" : "\89\98\82È\82­");
776 #endif
777         ptext = FALSE;
778         break;
779     case RANDOM_CLASS: /* This should mean fingers */
780         break;
781
782     /* The charge is removed from the wand before prompting for
783      * the engraving text, because all kinds of setup decisions
784      * and pre-engraving messages are based upon knowing what type
785      * of engraving the wand is going to do.  Also, the player
786      * will have potentially seen "You wrest .." message, and
787      * therefore will know they are using a charge.
788      */
789     case WAND_CLASS:
790         if (zappable(otmp)) {
791             check_unpaid(otmp);
792             if (otmp->cursed && !rn2(WAND_BACKFIRE_CHANCE)) {
793                 wand_explode(otmp, 0);
794                 return 1;
795             }
796             zapwand = TRUE;
797             if (!can_reach_floor(TRUE))
798                 ptext = FALSE;
799
800             switch (otmp->otyp) {
801             /* DUST wands */
802             default:
803                 break;
804             /* NODIR wands */
805             case WAN_LIGHT:
806             case WAN_SECRET_DOOR_DETECTION:
807             case WAN_CREATE_MONSTER:
808             case WAN_WISHING:
809             case WAN_ENLIGHTENMENT:
810                 zapnodir(otmp);
811                 break;
812             /* IMMEDIATE wands */
813             /* If wand is "IMMEDIATE", remember to affect the
814              * previous engraving even if turning to dust.
815              */
816             case WAN_STRIKING:
817                 Strcpy(post_engr_text,
818 /*JP
819                     "The wand unsuccessfully fights your attempt to write!");
820 */
821                        "\82 \82È\82½\82ª\8f\91\82±\82¤\82Æ\82·\82é\82Æ\8fñ\82Í\92ï\8dR\82µ\82½\81I");
822                 break;
823             case WAN_SLOW_MONSTER:
824                 if (!Blind) {
825 /*JP
826                     Sprintf(post_engr_text, "The bugs on the %s slow down!",
827 */
828                     Sprintf(post_engr_text, "%s\82Ì\8fã\82Ì\92\8e\82Ì\93®\82«\82ª\92x\82­\82È\82Á\82½\81I",
829                             surface(u.ux, u.uy));
830                 }
831                 break;
832             case WAN_SPEED_MONSTER:
833                 if (!Blind) {
834 /*JP
835                     Sprintf(post_engr_text, "The bugs on the %s speed up!",
836 */
837                     Sprintf(post_engr_text, "%s\82Ì\8fã\82Ì\92\8e\82Ì\93®\82«\82ª\91¬\82­\82È\82Á\82½\81I",
838                             surface(u.ux, u.uy));
839                 }
840                 break;
841             case WAN_POLYMORPH:
842                 if (oep) {
843                     if (!Blind) {
844                         type = (xchar) 0; /* random */
845                         (void) random_engraving(buf);
846                     }
847                     dengr = TRUE;
848                 }
849                 break;
850             case WAN_NOTHING:
851             case WAN_UNDEAD_TURNING:
852             case WAN_OPENING:
853             case WAN_LOCKING:
854             case WAN_PROBING:
855                 break;
856             /* RAY wands */
857             case WAN_MAGIC_MISSILE:
858                 ptext = TRUE;
859                 if (!Blind) {
860                     Sprintf(post_engr_text,
861 /*JP
862                             "The %s is riddled by bullet holes!",
863 */
864                             "%s\82Í\8eU\92e\82Å\8d×\82©\82¢\8c\8a\82¾\82ç\82¯\82É\82È\82Á\82½\81I",
865                             surface(u.ux, u.uy));
866                 }
867                 break;
868             /* can't tell sleep from death - Eric Backus */
869             case WAN_SLEEP:
870             case WAN_DEATH:
871                 if (!Blind) {
872 /*JP
873                     Sprintf(post_engr_text, "The bugs on the %s stop moving!",
874 */
875                     Sprintf(post_engr_text, "%s\82Ì\8fã\82Ì\92\8e\82Ì\93®\82«\82ª\8e~\82Ü\82Á\82½\81I",
876                             surface(u.ux, u.uy));
877                 }
878                 break;
879             case WAN_COLD:
880                 if (!Blind)
881                     Strcpy(post_engr_text,
882 /*JP
883                            "A few ice cubes drop from the wand.");
884 */
885                            "\95X\82Ì\82©\82¯\82ç\82ª\8fñ\82©\82ç\82±\82Ú\82ê\97\8e\82¿\82½\81D");
886                 if (!oep || (oep->engr_type != BURN))
887                     break;
888             case WAN_CANCELLATION:
889             case WAN_MAKE_INVISIBLE:
890                 if (oep && oep->engr_type != HEADSTONE) {
891                     if (!Blind)
892 /*JP
893                         pline_The("engraving on the %s vanishes!",
894 */
895                         pline("%s\82Ì\8fã\82Ì\95\8e\9a\82Í\8fÁ\82¦\82½\81I",
896                                   surface(u.ux, u.uy));
897                     dengr = TRUE;
898                 }
899                 break;
900             case WAN_TELEPORTATION:
901                 if (oep && oep->engr_type != HEADSTONE) {
902                     if (!Blind)
903 /*JP
904                         pline_The("engraving on the %s vanishes!",
905 */
906                         pline("%s\82Ì\8fã\82Ì\95\8e\9a\82Í\8fÁ\82¦\82½\81I",
907                                   surface(u.ux, u.uy));
908                     teleengr = TRUE;
909                 }
910                 break;
911             /* type = ENGRAVE wands */
912             case WAN_DIGGING:
913                 ptext = TRUE;
914                 type = ENGRAVE;
915                 if (!objects[otmp->otyp].oc_name_known) {
916                     if (flags.verbose)
917 /*JP
918                         pline("This %s is a wand of digging!", xname(otmp));
919 */
920                         pline("\82±\82ê\82Í\8c\8a\8c@\82è\82Ì\8fñ\82¾\81I");
921                     doknown = TRUE;
922                 }
923 #if 0 /*JP*/
924                 Strcpy(post_engr_text,
925                        Blind
926                           ? "You hear drilling!"
927                           : IS_GRAVE(levl[u.ux][u.uy].typ)
928                              ? "Chips fly out from the headstone."
929                              : is_ice(u.ux, u.uy)
930                                 ? "Ice chips fly up from the ice surface!"
931                                 : (level.locations[u.ux][u.uy].typ
932                                    == DRAWBRIDGE_DOWN)
933                                    ? "Splinters fly up from the bridge."
934                                    : "Gravel flies up from the floor.");
935 #else
936                 Strcpy(post_engr_text,
937                        Blind
938                           ? "\8c\8a\82ª\8aJ\82­\89¹\82ð\95·\82¢\82½\81I"
939                           : IS_GRAVE(levl[u.ux][u.uy].typ)
940                              ? "\95æ\90Î\82©\82ç\94j\95Ð\82ª\94ò\82Ñ\8eU\82Á\82½\81D"
941                              : is_ice(u.ux,u.uy)
942                                 ? "\95X\82Ì\95\\96Ê\82©\82ç\95X\82Ì\82©\82¯\82ç\82ª\94ò\82Ñ\8eU\82Á\82½\81D"
943                                 : (level.locations[u.ux][u.uy].typ
944                                    == DRAWBRIDGE_DOWN)
945                                    ? "\94j\95Ð\82ª\8b´\82©\82ç\95\91\82¢\82 \82ª\82Á\82½\81D"
946                                    : "\8d»\97\98\82ª\8f°\82©\82ç\94ò\82Ñ\8eU\82Á\82½\81D");
947 #endif
948                 break;
949             /* type = BURN wands */
950             case WAN_FIRE:
951                 ptext = TRUE;
952                 type = BURN;
953                 if (!objects[otmp->otyp].oc_name_known) {
954                     if (flags.verbose)
955 /*JP
956                         pline("This %s is a wand of fire!", xname(otmp));
957 */
958                         pline("\82±\82ê\82Í\89\8a\82Ì\8fñ\82¾\81I");
959                     doknown = TRUE;
960                 }
961 #if 0 /*JP*/
962                 Strcpy(post_engr_text, Blind ? "You feel the wand heat up."
963                                              : "Flames fly from the wand.");
964 #else
965                 Strcpy(post_engr_text, Blind ? "\8fñ\82ª\92g\82©\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D"
966                                              : "\89\8a\82ª\8fñ\82©\82ç\94ò\82Ñ\8eU\82Á\82½\81D");
967 #endif
968                 break;
969             case WAN_LIGHTNING:
970                 ptext = TRUE;
971                 type = BURN;
972                 if (!objects[otmp->otyp].oc_name_known) {
973                     if (flags.verbose)
974 /*JP
975                         pline("This %s is a wand of lightning!", xname(otmp));
976 */
977                         pline("\82±\82ê\82Í\97\8b\82Ì\8fñ\82¾\81I");
978                     doknown = TRUE;
979                 }
980                 if (!Blind) {
981 /*JP
982                     Strcpy(post_engr_text, "Lightning arcs from the wand.");
983 */
984                     Strcpy(post_engr_text, "\89Î\89Ô\82ª\8fñ\82©\82ç\94ò\82Ñ\8eU\82Á\82½\81D");
985                     doblind = TRUE;
986                 } else
987 /*JP
988                     Strcpy(post_engr_text, "You hear crackling!");
989 */
990                     Strcpy(post_engr_text, "\83p\83`\83p\83`\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81I");
991                 break;
992
993             /* type = MARK wands */
994             /* type = ENGR_BLOOD wands */
995             }
996         } else { /* end if zappable */
997             /* failing to wrest one last charge takes time */
998             ptext = FALSE; /* use "early exit" below, return 1 */
999             /* give feedback here if we won't be getting the
1000                "can't reach floor" message below */
1001             if (can_reach_floor(TRUE)) {
1002                 /* cancelled wand turns to dust */
1003                 if (otmp->spe < 0)
1004                     zapwand = TRUE;
1005                 /* empty wand just doesn't write */
1006                 else
1007 /*JP
1008                     pline_The("wand is too worn out to engrave.");
1009 */
1010                     pline_The("\8fñ\82Í\95\8e\9a\82ð\8d\8f\82Þ\82É\82Í\8eg\82¢\82·\82¬\82Ä\82¢\82é\81D");
1011             }
1012         }
1013         break;
1014
1015     case WEAPON_CLASS:
1016         if (is_blade(otmp)) {
1017             if ((int) otmp->spe > -3)
1018                 type = ENGRAVE;
1019             else
1020 /*JP
1021                 pline("%s too dull for engraving.", Yobjnam2(otmp, "are"));
1022 */
1023                 pline("%s\82Í\90n\82ª\83{\83\8d\83{\83\8d\82Å\81C\95\8e\9a\82ð\92¤\82ê\82È\82¢\81D", xname(otmp));
1024         }
1025         break;
1026
1027     case TOOL_CLASS:
1028         if (otmp == ublindf) {
1029             pline(
1030 /*JP
1031                 "That is a bit difficult to engrave with, don't you think?");
1032 */
1033                 "\82¿\82å\82Á\82Æ\82»\82ê\82Å\92¤\82é\82Ì\82Í\91å\95Ï\82¾\82ë\82¤\81C\82»\82¤\8ev\82í\82È\82¢\81H");
1034             return 0;
1035         }
1036         switch (otmp->otyp) {
1037         case MAGIC_MARKER:
1038             if (otmp->spe <= 0)
1039 /*JP
1040                 Your("marker has dried out.");
1041 */
1042                 Your("\83}\81[\83J\82Í\8a£\82«\82«\82Á\82½\81D");
1043             else
1044                 type = MARK;
1045             break;
1046         case TOWEL:
1047             /* Can't really engrave with a towel */
1048             ptext = FALSE;
1049             if (oep)
1050                 if (oep->engr_type == DUST
1051                     || oep->engr_type == ENGR_BLOOD
1052                     || oep->engr_type == MARK) {
1053                     if (is_wet_towel(otmp))
1054                         dry_a_towel(otmp, -1, TRUE);
1055                     if (!Blind)
1056 /*JP
1057                         You("wipe out the message here.");
1058 */
1059                         You("\83\81\83b\83Z\81[\83W\82ð\90@\82«\82Æ\82Á\82½\81D");
1060                     else
1061 #if 0 /*JP*/
1062                         pline("%s %s.", Yobjnam2(otmp, "get"),
1063                               is_ice(u.ux, u.uy) ? "frosty" : "dusty");
1064 #else
1065                         pline("%s\82Í%s\82É\82È\82Á\82½\81D", xname(otmp),
1066                               is_ice(u.ux,u.uy) ? "\91\9a\82¾\82ç\82¯" : "\82Ù\82±\82è\82Ü\82Ý\82ê");
1067 #endif
1068                     dengr = TRUE;
1069                 } else
1070 /*JP
1071                     pline("%s can't wipe out this engraving.", Yname2(otmp));
1072 */
1073                     pline("\82±\82Ì\95\8e\9a\82Í%s\82Å\82Í\90@\82«\82Æ\82ê\82È\82¢\81D", xname(otmp));
1074             else
1075 #if 0 /*JP*/
1076                 pline("%s %s.", Yobjnam2(otmp, "get"),
1077                       is_ice(u.ux, u.uy) ? "frosty" : "dusty");
1078 #else
1079                 pline("%s\82Í%s\82É\82È\82Á\82½\81D", xname(otmp),
1080                       is_ice(u.ux,u.uy) ? "\91\9a\82¾\82ç\82¯" : "\82Ù\82±\82è\82Ü\82Ý\82ê");
1081 #endif
1082             break;
1083         default:
1084             break;
1085         }
1086         break;
1087
1088     case VENOM_CLASS:
1089         if (wizard) {
1090 /*JP
1091             pline("Writing a poison pen letter??");
1092 */
1093             pline("\82Ó\82Þ\81D\82±\82ê\82±\82»\96{\93\96\82Ì\93Å\90ã\82¾\81D");
1094             break;
1095         }
1096         /*FALLTHRU*/
1097     case ILLOBJ_CLASS:
1098         impossible("You're engraving with an illegal object!");
1099         break;
1100     }
1101
1102     if (IS_GRAVE(levl[u.ux][u.uy].typ)) {
1103         if (type == ENGRAVE || type == 0) {
1104             type = HEADSTONE;
1105         } else {
1106             /* ensures the "cannot wipe out" case */
1107             type = DUST;
1108             dengr = FALSE;
1109             teleengr = FALSE;
1110             buf[0] = '\0';
1111         }
1112     }
1113
1114     /*
1115      * End of implement setup
1116      */
1117
1118     /* Identify stylus */
1119     if (doknown) {
1120         learnwand(otmp);
1121         if (objects[otmp->otyp].oc_name_known)
1122             more_experienced(0, 10);
1123     }
1124     if (teleengr) {
1125         rloc_engr(oep);
1126         oep = (struct engr *) 0;
1127     }
1128     if (dengr) {
1129         del_engr(oep);
1130         oep = (struct engr *) 0;
1131     }
1132     /* Something has changed the engraving here */
1133     if (*buf) {
1134         make_engr_at(u.ux, u.uy, buf, moves, type);
1135 /*JP
1136         pline_The("engraving now reads: \"%s\".", buf);
1137 */
1138         pline("\8d\8f\82Ü\82ê\82½\95\8e\9a\82ð\93Ç\82ñ\82¾\81F\81u%s\81v\81D", buf);
1139         ptext = FALSE;
1140     }
1141     if (zapwand && (otmp->spe < 0)) {
1142 #if 0 /*JP*/
1143         pline("%s %sturns to dust.", The(xname(otmp)),
1144               Blind ? "" : "glows violently, then ");
1145 #else
1146         pline("%s\82Í%s\82¿\82è\82Æ\82È\82Á\82½\81D", xname(otmp),
1147               Blind ? "" : "\8c\83\82µ\82­\8bP\82«\81C");
1148 #endif
1149         if (!IS_GRAVE(levl[u.ux][u.uy].typ))
1150 #if 0 /*JP*/
1151             You(
1152     "are not going to get anywhere trying to write in the %s with your dust.",
1153                 is_ice(u.ux, u.uy) ? "frost" : "dust");
1154 #else
1155             You(
1156                 "\90o\82Å%s\82É\89½\82©\8f\91\82±\82¤\82Æ\82µ\82½\82ª\81C\82Å\82«\82È\82©\82Á\82½\81D",
1157                 is_ice(u.ux,u.uy) ? "\95X" : "\82Ù\82±\82è");
1158 #endif
1159         useup(otmp);
1160         otmp = 0; /* wand is now gone */
1161         ptext = FALSE;
1162     }
1163     /* Early exit for some implements. */
1164     if (!ptext) {
1165         if (otmp && otmp->oclass == WAND_CLASS && !can_reach_floor(TRUE))
1166             cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
1167         return 1;
1168     }
1169     /*
1170      * Special effects should have deleted the current engraving (if
1171      * possible) by now.
1172      */
1173     if (oep) {
1174         register char c = 'n';
1175
1176         /* Give player the choice to add to engraving. */
1177         if (type == HEADSTONE) {
1178             /* no choice, only append */
1179             c = 'y';
1180         } else if (type == oep->engr_type
1181                    && (!Blind || oep->engr_type == BURN
1182                        || oep->engr_type == ENGRAVE)) {
1183 /*JP
1184             c = yn_function("Do you want to add to the current engraving?",
1185 */
1186             c = yn_function("\89½\82©\8f\91\82«\89Á\82¦\82Ü\82·\82©\81H",
1187                             ynqchars, 'y');
1188             if (c == 'q') {
1189                 pline1(Never_mind);
1190                 return 0;
1191             }
1192         }
1193
1194         if (c == 'n' || Blind) {
1195             if (oep->engr_type == DUST
1196                 || oep->engr_type == ENGR_BLOOD
1197                 || oep->engr_type == MARK) {
1198                 if (!Blind) {
1199 #if 0 /*JP*/
1200                     You("wipe out the message that was %s here.",
1201                         (oep->engr_type == DUST)
1202                             ? "written in the dust"
1203                             : (oep->engr_type == ENGR_BLOOD)
1204                                 ? "scrawled in blood"
1205                                 : "written");
1206 #else
1207                     You("%s\83\81\83b\83Z\81[\83W\82ð\90@\82«\82Æ\82Á\82½\81D",
1208                         (oep->engr_type == DUST)
1209                             ? "\82Ù\82±\82è\82É\8f\91\82©\82ê\82Ä\82¢\82é"
1210                             : (oep->engr_type == BLOOD)
1211                                 ? "\8c\8c\95\8e\9a\82Å\82È\82®\82è\8f\91\82«\82³\82ê\82Ä\82¢\82é"
1212                                 : "\8f\91\82©\82ê\82Ä\82¢\82é");
1213 #endif
1214                     del_engr(oep);
1215                     oep = (struct engr *) 0;
1216                 } else
1217                     /* Don't delete engr until after we *know* we're engraving
1218                      */
1219                     eow = TRUE;
1220             } else if (type == DUST || type == MARK || type == ENGR_BLOOD) {
1221 #if 0 /*JP*/
1222                 You("cannot wipe out the message that is %s the %s here.",
1223                     oep->engr_type == BURN
1224                         ? (is_ice(u.ux, u.uy) ? "melted into" : "burned into")
1225                         : "engraved in",
1226                     surface(u.ux, u.uy));
1227 #else
1228                 You("%s\83\81\83b\83Z\81[\83W\82ð\90@\82«\82Æ\82ê\82È\82©\82Á\82½\81D",
1229                     oep->engr_type == BURN
1230                         ? (is_ice(u.ux, u.uy) ? "\8d\8f\82Ü\82ê\82Ä\82¢\82é" : "\8fÄ\82«\95t\82¯\82ç\82ê\82Ä\82¢\82é")
1231                         : "\8d\8f\82Ü\82ê\82Ä\82¢\82é");
1232 #endif
1233                 return 1;
1234             } else if (type != oep->engr_type || c == 'n') {
1235                 if (!Blind || can_reach_floor(TRUE))
1236 /*JP
1237                     You("will overwrite the current message.");
1238 */
1239                     You("\83\81\83b\83Z\81[\83W\82ð\8fã\8f\91\82«\82µ\82æ\82¤\82Æ\82µ\82½\81D");
1240                 eow = TRUE;
1241             }
1242         }
1243     }
1244
1245     eloc = surface(u.ux, u.uy);
1246     switch (type) {
1247     default:
1248 /*JP
1249         everb = (oep && !eow ? "add to the weird writing on"
1250 */
1251         everb = (oep && !eow ? "\8aï\96­\82È\95\8e\9a\97ñ\82É\8f\91\82«\89Á\82¦\82é"
1252 /*JP
1253                              : "write strangely on");
1254 */
1255                              : "\8aï\96­\82È\95\8e\9a\97ñ\82ð\8f\91\82­");
1256         break;
1257     case DUST:
1258 /*JP
1259         everb = (oep && !eow ? "add to the writing in" : "write in");
1260 */
1261         everb = (oep && !eow ? "\8f\91\82«\89Á\82¦\82é" : "\8f\91\82­");
1262 /*JP
1263         eloc = is_ice(u.ux, u.uy) ? "frost" : "dust";
1264 */
1265         eloc = is_ice(u.ux,u.uy) ? "\91\9a" : "\82Ù\82±\82è";
1266         break;
1267     case HEADSTONE:
1268 /*JP
1269         everb = (oep && !eow ? "add to the epitaph on" : "engrave on");
1270 */
1271         everb = (oep && !eow ? "\95æ\94è\96Á\82ð\8d\8f\82Ý\89Á\82¦\82é" : "\95æ\94è\96Á\82ð\8d\8f\82Þ");
1272         break;
1273     case ENGRAVE:
1274 /*JP
1275         everb = (oep && !eow ? "add to the engraving in" : "engrave in");
1276 */
1277         everb = (oep && !eow ? "\8d\8f\82Ý\89Á\82¦\82é" : "\8d\8f\82Þ");
1278         break;
1279     case BURN:
1280 #if 0 /*JP*/
1281         everb = (oep && !eow
1282                      ? (is_ice(u.ux, u.uy) ? "add to the text melted into"
1283                                            : "add to the text burned into")
1284                      : (is_ice(u.ux, u.uy) ? "melt into" : "burn into"));
1285 #else
1286         everb = (oep && !eow
1287                  ? ( is_ice(u.ux,u.uy) ? "\8d\8f\82Ý\89Á\82¦\82é"
1288                                        : "\94R\82¦\82Ä\82¢\82é\95\8e\9a\82É\8f\91\82«\89Á\82¦\82é")
1289                  : ( is_ice(u.ux,u.uy) ? "\8d\8f\82Þ" : "\8fÄ\88ó\82ð\82¢\82ê\82é"));
1290 #endif
1291         break;
1292     case MARK:
1293 /*JP
1294         everb = (oep && !eow ? "add to the graffiti on" : "scribble on");
1295 */
1296         everb = (oep && !eow ? "\97\8e\8f\91\82É\8f\91\82«\89Á\82¦\82é" : "\82Í\82µ\82è\8f\91\82«\82·\82é");
1297         break;
1298     case ENGR_BLOOD:
1299 /*JP
1300         everb = (oep && !eow ? "add to the scrawl on" : "scrawl on");
1301 */
1302         everb = (oep && !eow ? "\82È\82®\82è\8f\91\82«\82É\8f\91\82«\89Á\82¦\82é" : "\82È\82®\82è\8f\91\82«\82·\82é");
1303         break;
1304     }
1305
1306     /* Tell adventurer what is going on */
1307     if (otmp != &zeroobj)
1308 /*JP
1309         You("%s the %s with %s.", everb, eloc, doname(otmp));
1310 */
1311         You("%s\82Å%s\82É%s\81D", doname(otmp), eloc, jpast(everb));
1312     else
1313 #if 0 /*JP*/
1314         You("%s the %s with your %s.", everb, eloc,
1315             makeplural(body_part(FINGER)));
1316 #else
1317         You("%s\82Å%s\82É%s\81D", body_part(FINGER),
1318             eloc, jpast(everb));
1319 #endif
1320
1321     /* Prompt for engraving! */
1322 /*JP
1323     Sprintf(qbuf, "What do you want to %s the %s here?", everb, eloc);
1324 */
1325     Sprintf(qbuf,"%s\82É\89½\82Æ%s\82©\81H", eloc, jpolite(everb));
1326     getlin(qbuf, ebuf);
1327     /* convert tabs to spaces and condense consecutive spaces to one */
1328     mungspaces(ebuf);
1329
1330     /* Count the actual # of chars engraved not including spaces */
1331     len = strlen(ebuf);
1332     for (sp = ebuf; *sp; sp++)
1333         if (*sp == ' ')
1334             len -= 1;
1335
1336     if (len == 0 || index(ebuf, '\033')) {
1337         if (zapwand) {
1338             if (!Blind)
1339 #if 0 /*JP*/
1340                 pline("%s, then %s.", Tobjnam(otmp, "glow"),
1341                       otense(otmp, "fade"));
1342 #else
1343                 pline("%s\82Í\8bP\82¢\82½\82ª\81C\82·\82®\82É\8fÁ\82¦\82½\81D", xname(otmp));
1344 #endif
1345             return 1;
1346         } else {
1347             pline1(Never_mind);
1348             return 0;
1349         }
1350     }
1351
1352     /* A single `x' is the traditional signature of an illiterate person */
1353     if (len != 1 || (!index(ebuf, 'x') && !index(ebuf, 'X')))
1354         u.uconduct.literate++;
1355
1356     /* Mix up engraving if surface or state of mind is unsound.
1357        Note: this won't add or remove any spaces. */
1358     for (sp = ebuf; *sp; sp++) {
1359         if (*sp == ' ')
1360             continue;
1361         if (((type == DUST || type == ENGR_BLOOD) && !rn2(25))
1362             || (Blind && !rn2(11)) || (Confusion && !rn2(7))
1363             || (Stunned && !rn2(4)) || (Hallucination && !rn2(2)))
1364 #if 0 /*JP*/
1365             *sp = ' ' + rnd(96 - 2); /* ASCII '!' thru '~'
1366                                         (excludes ' ' and DEL) */
1367 #else /*JP:\93ú\96{\8cê\82Å\83\89\83\93\83_\83\80\89» */
1368             {
1369                 if(is_kanji1(ebuf, sp-ebuf))
1370                     jrndm_replace(sp);
1371                 else if(is_kanji2(ebuf, sp-ebuf))
1372                     jrndm_replace(sp-1);
1373                 else
1374                     *sp = '!' + rn2(93); /* ASCII-code only */
1375             }
1376 #endif
1377     }
1378
1379     /* Previous engraving is overwritten */
1380     if (eow) {
1381         del_engr(oep);
1382         oep = (struct engr *) 0;
1383     }
1384
1385     /* Figure out how long it took to engrave, and if player has
1386      * engraved too much.
1387      */
1388     switch (type) {
1389     default:
1390         multi = -(len / 10);
1391         if (multi)
1392 /*JP
1393             nomovemsg = "You finish your weird engraving.";
1394 */
1395             nomovemsg = "\82 \82È\82½\82Í\8aï\96­\82È\8d\8f\82Ý\82ð\8fI\82¦\82½\81D";
1396         break;
1397     case DUST:
1398         multi = -(len / 10);
1399         if (multi)
1400 /*JP
1401             nomovemsg = "You finish writing in the dust.";
1402 */
1403             nomovemsg = "\82 \82È\82½\82Í\82Ù\82±\82è\82É\8f\91\82«\8fI\82¦\82½\81D";
1404         break;
1405     case HEADSTONE:
1406     case ENGRAVE:
1407         multi = -(len / 10);
1408         if (otmp->oclass == WEAPON_CLASS
1409             && (otmp->otyp != ATHAME || otmp->cursed)) {
1410             multi = -len;
1411             maxelen = ((otmp->spe + 3) * 2) + 1;
1412             /* -2 => 3, -1 => 5, 0 => 7, +1 => 9, +2 => 11
1413              * Note: this does not allow a +0 anything (except an athame)
1414              * to engrave "Elbereth" all at once.
1415              * However, you can engrave "Elb", then "ere", then "th".
1416              */
1417 /*JP
1418             pline("%s dull.", Yobjnam2(otmp, "get"));
1419 */
1420             Your("%s\82Í\90n\82±\82Ú\82ê\82µ\82½\81D", xname(otmp));
1421             costly_alteration(otmp, COST_DEGRD);
1422             if (len > maxelen) {
1423                 multi = -maxelen;
1424                 otmp->spe = -3;
1425             } else if (len > 1)
1426                 otmp->spe -= len >> 1;
1427             else
1428                 otmp->spe -= 1; /* Prevent infinite engraving */
1429         } else if (otmp->oclass == RING_CLASS || otmp->oclass == GEM_CLASS) {
1430             multi = -len;
1431         }
1432         if (multi)
1433 /*JP
1434             nomovemsg = "You finish engraving.";
1435 */
1436             nomovemsg = "\82 \82È\82½\82Í\8d\8f\82Ý\8fI\82¦\82½\81D";
1437         break;
1438     case BURN:
1439         multi = -(len / 10);
1440         if (multi)
1441             nomovemsg = is_ice(u.ux, u.uy)
1442 /*JP
1443                           ? "You finish melting your message into the ice."
1444 */
1445                           ? "\95X\82Ö\83\81\83b\83Z\81[\83W\82ð\8d\8f\82Ý\8fI\82¦\82½\81D"
1446 /*JP
1447                           : "You finish burning your message into the floor.";
1448 */
1449                           : "\8f°\82Ö\83\81\83b\83Z\81[\83W\82ð\8fÄ\82«\82¢\82ê\8fI\82¦\82½\81D";
1450         break;
1451     case MARK:
1452         multi = -(len / 10);
1453         if (otmp->otyp == MAGIC_MARKER) {
1454             maxelen = otmp->spe * 2; /* one charge / 2 letters */
1455             if (len > maxelen) {
1456 /*JP
1457                 Your("marker dries out.");
1458 */
1459                 Your("\83}\81[\83J\82Í\8a£\82«\82«\82Á\82½\81D");
1460                 otmp->spe = 0;
1461                 multi = -(maxelen / 10);
1462             } else if (len > 1)
1463                 otmp->spe -= len >> 1;
1464             else
1465                 otmp->spe -= 1; /* Prevent infinite graffiti */
1466         }
1467         if (multi)
1468 /*JP
1469             nomovemsg = "You finish defacing the dungeon.";
1470 */
1471             nomovemsg = "\82 \82È\82½\82Í\96À\8b{\82Ö\82Ì\97\8e\8f\91\82ð\8f\91\82«\8fI\82¦\82½\81D";
1472         break;
1473     case ENGR_BLOOD:
1474         multi = -(len / 10);
1475         if (multi)
1476 /*JP
1477             nomovemsg = "You finish scrawling.";
1478 */
1479             nomovemsg = "\82Í\82µ\82è\8f\91\82«\82ð\8f\91\82«\8fI\82¦\82½\81D";
1480         break;
1481     }
1482
1483     /* Chop engraving down to size if necessary */
1484     if (len > maxelen) {
1485         for (sp = ebuf; maxelen && *sp; sp++)
1486             if (*sp == ' ')
1487                 maxelen--;
1488         if (!maxelen && *sp) {
1489 #if 1 /*JP*//*\8a¿\8e\9a\82Ì1\83o\83C\83g\96Ú\82¾\82¯\82ª\8ec\82ç\82È\82¢\82æ\82¤\82É*/
1490             if(is_kanji2(ebuf, sp - ebuf))
1491                 --sp;
1492 #endif
1493             *sp = '\0';
1494             if (multi)
1495 /*JP
1496                 nomovemsg = "You cannot write any more.";
1497 */
1498                 nomovemsg = "\82±\82ê\88È\8fã\89½\82à\8f\91\82¯\82È\82©\82Á\82½\81D";
1499 /*JP
1500             You("are only able to write \"%s\".", ebuf);
1501 */
1502             You("\81u%s\81v\82Æ\82Ü\82Å\82µ\82©\8f\91\82¯\82È\82©\82Á\82½\81D", ebuf);
1503         }
1504     }
1505
1506     if (oep) /* add to existing engraving */
1507         Strcpy(buf, oep->engr_txt);
1508     (void) strncat(buf, ebuf, BUFSZ - (int) strlen(buf) - 1);
1509     /* Put the engraving onto the map */
1510     make_engr_at(u.ux, u.uy, buf, moves - multi, type);
1511
1512     if (post_engr_text[0])
1513         pline("%s", post_engr_text);
1514     if (doblind && !resists_blnd(&youmonst)) {
1515 /*JP
1516         You("are blinded by the flash!");
1517 */
1518         You("\82Ü\82Î\82ä\82¢\8cõ\82Å\96Ú\82ª\82­\82ç\82ñ\82¾\81I");
1519         make_blinded((long) rnd(50), FALSE);
1520         if (!Blind)
1521             Your1(vision_clears);
1522     }
1523     return 1;
1524 }
1525
1526 /* while loading bones, clean up text which might accidentally
1527    or maliciously disrupt player's terminal when displayed */
1528 void
1529 sanitize_engravings()
1530 {
1531     struct engr *ep;
1532
1533     for (ep = head_engr; ep; ep = ep->nxt_engr) {
1534         sanitize_name(ep->engr_txt);
1535     }
1536 }
1537
1538 void
1539 save_engravings(fd, mode)
1540 int fd, mode;
1541 {
1542     struct engr *ep, *ep2;
1543     unsigned no_more_engr = 0;
1544
1545     for (ep = head_engr; ep; ep = ep2) {
1546         ep2 = ep->nxt_engr;
1547         if (ep->engr_lth && ep->engr_txt[0] && perform_bwrite(mode)) {
1548             bwrite(fd, (genericptr_t) &ep->engr_lth, sizeof ep->engr_lth);
1549             bwrite(fd, (genericptr_t) ep, sizeof (struct engr) + ep->engr_lth);
1550         }
1551         if (release_data(mode))
1552             dealloc_engr(ep);
1553     }
1554     if (perform_bwrite(mode))
1555         bwrite(fd, (genericptr_t) &no_more_engr, sizeof no_more_engr);
1556     if (release_data(mode))
1557         head_engr = 0;
1558 }
1559
1560 void
1561 rest_engravings(fd)
1562 int fd;
1563 {
1564     struct engr *ep;
1565     unsigned lth;
1566
1567     head_engr = 0;
1568     while (1) {
1569         mread(fd, (genericptr_t) &lth, sizeof lth);
1570         if (lth == 0)
1571             return;
1572         ep = newengr(lth);
1573         mread(fd, (genericptr_t) ep, sizeof (struct engr) + lth);
1574         ep->nxt_engr = head_engr;
1575         head_engr = ep;
1576         ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
1577         /* Mark as finished for bones levels -- no problem for
1578          * normal levels as the player must have finished engraving
1579          * to be able to move again.
1580          */
1581         ep->engr_time = moves;
1582     }
1583 }
1584
1585 void
1586 del_engr(ep)
1587 register struct engr *ep;
1588 {
1589     if (ep == head_engr) {
1590         head_engr = ep->nxt_engr;
1591     } else {
1592         register struct engr *ept;
1593
1594         for (ept = head_engr; ept; ept = ept->nxt_engr)
1595             if (ept->nxt_engr == ep) {
1596                 ept->nxt_engr = ep->nxt_engr;
1597                 break;
1598             }
1599         if (!ept) {
1600             impossible("Error in del_engr?");
1601             return;
1602         }
1603     }
1604     dealloc_engr(ep);
1605 }
1606
1607 /* randomly relocate an engraving */
1608 void
1609 rloc_engr(ep)
1610 struct engr *ep;
1611 {
1612     int tx, ty, tryct = 200;
1613
1614     do {
1615         if (--tryct < 0)
1616             return;
1617         tx = rn1(COLNO - 3, 2);
1618         ty = rn2(ROWNO);
1619     } while (engr_at(tx, ty) || !goodpos(tx, ty, (struct monst *) 0, 0));
1620
1621     ep->engr_x = tx;
1622     ep->engr_y = ty;
1623 }
1624
1625 /* Create a headstone at the given location.
1626  * The caller is responsible for newsym(x, y).
1627  */
1628 void
1629 make_grave(x, y, str)
1630 int x, y;
1631 const char *str;
1632 {
1633     char buf[BUFSZ];
1634
1635     /* Can we put a grave here? */
1636     if ((levl[x][y].typ != ROOM && levl[x][y].typ != GRAVE) || t_at(x, y))
1637         return;
1638     /* Make the grave */
1639     levl[x][y].typ = GRAVE;
1640     /* Engrave the headstone */
1641     del_engr_at(x, y);
1642     if (!str)
1643         str = get_rnd_text(EPITAPHFILE, buf);
1644     make_engr_at(x, y, str, 0L, HEADSTONE);
1645     return;
1646 }
1647
1648 /*engrave.c*/