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;
194 You("can't reach the %s.",
196 : (check_pit && can_reach_floor(FALSE))
197 ? "bottom of the pit"
205 register struct rm *lev = &levl[x][y];
207 if (x == u.ux && y == u.uy && u.uswallow && is_animal(u.ustuck->data))
212 else if (IS_AIR(lev->typ) && Is_airlevel(&u.uz))
217 else if (is_pool(x, y))
219 return (Underwater && !Is_waterlevel(&u.uz)) ? "bottom" : "water";
221 return (Underwater && !Is_waterlevel(&u.uz)) ? "
\90\85\82Ì
\92ê" : "
\90\85\92\86";
222 else if (is_ice(x, y))
227 else if (is_lava(x, y))
232 else if (lev->typ == DRAWBRIDGE_DOWN)
237 else if (IS_ALTAR(levl[x][y].typ))
242 else if (IS_GRAVE(levl[x][y].typ))
247 else if (IS_FOUNTAIN(levl[x][y].typ))
252 else if ((IS_ROOM(lev->typ) && !Is_earthlevel(&u.uz))
253 || IS_WALL(lev->typ) || IS_DOOR(lev->typ) || lev->typ == SDOOR)
269 register struct rm *lev = &levl[x][y];
272 /* other room types will no longer exist when we're interested --
273 * see check_special_room()
275 if (*in_rooms(x, y, VAULT))
277 what = "vault's ceiling";
279 what = "
\91q
\8cÉ
\82Ì
\93V
\88ä";
280 else if (*in_rooms(x, y, TEMPLE))
282 what = "temple's ceiling";
284 what = "
\8e\9b\89@
\82Ì
\93V
\88ä";
285 else if (*in_rooms(x, y, SHOPBASE))
287 what = "shop's ceiling";
289 what = "
\93X
\82Ì
\93V
\88ä";
290 else if (Is_waterlevel(&u.uz))
291 /* water plane has no surface; its air bubbles aren't below sky */
293 what = "water above";
295 what = "
\90\85\82Ì
\8fã
\95û";
296 else if (IS_AIR(lev->typ))
303 what = "water's surface";
306 else if ((IS_ROOM(lev->typ) && !Is_earthlevel(&u.uz))
307 || IS_WALL(lev->typ) || IS_DOOR(lev->typ) || lev->typ == SDOOR)
314 what = "rock cavern";
316 what = "
\93´
\8cA
\82Ì
\93V
\88ä";
325 register struct engr *ep = head_engr;
328 if (x == ep->engr_x && y == ep->engr_y)
332 return (struct engr *) 0;
335 /* Decide whether a particular string is engraved at a specified
336 * location; a case-insensitive substring match is used.
337 * Ignore headstones, in case the player names herself "Elbereth".
339 * If strict checking is requested, the word is only considered to be
340 * present if it is intact and is the first word in the engraving.
341 * ("Elbereth burrito" matches; "o Elbereth" does not.)
344 sengr_at(s, x, y, strict)
349 register struct engr *ep = engr_at(x, y);
351 if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= moves) {
352 return strict ? (strncmpi(ep->engr_txt, s, strlen(s)) == 0)
353 : (strstri(ep->engr_txt, s) != 0);
362 if (can_reach_floor(TRUE))
363 wipe_engr_at(u.ux, u.uy, cnt, FALSE);
367 wipe_engr_at(x, y, cnt, magical)
368 xchar x, y, cnt, magical;
370 register struct engr *ep = engr_at(x, y);
372 /* Headstones are indelible */
373 if (ep && ep->engr_type != HEADSTONE) {
374 debugpline1("asked to erode %d characters", cnt);
375 if (ep->engr_type != BURN || is_ice(x, y) || (magical && !rn2(2))) {
376 if (ep->engr_type != DUST && ep->engr_type != ENGR_BLOOD) {
377 cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1;
378 debugpline1("actually eroding %d characters", cnt);
380 wipeout_text(ep->engr_txt, (int) cnt, 0);
381 while (ep->engr_txt[0] == ' ')
383 if (!ep->engr_txt[0])
393 register struct engr *ep = engr_at(x, y);
397 /* Sensing an engraving does not require sight,
398 * nor does it necessarily imply comprehension (literacy).
400 if (ep && ep->engr_txt[0]) {
401 switch (ep->engr_type) {
406 pline("%s is written here in the %s.", Something,
407 is_ice(x, y) ? "frost" : "dust");
409 pline("
\89½
\82©
\82Ì
\95¶
\8e\9a\82ª%s
\82É
\8f\91\82¢
\82Ä
\82 \82é
\81D",
410 is_ice(x, y) ? "
\91\9a" : "
\82Ù
\82±
\82è");
416 if (!Blind || can_reach_floor(TRUE)) {
419 pline("%s is engraved here on the %s.", Something,
421 pline("
\89½
\82©
\82Ì
\95¶
\8e\9a\82ª%s
\82É
\8d\8f\82Ü
\82ê
\82Ä
\82¢
\82é
\81D",
426 if (!Blind || can_reach_floor(TRUE)) {
429 pline("Some text has been %s into the %s here.",
430 is_ice(x, y) ? "melted" : "burned", surface(x, y));
432 pline("
\89½
\82©
\82Ì
\95¶
\8e\9a\82ª%s%s
\82¢
\82é
\81D",
434 is_ice(x,y) ? "
\82É
\8d\8f\82Ü
\82ê
\82Ä" : "
\82É
\8fÄ
\82«
\95t
\82¯
\82ç
\82ê
\82Ä");
442 pline("There's some graffiti on the %s here.", surface(x, y));
444 pline("%s
\82É
\97\8e\8f\91\82ª
\82 \82é
\81D", surface(x,y));
448 /* "It's a message! Scrawled in blood!"
450 * "It says... `See you next Wednesday.'" -- Thriller
455 You_see("a message scrawled in blood here.");
457 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");
461 impossible("%s is written in a very strange way.", Something);
467 unsigned maxelen = BUFSZ - sizeof("You feel the words: \"\". ");
469 unsigned maxelen = BUFSZ - sizeof("
\82 \82È
\82½
\82Í
\8e\9f\82Ì
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81F
\81u
\81v");
470 if (strlen(ep->engr_txt) > maxelen) {
471 (void) strncpy(buf, ep->engr_txt, (int) maxelen);
477 You("%s: \"%s\".", (Blind) ? "feel the words" : "read", et);
479 You("%s
\81F
\81u%s
\81v", (Blind) ? "
\8e\9f\82Ì
\82æ
\82¤
\82É
\8a´
\82¶
\82½" : "
\93Ç
\82ñ
\82¾", et);
487 make_engr_at(x, y, s, e_time, e_type)
495 if ((ep = engr_at(x, y)) != 0)
497 ep = newengr(strlen(s) + 1);
498 ep->nxt_engr = head_engr;
502 ep->engr_txt = (char *) (ep + 1);
503 Strcpy(ep->engr_txt, s);
504 /* engraving Elbereth shows wisdom */
505 if (!in_mklev && !strcmp(s, "Elbereth"))
506 exercise(A_WIS, TRUE);
507 ep->engr_time = e_time;
508 ep->engr_type = e_type > 0 ? e_type : rnd(N_ENGRAVE - 1);
509 ep->engr_lth = strlen(s) + 1;
512 /* delete any engraving at location <x,y> */
517 register struct engr *ep = engr_at(x, y);
524 * freehand - returns true if player has a free hand
529 return (!uwep || !welded(uwep)
530 || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
533 static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
534 TOOL_CLASS, WEAPON_CLASS,
535 WAND_CLASS, GEM_CLASS,
538 /* Mohs' Hardness Scale:
539 * 1 - Talc 6 - Orthoclase
540 * 2 - Gypsum 7 - Quartz
541 * 3 - Calcite 8 - Topaz
542 * 4 - Fluorite 9 - Corundum
543 * 5 - Apatite 10 - Diamond
545 * Since granite is an igneous rock hardness ~ 7, anything >= 8 should
546 * probably be able to scratch the rock.
547 * Devaluation of less hard gems is not easily possible because obj struct
548 * does not contain individual oc_cost currently. 7/91
550 * steel - 5-8.5 (usu. weapon)
551 * diamond - 10 * jade - 5-6 (nephrite)
552 * ruby - 9 (corundum) * turquoise - 5-6
553 * sapphire - 9 (corundum) * opal - 5-6
554 * topaz - 8 * glass - ~5.5
555 * emerald - 7.5-8 (beryl) * dilithium - 4-5??
556 * aquamarine - 7.5-8 (beryl) * iron - 4-5
557 * garnet - 7.25 (var. 6.5-8) * fluorite - 4
558 * agate - 7 (quartz) * brass - 3-4
559 * amethyst - 7 (quartz) * gold - 2.5-3
560 * jasper - 7 (quartz) * silver - 2.5-3
561 * onyx - 7 (quartz) * copper - 2.5-3
562 * moonstone - 6 (orthoclase) * amber - 2-2.5
565 /* return 1 if action took 1 (or more) moves, 0 if error or aborted */
569 boolean dengr = FALSE; /* TRUE if we wipe out the current engraving */
570 boolean doblind = FALSE; /* TRUE if engraving blinds the player */
571 boolean doknown = FALSE; /* TRUE if we identify the stylus */
572 boolean eow = FALSE; /* TRUE if we are overwriting oep */
573 boolean jello = FALSE; /* TRUE if we are engraving in slime */
574 boolean ptext = TRUE; /* TRUE if we must prompt for engrave text */
575 boolean teleengr = FALSE; /* TRUE if we move the old engraving */
576 boolean zapwand = FALSE; /* TRUE if we remove a wand charge */
577 xchar type = DUST; /* Type of engraving made */
578 char buf[BUFSZ]; /* Buffer for final/poly engraving text */
579 char ebuf[BUFSZ]; /* Buffer for initial engraving text */
580 char fbuf[BUFSZ]; /* Buffer for "your fingers" */
581 char qbuf[QBUFSZ]; /* Buffer for query text */
582 char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
583 const char *everb; /* Present tense of engraving type */
584 const char *eloc; /* Where the engraving is (ie dust/floor/...) */
585 char *sp; /* Place holder for space count of engr text */
586 int len; /* # of nonspace chars of new engraving text */
587 int maxelen; /* Max allowable length of engraving text */
588 struct engr *oep = engr_at(u.ux, u.uy);
589 /* The current engraving */
590 struct obj *otmp; /* Object selected with which to engrave */
593 multi = 0; /* moves consumed */
594 nomovemsg = (char *) 0; /* occupation end message */
598 post_engr_text[0] = (char) 0;
600 if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
603 /* Can the adventurer engrave at all? */
606 if (is_animal(u.ustuck->data)) {
608 pline("What would you write? \"Jonah was here\"?");
610 pline("
\89½
\82ð
\8f\91\82
\82ñ
\82¾
\82¢
\81H
\81u
\83\88\83i
\82Í
\82±
\82±
\82É
\82¢
\82é
\81v
\81H");
612 } else if (is_whirly(u.ustuck->data)) {
613 cant_reach_floor(u.ux, u.uy, FALSE, FALSE);
617 } else if (is_lava(u.ux, u.uy)) {
619 You_cant("write on the %s!", surface(u.ux, u.uy));
621 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81D", surface(u.ux,u.uy));
623 } else if (is_pool(u.ux, u.uy) || IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
625 You_cant("write on the %s!", surface(u.ux, u.uy));
627 You("%s
\82É
\82Í
\8f\91\82¯
\82È
\82¢
\81I", surface(u.ux, u.uy));
630 if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) /* in bubble */) {
632 You_cant("write in thin air!");
634 You("
\8bó
\92\86\82É
\82Í
\8f\91\82¯
\82È
\82¢
\81I");
636 } else if (!accessible(u.ux, u.uy)) {
637 /* stone, tree, wall, secret corridor, pool, lava, bars */
639 You_cant("write here.");
641 You_cant("
\82±
\82±
\82É
\82Í
\8f\91\82¯
\82È
\82¢
\81D");
644 if (cantwield(youmonst.data)) {
646 You_cant("even hold anything!");
648 You("
\89½
\82©
\82ð
\8e\9d\82Â
\82±
\82Æ
\82·
\82ç
\82Å
\82«
\82È
\82¢
\81I");
651 if (check_capacity((char *) 0))
654 /* One may write with finger, or weapon, or wand, or..., or...
655 * Edited by GAN 10/20/86 so as not to change weapon wielded.
658 otmp = getobj(styluses, "write with");
659 if (!otmp) /* otmp == zeroobj if fingers */
662 if (otmp == &zeroobj) {
663 Strcat(strcpy(fbuf, "your "), makeplural(body_part(FINGER)));
666 writer = yname(otmp);
668 /* There's no reason you should be able to write with a wand
669 * while both your hands are tied up.
671 if (!freehand() && otmp != uwep && !otmp->owornmask) {
673 You("have no free %s to write with!", body_part(HAND));
675 pline("%s
\82Ì
\8e©
\97R
\82ª
\8cø
\82©
\82È
\82¢
\82Ì
\82Å
\8f\91\82¯
\82È
\82¢
\81I", body_part(HAND));
681 You("tickle %s with %s.", mon_nam(u.ustuck), writer);
683 You("%s
\82Å%s
\82ð
\82
\82·
\82®
\82Á
\82½
\81D", writer, mon_nam(u.ustuck));
685 Your("message dissolves...");
687 Your("
\83\81\83b
\83Z
\81[
\83W
\82Í
\8fÁ
\82¦
\82½
\81D
\81D
\81D");
690 if (otmp->oclass != WAND_CLASS && !can_reach_floor(TRUE)) {
691 cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
694 if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
696 You("make a motion towards the altar with %s.", writer);
698 You("%s
\82ð
\8eg
\82Á
\82Ä
\8dÕ
\92d
\82É
\8f\91\82±
\82¤
\82Æ
\82µ
\82½
\81D", writer);
699 altar_wrath(u.ux, u.uy);
702 if (IS_GRAVE(levl[u.ux][u.uy].typ)) {
703 if (otmp == &zeroobj) { /* using only finger */
705 You("would only make a small smudge on the %s.",
707 You("
\82Í%s
\82É
\8f¬
\82³
\82È
\82µ
\82Ý
\82ð
\82Â
\82¯
\82é
\82±
\82Æ
\82µ
\82©
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D",
708 surface(u.ux, u.uy));
710 } else if (!levl[u.ux][u.uy].disturbed) {
712 You("disturb the undead!");
714 You("
\95s
\8e\80\82Ì
\8eÒ
\82Ì
\96°
\82è
\82ð
\96W
\82°
\82½
\81I");
715 levl[u.ux][u.uy].disturbed = 1;
716 (void) makemon(&mons[PM_GHOUL], u.ux, u.uy, NO_MM_FLAGS);
717 exercise(A_WIS, FALSE);
724 switch (otmp->oclass) {
732 /* "diamond" rings and others should work */
734 /* diamonds & other hard gems should work */
735 if (objects[otmp->otyp].oc_tough) {
741 if (is_boots(otmp)) {
746 /* Objects too large to engrave with */
750 You_cant("engrave with such a large object!");
752 pline("
\82»
\82ñ
\82È
\91å
\82«
\82È
\82à
\82Ì
\82ð
\8eg
\82Á
\82Ä
\95¶
\8e\9a\82ð
\8d\8f\82ß
\82È
\82¢
\81I");
755 /* Objects too silly to engrave with */
760 pline("%s would get %s.", Yname2(otmp),
761 is_ice(u.ux, u.uy) ? "all frosty" : "too dirty");
763 Your("%s
\82Í%s
\82È
\82Á
\82½
\81D", xname(otmp),
764 is_ice(u.ux,u.uy) ? "
\91\9a\82¾
\82ç
\82¯
\82É" : "
\89\98\82È
\82");
768 case RANDOM_CLASS: /* This should mean fingers */
771 /* The charge is removed from the wand before prompting for
772 * the engraving text, because all kinds of setup decisions
773 * and pre-engraving messages are based upon knowing what type
774 * of engraving the wand is going to do. Also, the player
775 * will have potentially seen "You wrest .." message, and
776 * therefore will know they are using a charge.
779 if (zappable(otmp)) {
781 if (otmp->cursed && !rn2(WAND_BACKFIRE_CHANCE)) {
782 wand_explode(otmp, 0);
786 if (!can_reach_floor(TRUE))
789 switch (otmp->otyp) {
795 case WAN_SECRET_DOOR_DETECTION:
796 case WAN_CREATE_MONSTER:
798 case WAN_ENLIGHTENMENT:
801 /* IMMEDIATE wands */
802 /* If wand is "IMMEDIATE", remember to affect the
803 * previous engraving even if turning to dust.
806 Strcpy(post_engr_text,
808 "The wand unsuccessfully fights your attempt to write!");
810 "
\82 \82È
\82½
\82ª
\8f\91\82±
\82¤
\82Æ
\82·
\82é
\82Æ
\8fñ
\82Í
\92ï
\8dR
\82µ
\82½
\81I");
812 case WAN_SLOW_MONSTER:
815 Sprintf(post_engr_text, "The bugs on the %s slow down!",
817 Sprintf(post_engr_text, "%s
\82Ì
\8fã
\82Ì
\92\8e\82Ì
\93®
\82«
\82ª
\92x
\82
\82È
\82Á
\82½
\81I",
818 surface(u.ux, u.uy));
821 case WAN_SPEED_MONSTER:
824 Sprintf(post_engr_text, "The bugs on the %s speed up!",
826 Sprintf(post_engr_text, "%s
\82Ì
\8fã
\82Ì
\92\8e\82Ì
\93®
\82«
\82ª
\91¬
\82
\82È
\82Á
\82½
\81I",
827 surface(u.ux, u.uy));
833 type = (xchar) 0; /* random */
834 (void) random_engraving(buf);
840 case WAN_UNDEAD_TURNING:
846 case WAN_MAGIC_MISSILE:
849 Sprintf(post_engr_text,
851 "The %s is riddled by bullet holes!",
853 "%s
\82Í
\8eU
\92e
\82Å
\8d×
\82©
\82¢
\8c\8a\82¾
\82ç
\82¯
\82É
\82È
\82Á
\82½
\81I",
854 surface(u.ux, u.uy));
857 /* can't tell sleep from death - Eric Backus */
862 Sprintf(post_engr_text, "The bugs on the %s stop moving!",
864 Sprintf(post_engr_text, "%s
\82Ì
\8fã
\82Ì
\92\8e\82Ì
\93®
\82«
\82ª
\8e~
\82Ü
\82Á
\82½
\81I",
865 surface(u.ux, u.uy));
870 Strcpy(post_engr_text,
872 "A few ice cubes drop from the wand.");
874 "
\95X
\82Ì
\82©
\82¯
\82ç
\82ª
\8fñ
\82©
\82ç
\82±
\82Ú
\82ê
\97\8e\82¿
\82½
\81D");
875 if (!oep || (oep->engr_type != BURN))
877 case WAN_CANCELLATION:
878 case WAN_MAKE_INVISIBLE:
879 if (oep && oep->engr_type != HEADSTONE) {
882 pline_The("engraving on the %s vanishes!",
884 pline("%s
\82Ì
\8fã
\82Ì
\95¶
\8e\9a\82Í
\8fÁ
\82¦
\82½
\81I",
885 surface(u.ux, u.uy));
889 case WAN_TELEPORTATION:
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 /* type = ENGRAVE wands */
904 if (!objects[otmp->otyp].oc_name_known) {
907 pline("This %s is a wand of digging!", xname(otmp));
909 pline("
\82±
\82ê
\82Í
\8c\8a\8c@
\82è
\82Ì
\8fñ
\82¾
\81I");
913 Strcpy(post_engr_text,
915 ? "You hear drilling!"
916 : IS_GRAVE(levl[u.ux][u.uy].typ)
917 ? "Chips fly out from the headstone."
919 ? "Ice chips fly up from the ice surface!"
920 : (level.locations[u.ux][u.uy].typ
922 ? "Splinters fly up from the bridge."
923 : "Gravel flies up from the floor.");
925 Strcpy(post_engr_text,
927 ? "
\8c\8a\82ª
\8aJ
\82
\89¹
\82ð
\95·
\82¢
\82½
\81I"
928 : IS_GRAVE(levl[u.ux][u.uy].typ)
929 ? "
\95æ
\90Î
\82©
\82ç
\94j
\95Ð
\82ª
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D"
931 ? "
\95X
\82Ì
\95\
\96Ê
\82©
\82ç
\95X
\82Ì
\82©
\82¯
\82ç
\82ª
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D"
932 : (level.locations[u.ux][u.uy].typ
934 ? "
\94j
\95Ð
\82ª
\8b´
\82©
\82ç
\95\91\82¢
\82 \82ª
\82Á
\82½
\81D"
935 : "
\8d»
\97\98\82ª
\8f°
\82©
\82ç
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D");
938 /* type = BURN wands */
942 if (!objects[otmp->otyp].oc_name_known) {
945 pline("This %s is a wand of fire!", xname(otmp));
947 pline("
\82±
\82ê
\82Í
\89\8a\82Ì
\8fñ
\82¾
\81I");
951 Strcpy(post_engr_text, Blind ? "You feel the wand heat up."
952 : "Flames fly from the wand.");
954 Strcpy(post_engr_text, Blind ? "
\8fñ
\82ª
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D"
955 : "
\89\8a\82ª
\8fñ
\82©
\82ç
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D");
961 if (!objects[otmp->otyp].oc_name_known) {
964 pline("This %s is a wand of lightning!", xname(otmp));
966 pline("
\82±
\82ê
\82Í
\97\8b\82Ì
\8fñ
\82¾
\81I");
971 Strcpy(post_engr_text, "Lightning arcs from the wand.");
973 Strcpy(post_engr_text, "
\89Î
\89Ô
\82ª
\8fñ
\82©
\82ç
\94ò
\82Ñ
\8eU
\82Á
\82½
\81D");
977 Strcpy(post_engr_text, "You hear crackling!");
979 Strcpy(post_engr_text, "
\83p
\83`
\83p
\83`
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81I");
982 /* type = MARK wands */
983 /* type = ENGR_BLOOD wands */
985 } else { /* end if zappable */
986 /* failing to wrest one last charge takes time */
987 ptext = FALSE; /* use "early exit" below, return 1 */
988 /* give feedback here if we won't be getting the
989 "can't reach floor" message below */
990 if (can_reach_floor(TRUE)) {
991 /* cancelled wand turns to dust */
994 /* empty wand just doesn't write */
997 pline_The("wand is too worn out to engrave.");
999 pline_The("
\8fñ
\82Í
\95¶
\8e\9a\82ð
\8d\8f\82Þ
\82É
\82Í
\8eg
\82¢
\82·
\82¬
\82Ä
\82¢
\82é
\81D");
1005 if (is_blade(otmp)) {
1006 if ((int) otmp->spe > -3)
1010 pline("%s too dull for engraving.", Yobjnam2(otmp, "are"));
1012 pline("%s
\82Í
\90n
\82ª
\83{
\83\8d\83{
\83\8d\82Å
\81C
\95¶
\8e\9a\82ð
\92¤
\82ê
\82È
\82¢
\81D", xname(otmp));
1017 if (otmp == ublindf) {
1020 "That is a bit difficult to engrave with, don't you think?");
1022 "
\82¿
\82å
\82Á
\82Æ
\82»
\82ê
\82Å
\92¤
\82é
\82Ì
\82Í
\91å
\95Ï
\82¾
\82ë
\82¤
\81C
\82»
\82¤
\8ev
\82í
\82È
\82¢
\81H");
1025 switch (otmp->otyp) {
1029 Your("marker has dried out.");
1031 Your("
\83}
\81[
\83J
\82Í
\8a£
\82«
\82«
\82Á
\82½
\81D");
1036 /* Can't really engrave with a towel */
1039 if (oep->engr_type == DUST
1040 || oep->engr_type == ENGR_BLOOD
1041 || oep->engr_type == MARK) {
1042 if (is_wet_towel(otmp))
1043 dry_a_towel(otmp, -1, TRUE);
1046 You("wipe out the message here.");
1048 You("
\83\81\83b
\83Z
\81[
\83W
\82ð
\90@
\82«
\82Æ
\82Á
\82½
\81D");
1051 pline("%s %s.", Yobjnam2(otmp, "get"),
1052 is_ice(u.ux, u.uy) ? "frosty" : "dusty");
1054 pline("%s
\82Í%s
\82É
\82È
\82Á
\82½
\81D", xname(otmp),
1055 is_ice(u.ux,u.uy) ? "
\91\9a\82¾
\82ç
\82¯" : "
\82Ù
\82±
\82è
\82Ü
\82Ý
\82ê");
1060 pline("%s can't wipe out this engraving.", Yname2(otmp));
1062 pline("
\82±
\82Ì
\95¶
\8e\9a\82Í%s
\82Å
\82Í
\90@
\82«
\82Æ
\82ê
\82È
\82¢
\81D", xname(otmp));
1065 pline("%s %s.", Yobjnam2(otmp, "get"),
1066 is_ice(u.ux, u.uy) ? "frosty" : "dusty");
1068 pline("%s
\82Í%s
\82É
\82È
\82Á
\82½
\81D", xname(otmp),
1069 is_ice(u.ux,u.uy) ? "
\91\9a\82¾
\82ç
\82¯" : "
\82Ù
\82±
\82è
\82Ü
\82Ý
\82ê");
1080 pline("Writing a poison pen letter??");
1082 pline("
\82Ó
\82Þ
\81D
\82±
\82ê
\82±
\82»
\96{
\93\96\82Ì
\93Å
\90ã
\82¾
\81D");
1087 impossible("You're engraving with an illegal object!");
1091 if (IS_GRAVE(levl[u.ux][u.uy].typ)) {
1092 if (type == ENGRAVE || type == 0) {
1095 /* ensures the "cannot wipe out" case */
1104 * End of implement setup
1107 /* Identify stylus */
1110 if (objects[otmp->otyp].oc_name_known)
1111 more_experienced(0, 10);
1115 oep = (struct engr *) 0;
1119 oep = (struct engr *) 0;
1121 /* Something has changed the engraving here */
1123 make_engr_at(u.ux, u.uy, buf, moves, type);
1125 pline_The("engraving now reads: \"%s\".", buf);
1127 pline("
\8d\8f\82Ü
\82ê
\82½
\95¶
\8e\9a\82ð
\93Ç
\82ñ
\82¾
\81F
\81u%s
\81v
\81D", buf);
1130 if (zapwand && (otmp->spe < 0)) {
1132 pline("%s %sturns to dust.", The(xname(otmp)),
1133 Blind ? "" : "glows violently, then ");
1135 pline("%s
\82Í%s
\82¿
\82è
\82Æ
\82È
\82Á
\82½
\81D", xname(otmp),
1136 Blind ? "" : "
\8c\83\82µ
\82
\8bP
\82«
\81C");
1138 if (!IS_GRAVE(levl[u.ux][u.uy].typ))
1141 "are not going to get anywhere trying to write in the %s with your dust.",
1142 is_ice(u.ux, u.uy) ? "frost" : "dust");
1145 "
\90o
\82Å%s
\82É
\89½
\82©
\8f\91\82±
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D",
1146 is_ice(u.ux,u.uy) ? "
\95X" : "
\82Ù
\82±
\82è");
1149 otmp = 0; /* wand is now gone */
1152 /* Early exit for some implements. */
1154 if (otmp && otmp->oclass == WAND_CLASS && !can_reach_floor(TRUE))
1155 cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
1159 * Special effects should have deleted the current engraving (if
1163 register char c = 'n';
1165 /* Give player the choice to add to engraving. */
1166 if (type == HEADSTONE) {
1167 /* no choice, only append */
1169 } else if (type == oep->engr_type
1170 && (!Blind || oep->engr_type == BURN
1171 || oep->engr_type == ENGRAVE)) {
1173 c = yn_function("Do you want to add to the current engraving?",
1175 c = yn_function("
\89½
\82©
\8f\91\82«
\89Á
\82¦
\82Ü
\82·
\82©
\81H",
1183 if (c == 'n' || Blind) {
1184 if (oep->engr_type == DUST
1185 || oep->engr_type == ENGR_BLOOD
1186 || oep->engr_type == MARK) {
1189 You("wipe out the message that was %s here.",
1190 (oep->engr_type == DUST)
1191 ? "written in the dust"
1192 : (oep->engr_type == ENGR_BLOOD)
1193 ? "scrawled in blood"
1196 You("%s
\83\81\83b
\83Z
\81[
\83W
\82ð
\90@
\82«
\82Æ
\82Á
\82½
\81D",
1197 (oep->engr_type == DUST)
1198 ? "
\82Ù
\82±
\82è
\82É
\8f\91\82©
\82ê
\82Ä
\82¢
\82é"
1199 : (oep->engr_type == BLOOD)
1200 ? "
\8c\8c\95¶
\8e\9a\82Å
\82È
\82®
\82è
\8f\91\82«
\82³
\82ê
\82Ä
\82¢
\82é"
1201 : "
\8f\91\82©
\82ê
\82Ä
\82¢
\82é");
1204 oep = (struct engr *) 0;
1206 /* Don't delete engr until after we *know* we're engraving
1209 } else if (type == DUST || type == MARK || type == ENGR_BLOOD) {
1211 You("cannot wipe out the message that is %s the %s here.",
1212 oep->engr_type == BURN
1213 ? (is_ice(u.ux, u.uy) ? "melted into" : "burned into")
1215 surface(u.ux, u.uy));
1217 You("%s
\83\81\83b
\83Z
\81[
\83W
\82ð
\90@
\82«
\82Æ
\82ê
\82È
\82©
\82Á
\82½
\81D",
1218 oep->engr_type == BURN
1219 ? (is_ice(u.ux, u.uy) ? "
\8d\8f\82Ü
\82ê
\82Ä
\82¢
\82é" : "
\8fÄ
\82«
\95t
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é")
1220 : "
\8d\8f\82Ü
\82ê
\82Ä
\82¢
\82é");
1223 } else if (type != oep->engr_type || c == 'n') {
1224 if (!Blind || can_reach_floor(TRUE))
1226 You("will overwrite the current message.");
1228 You("
\83\81\83b
\83Z
\81[
\83W
\82ð
\8fã
\8f\91\82«
\82µ
\82æ
\82¤
\82Æ
\82µ
\82½
\81D");
1234 eloc = surface(u.ux, u.uy);
1238 everb = (oep && !eow ? "add to the weird writing on"
1240 everb = (oep && !eow ? "
\8aï
\96
\82È
\95¶
\8e\9a\97ñ
\82É
\8f\91\82«
\89Á
\82¦
\82é"
1242 : "write strangely on");
1244 : "
\8aï
\96
\82È
\95¶
\8e\9a\97ñ
\82ð
\8f\91\82");
1248 everb = (oep && !eow ? "add to the writing in" : "write in");
1250 everb = (oep && !eow ? "
\8f\91\82«
\89Á
\82¦
\82é" : "
\8f\91\82");
1252 eloc = is_ice(u.ux, u.uy) ? "frost" : "dust";
1254 eloc = is_ice(u.ux,u.uy) ? "
\91\9a" : "
\82Ù
\82±
\82è";
1258 everb = (oep && !eow ? "add to the epitaph on" : "engrave on");
1260 everb = (oep && !eow ? "
\95æ
\94è
\96Á
\82ð
\8d\8f\82Ý
\89Á
\82¦
\82é" : "
\95æ
\94è
\96Á
\82ð
\8d\8f\82Þ");
1264 everb = (oep && !eow ? "add to the engraving in" : "engrave in");
1266 everb = (oep && !eow ? "
\8d\8f\82Ý
\89Á
\82¦
\82é" : "
\8d\8f\82Þ");
1270 everb = (oep && !eow
1271 ? (is_ice(u.ux, u.uy) ? "add to the text melted into"
1272 : "add to the text burned into")
1273 : (is_ice(u.ux, u.uy) ? "melt into" : "burn into"));
1275 everb = (oep && !eow
1276 ? ( is_ice(u.ux,u.uy) ? "
\8d\8f\82Ý
\89Á
\82¦
\82é"
1277 : "
\94R
\82¦
\82Ä
\82¢
\82é
\95¶
\8e\9a\82É
\8f\91\82«
\89Á
\82¦
\82é")
1278 : ( is_ice(u.ux,u.uy) ? "
\8d\8f\82Þ" : "
\8fÄ
\88ó
\82ð
\82¢
\82ê
\82é"));
1283 everb = (oep && !eow ? "add to the graffiti on" : "scribble on");
1285 everb = (oep && !eow ? "
\97\8e\8f\91\82É
\8f\91\82«
\89Á
\82¦
\82é" : "
\82Í
\82µ
\82è
\8f\91\82«
\82·
\82é");
1289 everb = (oep && !eow ? "add to the scrawl on" : "scrawl on");
1291 everb = (oep && !eow ? "
\82È
\82®
\82è
\8f\91\82«
\82É
\8f\91\82«
\89Á
\82¦
\82é" : "
\82È
\82®
\82è
\8f\91\82«
\82·
\82é");
1295 /* Tell adventurer what is going on */
1296 if (otmp != &zeroobj)
1298 You("%s the %s with %s.", everb, eloc, doname(otmp));
1300 You("%s
\82Å%s
\82É%s
\81D", doname(otmp), eloc, jpast(everb));
1303 You("%s the %s with your %s.", everb, eloc,
1304 makeplural(body_part(FINGER)));
1306 You("%s
\82Å%s
\82É%s
\81D", body_part(FINGER),
1307 eloc, jpast(everb));
1310 /* Prompt for engraving! */
1312 Sprintf(qbuf, "What do you want to %s the %s here?", everb, eloc);
1314 Sprintf(qbuf,"%s
\82É
\89½
\82Æ%s
\82©
\81H", eloc, jpolite(everb));
1316 /* convert tabs to spaces and condense consecutive spaces to one */
1319 /* Count the actual # of chars engraved not including spaces */
1321 for (sp = ebuf; *sp; sp++)
1325 if (len == 0 || index(ebuf, '\033')) {
1329 pline("%s, then %s.", Tobjnam(otmp, "glow"),
1330 otense(otmp, "fade"));
1332 pline("%s
\82Í
\8bP
\82¢
\82½
\82ª
\81C
\82·
\82®
\82É
\8fÁ
\82¦
\82½
\81D", xname(otmp));
1341 /* A single `x' is the traditional signature of an illiterate person */
1342 if (len != 1 || (!index(ebuf, 'x') && !index(ebuf, 'X')))
1343 u.uconduct.literate++;
1345 /* Mix up engraving if surface or state of mind is unsound.
1346 Note: this won't add or remove any spaces. */
1347 for (sp = ebuf; *sp; sp++) {
1350 if (((type == DUST || type == ENGR_BLOOD) && !rn2(25))
1351 || (Blind && !rn2(11)) || (Confusion && !rn2(7))
1352 || (Stunned && !rn2(4)) || (Hallucination && !rn2(2)))
1354 *sp = ' ' + rnd(96 - 2); /* ASCII '!' thru '~'
1355 (excludes ' ' and DEL) */
1356 #else /*JP:
\93ú
\96{
\8cê
\82Å
\83\89\83\93\83_
\83\80\89» */
1358 if(is_kanji1(ebuf, sp-ebuf))
1360 else if(is_kanji2(ebuf, sp-ebuf))
1361 jrndm_replace(sp-1);
1363 *sp = '!' + rn2(93); /* ASCII-code only */
1368 /* Previous engraving is overwritten */
1371 oep = (struct engr *) 0;
1374 /* Figure out how long it took to engrave, and if player has
1375 * engraved too much.
1379 multi = -(len / 10);
1382 nomovemsg = "You finish your weird engraving.";
1384 nomovemsg = "
\82 \82È
\82½
\82Í
\8aï
\96
\82È
\8d\8f\82Ý
\82ð
\8fI
\82¦
\82½
\81D";
1387 multi = -(len / 10);
1390 nomovemsg = "You finish writing in the dust.";
1392 nomovemsg = "
\82 \82È
\82½
\82Í
\82Ù
\82±
\82è
\82É
\8f\91\82«
\8fI
\82¦
\82½
\81D";
1396 multi = -(len / 10);
1397 if (otmp->oclass == WEAPON_CLASS
1398 && (otmp->otyp != ATHAME || otmp->cursed)) {
1400 maxelen = ((otmp->spe + 3) * 2) + 1;
1401 /* -2 => 3, -1 => 5, 0 => 7, +1 => 9, +2 => 11
1402 * Note: this does not allow a +0 anything (except an athame)
1403 * to engrave "Elbereth" all at once.
1404 * However, you can engrave "Elb", then "ere", then "th".
1407 pline("%s dull.", Yobjnam2(otmp, "get"));
1409 Your("%s
\82Í
\90n
\82±
\82Ú
\82ê
\82µ
\82½
\81D", xname(otmp));
1410 costly_alteration(otmp, COST_DEGRD);
1411 if (len > maxelen) {
1415 otmp->spe -= len >> 1;
1417 otmp->spe -= 1; /* Prevent infinite engraving */
1418 } else if (otmp->oclass == RING_CLASS || otmp->oclass == GEM_CLASS) {
1423 nomovemsg = "You finish engraving.";
1425 nomovemsg = "
\82 \82È
\82½
\82Í
\8d\8f\82Ý
\8fI
\82¦
\82½
\81D";
1428 multi = -(len / 10);
1430 nomovemsg = is_ice(u.ux, u.uy)
1432 ? "You finish melting your message into the ice."
1434 ? "
\95X
\82Ö
\83\81\83b
\83Z
\81[
\83W
\82ð
\8d\8f\82Ý
\8fI
\82¦
\82½
\81D"
1436 : "You finish burning your message into the floor.";
1438 : "
\8f°
\82Ö
\83\81\83b
\83Z
\81[
\83W
\82ð
\8fÄ
\82«
\82¢
\82ê
\8fI
\82¦
\82½
\81D";
1441 multi = -(len / 10);
1442 if (otmp->otyp == MAGIC_MARKER) {
1443 maxelen = otmp->spe * 2; /* one charge / 2 letters */
1444 if (len > maxelen) {
1446 Your("marker dries out.");
1448 Your("
\83}
\81[
\83J
\82Í
\8a£
\82«
\82«
\82Á
\82½
\81D");
1450 multi = -(maxelen / 10);
1452 otmp->spe -= len >> 1;
1454 otmp->spe -= 1; /* Prevent infinite graffiti */
1458 nomovemsg = "You finish defacing the dungeon.";
1460 nomovemsg = "
\82 \82È
\82½
\82Í
\96À
\8b{
\82Ö
\82Ì
\97\8e\8f\91\82ð
\8f\91\82«
\8fI
\82¦
\82½
\81D";
1463 multi = -(len / 10);
1466 nomovemsg = "You finish scrawling.";
1468 nomovemsg = "
\82Í
\82µ
\82è
\8f\91\82«
\82ð
\8f\91\82«
\8fI
\82¦
\82½
\81D";
1472 /* Chop engraving down to size if necessary */
1473 if (len > maxelen) {
1474 for (sp = ebuf; maxelen && *sp; sp++)
1477 if (!maxelen && *sp) {
1478 #if 1 /*JP*//*
\8a¿
\8e\9a\82Ì1
\83o
\83C
\83g
\96Ú
\82¾
\82¯
\82ª
\8ec
\82ç
\82È
\82¢
\82æ
\82¤
\82É*/
1479 if(is_kanji2(ebuf, sp - ebuf))
1485 nomovemsg = "You cannot write any more.";
1487 nomovemsg = "
\82±
\82ê
\88È
\8fã
\89½
\82à
\8f\91\82¯
\82È
\82©
\82Á
\82½
\81D";
1489 You("are only able to write \"%s\".", ebuf);
1491 You("
\81u%s
\81v
\82Æ
\82Ü
\82Å
\82µ
\82©
\8f\91\82¯
\82È
\82©
\82Á
\82½
\81D", ebuf);
1495 if (oep) /* add to existing engraving */
1496 Strcpy(buf, oep->engr_txt);
1497 (void) strncat(buf, ebuf, BUFSZ - (int) strlen(buf) - 1);
1498 /* Put the engraving onto the map */
1499 make_engr_at(u.ux, u.uy, buf, moves - multi, type);
1501 if (post_engr_text[0])
1502 pline("%s", post_engr_text);
1503 if (doblind && !resists_blnd(&youmonst)) {
1505 You("are blinded by the flash!");
1507 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81I");
1508 make_blinded((long) rnd(50), FALSE);
1510 Your1(vision_clears);
1515 /* while loading bones, clean up text which might accidentally
1516 or maliciously disrupt player's terminal when displayed */
1518 sanitize_engravings()
1522 for (ep = head_engr; ep; ep = ep->nxt_engr) {
1523 sanitize_name(ep->engr_txt);
1528 save_engravings(fd, mode)
1531 struct engr *ep, *ep2;
1532 unsigned no_more_engr = 0;
1534 for (ep = head_engr; ep; ep = ep2) {
1536 if (ep->engr_lth && ep->engr_txt[0] && perform_bwrite(mode)) {
1537 bwrite(fd, (genericptr_t) &ep->engr_lth, sizeof ep->engr_lth);
1538 bwrite(fd, (genericptr_t) ep, sizeof (struct engr) + ep->engr_lth);
1540 if (release_data(mode))
1543 if (perform_bwrite(mode))
1544 bwrite(fd, (genericptr_t) &no_more_engr, sizeof no_more_engr);
1545 if (release_data(mode))
1558 mread(fd, (genericptr_t) <h, sizeof lth);
1562 mread(fd, (genericptr_t) ep, sizeof (struct engr) + lth);
1563 ep->nxt_engr = head_engr;
1565 ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
1566 /* Mark as finished for bones levels -- no problem for
1567 * normal levels as the player must have finished engraving
1568 * to be able to move again.
1570 ep->engr_time = moves;
1576 register struct engr *ep;
1578 if (ep == head_engr) {
1579 head_engr = ep->nxt_engr;
1581 register struct engr *ept;
1583 for (ept = head_engr; ept; ept = ept->nxt_engr)
1584 if (ept->nxt_engr == ep) {
1585 ept->nxt_engr = ep->nxt_engr;
1589 impossible("Error in del_engr?");
1596 /* randomly relocate an engraving */
1601 int tx, ty, tryct = 200;
1606 tx = rn1(COLNO - 3, 2);
1608 } while (engr_at(tx, ty) || !goodpos(tx, ty, (struct monst *) 0, 0));
1614 /* Create a headstone at the given location.
1615 * The caller is responsible for newsym(x, y).
1618 make_grave(x, y, str)
1624 /* Can we put a grave here? */
1625 if ((levl[x][y].typ != ROOM && levl[x][y].typ != GRAVE) || t_at(x, y))
1627 /* Make the grave */
1628 levl[x][y].typ = GRAVE;
1629 /* Engrave the headstone */
1632 str = get_rnd_text(EPITAPHFILE, buf);
1633 make_engr_at(x, y, str, 0L, HEADSTONE);