1 /* NetHack 3.6 engrave.c $NHDT-Date: 1445388915 2015/10/21 00:55:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.59 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
13 STATIC_VAR NEARDATA struct engr *head_engr;
16 random_engraving(outbuf)
21 /* a random engraving may come from the "rumors" file,
22 or from the "engrave" file (formerly in an array here) */
23 if (!rn2(4) || !(rumor = getrumor(0, outbuf, TRUE)) || !*rumor)
24 (void) get_rnd_text(ENGRAVEFILE, outbuf);
26 wipeout_text(outbuf, (int) (strlen(outbuf) / 4), 0);
30 /* Partial rubouts for engraving characters. -3. */
34 } rubouts[] = { { 'A', "^" },
83 /* degrade some of the characters in a string */
85 wipeout_text(engr, cnt, seed)
88 unsigned seed; /* for semi-controlled randomization */
95 int i, j, nxt, use_rubout, lth = (int) strlen(engr);
99 /* pick next character */
105 /* predictable; caller can reproduce the same sequence by
106 supplying the same arguments later, or a pseudo-random
107 sequence by varying any of them */
109 seed *= 31, seed %= (BUFSZ - 1);
110 use_rubout = seed & 3;
114 #else /*JP:
\93ú
\96{
\8cê
\82Ì
\8fê
\8d\87\82Íjrubout()
\82ð
\8eg
\82Á
\82Ä
\8fÁ
\82·*/
118 seed *= 31, seed %= (BUFSZ-1);
122 if(jrubout(engr, nxt, use_rubout, j)){
126 s = (unsigned char *)&engr[nxt];
131 /* rub out unreadable & small punctuation marks */
132 if (index("?.,'`-|_", *s)) {
140 for (i = 0; i < SIZE(rubouts); i++)
141 if (*s == rubouts[i].wipefrom) {
143 * Pick one of the substitutes at random.
146 j = rn2(strlen(rubouts[i].wipeto));
148 seed *= 31, seed %= (BUFSZ - 1);
149 j = seed % (strlen(rubouts[i].wipeto));
151 *s = rubouts[i].wipeto[j];
155 /* didn't pick rubout; use '?' for unreadable character */
156 if (i == SIZE(rubouts))
161 /* trim trailing spaces */
162 while (lth && engr[lth - 1] == ' ')
166 /* check whether hero can reach something at ground level */
168 can_reach_floor(check_pit)
175 /* Restricted/unskilled riders can't reach the floor */
176 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
178 if (check_pit && !Flying
179 && (t = t_at(u.ux, u.uy)) != 0 && uteetering_at_seen_pit(t))
182 return (boolean) ((!Levitation || Is_airlevel(&u.uz)
183 || Is_waterlevel(&u.uz))
184 && (!u.uundetected || !is_hider(youmonst.data)
185 || u.umonnum == PM_TRAPPER));
188 /* give a message after caller has determined that hero can't reach */
190 cant_reach_floor(x, y, up, check_pit)
192 boolean up, check_pit;
195 You("can't reach the %s.",
197 : (check_pit && can_reach_floor(FALSE))
198 ? "bottom of the pit"
201 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81D",
203 : (check_pit && can_reach_floor(FALSE))
204 ? "
\97\8e\82µ
\8c\8a\82Ì
\92ê"
213 register struct rm *lev = &levl[x][y];
215 if (x == u.ux && y == u.uy && u.uswallow && is_animal(u.ustuck->data))
220 else if (IS_AIR(lev->typ) && Is_airlevel(&u.uz))
225 else if (is_pool(x, y))
227 return (Underwater && !Is_waterlevel(&u.uz)) ? "bottom" : "water";
229 return (Underwater && !Is_waterlevel(&u.uz)) ? "
\90\85\82Ì
\92ê" : "
\90\85\92\86";
230 else if (is_ice(x, y))
235 else if (is_lava(x, y))
240 else if (lev->typ == DRAWBRIDGE_DOWN)
245 else if (IS_ALTAR(levl[x][y].typ))
250 else if (IS_GRAVE(levl[x][y].typ))
255 else if (IS_FOUNTAIN(levl[x][y].typ))
260 else if ((IS_ROOM(lev->typ) && !Is_earthlevel(&u.uz))
261 || IS_WALL(lev->typ) || IS_DOOR(lev->typ) || lev->typ == SDOOR)
277 register struct rm *lev = &levl[x][y];
280 /* other room types will no longer exist when we're interested --
281 * see check_special_room()
283 if (*in_rooms(x, y, VAULT))
285 what = "vault's ceiling";
287 what = "
\91q
\8cÉ
\82Ì
\93V
\88ä";
288 else if (*in_rooms(x, y, TEMPLE))
290 what = "temple's ceiling";
292 what = "
\8e\9b\89@
\82Ì
\93V
\88ä";
293 else if (*in_rooms(x, y, SHOPBASE))
295 what = "shop's ceiling";
297 what = "
\93X
\82Ì
\93V
\88ä";
298 else if (Is_waterlevel(&u.uz))
299 /* water plane has no surface; its air bubbles aren't below sky */
301 what = "water above";
303 what = "
\90\85\82Ì
\8fã
\95û";
304 else if (IS_AIR(lev->typ))
311 what = "water's surface";
314 else if ((IS_ROOM(lev->typ) && !Is_earthlevel(&u.uz))
315 || IS_WALL(lev->typ) || IS_DOOR(lev->typ) || lev->typ == SDOOR)
322 what = "rock cavern";
324 what = "
\93´
\8cA
\82Ì
\93V
\88ä";
333 register struct engr *ep = head_engr;
336 if (x == ep->engr_x && y == ep->engr_y)
340 return (struct engr *) 0;
343 /* Decide whether a particular string is engraved at a specified
344 * location; a case-insensitive substring match is used.
345 * Ignore headstones, in case the player names herself "Elbereth".
347 * If strict checking is requested, the word is only considered to be
348 * present if it is intact and is the first word in the engraving.
349 * ("Elbereth burrito" matches; "o Elbereth" does not.)
352 sengr_at(s, x, y, strict)
357 register struct engr *ep = engr_at(x, y);
359 if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= moves) {
360 return strict ? (strncmpi(ep->engr_txt, s, strlen(s)) == 0)
361 : (strstri(ep->engr_txt, s) != 0);
370 if (can_reach_floor(TRUE))
371 wipe_engr_at(u.ux, u.uy, cnt, FALSE);
375 wipe_engr_at(x, y, cnt, magical)
376 xchar x, y, cnt, magical;
378 register struct engr *ep = engr_at(x, y);
380 /* Headstones are indelible */
381 if (ep && ep->engr_type != HEADSTONE) {
382 debugpline1("asked to erode %d characters", cnt);
383 if (ep->engr_type != BURN || is_ice(x, y) || (magical && !rn2(2))) {
384 if (ep->engr_type != DUST && ep->engr_type != ENGR_BLOOD) {
385 cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1;
386 debugpline1("actually eroding %d characters", cnt);
388 wipeout_text(ep->engr_txt, (int) cnt, 0);
389 while (ep->engr_txt[0] == ' ')
391 if (!ep->engr_txt[0])
401 register struct engr *ep = engr_at(x, y);
405 /* Sensing an engraving does not require sight,
406 * nor does it necessarily imply comprehension (literacy).
408 if (ep && ep->engr_txt[0]) {
409 switch (ep->engr_type) {
414 pline("%s is written here in the %s.", Something,
415 is_ice(x, y) ? "frost" : "dust");
417 pline("
\89½
\82©
\82Ì
\95¶
\8e\9a\82ª%s
\82É
\8f\91\82¢
\82Ä
\82 \82é
\81D",
418 is_ice(x, y) ? "
\91\9a" : "
\82Ù
\82±
\82è");
424 if (!Blind || can_reach_floor(TRUE)) {
427 pline("%s is engraved here on the %s.", Something,
429 pline("
\89½
\82©
\82Ì
\95¶
\8e\9a\82ª%s
\82É
\8d\8f\82Ü
\82ê
\82Ä
\82¢
\82é
\81D",
434 if (!Blind || can_reach_floor(TRUE)) {
437 pline("Some text has been %s into the %s here.",
438 is_ice(x, y) ? "melted" : "burned", surface(x, y));
440 pline("
\89½
\82©
\82Ì
\95¶
\8e\9a\82ª%s%s
\82¢
\82é
\81D",
442 is_ice(x,y) ? "
\82É
\8d\8f\82Ü
\82ê
\82Ä" : "
\82É
\8fÄ
\82«
\95t
\82¯
\82ç
\82ê
\82Ä");
450 pline("There's some graffiti on the %s here.", surface(x, y));
452 pline("%s
\82É
\97\8e\8f\91\82ª
\82 \82é
\81D", surface(x,y));
456 /* "It's a message! Scrawled in blood!"
458 * "It says... `See you next Wednesday.'" -- Thriller
463 You_see("a message scrawled in blood here.");
465 You("
\8c\8c\95¶
\8e\9a\82ª
\82È
\82®
\82è
\8f\91\82«
\82³
\82ê
\82Ä
\82¢
\82é
\82Ì
\82ð
\8c©
\82Â
\82¯
\82½
\81D");
469 impossible("%s is written in a very strange way.", Something);
475 unsigned maxelen = BUFSZ - sizeof("You feel the words: \"\". ");
477 unsigned maxelen = BUFSZ - sizeof("
\82 \82È
\82½
\82Í
\8e\9f\82Ì
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81F
\81u
\81v");
478 if (strlen(ep->engr_txt) > maxelen) {
479 (void) strncpy(buf, ep->engr_txt, (int) maxelen);
485 You("%s: \"%s\".", (Blind) ? "feel the words" : "read", et);
487 You("%s
\81F
\81u%s
\81v", (Blind) ? "
\8e\9f\82Ì
\82æ
\82¤
\82É
\8a´
\82¶
\82½" : "
\93Ç
\82ñ
\82¾", et);
495 make_engr_at(x, y, s, e_time, e_type)
503 if ((ep = engr_at(x, y)) != 0)
505 ep = newengr(strlen(s) + 1);
506 ep->nxt_engr = head_engr;
510 ep->engr_txt = (char *) (ep + 1);
511 Strcpy(ep->engr_txt, s);
512 /* engraving Elbereth shows wisdom */
513 if (!in_mklev && !strcmp(s, "Elbereth"))
514 exercise(A_WIS, TRUE);
515 ep->engr_time = e_time;
516 ep->engr_type = e_type > 0 ? e_type : rnd(N_ENGRAVE - 1);
517 ep->engr_lth = strlen(s) + 1;
520 /* delete any engraving at location <x,y> */
525 register struct engr *ep = engr_at(x, y);
532 * freehand - returns true if player has a free hand
537 return (!uwep || !welded(uwep)
538 || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
541 static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
542 TOOL_CLASS, WEAPON_CLASS,
543 WAND_CLASS, GEM_CLASS,
546 /* Mohs' Hardness Scale:
547 * 1 - Talc 6 - Orthoclase
548 * 2 - Gypsum 7 - Quartz
549 * 3 - Calcite 8 - Topaz
550 * 4 - Fluorite 9 - Corundum
551 * 5 - Apatite 10 - Diamond
553 * Since granite is an igneous rock hardness ~ 7, anything >= 8 should
554 * probably be able to scratch the rock.
555 * Devaluation of less hard gems is not easily possible because obj struct
556 * does not contain individual oc_cost currently. 7/91
558 * steel - 5-8.5 (usu. weapon)
559 * diamond - 10 * jade - 5-6 (nephrite)
560 * ruby - 9 (corundum) * turquoise - 5-6
561 * sapphire - 9 (corundum) * opal - 5-6
562 * topaz - 8 * glass - ~5.5
563 * emerald - 7.5-8 (beryl) * dilithium - 4-5??
564 * aquamarine - 7.5-8 (beryl) * iron - 4-5
565 * garnet - 7.25 (var. 6.5-8) * fluorite - 4
566 * agate - 7 (quartz) * brass - 3-4
567 * amethyst - 7 (quartz) * gold - 2.5-3
568 * jasper - 7 (quartz) * silver - 2.5-3
569 * onyx - 7 (quartz) * copper - 2.5-3
570 * moonstone - 6 (orthoclase) * amber - 2-2.5
573 /* return 1 if action took 1 (or more) moves, 0 if error or aborted */
577 boolean dengr = FALSE; /* TRUE if we wipe out the current engraving */
578 boolean doblind = FALSE; /* TRUE if engraving blinds the player */
579 boolean doknown = FALSE; /* TRUE if we identify the stylus */
580 boolean eow = FALSE; /* TRUE if we are overwriting oep */
581 boolean jello = FALSE; /* TRUE if we are engraving in slime */
582 boolean ptext = TRUE; /* TRUE if we must prompt for engrave text */
583 boolean teleengr = FALSE; /* TRUE if we move the old engraving */
584 boolean zapwand = FALSE; /* TRUE if we remove a wand charge */
585 xchar type = DUST; /* Type of engraving made */
586 char buf[BUFSZ]; /* Buffer for final/poly engraving text */
587 char ebuf[BUFSZ]; /* Buffer for initial engraving text */
588 char fbuf[BUFSZ]; /* Buffer for "your fingers" */
589 char qbuf[QBUFSZ]; /* Buffer for query text */
590 char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
591 const char *everb; /* Present tense of engraving type */
592 const char *eloc; /* Where the engraving is (ie dust/floor/...) */
593 char *sp; /* Place holder for space count of engr text */
594 int len; /* # of nonspace chars of new engraving text */
595 int maxelen; /* Max allowable length of engraving text */
596 struct engr *oep = engr_at(u.ux, u.uy);
597 /* The current engraving */
598 struct obj *otmp; /* Object selected with which to engrave */
601 multi = 0; /* moves consumed */
602 nomovemsg = (char *) 0; /* occupation end message */
606 post_engr_text[0] = (char) 0;
608 if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
611 /* Can the adventurer engrave at all? */
614 if (is_animal(u.ustuck->data)) {
616 pline("What would you write? \"Jonah was here\"?");
618 pline("
\89½
\82ð
\8f\91\82
\82ñ
\82¾
\82¢
\81H
\81u
\83\88\83i
\82Í
\82±
\82±
\82É
\82¢
\82é
\81v
\81H");
620 } else if (is_whirly(u.ustuck->data)) {
621 cant_reach_floor(u.ux, u.uy, FALSE, FALSE);
625 } else if (is_lava(u.ux, u.uy)) {
627 You_cant("write on the %s!", surface(u.ux, u.uy));
629 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81D", surface(u.ux,u.uy));
631 } else if (is_pool(u.ux, u.uy) || IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
633 You_cant("write on the %s!", surface(u.ux, u.uy));
635 You("%s
\82É
\82Í
\8f\91\82¯
\82È
\82¢
\81I", surface(u.ux, u.uy));
638 if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) /* in bubble */) {
640 You_cant("write in thin air!");
642 You("
\8bó
\92\86\82É
\82Í
\8f\91\82¯
\82È
\82¢
\81I");
644 } else if (!accessible(u.ux, u.uy)) {
645 /* stone, tree, wall, secret corridor, pool, lava, bars */
647 You_cant("write here.");
649 You_cant("
\82±
\82±
\82É
\82Í
\8f\91\82¯
\82È
\82¢
\81D");
652 if (cantwield(youmonst.data)) {
654 You_cant("even hold anything!");
656 You("
\89½
\82©
\82ð
\8e\9d\82Â
\82±
\82Æ
\82·
\82ç
\82Å
\82«
\82È
\82¢
\81I");
659 if (check_capacity((char *) 0))
662 /* One may write with finger, or weapon, or wand, or..., or...
663 * Edited by GAN 10/20/86 so as not to change weapon wielded.
666 otmp = getobj(styluses, "write with");
667 if (!otmp) /* otmp == zeroobj if fingers */
670 if (otmp == &zeroobj) {
672 Strcat(strcpy(fbuf, "your "), makeplural(body_part(FINGER)));
674 Strcat(strcpy(fbuf, "
\82 \82È
\82½
\82Ì"), makeplural(body_part(FINGER)));
677 writer = yname(otmp);
679 /* There's no reason you should be able to write with a wand
680 * while both your hands are tied up.
682 if (!freehand() && otmp != uwep && !otmp->owornmask) {
684 You("have no free %s to write with!", body_part(HAND));
686 pline("%s
\82Ì
\8e©
\97R
\82ª
\8cø
\82©
\82È
\82¢
\82Ì
\82Å
\8f\91\82¯
\82È
\82¢
\81I", body_part(HAND));
692 You("tickle %s with %s.", mon_nam(u.ustuck), writer);
694 You("%s
\82Å%s
\82ð
\82
\82·
\82®
\82Á
\82½
\81D", writer, mon_nam(u.ustuck));
696 Your("message dissolves...");
698 Your("
\83\81\83b
\83Z
\81[
\83W
\82Í
\8fÁ
\82¦
\82½
\81D
\81D
\81D");
701 if (otmp->oclass != WAND_CLASS && !can_reach_floor(TRUE)) {
702 cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
705 if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
707 You("make a motion towards the altar with %s.", writer);
709 You("%s
\82ð
\8eg
\82Á
\82Ä
\8dÕ
\92d
\82É
\8f\91\82±
\82¤
\82Æ
\82µ
\82½
\81D", writer);
710 altar_wrath(u.ux, u.uy);
713 if (IS_GRAVE(levl[u.ux][u.uy].typ)) {
714 if (otmp == &zeroobj) { /* using only finger */
716 You("would only make a small smudge on the %s.",
718 You("
\82Í%s
\82É
\8f¬
\82³
\82È
\82µ
\82Ý
\82ð
\82Â
\82¯
\82é
\82±
\82Æ
\82µ
\82©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D",
719 surface(u.ux, u.uy));
721 } else if (!levl[u.ux][u.uy].disturbed) {
723 You("disturb the undead!");
725 You("
\95s
\8e\80\82Ì
\8eÒ
\82Ì
\96°
\82è
\82ð
\96W
\82°
\82½
\81I");
726 levl[u.ux][u.uy].disturbed = 1;
727 (void) makemon(&mons[PM_GHOUL], u.ux, u.uy, NO_MM_FLAGS);
728 exercise(A_WIS, FALSE);
735 switch (otmp->oclass) {
743 /* "diamond" rings and others should work */
745 /* diamonds & other hard gems should work */
746 if (objects[otmp->otyp].oc_tough) {
752 if (is_boots(otmp)) {
757 /* Objects too large to engrave with */
761 You_cant("engrave with such a large object!");
763 pline("
\82»
\82ñ
\82È
\91å
\82«
\82È
\82à
\82Ì
\82ð
\8eg
\82Á
\82Ä
\95¶
\8e\9a\82ð
\8d\8f\82ß
\82È
\82¢
\81I");
766 /* Objects too silly to engrave with */
771 pline("%s would get %s.", Yname2(otmp),
772 is_ice(u.ux, u.uy) ? "all frosty" : "too dirty");
774 Your("%s
\82Í%s
\82È
\82Á
\82½
\81D", xname(otmp),
775 is_ice(u.ux,u.uy) ? "
\91\9a\82¾
\82ç
\82¯
\82É" : "
\89\98\82È
\82");
779 case RANDOM_CLASS: /* This should mean fingers */
782 /* The charge is removed from the wand before prompting for
783 * the engraving text, because all kinds of setup decisions
784 * and pre-engraving messages are based upon knowing what type
785 * of engraving the wand is going to do. Also, the player
786 * will have potentially seen "You wrest .." message, and
787 * therefore will know they are using a charge.
790 if (zappable(otmp)) {
792 if (otmp->cursed && !rn2(WAND_BACKFIRE_CHANCE)) {
793 wand_explode(otmp, 0);
797 if (!can_reach_floor(TRUE))
800 switch (otmp->otyp) {
806 case WAN_SECRET_DOOR_DETECTION:
807 case WAN_CREATE_MONSTER:
809 case WAN_ENLIGHTENMENT:
812 /* IMMEDIATE wands */
813 /* If wand is "IMMEDIATE", remember to affect the
814 * previous engraving even if turning to dust.
817 Strcpy(post_engr_text,
819 "The wand unsuccessfully fights your attempt to write!");
821 "
\82 \82È
\82½
\82ª
\8f\91\82±
\82¤
\82Æ
\82·
\82é
\82Æ
\8fñ
\82Í
\92ï
\8dR
\82µ
\82½
\81I");
823 case WAN_SLOW_MONSTER:
826 Sprintf(post_engr_text, "The bugs on the %s slow down!",
828 Sprintf(post_engr_text, "%s
\82Ì
\8fã
\82Ì
\92\8e\82Ì
\93®
\82«
\82ª
\92x
\82
\82È
\82Á
\82½
\81I",
829 surface(u.ux, u.uy));
832 case WAN_SPEED_MONSTER:
835 Sprintf(post_engr_text, "The bugs on the %s speed up!",
837 Sprintf(post_engr_text, "%s
\82Ì
\8fã
\82Ì
\92\8e\82Ì
\93®
\82«
\82ª
\91¬
\82
\82È
\82Á
\82½
\81I",
838 surface(u.ux, u.uy));
844 type = (xchar) 0; /* random */
845 (void) random_engraving(buf);
851 case WAN_UNDEAD_TURNING:
857 case WAN_MAGIC_MISSILE:
860 Sprintf(post_engr_text,
862 "The %s is riddled by bullet holes!",
864 "%s
\82Í
\8eU
\92e
\82Å
\8d×
\82©
\82¢
\8c\8a\82¾
\82ç
\82¯
\82É
\82È
\82Á
\82½
\81I",
865 surface(u.ux, u.uy));
868 /* can't tell sleep from death - Eric Backus */
873 Sprintf(post_engr_text, "The bugs on the %s stop moving!",
875 Sprintf(post_engr_text, "%s
\82Ì
\8fã
\82Ì
\92\8e\82Ì
\93®
\82«
\82ª
\8e~
\82Ü
\82Á
\82½
\81I",
876 surface(u.ux, u.uy));
881 Strcpy(post_engr_text,
883 "A few ice cubes drop from the wand.");
885 "
\95X
\82Ì
\82©
\82¯
\82ç
\82ª
\8fñ
\82©
\82ç
\82±
\82Ú
\82ê
\97\8e\82¿
\82½
\81D");
886 if (!oep || (oep->engr_type != BURN))
888 case WAN_CANCELLATION:
889 case WAN_MAKE_INVISIBLE:
890 if (oep && oep->engr_type != HEADSTONE) {
893 pline_The("engraving on the %s vanishes!",
895 pline("%s
\82Ì
\8fã
\82Ì
\95¶
\8e\9a\82Í
\8fÁ
\82¦
\82½
\81I",
896 surface(u.ux, u.uy));
900 case WAN_TELEPORTATION:
901 if (oep && oep->engr_type != HEADSTONE) {
904 pline_The("engraving on the %s vanishes!",
906 pline("%s
\82Ì
\8fã
\82Ì
\95¶
\8e\9a\82Í
\8fÁ
\82¦
\82½
\81I",
907 surface(u.ux, u.uy));
911 /* type = ENGRAVE wands */
915 if (!objects[otmp->otyp].oc_name_known) {
918 pline("This %s is a wand of digging!", xname(otmp));
920 pline("
\82±
\82ê
\82Í
\8c\8a\8c@
\82è
\82Ì
\8fñ
\82¾
\81I");
924 Strcpy(post_engr_text,
926 ? "You hear drilling!"
927 : IS_GRAVE(levl[u.ux][u.uy].typ)
928 ? "Chips fly out from the headstone."
930 ? "Ice chips fly up from the ice surface!"
931 : (level.locations[u.ux][u.uy].typ
933 ? "Splinters fly up from the bridge."
934 : "Gravel flies up from the floor.");
936 Strcpy(post_engr_text,
938 ? "
\8c\8a\82ª
\8aJ
\82
\89¹
\82ð
\95·
\82¢
\82½
\81I"
939 : IS_GRAVE(levl[u.ux][u.uy].typ)
940 ? "
\95æ
\90Î
\82©
\82ç
\94j
\95Ð
\82ª
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D"
942 ? "
\95X
\82Ì
\95\
\96Ê
\82©
\82ç
\95X
\82Ì
\82©
\82¯
\82ç
\82ª
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D"
943 : (level.locations[u.ux][u.uy].typ
945 ? "
\94j
\95Ð
\82ª
\8b´
\82©
\82ç
\95\91\82¢
\82 \82ª
\82Á
\82½
\81D"
946 : "
\8d»
\97\98\82ª
\8f°
\82©
\82ç
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D");
949 /* type = BURN wands */
953 if (!objects[otmp->otyp].oc_name_known) {
956 pline("This %s is a wand of fire!", xname(otmp));
958 pline("
\82±
\82ê
\82Í
\89\8a\82Ì
\8fñ
\82¾
\81I");
962 Strcpy(post_engr_text, Blind ? "You feel the wand heat up."
963 : "Flames fly from the wand.");
965 Strcpy(post_engr_text, Blind ? "
\8fñ
\82ª
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D"
966 : "
\89\8a\82ª
\8fñ
\82©
\82ç
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D");
972 if (!objects[otmp->otyp].oc_name_known) {
975 pline("This %s is a wand of lightning!", xname(otmp));
977 pline("
\82±
\82ê
\82Í
\97\8b\82Ì
\8fñ
\82¾
\81I");
982 Strcpy(post_engr_text, "Lightning arcs from the wand.");
984 Strcpy(post_engr_text, "
\89Î
\89Ô
\82ª
\8fñ
\82©
\82ç
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D");
988 Strcpy(post_engr_text, "You hear crackling!");
990 Strcpy(post_engr_text, "
\83p
\83`
\83p
\83`
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
993 /* type = MARK wands */
994 /* type = ENGR_BLOOD wands */
996 } else { /* end if zappable */
997 /* failing to wrest one last charge takes time */
998 ptext = FALSE; /* use "early exit" below, return 1 */
999 /* give feedback here if we won't be getting the
1000 "can't reach floor" message below */
1001 if (can_reach_floor(TRUE)) {
1002 /* cancelled wand turns to dust */
1005 /* empty wand just doesn't write */
1008 pline_The("wand is too worn out to engrave.");
1010 pline_The("
\8fñ
\82Í
\95¶
\8e\9a\82ð
\8d\8f\82Þ
\82É
\82Í
\8eg
\82¢
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
1016 if (is_blade(otmp)) {
1017 if ((int) otmp->spe > -3)
1021 pline("%s too dull for engraving.", Yobjnam2(otmp, "are"));
1023 pline("%s
\82Í
\90n
\82ª
\83{
\83\8d\83{
\83\8d\82Å
\81C
\95¶
\8e\9a\82ð
\92¤
\82ê
\82È
\82¢
\81D", xname(otmp));
1028 if (otmp == ublindf) {
1031 "That is a bit difficult to engrave with, don't you think?");
1033 "
\82¿
\82å
\82Á
\82Æ
\82»
\82ê
\82Å
\92¤
\82é
\82Ì
\82Í
\91å
\95Ï
\82¾
\82ë
\82¤
\81C
\82»
\82¤
\8ev
\82í
\82È
\82¢
\81H");
1036 switch (otmp->otyp) {
1040 Your("marker has dried out.");
1042 Your("
\83}
\81[
\83J
\82Í
\8a£
\82«
\82«
\82Á
\82½
\81D");
1047 /* Can't really engrave with a towel */
1050 if (oep->engr_type == DUST
1051 || oep->engr_type == ENGR_BLOOD
1052 || oep->engr_type == MARK) {
1053 if (is_wet_towel(otmp))
1054 dry_a_towel(otmp, -1, TRUE);
1057 You("wipe out the message here.");
1059 You("
\83\81\83b
\83Z
\81[
\83W
\82ð
\90@
\82«
\82Æ
\82Á
\82½
\81D");
1062 pline("%s %s.", Yobjnam2(otmp, "get"),
1063 is_ice(u.ux, u.uy) ? "frosty" : "dusty");
1065 pline("%s
\82Í%s
\82É
\82È
\82Á
\82½
\81D", xname(otmp),
1066 is_ice(u.ux,u.uy) ? "
\91\9a\82¾
\82ç
\82¯" : "
\82Ù
\82±
\82è
\82Ü
\82Ý
\82ê");
1071 pline("%s can't wipe out this engraving.", Yname2(otmp));
1073 pline("
\82±
\82Ì
\95¶
\8e\9a\82Í%s
\82Å
\82Í
\90@
\82«
\82Æ
\82ê
\82È
\82¢
\81D", xname(otmp));
1076 pline("%s %s.", Yobjnam2(otmp, "get"),
1077 is_ice(u.ux, u.uy) ? "frosty" : "dusty");
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ê");
1091 pline("Writing a poison pen letter??");
1093 pline("
\82Ó
\82Þ
\81D
\82±
\82ê
\82±
\82»
\96{
\93\96\82Ì
\93Å
\90ã
\82¾
\81D");
1098 impossible("You're engraving with an illegal object!");
1102 if (IS_GRAVE(levl[u.ux][u.uy].typ)) {
1103 if (type == ENGRAVE || type == 0) {
1106 /* ensures the "cannot wipe out" case */
1115 * End of implement setup
1118 /* Identify stylus */
1121 if (objects[otmp->otyp].oc_name_known)
1122 more_experienced(0, 10);
1126 oep = (struct engr *) 0;
1130 oep = (struct engr *) 0;
1132 /* Something has changed the engraving here */
1134 make_engr_at(u.ux, u.uy, buf, moves, type);
1136 pline_The("engraving now reads: \"%s\".", buf);
1138 pline("
\8d\8f\82Ü
\82ê
\82½
\95¶
\8e\9a\82ð
\93Ç
\82ñ
\82¾
\81F
\81u%s
\81v
\81D", buf);
1141 if (zapwand && (otmp->spe < 0)) {
1143 pline("%s %sturns to dust.", The(xname(otmp)),
1144 Blind ? "" : "glows violently, then ");
1146 pline("%s
\82Í%s
\82¿
\82è
\82Æ
\82È
\82Á
\82½
\81D", xname(otmp),
1147 Blind ? "" : "
\8c\83\82µ
\82
\8bP
\82«
\81C");
1149 if (!IS_GRAVE(levl[u.ux][u.uy].typ))
1152 "are not going to get anywhere trying to write in the %s with your dust.",
1153 is_ice(u.ux, u.uy) ? "frost" : "dust");
1156 "
\90o
\82Å%s
\82É
\89½
\82©
\8f\91\82±
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D",
1157 is_ice(u.ux,u.uy) ? "
\95X" : "
\82Ù
\82±
\82è");
1160 otmp = 0; /* wand is now gone */
1163 /* Early exit for some implements. */
1165 if (otmp && otmp->oclass == WAND_CLASS && !can_reach_floor(TRUE))
1166 cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
1170 * Special effects should have deleted the current engraving (if
1174 register char c = 'n';
1176 /* Give player the choice to add to engraving. */
1177 if (type == HEADSTONE) {
1178 /* no choice, only append */
1180 } else if (type == oep->engr_type
1181 && (!Blind || oep->engr_type == BURN
1182 || oep->engr_type == ENGRAVE)) {
1184 c = yn_function("Do you want to add to the current engraving?",
1186 c = yn_function("
\89½
\82©
\8f\91\82«
\89Á
\82¦
\82Ü
\82·
\82©
\81H",
1194 if (c == 'n' || Blind) {
1195 if (oep->engr_type == DUST
1196 || oep->engr_type == ENGR_BLOOD
1197 || oep->engr_type == MARK) {
1200 You("wipe out the message that was %s here.",
1201 (oep->engr_type == DUST)
1202 ? "written in the dust"
1203 : (oep->engr_type == ENGR_BLOOD)
1204 ? "scrawled in blood"
1207 You("%s
\83\81\83b
\83Z
\81[
\83W
\82ð
\90@
\82«
\82Æ
\82Á
\82½
\81D",
1208 (oep->engr_type == DUST)
1209 ? "
\82Ù
\82±
\82è
\82É
\8f\91\82©
\82ê
\82Ä
\82¢
\82é"
1210 : (oep->engr_type == BLOOD)
1211 ? "
\8c\8c\95¶
\8e\9a\82Å
\82È
\82®
\82è
\8f\91\82«
\82³
\82ê
\82Ä
\82¢
\82é"
1212 : "
\8f\91\82©
\82ê
\82Ä
\82¢
\82é");
1215 oep = (struct engr *) 0;
1217 /* Don't delete engr until after we *know* we're engraving
1220 } else if (type == DUST || type == MARK || type == ENGR_BLOOD) {
1222 You("cannot wipe out the message that is %s the %s here.",
1223 oep->engr_type == BURN
1224 ? (is_ice(u.ux, u.uy) ? "melted into" : "burned into")
1226 surface(u.ux, u.uy));
1228 You("%s
\83\81\83b
\83Z
\81[
\83W
\82ð
\90@
\82«
\82Æ
\82ê
\82È
\82©
\82Á
\82½
\81D",
1229 oep->engr_type == BURN
1230 ? (is_ice(u.ux, u.uy) ? "
\8d\8f\82Ü
\82ê
\82Ä
\82¢
\82é" : "
\8fÄ
\82«
\95t
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é")
1231 : "
\8d\8f\82Ü
\82ê
\82Ä
\82¢
\82é");
1234 } else if (type != oep->engr_type || c == 'n') {
1235 if (!Blind || can_reach_floor(TRUE))
1237 You("will overwrite the current message.");
1239 You("
\83\81\83b
\83Z
\81[
\83W
\82ð
\8fã
\8f\91\82«
\82µ
\82æ
\82¤
\82Æ
\82µ
\82½
\81D");
1245 eloc = surface(u.ux, u.uy);
1249 everb = (oep && !eow ? "add to the weird writing on"
1251 everb = (oep && !eow ? "
\8aï
\96
\82È
\95¶
\8e\9a\97ñ
\82É
\8f\91\82«
\89Á
\82¦
\82é"
1253 : "write strangely on");
1255 : "
\8aï
\96
\82È
\95¶
\8e\9a\97ñ
\82ð
\8f\91\82");
1259 everb = (oep && !eow ? "add to the writing in" : "write in");
1261 everb = (oep && !eow ? "
\8f\91\82«
\89Á
\82¦
\82é" : "
\8f\91\82");
1263 eloc = is_ice(u.ux, u.uy) ? "frost" : "dust";
1265 eloc = is_ice(u.ux,u.uy) ? "
\91\9a" : "
\82Ù
\82±
\82è";
1269 everb = (oep && !eow ? "add to the epitaph on" : "engrave on");
1271 everb = (oep && !eow ? "
\95æ
\94è
\96Á
\82ð
\8d\8f\82Ý
\89Á
\82¦
\82é" : "
\95æ
\94è
\96Á
\82ð
\8d\8f\82Þ");
1275 everb = (oep && !eow ? "add to the engraving in" : "engrave in");
1277 everb = (oep && !eow ? "
\8d\8f\82Ý
\89Á
\82¦
\82é" : "
\8d\8f\82Þ");
1281 everb = (oep && !eow
1282 ? (is_ice(u.ux, u.uy) ? "add to the text melted into"
1283 : "add to the text burned into")
1284 : (is_ice(u.ux, u.uy) ? "melt into" : "burn into"));
1286 everb = (oep && !eow
1287 ? ( is_ice(u.ux,u.uy) ? "
\8d\8f\82Ý
\89Á
\82¦
\82é"
1288 : "
\94R
\82¦
\82Ä
\82¢
\82é
\95¶
\8e\9a\82É
\8f\91\82«
\89Á
\82¦
\82é")
1289 : ( is_ice(u.ux,u.uy) ? "
\8d\8f\82Þ" : "
\8fÄ
\88ó
\82ð
\82¢
\82ê
\82é"));
1294 everb = (oep && !eow ? "add to the graffiti on" : "scribble on");
1296 everb = (oep && !eow ? "
\97\8e\8f\91\82É
\8f\91\82«
\89Á
\82¦
\82é" : "
\82Í
\82µ
\82è
\8f\91\82«
\82·
\82é");
1300 everb = (oep && !eow ? "add to the scrawl on" : "scrawl on");
1302 everb = (oep && !eow ? "
\82È
\82®
\82è
\8f\91\82«
\82É
\8f\91\82«
\89Á
\82¦
\82é" : "
\82È
\82®
\82è
\8f\91\82«
\82·
\82é");
1306 /* Tell adventurer what is going on */
1307 if (otmp != &zeroobj)
1309 You("%s the %s with %s.", everb, eloc, doname(otmp));
1311 You("%s
\82Å%s
\82É%s
\81D", doname(otmp), eloc, jpast(everb));
1314 You("%s the %s with your %s.", everb, eloc,
1315 makeplural(body_part(FINGER)));
1317 You("%s
\82Å%s
\82É%s
\81D", body_part(FINGER),
1318 eloc, jpast(everb));
1321 /* Prompt for engraving! */
1323 Sprintf(qbuf, "What do you want to %s the %s here?", everb, eloc);
1325 Sprintf(qbuf,"%s
\82É
\89½
\82Æ%s
\82©
\81H", eloc, jpolite(everb));
1327 /* convert tabs to spaces and condense consecutive spaces to one */
1330 /* Count the actual # of chars engraved not including spaces */
1332 for (sp = ebuf; *sp; sp++)
1336 if (len == 0 || index(ebuf, '\033')) {
1340 pline("%s, then %s.", Tobjnam(otmp, "glow"),
1341 otense(otmp, "fade"));
1343 pline("%s
\82Í
\8bP
\82¢
\82½
\82ª
\81C
\82·
\82®
\82É
\8fÁ
\82¦
\82½
\81D", xname(otmp));
1352 /* A single `x' is the traditional signature of an illiterate person */
1353 if (len != 1 || (!index(ebuf, 'x') && !index(ebuf, 'X')))
1354 u.uconduct.literate++;
1356 /* Mix up engraving if surface or state of mind is unsound.
1357 Note: this won't add or remove any spaces. */
1358 for (sp = ebuf; *sp; sp++) {
1361 if (((type == DUST || type == ENGR_BLOOD) && !rn2(25))
1362 || (Blind && !rn2(11)) || (Confusion && !rn2(7))
1363 || (Stunned && !rn2(4)) || (Hallucination && !rn2(2)))
1365 *sp = ' ' + rnd(96 - 2); /* ASCII '!' thru '~'
1366 (excludes ' ' and DEL) */
1367 #else /*JP:
\93ú
\96{
\8cê
\82Å
\83\89\83\93\83_
\83\80\89» */
1369 if(is_kanji1(ebuf, sp-ebuf))
1371 else if(is_kanji2(ebuf, sp-ebuf))
1372 jrndm_replace(sp-1);
1374 *sp = '!' + rn2(93); /* ASCII-code only */
1379 /* Previous engraving is overwritten */
1382 oep = (struct engr *) 0;
1385 /* Figure out how long it took to engrave, and if player has
1386 * engraved too much.
1390 multi = -(len / 10);
1393 nomovemsg = "You finish your weird engraving.";
1395 nomovemsg = "
\82 \82È
\82½
\82Í
\8aï
\96
\82È
\8d\8f\82Ý
\82ð
\8fI
\82¦
\82½
\81D";
1398 multi = -(len / 10);
1401 nomovemsg = "You finish writing in the dust.";
1403 nomovemsg = "
\82 \82È
\82½
\82Í
\82Ù
\82±
\82è
\82É
\8f\91\82«
\8fI
\82¦
\82½
\81D";
1407 multi = -(len / 10);
1408 if (otmp->oclass == WEAPON_CLASS
1409 && (otmp->otyp != ATHAME || otmp->cursed)) {
1411 maxelen = ((otmp->spe + 3) * 2) + 1;
1412 /* -2 => 3, -1 => 5, 0 => 7, +1 => 9, +2 => 11
1413 * Note: this does not allow a +0 anything (except an athame)
1414 * to engrave "Elbereth" all at once.
1415 * However, you can engrave "Elb", then "ere", then "th".
1418 pline("%s dull.", Yobjnam2(otmp, "get"));
1420 Your("%s
\82Í
\90n
\82±
\82Ú
\82ê
\82µ
\82½
\81D", xname(otmp));
1421 costly_alteration(otmp, COST_DEGRD);
1422 if (len > maxelen) {
1426 otmp->spe -= len >> 1;
1428 otmp->spe -= 1; /* Prevent infinite engraving */
1429 } else if (otmp->oclass == RING_CLASS || otmp->oclass == GEM_CLASS) {
1434 nomovemsg = "You finish engraving.";
1436 nomovemsg = "
\82 \82È
\82½
\82Í
\8d\8f\82Ý
\8fI
\82¦
\82½
\81D";
1439 multi = -(len / 10);
1441 nomovemsg = is_ice(u.ux, u.uy)
1443 ? "You finish melting your message into the ice."
1445 ? "
\95X
\82Ö
\83\81\83b
\83Z
\81[
\83W
\82ð
\8d\8f\82Ý
\8fI
\82¦
\82½
\81D"
1447 : "You finish burning your message into the floor.";
1449 : "
\8f°
\82Ö
\83\81\83b
\83Z
\81[
\83W
\82ð
\8fÄ
\82«
\82¢
\82ê
\8fI
\82¦
\82½
\81D";
1452 multi = -(len / 10);
1453 if (otmp->otyp == MAGIC_MARKER) {
1454 maxelen = otmp->spe * 2; /* one charge / 2 letters */
1455 if (len > maxelen) {
1457 Your("marker dries out.");
1459 Your("
\83}
\81[
\83J
\82Í
\8a£
\82«
\82«
\82Á
\82½
\81D");
1461 multi = -(maxelen / 10);
1463 otmp->spe -= len >> 1;
1465 otmp->spe -= 1; /* Prevent infinite graffiti */
1469 nomovemsg = "You finish defacing the dungeon.";
1471 nomovemsg = "
\82 \82È
\82½
\82Í
\96À
\8b{
\82Ö
\82Ì
\97\8e\8f\91\82ð
\8f\91\82«
\8fI
\82¦
\82½
\81D";
1474 multi = -(len / 10);
1477 nomovemsg = "You finish scrawling.";
1479 nomovemsg = "
\82Í
\82µ
\82è
\8f\91\82«
\82ð
\8f\91\82«
\8fI
\82¦
\82½
\81D";
1483 /* Chop engraving down to size if necessary */
1484 if (len > maxelen) {
1485 for (sp = ebuf; maxelen && *sp; sp++)
1488 if (!maxelen && *sp) {
1489 #if 1 /*JP*//*
\8a¿
\8e\9a\82Ì1
\83o
\83C
\83g
\96Ú
\82¾
\82¯
\82ª
\8ec
\82ç
\82È
\82¢
\82æ
\82¤
\82É*/
1490 if(is_kanji2(ebuf, sp - ebuf))
1496 nomovemsg = "You cannot write any more.";
1498 nomovemsg = "
\82±
\82ê
\88È
\8fã
\89½
\82à
\8f\91\82¯
\82È
\82©
\82Á
\82½
\81D";
1500 You("are only able to write \"%s\".", ebuf);
1502 You("
\81u%s
\81v
\82Æ
\82Ü
\82Å
\82µ
\82©
\8f\91\82¯
\82È
\82©
\82Á
\82½
\81D", ebuf);
1506 if (oep) /* add to existing engraving */
1507 Strcpy(buf, oep->engr_txt);
1508 (void) strncat(buf, ebuf, BUFSZ - (int) strlen(buf) - 1);
1509 /* Put the engraving onto the map */
1510 make_engr_at(u.ux, u.uy, buf, moves - multi, type);
1512 if (post_engr_text[0])
1513 pline("%s", post_engr_text);
1514 if (doblind && !resists_blnd(&youmonst)) {
1516 You("are blinded by the flash!");
1518 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
1519 make_blinded((long) rnd(50), FALSE);
1521 Your1(vision_clears);
1526 /* while loading bones, clean up text which might accidentally
1527 or maliciously disrupt player's terminal when displayed */
1529 sanitize_engravings()
1533 for (ep = head_engr; ep; ep = ep->nxt_engr) {
1534 sanitize_name(ep->engr_txt);
1539 save_engravings(fd, mode)
1542 struct engr *ep, *ep2;
1543 unsigned no_more_engr = 0;
1545 for (ep = head_engr; ep; ep = ep2) {
1547 if (ep->engr_lth && ep->engr_txt[0] && perform_bwrite(mode)) {
1548 bwrite(fd, (genericptr_t) &ep->engr_lth, sizeof ep->engr_lth);
1549 bwrite(fd, (genericptr_t) ep, sizeof (struct engr) + ep->engr_lth);
1551 if (release_data(mode))
1554 if (perform_bwrite(mode))
1555 bwrite(fd, (genericptr_t) &no_more_engr, sizeof no_more_engr);
1556 if (release_data(mode))
1569 mread(fd, (genericptr_t) <h, sizeof lth);
1573 mread(fd, (genericptr_t) ep, sizeof (struct engr) + lth);
1574 ep->nxt_engr = head_engr;
1576 ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
1577 /* Mark as finished for bones levels -- no problem for
1578 * normal levels as the player must have finished engraving
1579 * to be able to move again.
1581 ep->engr_time = moves;
1587 register struct engr *ep;
1589 if (ep == head_engr) {
1590 head_engr = ep->nxt_engr;
1592 register struct engr *ept;
1594 for (ept = head_engr; ept; ept = ept->nxt_engr)
1595 if (ept->nxt_engr == ep) {
1596 ept->nxt_engr = ep->nxt_engr;
1600 impossible("Error in del_engr?");
1607 /* randomly relocate an engraving */
1612 int tx, ty, tryct = 200;
1617 tx = rn1(COLNO - 3, 2);
1619 } while (engr_at(tx, ty) || !goodpos(tx, ty, (struct monst *) 0, 0));
1625 /* Create a headstone at the given location.
1626 * The caller is responsible for newsym(x, y).
1629 make_grave(x, y, str)
1635 /* Can we put a grave here? */
1636 if ((levl[x][y].typ != ROOM && levl[x][y].typ != GRAVE) || t_at(x, y))
1638 /* Make the grave */
1639 levl[x][y].typ = GRAVE;
1640 /* Engrave the headstone */
1643 str = get_rnd_text(EPITAPHFILE, buf);
1644 make_engr_at(x, y, str, 0L, HEADSTONE);