OSDN Git Service

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