OSDN Git Service

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