1 /* NetHack 3.6 read.c $NHDT-Date: 1448862378 2015/11/30 05:46:18 $ $NHDT-Branch: master $:$NHDT-Revision: 1.125 $ */
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. */
12 #define Your_Own_Role(mndx) \
13 ((mndx) == urole.malenum \
14 || (urole.femalenum != NON_PM && (mndx) == urole.femalenum))
15 #define Your_Own_Race(mndx) \
16 ((mndx) == urace.malenum \
17 || (urace.femalenum != NON_PM && (mndx) == urace.femalenum))
21 static NEARDATA const char readable[] = { ALL_CLASSES, SCROLL_CLASS,
23 static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
25 STATIC_DCL boolean FDECL(learnscrolltyp, (SHORT_P));
26 STATIC_DCL char * FDECL(erode_obj_text, (struct obj *, char *));
27 STATIC_DCL void NDECL(do_class_genocide);
28 STATIC_DCL void FDECL(stripspe, (struct obj *));
29 STATIC_DCL void FDECL(p_glow1, (struct obj *));
30 STATIC_DCL void FDECL(p_glow2, (struct obj *, const char *));
31 STATIC_DCL void FDECL(randomize, (int *, int));
32 STATIC_DCL void FDECL(forget_single_object, (int));
33 STATIC_DCL void FDECL(forget, (int));
34 STATIC_DCL int FDECL(maybe_tame, (struct monst *, struct obj *));
35 STATIC_DCL boolean FDECL(is_valid_stinking_cloud_pos, (int, int, BOOLEAN_P));
36 STATIC_DCL void FDECL(display_stinking_cloud_positions, (int));
37 STATIC_PTR void FDECL(set_lit, (int, int, genericptr));
40 learnscrolltyp(scrolltyp)
43 if (!objects[scrolltyp].oc_name_known) {
45 more_experienced(0, 10);
51 /* also called from teleport.c for scroll of teleportation */
56 /* it's implied that sobj->dknown is set;
57 we couldn't be reading this scroll otherwise */
58 if (sobj->oclass != SPBOOK_CLASS)
59 (void) learnscrolltyp(sobj->otyp);
63 erode_obj_text(otmp, buf)
67 int erosion = greatest_erosion(otmp);
69 wipeout_text(buf, (int) (strlen(buf) * erosion / (2 * MAX_ERODE)),
70 otmp->o_id ^ (unsigned) ubirthday);
75 tshirt_text(tshirt, buf)
79 static const char *shirt_msgs[] = {
81 "I explored the Dungeons of Doom and all I got was this lousy T-shirt!",
82 "Is that Mjollnir in your pocket or are you just happy to see me?",
83 "It's not the size of your sword, it's how #enhance'd you are with it.",
84 "Madame Elvira's House O' Succubi Lifetime Customer",
85 "Madame Elvira's House O' Succubi Employee of the Month",
86 "Ludios Vault Guards Do It In Small, Dark Rooms",
87 "Yendor Military Soldiers Do It In Large Groups",
88 "I survived Yendor Military Boot Camp",
89 "Ludios Accounting School Intra-Mural Lacrosse Team",
90 "Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest",
91 "Hey, black dragon! Disintegrate THIS!",
92 "I'm With Stupid -->",
93 "Don't blame me, I voted for Izchak!",
94 "Don't Panic", /* HHGTTG */
95 "Furinkan High School Athletic Dept.", /* Ranma 1/2 */
96 "Hel-LOOO, Nurse!", /* Animaniacs */
98 "100% goblin hair - do not wash",
99 "Aberzombie and Fitch",
100 "cK -- Cockatrice touches the Kop",
101 "Don't ask me, I only adventure here",
103 "d, your dog or a killer?",
104 "FREE PUG AND NEWT!",
107 "Hello, my darlings!", /* Charlie Drake */
108 "Hey! Nymphs! Steal This T-Shirt!",
109 "I <3 Dungeon of Doom",
111 "I am a Valkyrie. If you see me running, try to keep up.",
112 "I am not a pack rat - I am a collector",
113 "I bounced off a rubber tree", /* Monkey Island */
114 "Plunder Island Brimstone Beach Club", /* Monkey Island */
115 "If you can read this, I can hit you with my polearm",
117 "I scored with the princess",
118 "I want to live forever or die in the attempt.",
120 "LOST IN THOUGHT - please send search party",
122 "Minetown Better Business Bureau",
124 "Ms. Palm's House of Negotiable Affection -- A Very Reputable House Of Disrepute",
125 "Protection Racketeer",
126 "Real men love Crom",
127 "Somebody stole my Mojo!",
128 "The Hellhound Gang",
130 "They Might Be Storm Giants",
131 "Weapons don't kill people, I kill people",
133 "You're killing me!",
134 "Anhur State University - Home of the Fighting Fire Ants!",
137 "Real men are valkyries",
138 "Young Men's Cavedigging Association",
139 "Occupy Fort Ludios",
140 "I couldn't afford this T-shirt so I stole it!",
142 "I'm not wearing any pants",
143 "Down with the living!",
149 Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]);
150 return erode_obj_text(tshirt, buf);
154 apron_text(apron, buf)
158 static const char *apron_msgs[] = {
160 "I'm making SCIENCE!",
161 "Don't mess with the chef",
162 "Don't make me poison you",
163 "Gehennom's Kitchen",
164 "Rat: The other white meat",
165 "If you can't stand the heat, get out of Gehennom!",
166 "If we weren't meant to eat animals, why are they made out of meat?",
167 "If you don't like the food, I'll stab you",
170 Strcpy(buf, apron_msgs[apron->o_id % SIZE(apron_msgs)]);
171 return erode_obj_text(apron, buf);
177 register struct obj *scroll;
178 boolean confused, nodisappear;
181 if (check_capacity((char *) 0))
183 scroll = getobj(readable, "read");
187 /* outrumor has its own blindness check */
188 if (scroll->otyp == FORTUNE_COOKIE) {
191 You("break up the cookie and throw away the pieces.");
193 You("
\83N
\83b
\83L
\81[
\82ð
\8a\84\82è
\81C
\82©
\82¯
\82ç
\82ð
\93\8a\82°
\82·
\82Ä
\82½
\81D");
194 outrumor(bcsign(scroll), BY_COOKIE);
196 u.uconduct.literate++;
199 } else if (scroll->otyp == T_SHIRT || scroll->otyp == ALCHEMY_SMOCK) {
203 You_cant("feel any Braille writing.");
205 You("
\93_
\8e\9a\82Í
\82Ç
\82¤
\82à
\8f\91\82¢
\82Ä
\82È
\82¢
\82æ
\82¤
\82¾
\81D");
208 /* can't read shirt worn under suit (under cloak is ok though) */
209 if (scroll->otyp == T_SHIRT && uarm && scroll == uarmu) {
211 pline("%s shirt is obscured by %s%s.",
212 scroll->unpaid ? "That" : "Your", shk_your(buf, uarm),
213 suit_simple_name(uarm));
215 pline("
\83V
\83\83\83c
\82Í%s
\82Å
\89B
\82³
\82ê
\82Ä
\82¢
\82é
\81D",
216 suit_simple_name(uarm));
220 u.uconduct.literate++;
225 pline("
\82»
\82ê
\82ð
\93Ç
\82ñ
\82¾
\81F");
227 pline("\"%s\"", (scroll->otyp == T_SHIRT) ? tshirt_text(scroll, buf)
228 : apron_text(scroll, buf));
230 pline("
\81u%s
\81v", (scroll->otyp == T_SHIRT) ? tshirt_text(scroll, buf)
231 : apron_text(scroll, buf));
234 } else if (scroll->otyp == CREDIT_CARD) {
235 static const char *card_msgs[] = {
236 "Leprechaun Gold Tru$t - Shamrock Card",
237 "Magic Memory Vault Charge Card", "Larn National Bank", /* Larn */
238 "First Bank of Omega", /* Omega */
239 "Bank of Zork - Frobozz Magic Card", /* Zork */
240 "Ankh-Morpork Merchant's Guild Barter Card",
241 "Ankh-Morpork Thieves' Guild Unlimited Transaction Card",
242 "Ransmannsby Moneylenders Association",
243 "Bank of Gehennom - 99% Interest Card",
244 "Yendorian Express - Copper Card",
245 "Yendorian Express - Silver Card",
246 "Yendorian Express - Gold Card",
247 "Yendorian Express - Mithril Card",
248 "Yendorian Express - Platinum Card", /* must be last */
253 You("feel the embossed numbers:");
255 You("
\95\82\82«
\92¤
\82è
\82É
\82³
\82ê
\82Ä
\82¢
\82é
\94Ô
\8d\86\82ð
\8a´
\82¶
\82½:");
261 pline("
\82»
\82ê
\82ð
\93Ç
\82ñ
\82¾
\81F");
267 ? card_msgs[SIZE(card_msgs) - 1]
268 : card_msgs[scroll->o_id % (SIZE(card_msgs) - 1)]);
270 /* Make a credit card number */
271 pline("\"%d0%d %d%d1 0%d%d0\"", ((scroll->o_id % 89) + 10),
272 (scroll->o_id % 4), (((scroll->o_id * 499) % 899999) + 100000),
273 (scroll->o_id % 10), (!(scroll->o_id % 3)),
274 ((scroll->o_id * 7) % 10));
275 u.uconduct.literate++;
277 } else if (scroll->otyp == CAN_OF_GREASE) {
279 pline("This %s has no label.", singular(scroll, xname));
281 pline("
\82±
\82Ì%s
\82É
\82Í
\83\89\83x
\83\8b\82ª
\82È
\82¢
\81D", singular(scroll, xname));
283 } else if (scroll->otyp == MAGIC_MARKER) {
286 You_cant("feel any Braille writing.");
288 You("
\93_
\8e\9a\82Í
\82Ç
\82¤
\82à
\8f\91\82¢
\82Ä
\82È
\82¢
\82æ
\82¤
\82¾
\81D");
295 pline("
\82»
\82ê
\82ð
\93Ç
\82ñ
\82¾
\81F");
297 pline("\"Magic Marker(TM) Red Ink Marker Pen. Water Soluble.\"");
299 pline("
\81u
\96\82\96@
\82Ì
\83}
\81[
\83J(TM)
\90Ô
\83C
\83\93\83N
\83}
\81[
\83J
\83y
\83\93\81D
\90\85\90«
\81D
\81v");
300 u.uconduct.literate++;
302 } else if (scroll->oclass == COIN_CLASS) {
305 You("feel the embossed words:");
307 You("
\95\82\82«
\92¤
\82è
\82É
\82³
\82ê
\82Ä
\82¢
\82é
\95¶
\8e\9a\82ð
\8a´
\82¶
\82½:");
308 else if (flags.verbose)
312 pline("
\82»
\82ê
\82ð
\93Ç
\82ñ
\82¾
\81F");
313 pline("\"1 Zorkmid. 857 GUE. In Frobs We Trust.\"");
314 u.uconduct.literate++;
316 } else if (scroll->oartifact == ART_ORB_OF_FATE) {
319 You("feel the engraved signature:");
321 You("
\92¤
\82è
\8d\9e\82Ü
\82ê
\82Ä
\82¢
\82é
\83T
\83C
\83\93\82ð
\8a´
\82¶
\82½
\81F");
324 pline("It is signed:");
326 pline("
\83T
\83C
\83\93\82ª
\82 \82é
\81F");
330 pline("
\81u
\83I
\81[
\83f
\83B
\83\93\81v");
331 u.uconduct.literate++;
333 } else if (scroll->otyp == CANDY_BAR) {
334 static const char *wrapper_msgs[] = {
336 "Moon Crunchy", /* South Park */
337 "Snacky Cake", "Chocolate Nuggie", "The Small Bar",
338 "Crispy Yum Yum", "Nilla Crunchie", "Berry Bar",
339 "Choco Nummer", "Om-nom", /* Cat Macro */
340 "Fruity Oaty", /* Serenity */
341 "Wonka Bar" /* Charlie and the Chocolate Factory */
346 You_cant("feel any Braille writing.");
348 You("
\93_
\8e\9a\82Í
\82Ç
\82¤
\82à
\8f\91\82¢
\82Ä
\82È
\82¢
\82æ
\82¤
\82¾
\81D");
352 pline("The wrapper reads: \"%s\"",
354 pline("
\95ï
\82Ý
\8e\86\82Ì
\95¶
\8e\9a\82ð
\93Ç
\82ñ
\82¾
\81F
\81u%s
\81v",
355 wrapper_msgs[scroll->o_id % SIZE(wrapper_msgs)]);
356 u.uconduct.literate++;
358 } else if (scroll->oclass != SCROLL_CLASS
359 && scroll->oclass != SPBOOK_CLASS) {
361 pline(silly_thing_to, "read");
363 pline(silly_thing_to, "
\93Ç
\82Þ");
365 } else if (Blind && (scroll->otyp != SPE_BOOK_OF_THE_DEAD)) {
366 const char *what = 0;
367 if (scroll->oclass == SPBOOK_CLASS)
369 what = "mystic runes";
371 what = "
\90_
\94é
\93I
\82È
\83\8b\81[
\83\93\95¶
\8e\9a";
372 else if (!scroll->dknown)
374 what = "formula on the scroll";
376 what = "
\8aª
\95¨
\82Ì
\8eô
\95¶";
379 pline("Being blind, you cannot read the %s.", what);
381 pline("
\96Ú
\82ª
\8c©
\82¦
\82È
\82¢
\82Ì
\82Å
\81C
\82 \82È
\82½
\82Í%s
\82ð
\93Ç
\82Þ
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", what);
386 confused = (Confusion != 0);
388 if (scroll->otyp == SCR_MAIL) {
389 confused = FALSE; /* override */
390 /* reading mail is a convenience for the player and takes
391 place outside the game, so shouldn't affect gameplay;
392 on the other hand, it starts by explicitly making the
393 hero actively read something, which is pretty hard
394 to simply ignore; as a compromise, if the player has
395 maintained illiterate conduct so far, and this mail
396 scroll didn't come from bones, ask for confirmation */
397 if (!u.uconduct.literate) {
398 if (!scroll->spe && yn(
399 "Reading mail will violate \"illiterate\" conduct. Read anyway?"
406 /* Actions required to win the game aren't counted towards conduct */
407 /* Novel conduct is handled in read_tribute so exclude it too*/
408 if (scroll->otyp != SPE_BOOK_OF_THE_DEAD
409 && scroll->otyp != SPE_BLANK_PAPER && scroll->otyp != SCR_BLANK_PAPER
410 && scroll->otyp != SPE_NOVEL)
411 u.uconduct.literate++;
413 if (scroll->oclass == SPBOOK_CLASS) {
414 return study_book(scroll);
416 scroll->in_use = TRUE; /* scroll, not spellbook, now being read */
417 if (scroll->otyp != SCR_BLANK_PAPER) {
418 /* a few scroll feedback messages describe something happening
419 to the scroll itself, so avoid "it disappears" for those */
420 nodisappear = (scroll->otyp == SCR_FIRE
421 || (scroll->otyp == SCR_REMOVE_CURSE
426 ? "You %s the formula on the scroll."
427 : "As you %s the formula on it, the scroll disappears.",
428 is_silent(youmonst.data) ? "cogitate" : "pronounce");
431 ? "
\82 \82È
\82½
\82Í
\8eô
\95¶
\82ð%s
\82½
\81D"
432 : "
\8eô
\95¶
\82ð%s
\82é
\82Æ
\81C
\8aª
\95¨
\82Í
\8fÁ
\82¦
\82½
\81D",
433 is_silent(youmonst.data) ? "
\94O
\82¶" : "
\8f¥
\82¦");
437 pline(nodisappear ? "You read the scroll."
438 : "As you read the scroll, it disappears.");
440 pline(nodisappear ? "
\82 \82È
\82½
\82Í
\8aª
\95¨
\82ð
\93Ç
\82ñ
\82¾
\81D"
441 : "
\8aª
\95¨
\82ð
\93Ç
\82Þ
\82Æ
\81C
\82»
\82ê
\82Í
\8fÁ
\82¦
\82½
\81D");
446 pline("Being so trippy, you screw up...");
448 pline("
\82Æ
\82Ä
\82à
\82Ö
\82ë
\82Ö
\82ë
\82È
\82Ì
\82Å
\81C
\82
\82µ
\82á
\82
\82µ
\82á
\82É
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\81D
\81D");
451 pline("Being confused, you %s the magic words...",
452 is_silent(youmonst.data) ? "misunderstand"
455 pline("
\8d¬
\97\90\82µ
\82Ä
\82¢
\82é
\82Ì
\82Å
\81C
\8eô
\95¶
\82ð
\8aÔ
\88á
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\81D
\81D");
459 if (!seffects(scroll)) {
460 if (!objects[scroll->otyp].oc_name_known) {
463 else if (!objects[scroll->otyp].oc_uname)
466 scroll->in_use = FALSE;
467 if (scroll->otyp != SCR_BLANK_PAPER)
475 register struct obj *obj;
477 if (obj->blessed || obj->spe <= 0) {
478 pline1(nothing_happens);
480 /* order matters: message, shop handling, actual transformation */
482 pline("%s briefly.", Yobjnam2(obj, "vibrate"));
484 Your("%s
\82Í
\8f¬
\8d\8f\82Ý
\82É
\90U
\93®
\82µ
\82½
\81D",xname(obj));
485 costly_alteration(obj, COST_UNCHRG);
487 if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
494 register struct obj *otmp;
497 pline("%s briefly.", Yobjnam2(otmp, Blind ? "vibrate" : "glow"));
499 Your("%s
\82Í
\8f¬
\8d\8f\82Ý
\82É%s
\81D", xname(otmp), Blind ? "
\90U
\93®
\82µ
\82½" : "
\8bP
\82¢
\82½");
504 register struct obj *otmp;
505 register const char *color;
508 pline("%s%s%s for a moment.", Yobjnam2(otmp, Blind ? "vibrate" : "glow"),
509 Blind ? "" : " ", Blind ? "" : hcolor(color));
511 Your("%s
\82Í
\88ê
\8fu%s%s
\81D", xname(otmp),
512 Blind ? "" : jconj_adj(hcolor(color)),
513 Blind ? "
\90U
\93®
\82µ
\82½" : "
\8bP
\82¢
\82½");
517 /* Is the object chargeable? For purposes of inventory display; it is
518 possible to be able to charge things for which this returns FALSE. */
523 if (obj->oclass == WAND_CLASS)
525 /* known && !oc_name_known is possible after amnesia/mind flayer */
526 if (obj->oclass == RING_CLASS)
527 return (boolean) (objects[obj->otyp].oc_charged
530 && objects[obj->otyp].oc_name_known)));
531 if (is_weptool(obj)) /* specific check before general tools */
533 if (obj->oclass == TOOL_CLASS)
534 return (boolean) objects[obj->otyp].oc_charged;
535 return FALSE; /* why are weapons/armor considered charged anyway? */
538 /* recharge an object; curse_bless is -1 if the recharging implement
539 was cursed, +1 if blessed, 0 otherwise. */
541 recharge(obj, curse_bless)
546 boolean is_cursed, is_blessed;
548 is_cursed = curse_bless < 0;
549 is_blessed = curse_bless > 0;
551 if (obj->oclass == WAND_CLASS) {
552 int lim = (obj->otyp == WAN_WISHING)
554 : (objects[obj->otyp].oc_dir != NODIR) ? 8 : 15;
556 /* undo any prior cancellation, even when is_cursed */
561 * Recharging might cause wands to explode.
562 * v = number of previous recharges
563 * v = percentage chance to explode on this attempt
564 * v = cumulative odds for exploding
574 n = (int) obj->recharged;
575 if (n > 0 && (obj->otyp == WAN_WISHING
576 || (n * n * n > rn2(7 * 7 * 7)))) { /* recharge_limit */
577 wand_explode(obj, rnd(lim));
580 /* didn't explode, so increment the recharge count */
581 obj->recharged = (unsigned) (n + 1);
583 /* now handle the actual recharging */
587 n = (lim == 3) ? 3 : rn1(5, lim + 1 - 5);
595 if (obj->otyp == WAN_WISHING && obj->spe > 3) {
596 wand_explode(obj, 1);
600 p_glow2(obj, NH_BLUE);
603 #if 0 /*[shop price doesn't vary by charge count]*/
604 /* update shop bill to reflect new higher price */
610 } else if (obj->oclass == RING_CLASS && objects[obj->otyp].oc_charged) {
611 /* charging does not affect ring's curse/bless status */
612 int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
613 boolean is_on = (obj == uleft || obj == uright);
615 /* destruction depends on current state, not adjustment */
616 if (obj->spe > rn2(7) || obj->spe <= -5) {
618 pline("%s momentarily, then %s!", Yobjnam2(obj, "pulsate"),
619 otense(obj, "explode"));
621 Your("%s
\82Í
\88ê
\8fu
\96¬
\93®
\82µ
\81C
\94\9a\94
\82µ
\82½
\81I", xname(obj));
625 s = rnd(3 * abs(obj->spe)); /* amount of damage */
628 losehp(Maybe_Half_Phys(s), "exploding ring", KILLED_BY_AN);
630 losehp(Maybe_Half_Phys(s), "
\8ew
\97Ö
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
632 long mask = is_on ? (obj == uleft ? LEFT_RING : RIGHT_RING) : 0L;
635 pline("%s spins %sclockwise for a moment.", Yname2(obj),
636 s < 0 ? "counter" : "");
638 Your("%s
\82Í
\88ê
\8fu%s
\8e\9e\8cv
\89ñ
\82è
\82É
\89ñ
\93]
\82µ
\82½
\81D", xname(obj),
639 s < 0 ? "
\94½" : "");
642 costly_alteration(obj, COST_DECHNT);
643 /* cause attributes and/or properties to be updated */
646 obj->spe += s; /* update the ring while it's off */
648 setworn(obj, mask), Ring_on(obj);
649 /* oartifact: if a touch-sensitive artifact ring is
650 ever created the above will need to be revised */
651 /* update shop bill to reflect new higher price */
652 if (s > 0 && obj->unpaid)
656 } else if (obj->oclass == TOOL_CLASS) {
657 int rechrg = (int) obj->recharged;
659 if (objects[obj->otyp].oc_charged) {
660 /* tools don't have a limit, but the counter used does */
661 if (rechrg < 7) /* recharge_limit */
665 case BELL_OF_OPENING:
677 case EXPENSIVE_CAMERA:
682 == MAGIC_MARKER) { /* previously recharged */
683 obj->recharged = 1; /* override increment done above */
686 Your("marker seems permanently dried out.");
688 Your("
\83}
\81[
\83J
\82Í
\8a®
\91S
\82É
\8a£
\82«
\82«
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
690 pline1(nothing_happens);
691 } else if (is_blessed) {
692 n = rn1(16, 15); /* 15..30 */
693 if (obj->spe + n <= 50)
695 else if (obj->spe + n <= 75)
698 int chrg = (int) obj->spe;
699 if ((chrg + n) > 127)
704 p_glow2(obj, NH_BLUE);
706 n = rn1(11, 10); /* 10..20 */
707 if (obj->spe + n <= 50)
710 int chrg = (int) obj->spe;
711 if ((chrg + n) > 127)
716 p_glow2(obj, NH_WHITE);
726 pline("%s out!", Tobjnam(obj, "go"));
728 pline("%s
\82Í
\8fÁ
\82¦
\82½
\81I", xname(obj));
732 } else if (is_blessed) {
735 p_glow2(obj, NH_BLUE);
747 } else if (is_blessed) {
749 p_glow2(obj, NH_BLUE);
755 pline1(nothing_happens);
763 } else if (is_blessed) {
765 obj->spe += rn1(10, 6);
767 obj->spe += rn1(5, 6);
770 p_glow2(obj, NH_BLUE);
782 case DRUM_OF_EARTHQUAKE:
785 } else if (is_blessed) {
789 p_glow2(obj, NH_BLUE);
806 You("have a feeling of loss.");
808 You("
\82È
\82É
\82©
\91¹
\82µ
\82½
\8bC
\95ª
\82É
\82È
\82Á
\82½
\81D");
812 /* Forget known information about this object type. */
814 forget_single_object(obj_id)
817 objects[obj_id].oc_name_known = 0;
818 objects[obj_id].oc_pre_discovered = 0; /* a discovery when relearned */
819 if (objects[obj_id].oc_uname) {
820 free((genericptr_t) objects[obj_id].oc_uname);
821 objects[obj_id].oc_uname = 0;
823 undiscover_object(obj_id); /* after clearing oc_name_known */
825 /* clear & free object names from matching inventory items too? */
828 #if 0 /* here if anyone wants it.... */
829 /* Forget everything known about a particular object class. */
831 forget_objclass(oclass)
836 for (i = bases[oclass];
837 i < NUM_OBJECTS && objects[i].oc_class == oclass; i++)
838 forget_single_object(i);
842 /* randomize the given list of numbers 0 <= i < count */
844 randomize(indices, count)
850 for (i = count - 1; i > 0; i--) {
851 if ((iswap = rn2(i + 1)) == i)
854 indices[i] = indices[iswap];
855 indices[iswap] = temp;
859 /* Forget % of known objects. */
861 forget_objects(percent)
865 int indices[NUM_OBJECTS];
869 if (percent <= 0 || percent > 100) {
870 impossible("forget_objects: bad percent %d", percent);
874 indices[0] = 0; /* lint suppression */
875 for (count = 0, i = 1; i < NUM_OBJECTS; i++)
876 if (OBJ_DESCR(objects[i])
877 && (objects[i].oc_name_known || objects[i].oc_uname))
878 indices[count++] = i;
881 randomize(indices, count);
883 /* forget first % of randomized indices */
884 count = ((count * percent) + rn2(100)) / 100;
885 for (i = 0; i < count; i++)
886 forget_single_object(indices[i]);
890 /* Forget some or all of map (depends on parameters). */
901 for (zx = 0; zx < COLNO; zx++)
902 for (zy = 0; zy < ROWNO; zy++)
903 if (howmuch & ALL_MAP || rn2(7)) {
904 /* Zonk all memory of this location. */
905 levl[zx][zy].seenv = 0;
906 levl[zx][zy].waslit = 0;
907 levl[zx][zy].glyph = cmap_to_glyph(S_stone);
908 lastseentyp[zx][zy] = STONE;
910 /* forget overview data for this level */
911 forget_mapseen(ledger_no(&u.uz));
914 /* Forget all traps on the level. */
918 register struct trap *trap;
920 /* forget all traps (except the one the hero is in :-) */
921 for (trap = ftrap; trap; trap = trap->ntrap)
922 if ((trap->tx != u.ux || trap->ty != u.uy) && (trap->ttyp != HOLE))
927 * Forget given % of all levels that the hero has visited and not forgotten,
931 forget_levels(percent)
935 xchar maxl, this_lev;
936 int indices[MAXLINFO];
941 if (percent <= 0 || percent > 100) {
942 impossible("forget_levels: bad percent %d", percent);
946 this_lev = ledger_no(&u.uz);
947 maxl = maxledgerno();
949 /* count & save indices of non-forgotten visited levels */
950 /* Sokoban levels are pre-mapped for the player, and should stay
951 * so, or they become nearly impossible to solve. But try to
952 * shift the forgetting elsewhere by fiddling with percent
953 * instead of forgetting fewer levels.
955 indices[0] = 0; /* lint suppression */
956 for (count = 0, i = 0; i <= maxl; i++)
957 if ((level_info[i].flags & VISITED)
958 && !(level_info[i].flags & FORGOTTEN) && i != this_lev) {
959 if (ledger_to_dnum(i) == sokoban_dnum)
962 indices[count++] = i;
969 randomize(indices, count);
971 /* forget first % of randomized indices */
972 count = ((count * percent) + 50) / 100;
973 for (i = 0; i < count; i++) {
974 level_info[indices[i]].flags |= FORGOTTEN;
975 forget_mapseen(indices[i]);
981 * Forget some things (e.g. after reading a scroll of amnesia). When called,
982 * the following are always forgotten:
983 * - felt ball & chain
985 * - part (6 out of 7) of the map
987 * Other things are subject to flags:
988 * howmuch & ALL_MAP = forget whole map
989 * howmuch & ALL_SPELLS = forget all spells
996 u.bc_felt = 0; /* forget felt ball&chain */
1001 /* 1 in 3 chance of forgetting some levels */
1003 forget_levels(rn2(25));
1005 /* 1 in 3 chance of forgetting some objects */
1007 forget_objects(rn2(25));
1009 if (howmuch & ALL_SPELLS)
1012 * Make sure that what was seen is restored correctly. To do this,
1013 * we need to go blind for an instant --- turn off the display,
1014 * then restart it. All this work is needed to correctly handle
1015 * walls which are stone on one side and wall on the other. Turning
1016 * off the seen bits above will make the wall revert to stone, but
1017 * there are cases where we don't want this to happen. The easiest
1018 * thing to do is to run it through the vision system again, which
1019 * is always correct.
1021 docrt(); /* this correctly will reset vision */
1024 /* monster is hit by scroll of taming's effect */
1026 maybe_tame(mtmp, sobj)
1030 int was_tame = mtmp->mtame;
1031 unsigned was_peaceful = mtmp->mpeaceful;
1035 if (was_peaceful && !mtmp->mpeaceful)
1039 make_happy_shk(mtmp, FALSE);
1040 else if (!resist(mtmp, sobj->oclass, 0, NOTELL))
1041 (void) tamedog(mtmp, (struct obj *) 0);
1042 if ((!was_peaceful && mtmp->mpeaceful) || (!was_tame && mtmp->mtame))
1049 is_valid_stinking_cloud_pos(x, y, showmsg)
1053 if (!cansee(x, y) || !ACCESSIBLE(levl[x][y].typ) || distu(x, y) >= 32) {
1056 You("smell rotten eggs.");
1058 pline("
\82
\82³
\82Á
\82½
\97\91\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
1065 display_stinking_cloud_positions(state)
1069 tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos));
1070 } else if (state == 1) {
1074 for (dx = -dist; dx <= dist; dx++)
1075 for (dy = -dist; dy <= dist; dy++) {
1078 if (isok(x, y) && is_valid_stinking_cloud_pos(x, y, FALSE))
1082 tmp_at(DISP_END, 0);
1086 /* scroll effects; return 1 if we use up the scroll and possibly make it
1087 become discovered, 0 if caller should take care of those side-effects */
1090 struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
1092 int cval, otyp = sobj->otyp;
1093 boolean confused = (Confusion != 0), sblessed = sobj->blessed,
1094 scursed = sobj->cursed, already_known, old_erodeproof,
1098 if (objects[otyp].oc_magic)
1099 exercise(A_WIS, TRUE); /* just for trying */
1100 already_known = (sobj->oclass == SPBOOK_CLASS /* spell */
1101 || objects[otyp].oc_name_known);
1110 "This seems to be junk mail addressed to the finder of the Eye of Larn.");
1112 "Eye of Larn
\82Ì
\94
\8c©
\8eÒ
\82É
\88¶
\82Ä
\82ç
\82ê
\82½
\83S
\83~
\83\81\83C
\83\8b\82Ì
\82æ
\82¤
\82¾
\81D");
1113 /* note to the puzzled: the game Larn actually sends you junk
1120 case SCR_ENCHANT_ARMOR: {
1122 boolean special_armor;
1125 otmp = some_armor(&youmonst);
1128 strange_feeling(sobj, !Blind
1129 ? "Your skin glows then fades."
1130 : "Your skin feels warm for a moment.");
1132 strange_feeling(sobj, !Blind
1133 ? "
\82 \82È
\82½
\82Ì
\91Ì
\82Í
\88ê
\8fu
\8bP
\82¢
\82½
\81D"
1134 : "
\82 \82È
\82½
\82Ì
\91Ì
\82Í
\88ê
\8fu
\92g
\82©
\82
\82È
\82Á
\82½
\81D");
1136 sobj = 0; /* useup() in strange_feeling() */
1137 exercise(A_CON, !scursed);
1138 exercise(A_STR, !scursed);
1142 old_erodeproof = (otmp->oerodeproof != 0);
1143 new_erodeproof = !scursed;
1144 otmp->oerodeproof = 0; /* for messages */
1146 otmp->rknown = FALSE;
1148 pline("%s warm for a moment.", Yobjnam2(otmp, "feel"));
1150 Your("%s
\82Í
\88ê
\8fu
\92g
\82©
\82
\82È
\82Á
\82½
\81D", xname(otmp));
1152 otmp->rknown = TRUE;
1154 pline("%s covered by a %s %s %s!", Yobjnam2(otmp, "are"),
1155 scursed ? "mottled" : "shimmering",
1156 hcolor(scursed ? NH_BLACK : NH_GOLDEN),
1158 : (is_shield(otmp) ? "layer" : "shield"));
1160 Your("%s
\82Í%s%s%s
\82Å
\95¢
\82í
\82ê
\82½
\81I", xname(otmp),
1161 jconj_adj(hcolor(scursed ? NH_BLACK : NH_GOLDEN)),
1162 scursed ? "
\8cõ
\82é
\82Ü
\82¾
\82ç
\82Ì" : "
\82ä
\82ç
\82ß
\82",
1163 scursed ? "
\8bP
\82«"
1164 : "
\83o
\83\8a\83A");
1167 if (new_erodeproof && (otmp->oeroded || otmp->oeroded2)) {
1168 otmp->oeroded = otmp->oeroded2 = 0;
1170 pline("%s as good as new!",
1171 Yobjnam2(otmp, Blind ? "feel" : "look"));
1173 Your("%s
\82Í
\90V
\95i
\93¯
\97l
\82É
\82È
\82Á
\82½
\81I",
1177 if (old_erodeproof && !new_erodeproof) {
1178 /* restore old_erodeproof before shop charges */
1179 otmp->oerodeproof = 1;
1180 costly_alteration(otmp, COST_DEGRD);
1182 otmp->oerodeproof = new_erodeproof ? 1 : 0;
1185 /* elven armor vibrates warningly when enchanted beyond a limit */
1186 special_armor = is_elven_armor(otmp)
1187 || (Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM);
1189 same_color = (otmp->otyp == BLACK_DRAGON_SCALE_MAIL
1190 || otmp->otyp == BLACK_DRAGON_SCALES);
1192 same_color = (otmp->otyp == SILVER_DRAGON_SCALE_MAIL
1193 || otmp->otyp == SILVER_DRAGON_SCALES
1194 || otmp->otyp == SHIELD_OF_REFLECTION);
1198 /* KMH -- catch underflow */
1199 s = scursed ? -otmp->spe : otmp->spe;
1200 if (s > (special_armor ? 5 : 3) && rn2(s)) {
1201 otmp->in_use = TRUE;
1203 pline("%s violently %s%s%s for a while, then %s.", Yname2(otmp),
1204 otense(otmp, Blind ? "vibrate" : "glow"),
1205 (!Blind && !same_color) ? " " : "",
1206 (Blind || same_color) ? "" : hcolor(scursed ? NH_BLACK
1208 otense(otmp, "evaporate"));
1210 Your("%s
\82Í
\82µ
\82Î
\82ç
\82
\82Ì
\8aÔ
\8c\83\82µ
\82%s%s
\81C
\8fö
\94
\82µ
\82½
\81D", xname(otmp),
1211 (Blind || same_color) ? "" : jconj_adj(hcolor(scursed ? NH_BLACK : NH_SILVER)),
1212 Blind ? "
\90U
\93®
\82µ" : "
\8bP
\82«");
1214 remove_worn_item(otmp, FALSE);
1218 s = scursed ? -1 : otmp->spe >= 9
1219 ? (rn2(otmp->spe) == 0)
1220 : sblessed ? rnd(3 - otmp->spe / 3) : 1;
1221 if (s >= 0 && Is_dragon_scales(otmp)) {
1222 /* dragon scales get turned into dragon scale mail */
1224 pline("%s merges and hardens!", Yname2(otmp));
1226 Your("%s
\82Í
\97Z
\8d\87\82µ
\8cÅ
\82
\82È
\82Á
\82½
\81I", xname(otmp));
1227 setworn((struct obj *) 0, W_ARM);
1228 /* assumes same order */
1229 otmp->otyp += GRAY_DRAGON_SCALE_MAIL - GRAY_DRAGON_SCALES;
1234 } else if (otmp->cursed)
1237 setworn(otmp, W_ARM);
1239 alter_cost(otmp, 0L); /* shop bill */
1243 pline("%s %s%s%s%s for a %s.", Yname2(otmp),
1244 s == 0 ? "violently " : "",
1245 otense(otmp, Blind ? "vibrate" : "glow"),
1246 (!Blind && !same_color) ? " " : "",
1247 (Blind || same_color) ? ""
1248 : hcolor(scursed ? NH_BLACK : NH_SILVER),
1249 (s * s > 1) ? "while" : "moment");
1251 Your("%s
\82Í%s%s%s%s
\81D", xname(otmp),
1252 (s * s > 1) ? "
\82µ
\82Î
\82ç
\82
\82Ì
\8aÔ" : "
\88ê
\8fu",
1253 s == 0 ? "
\8c\83\82µ
\82" : "",
1254 (Blind || same_color) ? ""
1255 : jconj_adj(hcolor(sobj->cursed ? NH_BLACK : NH_SILVER)),
1256 Blind ? "
\90U
\93®
\82µ
\82½" : "
\8bP
\82¢
\82½");
1258 /* [this cost handling will need updating if shop pricing is
1259 ever changed to care about curse/bless status of armor] */
1261 costly_alteration(otmp, COST_DECHNT);
1262 if (scursed && !otmp->cursed)
1264 else if (sblessed && !otmp->blessed)
1269 known = otmp->known;
1270 /* update shop bill to reflect new higher price */
1271 if (s > 0 && otmp->unpaid)
1272 alter_cost(otmp, 0L);
1275 if ((otmp->spe > (special_armor ? 5 : 3))
1276 && (special_armor || !rn2(7)))
1278 pline("%s %s.", Yobjnam2(otmp, "suddenly vibrate"),
1279 Blind ? "again" : "unexpectedly");
1281 Your("%s
\82Í
\93Ë
\91R%s
\90U
\93®
\82µ
\82½
\81D", xname(otmp),
1282 Blind ? "
\82Ü
\82½" : "
\8ev
\82¢
\82à
\82æ
\82ç
\82¸");
1286 case SCR_DESTROY_ARMOR: {
1287 otmp = some_armor(&youmonst);
1291 strange_feeling(sobj, "Your bones itch.");
1293 strange_feeling(sobj, "
\8d\9c\82ª
\83\80\83Y
\83\80\83Y
\82·
\82é
\81D");
1294 sobj = 0; /* useup() in strange_feeling() */
1295 exercise(A_STR, FALSE);
1296 exercise(A_CON, FALSE);
1299 old_erodeproof = (otmp->oerodeproof != 0);
1300 new_erodeproof = scursed;
1301 otmp->oerodeproof = 0; /* for messages */
1302 p_glow2(otmp, NH_PURPLE);
1303 if (old_erodeproof && !new_erodeproof) {
1304 /* restore old_erodeproof before shop charges */
1305 otmp->oerodeproof = 1;
1306 costly_alteration(otmp, COST_DEGRD);
1308 otmp->oerodeproof = new_erodeproof ? 1 : 0;
1311 if (!scursed || !otmp || !otmp->cursed) {
1312 if (!destroy_arm(otmp)) {
1314 strange_feeling(sobj, "Your skin itches.");
1316 strange_feeling(sobj,"
\94ç
\95\86\82ª
\83\80\83Y
\83\80\83Y
\82·
\82é
\81D");
1317 sobj = 0; /* useup() in strange_feeling() */
1318 exercise(A_STR, FALSE);
1319 exercise(A_CON, FALSE);
1323 } else { /* armor and scroll both cursed */
1325 pline("%s.", Yobjnam2(otmp, "vibrate"));
1327 Your("%s
\82Í
\90U
\93®
\82µ
\82½
\81D", xname(otmp));
1328 if (otmp->spe >= -6) {
1332 make_stunned((HStun & TIMEOUT) + (long) rn1(10, 10), TRUE);
1335 case SCR_CONFUSE_MONSTER:
1336 case SPE_CONFUSE_MONSTER:
1337 if (youmonst.data->mlet != S_HUMAN || scursed) {
1340 You_feel("confused.");
1342 You_feel("confused.");
1343 make_confused(HConfusion + rnd(100), FALSE);
1344 } else if (confused) {
1347 Your("%s begin to %s%s.", makeplural(body_part(HAND)),
1348 Blind ? "tingle" : "glow ",
1349 Blind ? "" : hcolor(NH_PURPLE));
1351 Your("%s
\82Í%s%s
\82Í
\82¶
\82ß
\82½
\81D", makeplural(body_part(HAND)),
1352 Blind ? "" : jconj_adj(hcolor(NH_PURPLE)),
1353 Blind ? "
\83q
\83\8a\83q
\83\8a\82µ" : "
\8bP
\82«");
1355 make_confused(HConfusion + rnd(100), FALSE);
1358 pline("A %s%s surrounds your %s.",
1359 Blind ? "" : hcolor(NH_RED),
1360 Blind ? "faint buzz" : " glow", body_part(HEAD));
1362 pline("%s%s
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\8eæ
\82è
\8aª
\82¢
\82½
\81D",
1363 Blind ? "" : jconj_adj(hcolor(NH_RED)),
1364 Blind ? "
\82©
\82·
\82©
\82É
\83u
\81[
\83\93\82Æ
\96Â
\82é
\82à
\82Ì" : "
\8bP
\82
\82à
\82Ì",
1367 make_confused(0L, TRUE);
1372 Your("%s%s %s%s.", makeplural(body_part(HAND)),
1373 Blind ? "" : " begin to glow",
1374 Blind ? (const char *) "tingle" : hcolor(NH_RED),
1375 u.umconf ? " even more" : "");
1377 Your("%s
\82Í%s%s%s
\81D", makeplural(body_part(HAND)),
1378 u.umconf ? "
\8f
\82µ" : "",
1379 Blind ? (const char *) "
\83q
\83\8a\83q
\83\8a\82µ
\82½" : jconj_adj(hcolor(NH_RED)),
1380 Blind ? "" : "
\8bP
\82«
\82Í
\82¶
\82ß
\82½");
1386 Your("%s tingle %s sharply.", makeplural(body_part(HAND)),
1387 u.umconf ? "even more" : "very");
1389 Your("%s
\82Í%s
\83s
\83\8a\83s
\83\8a\82·
\82é
\81D", makeplural(body_part(HAND)),
1390 u.umconf ? "
\8f
\82µ" : "
\82Æ
\82Ä
\82à");
1394 Your("%s glow a%s brilliant %s.",
1395 makeplural(body_part(HAND)),
1396 u.umconf ? "n even more" : "", hcolor(NH_RED));
1398 Your("%s
\82Í%s%s
\96¾
\82é
\82
\8bP
\82¢
\82½
\81D",
1399 makeplural(body_part(HAND)),
1400 u.umconf ? "
\8f
\82µ" : "", jconj_adj(hcolor(NH_RED)));
1402 /* after a while, repeated uses become less effective */
1406 u.umconf += rn1(8, 2);
1410 case SCR_SCARE_MONSTER:
1411 case SPE_CAUSE_FEAR: {
1412 register int ct = 0;
1413 register struct monst *mtmp;
1415 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1416 if (DEADMONSTER(mtmp))
1418 if (cansee(mtmp->mx, mtmp->my)) {
1419 if (confused || scursed) {
1420 mtmp->mflee = mtmp->mfrozen = mtmp->msleeping = 0;
1422 } else if (!resist(mtmp, sobj->oclass, 0, NOTELL))
1423 monflee(mtmp, 0, FALSE, FALSE);
1425 ct++; /* pets don't laugh at you */
1428 if (otyp == SCR_SCARE_MONSTER || !ct)
1430 You_hear("%s %s.", (confused || scursed) ? "sad wailing"
1431 : "maniacal laughter",
1432 !ct ? "in the distance" : "close by");
1434 You_hear("
\89\93\82
\82Å%s
\82ð
\95·
\82¢
\82½
\81D",
1435 (confused || sobj->cursed) ? "
\94ß
\82µ
\82
\8b\83\82«
\8b©
\82Ô
\90º"
1436 : "
\8b¶
\82Á
\82½
\82æ
\82¤
\82É
\8fÎ
\82¤
\90º");
1440 case SCR_BLANK_PAPER:
1443 You("don't remember there being any magic words on this scroll.");
1445 You("
\8aª
\95¨
\82É
\8eô
\95¶
\82ª
\8f\91\82¢
\82Ä
\82È
\82©
\82Á
\82½
\82±
\82Æ
\82ð
\8ev
\82¢
\82¾
\82µ
\82½
\81D");
1448 pline("This scroll seems to be blank.");
1450 pline("
\82±
\82Ì
\8aª
\95¨
\82É
\82Í
\89½
\82à
\8f\91\82¢
\82Ä
\82È
\82¢
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D");
1453 case SCR_REMOVE_CURSE:
1454 case SPE_REMOVE_CURSE: {
1455 register struct obj *obj;
1458 You_feel(!Hallucination
1459 ? (!confused ? "like someone is helping you."
1460 : "like you need some help.")
1461 : (!confused ? "in touch with the Universal Oneness."
1462 : "the power of the Force against you!"));
1465 ? (!confused ? "
\92N
\82©
\82ª
\82 \82È
\82½
\82ð
\8f\95\82¯
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D"
1466 : "
\8e©
\95ª
\82ª
\8f\95\82¯
\82ð
\95K
\97v
\82Æ
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D")
1467 : (!confused ? "
\89F
\92\88\92²
\98a
\82Ì
\8c´
\97\9d\82É
\90G
\82ê
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D"
1468 : "
\83t
\83H
\81[
\83X
\82Ì
\97Í
\82ª
\82 \82È
\82½
\82É
\82Í
\82Þ
\82©
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81I"));
1473 pline_The("scroll disintegrates.");
1475 pline("
\8aª
\95¨
\82Í
\95²
\81X
\82É
\82È
\82Á
\82½
\81D");
1477 for (obj = invent; obj; obj = obj->nobj) {
1479 /* gold isn't subject to cursing and blessing */
1480 if (obj->oclass == COIN_CLASS)
1482 wornmask = (obj->owornmask & ~(W_BALL | W_ART | W_ARTI));
1483 if (wornmask && !sblessed) {
1484 /* handle a couple of special cases; we don't
1485 allow auxiliary weapon slots to be used to
1486 artificially increase number of worn items */
1487 if (obj == uswapwep) {
1490 } else if (obj == uquiver) {
1491 if (obj->oclass == WEAPON_CLASS) {
1492 /* mergeable weapon test covers ammo,
1493 missiles, spears, daggers & knives */
1494 if (!objects[obj->otyp].oc_merge)
1496 } else if (obj->oclass == GEM_CLASS) {
1497 /* possibly ought to check whether
1498 alternate weapon is a sling... */
1502 /* weptools don't merge and aren't
1503 reasonable quivered weapons */
1508 if (sblessed || wornmask || obj->otyp == LOADSTONE
1509 || (obj->otyp == LEASH && obj->leashmon)) {
1510 /* water price varies by curse/bless status */
1512 (obj->unpaid && obj->otyp == POT_WATER);
1515 blessorcurse(obj, 2);
1516 /* lose knowledge of this object's curse/bless
1517 state (even if it didn't actually change) */
1519 /* blessorcurse() only affects uncursed items
1520 so no need to worry about price of water
1521 going down (hence no costly_alteration) */
1522 if (shop_h2o && (obj->cursed || obj->blessed))
1523 alter_cost(obj, 0L); /* price goes up */
1524 } else if (obj->cursed) {
1526 costly_alteration(obj, COST_UNCURS);
1532 if (Punished && !confused)
1534 if (u.utrap && u.utraptype == TT_BURIEDBALL) {
1535 buried_ball_to_freedom();
1537 pline_The("clasp on your %s vanishes.", body_part(LEG));
1539 pline_The("%s
\82Ì
\8bà
\8bï
\82ª
\8fÁ
\82¦
\82½
\81D", body_part(LEG));
1544 case SCR_CREATE_MONSTER:
1545 case SPE_CREATE_MONSTER:
1546 if (create_critters(1 + ((confused || scursed) ? 12 : 0)
1547 + ((sblessed || rn2(73)) ? 0 : rnd(4)),
1548 confused ? &mons[PM_ACID_BLOB]
1549 : (struct permonst *) 0,
1552 /* no need to flush monsters; we ask for identification only if the
1553 * monsters are not visible
1556 case SCR_ENCHANT_WEAPON:
1557 if (confused && uwep
1558 && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) {
1559 old_erodeproof = (uwep->oerodeproof != 0);
1560 new_erodeproof = !scursed;
1561 uwep->oerodeproof = 0; /* for messages */
1563 uwep->rknown = FALSE;
1565 Your("weapon feels warm for a moment.");
1567 pline("
\95\90\8aí
\82ª
\88ê
\8fu
\92g
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1569 uwep->rknown = TRUE;
1571 pline("%s covered by a %s %s %s!", Yobjnam2(uwep, "are"),
1572 scursed ? "mottled" : "shimmering",
1573 hcolor(scursed ? NH_PURPLE : NH_GOLDEN),
1574 scursed ? "glow" : "shield");
1576 Your("%s
\82Í%s%s%s
\82Å
\95¢
\82í
\82ê
\82½
\81I", xname(uwep),
1577 jconj_adj(hcolor(scursed ? NH_PURPLE : NH_GOLDEN)),
1578 scursed ? "
\8cõ
\82é
\82Ü
\82¾
\82ç
\82Ì" : "
\82ä
\82ç
\82ß
\82",
1579 scursed ? "
\8bP
\82«" : "
\83o
\83\8a\83A");
1582 if (new_erodeproof && (uwep->oeroded || uwep->oeroded2)) {
1583 uwep->oeroded = uwep->oeroded2 = 0;
1585 pline("%s as good as new!",
1586 Yobjnam2(uwep, Blind ? "feel" : "look"));
1588 pline("%s
\82Í
\90V
\95i
\93¯
\97l
\82É
\82È
\82Á
\82½
\81I", xname(uwep));
1591 if (old_erodeproof && !new_erodeproof) {
1592 /* restore old_erodeproof before shop charges */
1593 uwep->oerodeproof = 1;
1594 costly_alteration(uwep, COST_DEGRD);
1596 uwep->oerodeproof = new_erodeproof ? 1 : 0;
1602 : !uwep ? 1 : (uwep->spe >= 9)
1604 : sblessed ? rnd(3 - uwep->spe / 3)
1606 sobj = 0; /* nothing enchanted: strange_feeling -> useup */
1609 case SPE_CHARM_MONSTER: {
1610 int candidates, res, results, vis_results;
1614 results = vis_results = maybe_tame(u.ustuck, sobj);
1616 int i, j, bd = confused ? 5 : 1;
1619 /* note: maybe_tame() can return either positive or
1620 negative values, but not both for the same scroll */
1621 candidates = results = vis_results = 0;
1622 for (i = -bd; i <= bd; i++)
1623 for (j = -bd; j <= bd; j++) {
1624 if (!isok(u.ux + i, u.uy + j))
1626 if ((mtmp = m_at(u.ux + i, u.uy + j)) != 0
1627 || (!i && !j && (mtmp = u.usteed) != 0)) {
1629 res = maybe_tame(mtmp, sobj);
1631 if (canspotmon(mtmp))
1637 pline("Nothing interesting %s.",
1638 !candidates ? "happens" : "seems to happen");
1640 pline_The("neighborhood %s %sfriendlier.",
1641 vis_results ? "is" : "seems",
1642 (results < 0) ? "un" : "");
1643 if (vis_results > 0)
1650 You("have found a scroll of genocide!");
1652 pline("
\82±
\82ê
\82Í
\8bs
\8eE
\82Ì
\8aª
\95¨
\82¾
\81I");
1655 do_class_genocide();
1657 do_genocide(!scursed | (2 * !!Confusion));
1660 if (!confused || rn2(5)) {
1663 litroom(!confused && !scursed, sobj);
1664 if (!confused && !scursed) {
1665 if (lightdamage(sobj, TRUE, 5))
1669 /* could be scroll of create monster, don't set known ...*/
1670 (void) create_critters(1, !scursed ? &mons[PM_YELLOW_LIGHT]
1671 : &mons[PM_BLACK_LIGHT],
1673 if (!objects[sobj->otyp].oc_uname)
1677 case SCR_TELEPORTATION:
1678 if (confused || scursed) {
1681 known = scrolltele(sobj);
1684 case SCR_GOLD_DETECTION:
1685 if ((confused || scursed) ? trap_detect(sobj) : gold_detect(sobj))
1686 sobj = 0; /* failure: strange_feeling() -> useup() */
1688 case SCR_FOOD_DETECTION:
1689 case SPE_DETECT_FOOD:
1690 if (food_detect(sobj))
1691 sobj = 0; /* nothing detected: strange_feeling -> useup */
1694 /* known = TRUE; -- handled inline here */
1695 /* use up the scroll first, before makeknown() performs a
1696 perm_invent update; also simplifies empty invent check */
1698 sobj = 0; /* it's gone */
1701 You("identify this as an identify scroll.");
1703 You("
\82±
\82ê
\82Í
\8e¯
\95Ê
\82Ì
\8aª
\95¨
\82¾
\82Æ
\8e¯
\95Ê
\82µ
\82½
\81D");
1704 else if (!already_known || !invent)
1705 /* force feedback now if invent became
1706 empty after using up this scroll */
1708 pline("This is an identify scroll.");
1710 pline("
\82±
\82ê
\82Í
\8e¯
\95Ê
\82Ì
\8aª
\95¨
\82¾
\81D");
1712 (void) learnscrolltyp(SCR_IDENTIFY);
1716 if (sblessed || (!scursed && !rn2(5))) {
1718 /* note: if cval==0, identify all items */
1719 if (cval == 1 && sblessed && Luck > 0)
1722 if (invent && !confused) {
1723 identify_pack(cval, !already_known);
1724 } else if (otyp == SPE_IDENTIFY) {
1725 /* when casting a spell we know we're not confused,
1726 so inventory must be empty (another message has
1727 already been given above if reading a scroll) */
1728 pline("You're not carrying anything to be identified.");
1735 You_feel("discharged.");
1737 You_feel("
\95ú
\8fo
\82³
\82ê
\82½
\8bC
\82ª
\82·
\82é
\81D");
1741 You_feel("charged up!");
1743 You_feel("
\8f[
\93U
\82³
\82ê
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82·
\82é
\81I");
1744 u.uen += d(sblessed ? 6 : 4, 4);
1745 if (u.uen > u.uenmax) /* if current energy is already at */
1746 u.uenmax = u.uen; /* or near maximum, increase maximum */
1748 u.uen = u.uenmax; /* otherwise restore current to max */
1753 /* known = TRUE; -- handled inline here */
1754 if (!already_known) {
1756 pline("This is a charging scroll.");
1758 pline("
\82±
\82ê
\82Í
\8f[
\93U
\82Ì
\8aª
\95¨
\82¾
\81I");
1761 /* use it up now to prevent it from showing in the
1762 getobj picklist because the "disappears" message
1763 was already delivered */
1765 sobj = 0; /* it's gone */
1766 otmp = getobj(all_count, "charge");
1768 recharge(otmp, scursed ? -1 : sblessed ? 1 : 0);
1770 case SCR_MAGIC_MAPPING:
1771 if (level.flags.nommap) {
1773 Your("mind is filled with crazy lines!");
1775 Your("
\90S
\82É
\82½
\82¾
\82È
\82ç
\82Ê
\90ü
\81I
\90ü
\81I
\90ü
\81I
\82ª
\95\82\82Ñ
\82 \82ª
\82Á
\82½
\81I");
1778 pline("Wow! Modern art.");
1780 pline("
\83\8f\83H
\81I
\83\82\83_
\83\93\83A
\81[
\83g
\82¾
\81I");
1783 Your("%s spins in bewilderment.", body_part(HEAD));
1785 You("
\93\96\98f
\82µ
\82Ä
\96Ú
\82ª
\82Ü
\82í
\82Á
\82½
\81D");
1786 make_confused(HConfusion + rnd(30), FALSE);
1792 for (x = 1; x < COLNO; x++)
1793 for (y = 0; y < ROWNO; y++)
1794 if (levl[x][y].typ == SDOOR)
1795 cvt_sdoor_to_door(&levl[x][y]);
1796 /* do_mapping() already reveals secret passages */
1799 case SPE_MAGIC_MAPPING:
1800 if (level.flags.nommap) {
1802 Your("%s spins as %s blocks the spell!", body_part(HEAD),
1805 You("
\89½
\82©
\82ª
\8eô
\95¶
\82ð
\82³
\82¦
\82¬
\82è
\81C
\96Ú
\82ª
\82Ü
\82í
\82Á
\82½
\81I");
1807 make_confused(HConfusion + rnd(30), FALSE);
1811 pline("A map coalesces in your mind!");
1813 pline("
\92n
\90}
\82ª
\82 \82È
\82½
\82Ì
\90S
\82É
\97Z
\8d\87\82µ
\82½
\81I");
1814 cval = (scursed && !confused);
1816 HConfusion = 1; /* to screw up map */
1819 HConfusion = 0; /* restore */
1821 pline("Unfortunately, you can't grasp the details.");
1823 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í
\8fÚ
\8d×
\82ð
\93¾
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
1828 forget((!sblessed ? ALL_SPELLS : 0)
1829 | (!confused || scursed ? ALL_MAP : 0));
1830 if (Hallucination) /* Ommmmmm! */
1832 Your("mind releases itself from mundane concerns.");
1834 Your("
\90S
\82Í
\95½
\96}
\82È
\97\98\8aQ
\8aÖ
\8cW
\82©
\82ç
\89ð
\95ú
\82³
\82ê
\82½
\81D");
1835 else if (!strncmpi(plname, "Maud", 4))
1838 "As your mind turns inward on itself, you forget everything else.");
1840 "
\82 \82È
\82½
\82Ì
\90S
\82Í
\93à
\91¤
\82É
\8cü
\82«
\81C
\91S
\82Ä
\82ð
\96Y
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
1843 pline("Who was that Maud person anyway?");
1845 pline("Maud
\82Á
\82Ä
\96º
\82Í
\82¢
\82Á
\82½
\82¢
\92N
\82¾
\82¢
\81H");
1848 pline("Thinking of Maud you forget everything else.");
1850 pline("Maud
\82ð
\8dl
\82¦
\82é
\82±
\82Æ
\88È
\8aO
\81C
\82 \82È
\82½
\82Í
\91S
\82Ä
\82ð
\96Y
\82ê
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
1851 exercise(A_WIS, FALSE);
1854 cval = bcsign(sobj);
1856 sobj = 0; /* it's gone */
1858 (void) learnscrolltyp(SCR_FIRE);
1860 if (Fire_resistance) {
1861 shieldeff(u.ux, u.uy);
1864 pline("Oh, look, what a pretty fire in your %s.",
1866 pline("
\82í
\82\9f\82²
\82ç
\82ñ
\81D
\8f¬
\82³
\82È
\89Î
\82ª%s
\82É
\82 \82é
\81D",
1867 makeplural(body_part(HAND)));
1870 You_feel("a pleasant warmth in your %s.",
1872 You_feel("%s
\82Ì
\92\86\82É
\89õ
\93K
\82È
\92g
\82©
\82³
\82ð
\8a´
\82¶
\82½
\81D",
1873 makeplural(body_part(HAND)));
1876 pline_The("scroll catches fire and you burn your %s.",
1878 pline("
\8aª
\95¨
\82É
\89Î
\82ª
\94R
\82¦
\82¤
\82Â
\82è
\81C
\82 \82È
\82½
\82Ì%s
\82ð
\8fÄ
\82¢
\82½
\81D",
1879 makeplural(body_part(HAND)));
1881 losehp(1, "scroll of fire", KILLED_BY_AN);
1883 losehp(1, "
\89\8a\82Ì
\8aª
\95¨
\82Å", KILLED_BY_AN);
1889 pline_The("water around you vaporizes violently!");
1891 pline("
\82 \82È
\82½
\82Ì
\89ñ
\82è
\82Ì
\90\85\82Í
\95¦
\93«
\82µ
\82½
\81I");
1894 pline_The("scroll erupts in a tower of flame!");
1896 pline("
\8aª
\95¨
\82©
\82ç
\89Î
\92\8c\82ª
\97§
\82¿
\8f¸
\82Á
\82½
\81I");
1897 iflags.last_msg = PLNMSG_TOWER_OF_FLAME; /* for explode() */
1900 explode(u.ux, u.uy, 11, (2 * (rn1(3, 3) + 2 * cval) + 1) / 3,
1901 SCROLL_CLASS, EXPL_FIERY);
1904 /* TODO: handle steeds */
1905 if (!Is_rogue_level(&u.uz) && has_ceiling(&u.uz)
1906 && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1910 /* Identify the scroll */
1913 You_hear("rumbling.");
1915 You_hear("
\83S
\83\8d\83S
\83\8d\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1918 pline_The("%s rumbles %s you!", ceiling(u.ux, u.uy),
1919 sblessed ? "around" : "above");
1921 pline("
\82 \82È
\82½
\82Ì%s
\82Ì%s
\82©
\82ç
\83S
\83\8d\83S
\83\8d\82Æ
\89¹
\82ª
\95·
\82±
\82¦
\82Ä
\82«
\82½
\81I",
1922 sblessed ? "
\82Ü
\82í
\82è" : "
\90^
\8fã", ceiling(u.ux,u.uy));
1927 /* Loop through the surrounding squares */
1929 for (x = u.ux - 1; x <= u.ux + 1; x++) {
1930 for (y = u.uy - 1; y <= u.uy + 1; y++) {
1931 /* Is this a suitable spot? */
1932 if (isok(x, y) && !closed_door(x, y)
1933 && !IS_ROCK(levl[x][y].typ)
1934 && !IS_AIR(levl[x][y].typ)
1935 && (x != u.ux || y != u.uy)) {
1937 drop_boulder_on_monster(x, y, confused, TRUE);
1941 /* Attack the player */
1943 drop_boulder_on_player(confused, !scursed, TRUE, FALSE);
1944 } else if (!nboulders)
1945 pline("But nothing else happens.");
1948 case SCR_PUNISHMENT:
1950 if (confused || sblessed) {
1952 You_feel("guilty.");
1954 You("
\8dß
\82ð
\8a´
\82¶
\82½
\81D");
1959 case SCR_STINKING_CLOUD: {
1964 You("have found a scroll of stinking cloud!");
1966 You("
\88«
\8fL
\89_
\82Ì
\8aª
\95¨
\82ð
\94
\8c©
\82µ
\82½
\81I");
1969 pline("Where do you want to center the %scloud?",
1970 already_known ? "stinking " : "");
1972 pline("
\89_
\82Ì
\92\86\90S
\82ð
\82Ç
\82±
\82É
\82µ
\82Ü
\82·
\82©
\81H");
1976 getpos_sethilite(display_stinking_cloud_positions);
1978 if (getpos(&cc, TRUE, "the desired position") < 0) {
1980 if (getpos(&cc, TRUE, "
\91_
\82¤
\8fê
\8f\8a") < 0) {
1984 if (!is_valid_stinking_cloud_pos(cc.x, cc.y, TRUE))
1986 (void) create_gas_cloud(cc.x, cc.y, 3 + bcsign(sobj),
1987 8 + 4 * bcsign(sobj));
1991 impossible("What weird effect is this? (%u)", otyp);
1993 return sobj ? 0 : 1;
1997 drop_boulder_on_player(confused, helmet_protects, byu, skip_uswallow)
1998 boolean confused, helmet_protects, byu, skip_uswallow;
2003 /* hit monster if swallowed */
2004 if (u.uswallow && !skip_uswallow) {
2005 drop_boulder_on_monster(u.ux, u.uy, confused, byu);
2009 otmp2 = mksobj(confused ? ROCK : BOULDER, FALSE, FALSE);
2012 otmp2->quan = confused ? rn1(5, 2) : 1;
2013 otmp2->owt = weight(otmp2);
2014 if (!amorphous(youmonst.data) && !Passes_walls
2015 && !noncorporeal(youmonst.data) && !unsolid(youmonst.data)) {
2017 You("are hit by %s!", doname(otmp2));
2019 pline("%s
\82ª
\96½
\92\86\82µ
\82½
\81I", doname(otmp2));
2020 dmg = dmgval(otmp2, &youmonst) * otmp2->quan;
2021 if (uarmh && helmet_protects) {
2022 if (is_metallic(uarmh)) {
2024 pline("Fortunately, you are wearing a hard helmet.");
2026 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\81D");
2029 } else if (flags.verbose) {
2031 pline("%s does not protect you.", Yname2(uarmh));
2033 Your("%s
\82Å
\82Í
\8eç
\82ê
\82È
\82¢
\81D", xname(uarmh));
2038 /* Must be before the losehp(), for bones files */
2040 if (!flooreffects(otmp2, u.ux, u.uy, "fall")) {
2042 if (!flooreffects(otmp2, u.ux, u.uy, "
\97\8e\82¿
\82é")) {
2043 place_object(otmp2, u.ux, u.uy);
2049 losehp(Maybe_Half_Phys(dmg), "scroll of earth", KILLED_BY_AN);
2051 losehp(Maybe_Half_Phys(dmg), "
\91å
\92n
\82Ì
\8aª
\95¨
\82Å", KILLED_BY_AN);
2055 drop_boulder_on_monster(x, y, confused, byu)
2057 boolean confused, byu;
2059 register struct obj *otmp2;
2060 register struct monst *mtmp;
2062 /* Make the object(s) */
2063 otmp2 = mksobj(confused ? ROCK : BOULDER, FALSE, FALSE);
2065 return FALSE; /* Shouldn't happen */
2066 otmp2->quan = confused ? rn1(5, 2) : 1;
2067 otmp2->owt = weight(otmp2);
2069 /* Find the monster here (won't be player) */
2071 if (mtmp && !amorphous(mtmp->data) && !passes_walls(mtmp->data)
2072 && !noncorporeal(mtmp->data) && !unsolid(mtmp->data)) {
2073 struct obj *helmet = which_armor(mtmp, W_ARMH);
2076 if (cansee(mtmp->mx, mtmp->my)) {
2078 pline("%s is hit by %s!", Monnam(mtmp), doname(otmp2));
2080 pline("%s
\82ª%s
\82É
\96½
\92\86\82µ
\82½
\81I", doname(otmp2), Monnam(mtmp));
2081 if (mtmp->minvis && !canspotmon(mtmp))
2082 map_invisible(mtmp->mx, mtmp->my);
2083 } else if (u.uswallow && mtmp == u.ustuck)
2084 You_hear("something hit %s %s over your %s!",
2085 s_suffix(mon_nam(mtmp)), mbodypart(mtmp, STOMACH),
2088 mdmg = dmgval(otmp2, mtmp) * otmp2->quan;
2090 if (is_metallic(helmet)) {
2091 if (canspotmon(mtmp))
2093 pline("Fortunately, %s is wearing a hard helmet.",
2095 pline("
\8dK
\89^
\82É
\82à
\81C%s
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\81D",
2099 You_hear("a clanging sound.");
2101 You_hear("
\83K
\83\89\83\93\83K
\83\89\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2105 if (canspotmon(mtmp))
2107 pline("%s's %s does not protect %s.", Monnam(mtmp),
2108 xname(helmet), mhim(mtmp));
2110 pline("%s
\82Ì%s
\82Å
\82Í
\8eç
\82ê
\82È
\82¢
\81D", Monnam(mtmp),
2116 if (mtmp->mhp <= 0) {
2120 pline("%s is killed.", Monnam(mtmp));
2124 } else if (u.uswallow && mtmp == u.ustuck) {
2125 obfree(otmp2, (struct obj *) 0);
2126 /* fall through to player */
2127 drop_boulder_on_player(confused, TRUE, FALSE, TRUE);
2130 /* Drop the rock/boulder to the floor */
2132 if (!flooreffects(otmp2, x, y, "fall")) {
2134 if (!flooreffects(otmp2, x, y, "
\97\8e\82¿
\82é")) {
2135 place_object(otmp2, x, y);
2137 newsym(x, y); /* map the rock */
2142 /* overcharging any wand or zapping/engraving cursed wand */
2144 wand_explode(obj, chg)
2146 int chg; /* recharging */
2149 const char *expl = !chg ? "suddenly" : "vibrates violently and";
2151 const char *expl = !chg ? "
\93Ë
\91R" : "
\8c\83\82µ
\82
\90U
\93®
\82µ
\81C";
2154 /* number of damage dice */
2156 chg = 2; /* zap/engrave adjustment */
2159 n = 2; /* arbitrary minimum */
2160 /* size of damage dice */
2161 switch (obj->otyp) {
2165 case WAN_CANCELLATION:
2168 case WAN_UNDEAD_TURNING:
2174 case WAN_MAGIC_MISSILE:
2184 /* inflict damage and destroy the wand */
2186 obj->in_use = TRUE; /* in case losehp() is fatal (or --More--^C) */
2188 pline("%s %s explodes!", Yname2(obj), expl);
2190 pline("%s
\82Í%s
\94\9a\94
\82µ
\82½
\81I", xname(obj), expl);
2193 losehp(Maybe_Half_Phys(dmg), "exploding wand", KILLED_BY_AN);
2195 losehp(Maybe_Half_Phys(dmg), "
\8fñ
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
2197 /* obscure side-effect */
2198 exercise(A_STR, FALSE);
2201 /* used to collect gremlins being hit by light so that they can be processed
2202 after vision for the entire lit area has been brought up to date */
2207 STATIC_VAR struct litmon *gremlins = 0;
2210 * Low-level lit-field update routine.
2218 struct litmon *gremlin;
2222 if ((mtmp = m_at(x, y)) != 0 && mtmp->data == &mons[PM_GREMLIN]) {
2223 gremlin = (struct litmon *) alloc(sizeof *gremlin);
2224 gremlin->mon = mtmp;
2225 gremlin->nxt = gremlins;
2230 snuff_light_source(x, y);
2236 register boolean on;
2239 char is_lit; /* value is irrelevant; we use its address
2240 as a `not null' flag for set_lit() */
2242 /* first produce the text (provided you're not blind) */
2244 register struct obj *otmp;
2249 pline("It seems even darker in here than before.");
2251 pline("
\91O
\82æ
\82è
\88Ã
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D");
2253 if (uwep && artifact_light(uwep) && uwep->lamplit)
2255 pline("Suddenly, the only light left comes from %s!",
2257 pline("
\93Ë
\91R
\81C
\96¾
\82©
\82è
\82ª%s
\82¾
\82¯
\82É
\82È
\82Á
\82½
\81I",
2261 You("are surrounded by darkness!");
2263 You("
\88Ã
\88Å
\82É
\95¢
\82í
\82ê
\82½
\81I");
2267 /* the magic douses lamps, et al, too */
2268 for (otmp = invent; otmp; otmp = otmp->nobj)
2270 (void) snuff_lit(otmp);
2275 else if (is_animal(u.ustuck->data))
2277 pline("%s %s is lit.", s_suffix(Monnam(u.ustuck)),
2278 mbodypart(u.ustuck, STOMACH));
2280 pline("%s
\82Ì%s
\82Í
\96¾
\82é
\82
\82È
\82Á
\82½
\81D", Monnam(u.ustuck),
2281 mbodypart(u.ustuck, STOMACH));
2283 else if (is_whirly(u.ustuck->data))
2285 pline("%s shines briefly.", Monnam(u.ustuck));
2287 pline("%s
\82Í
\82¿
\82å
\82Á
\82Æ
\8bP
\82¢
\82½
\81D", Monnam(u.ustuck));
2290 pline("%s glistens.", Monnam(u.ustuck));
2292 pline("%s
\82Í
\82«
\82ç
\82«
\82ç
\8bP
\82¢
\82½
\81D", Monnam(u.ustuck));
2295 pline("A lit field surrounds you!");
2297 pline("
\93\94\82è
\82ª
\82 \82È
\82½
\82ð
\8eæ
\82è
\88Í
\82ñ
\82¾
\81I");
2300 /* No-op when swallowed or in water */
2301 if (u.uswallow || Underwater || Is_waterlevel(&u.uz))
2304 * If we are darkening the room and the hero is punished but not
2305 * blind, then we have to pick up and replace the ball and chain so
2306 * that we don't remember them if they are out of sight.
2308 if (Punished && !on && !Blind)
2309 move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
2311 if (Is_rogue_level(&u.uz)) {
2312 /* Can't use do_clear_area because MAX_RADIUS is too small */
2313 /* rogue lighting must light the entire room */
2314 int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
2318 for (rx = rooms[rnum].lx - 1; rx <= rooms[rnum].hx + 1; rx++)
2319 for (ry = rooms[rnum].ly - 1; ry <= rooms[rnum].hy + 1; ry++)
2321 (genericptr_t) (on ? &is_lit : (char *) 0));
2322 rooms[rnum].rlit = on;
2324 /* hallways remain dark on the rogue level */
2326 do_clear_area(u.ux, u.uy,
2327 (obj && obj->oclass == SCROLL_CLASS && obj->blessed)
2329 set_lit, (genericptr_t) (on ? &is_lit : (char *) 0));
2332 * If we are not blind, then force a redraw on all positions in sight
2333 * by temporarily blinding the hero. The vision recalculation will
2334 * correctly update all previously seen positions *and* correctly
2335 * set the waslit bit [could be messed up from above].
2340 /* replace ball&chain */
2341 if (Punished && !on)
2342 move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
2345 vision_full_recalc = 1; /* delayed vision recalculation */
2347 struct litmon *gremlin;
2349 /* can't delay vision recalc after all */
2351 /* after vision has been updated, monsters who are affected
2352 when hit by light can now be hit by it */
2355 gremlins = gremlin->nxt;
2356 light_hits_gremlin(gremlin->mon, rnd(5));
2357 free((genericptr_t) gremlin);
2365 int i, j, immunecnt, gonecnt, goodcnt, class, feel_dead = 0;
2367 boolean gameover = FALSE; /* true iff killed self */
2371 pline1(thats_enough_tries);
2376 getlin("What class of monsters do you wish to genocide?", buf);
2378 getlin("
\82Ç
\82Ì
\83N
\83\89\83X
\82É
\91®
\82·
\82é
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ
\82Ü
\82·
\82©
\81H[
\95¶
\8e\9a\82ð
\93ü
\82ê
\82Ä
\82Ë]", buf);
2379 (void) mungspaces(buf);
2381 /* choosing "none" preserves genocideless conduct */
2383 if (*buf == '\033' || !strcmpi(buf, "none")
2384 || !strcmpi(buf, "nothing"))
2386 if (*buf == '\033' || !strcmpi(buf, "
\82È
\82µ")
2387 || !strcmpi(buf, "
\96³
\82µ"))
2391 class = name_to_monclass(buf, (int *) 0);
2392 if (class == 0 && (i = name_to_mon(buf)) != NON_PM)
2393 class = mons[i].mlet;
2394 immunecnt = gonecnt = goodcnt = 0;
2395 for (i = LOW_PM; i < NUMMONS; i++) {
2396 if (mons[i].mlet == class) {
2397 if (!(mons[i].geno & G_GENO))
2399 else if (mvitals[i].mvflags & G_GENOD)
2405 if (!goodcnt && class != mons[urole.malenum].mlet
2406 && class != mons[urace.malenum].mlet) {
2409 pline("All such monsters are already nonexistent.");
2411 pline("
\82»
\82Ì
\89ö
\95¨
\82Í
\82à
\82¤
\82¢
\82È
\82¢
\81D");
2412 else if (immunecnt || class == S_invisible)
2414 You("aren't permitted to genocide such monsters.");
2416 You("
\82»
\82Ì
\89ö
\95¨
\82ð
\8bs
\8eE
\82·
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
2417 else if (wizard && buf[0] == '*') {
2418 register struct monst *mtmp, *mtmp2;
2421 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
2423 if (DEADMONSTER(mtmp))
2429 pline("Eliminated %d monster%s.", gonecnt, plur(gonecnt));
2431 pline("%d
\82Ì
\89ö
\95¨
\82ð
\8f\9c\82¢
\82½
\81D", gonecnt);
2435 pline("That %s does not represent any monster.",
2436 strlen(buf) == 1 ? "symbol" : "response");
2438 pline("
\82»
\82Ì
\82æ
\82¤
\82È
\89ö
\95¨
\82Í
\82¢
\82È
\82¢
\81D");
2443 for (i = LOW_PM; i < NUMMONS; i++) {
2444 if (mons[i].mlet == class) {
2447 Strcpy(nam, makeplural(mons[i].mname));
2448 /* Although "genus" is Latin for race, the hero benefits
2449 * from both race and role; thus genocide affects either.
2451 if (Your_Own_Role(i) || Your_Own_Race(i)
2452 || ((mons[i].geno & G_GENO)
2453 && !(mvitals[i].mvflags & G_GENOD))) {
2454 /* This check must be first since player monsters might
2455 * have G_GENOD or !G_GENO.
2457 mvitals[i].mvflags |= (G_GENOD | G_NOCORPSE);
2459 kill_genocided_monsters();
2460 update_inventory(); /* eggs & tins */
2462 pline("Wiped out all %s.", nam);
2464 pline("%s
\82ð
\91S
\82Ä
\94r
\8f\9c\82µ
\82½
\81D", nam);
2465 if (Upolyd && i == u.umonnum) {
2472 You("
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
2473 /* finish genociding this class of
2474 monsters before ultimately dying */
2479 /* Self-genocide if it matches either your race
2480 or role. Assumption: male and female forms
2481 share same monster class. */
2482 if (i == urole.malenum || i == urace.malenum) {
2487 You_feel("dead inside.");
2489 You("
\8d°
\82ª
\8e\80\82ñ
\82¾
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
2495 You("
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
2499 } else if (mvitals[i].mvflags & G_GENOD) {
2502 pline("All %s are already nonexistent.", nam);
2504 pline("%s
\82Í
\8aù
\82É
\82¢
\82È
\82¢
\81D", nam);
2505 } else if (!gameover) {
2506 /* suppress feedback about quest beings except
2507 for those applicable to our own role */
2508 if ((mons[i].msound != MS_LEADER
2509 || quest_info(MS_LEADER) == i)
2510 && (mons[i].msound != MS_NEMESIS
2511 || quest_info(MS_NEMESIS) == i)
2512 && (mons[i].msound != MS_GUARDIAN
2513 || quest_info(MS_GUARDIAN) == i)
2514 /* non-leader/nemesis/guardian role-specific monster
2516 && (i != PM_NINJA /* nuisance */
2517 || Role_if(PM_SAMURAI))) {
2518 boolean named, uniq;
2520 named = type_is_pname(&mons[i]) ? TRUE : FALSE;
2521 uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE;
2522 /* one special case */
2523 if (i == PM_HIGH_PRIEST)
2527 You("aren't permitted to genocide %s%s.",
2528 (uniq && !named) ? "the " : "",
2529 (uniq || named) ? mons[i].mname : nam);
2531 You("%s
\82ð
\8bs
\8eE
\82Å
\82«
\82È
\82¢
\81D",
2532 (uniq || named) ? mons[i].mname : nam);
2538 if (gameover || u.uhp == -1) {
2539 killer.format = KILLED_BY_AN;
2541 Strcpy(killer.name, "scroll of genocide");
2543 Strcpy(killer.name, "
\8bs
\8eE
\82Ì
\8aª
\95¨
\82Å");
2557 /* 0 = no genocide; create monsters (cursed scroll) */
2558 /* 1 = normal genocide */
2559 /* 3 = forced genocide of player */
2560 /* 5 (4 | 1) = normal genocide from throne */
2563 register int i, killplayer = 0;
2565 register struct permonst *ptr;
2569 mndx = u.umonster; /* non-polymorphed mon num */
2571 Strcpy(buf, ptr->mname);
2576 pline1(thats_enough_tries);
2580 getlin("What monster do you want to genocide? [type the name]",
2582 getlin("
\82Ç
\82Ì
\89ö
\95¨
\82ð
\8bs
\8eE
\82µ
\82Ü
\82·
\82©
\81H[
\96¼
\91O
\82ð
\93ü
\82ê
\82Ä
\82Ë]",
2584 (void) mungspaces(buf);
2585 /* choosing "none" preserves genocideless conduct */
2587 if (!strcmpi(buf, "none") || !strcmpi(buf, "nothing")) {
2589 if (!strcmpi(buf, "
\82È
\82µ") || !strcmpi(buf, "
\96³
\82µ")) {
2590 /* ... but no free pass if cursed */
2591 if (!(how & REALLY)) {
2594 return; /* no message, like normal case */
2595 mndx = monsndx(ptr);
2596 break; /* remaining checks don't apply */
2601 mndx = name_to_mon(buf);
2602 if (mndx == NON_PM || (mvitals[mndx].mvflags & G_GENOD)) {
2604 pline("Such creatures %s exist in this world.",
2605 (mndx == NON_PM) ? "do not" : "no longer");
2607 pline("
\82»
\82Ì
\82æ
\82¤
\82È
\90¶
\82«
\95¨
\82Í%s
\82±
\82Ì
\90¢
\8aE
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\81D",
2608 (mndx == NON_PM) ? "" : "
\82à
\82Í
\82â");
2613 /* Although "genus" is Latin for race, the hero benefits
2614 * from both race and role; thus genocide affects either.
2616 if (Your_Own_Role(mndx) || Your_Own_Race(mndx)) {
2621 adjalign(-sgn(u.ualign.type));
2623 adjalign(sgn(u.ualign.type));
2625 if (!(ptr->geno & G_GENO)) {
2627 /* fixme: unconditional "caverns" will be silly in some
2632 "A thunderous voice booms through the caverns:");
2634 "
\97\8b\82Ì
\82æ
\82¤
\82È
\90º
\82ª
\93´
\8cA
\82É
\8b¿
\82¢
\82½
\81F");
2636 verbalize("No, mortal! That will not be done.");
2638 pline("
\81u
\92è
\96½
\82Ì
\8eÒ
\82æ
\81I
\82»
\82Ì
\96]
\82Ý
\82Í
\82©
\82È
\82¤
\82Ü
\82¢
\81D
\81v");
2642 /* KMH -- Unchanging prevents rehumanization */
2643 if (Unchanging && ptr == youmonst.data)
2653 if (Hallucination) {
2655 Strcpy(buf, youmonst.data->mname);
2657 Strcpy(buf, (flags.female && urole.name.f) ? urole.name.f
2659 buf[0] = lowc(buf[0]);
2662 Strcpy(buf, ptr->mname); /* make sure we have standard singular */
2663 if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST])
2665 which = !type_is_pname(ptr) ? "the " : "";
2667 which = !type_is_pname(ptr) ? "" : "";
2670 /* setting no-corpse affects wishing and random tin generation */
2671 mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE);
2673 pline("Wiped out %s%s.", which,
2674 (*which != 'a') ? buf : makeplural(buf));
2676 pline("%s
\82ð%s
\88ê
\91|
\82µ
\82½
\81D", buf, which);
2680 /* might need to wipe out dual role */
2681 if (urole.femalenum != NON_PM && mndx == urole.malenum)
2682 mvitals[urole.femalenum].mvflags |= (G_GENOD | G_NOCORPSE);
2683 if (urole.femalenum != NON_PM && mndx == urole.femalenum)
2684 mvitals[urole.malenum].mvflags |= (G_GENOD | G_NOCORPSE);
2685 if (urace.femalenum != NON_PM && mndx == urace.malenum)
2686 mvitals[urace.femalenum].mvflags |= (G_GENOD | G_NOCORPSE);
2687 if (urace.femalenum != NON_PM && mndx == urace.femalenum)
2688 mvitals[urace.malenum].mvflags |= (G_GENOD | G_NOCORPSE);
2692 killer.format = KILLED_BY;
2694 Strcpy(killer.name, "genocidal confusion");
2696 Strcpy(killer.name, "
\8d¬
\97\90\82É
\82æ
\82é
\8e©
\8bs
\93I
\8bs
\8eE
\82Å");
2697 } else if (how & ONTHRONE) {
2698 /* player selected while on a throne */
2699 killer.format = KILLED_BY_AN;
2701 Strcpy(killer.name, "imperious order");
2703 Strcpy(killer.name, "
\98ü
\96\9d\82È
\96½
\97ß
\82Å");
2704 } else { /* selected player deliberately, not confused */
2705 killer.format = KILLED_BY_AN;
2707 Strcpy(killer.name, "scroll of genocide");
2709 Strcpy(killer.name, "
\8bs
\8eE
\82Ì
\8aª
\95¨
\82Å");
2712 /* Polymorphed characters will die as soon as they're rehumanized.
2714 /* KMH -- Unchanging prevents rehumanization */
2715 if (Upolyd && ptr != youmonst.data) {
2716 delayed_killer(POLYMORPH, killer.format, killer.name);
2718 You_feel("dead inside.");
2720 You("
\8d°
\82ª
\8e\80\82ñ
\82¾
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
2723 } else if (ptr == youmonst.data) {
2726 reset_rndmonst(mndx);
2727 kill_genocided_monsters();
2728 update_inventory(); /* in case identified eggs were affected */
2730 int cnt = 0, census = monster_census(FALSE);
2732 if (!(mons[mndx].geno & G_UNIQ)
2733 && !(mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT)))
2734 for (i = rn1(3, 4); i > 0; i--) {
2735 if (!makemon(ptr, u.ux, u.uy, NO_MINVENT))
2736 break; /* couldn't make one */
2738 if (mvitals[mndx].mvflags & G_EXTINCT)
2739 break; /* just made last one */
2742 /* accumulated 'cnt' doesn't take groups into account;
2743 assume bringing in new mon(s) didn't remove any old ones */
2744 cnt = monster_census(FALSE) - census;
2746 pline("Sent in %s%s.", (cnt > 1) ? "some " : "",
2747 (cnt > 1) ? makeplural(buf) : an(buf));
2749 pline("%s
\82ª
\91\97\82ç
\82ê
\82Ä
\82«
\82½
\81D", buf);
2752 pline1(nothing_happens);
2760 struct obj *reuse_ball = (sobj && sobj->otyp == HEAVY_IRON_BALL)
2761 ? sobj : (struct obj *) 0;
2763 /* KMH -- Punishment is still okay when you are riding */
2766 You("are being punished for your misbehavior!");
2768 You("
\95s
\8dì
\96@
\82Ì
\82½
\82ß
\94±
\82ð
\8eó
\82¯
\82½
\81I");
2771 Your("iron ball gets heavier.");
2773 Your("
\93S
\8b\85\82Í
\82³
\82ç
\82É
\8fd
\82
\82È
\82Á
\82½
\81D");
2774 uball->owt += 160 * (1 + sobj->cursed);
2777 if (amorphous(youmonst.data) || is_whirly(youmonst.data)
2778 || unsolid(youmonst.data)) {
2781 pline("A ball and chain appears, then falls away.");
2783 pline("
\93S
\8b\85\82Æ
\8d½
\82ª
\8c»
\82í
\82ê
\82½
\82ª
\81C
\82·
\82é
\82Á
\82Æ
\94²
\82¯
\82½
\81D");
2784 dropy(mkobj(BALL_CLASS, TRUE));
2790 setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
2792 setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
2794 setworn(reuse_ball, W_BALL);
2795 uball->spe = 1; /* special ball (see save) */
2798 * Place ball & chain if not swallowed. If swallowed, the ball &
2799 * chain variables will be set at the next call to placebc().
2804 set_bc(1); /* set up ball and chain variables */
2805 newsym(u.ux, u.uy); /* see ball&chain if can't see self */
2809 /* remove the ball and chain */
2813 struct obj *savechain = uchain;
2815 obj_extract_self(uchain);
2816 newsym(uchain->ox, uchain->oy);
2817 setworn((struct obj *) 0, W_CHAIN);
2818 dealloc_obj(savechain);
2820 setworn((struct obj *) 0, W_BALL);
2823 /* some creatures have special data structures that only make sense in their
2824 * normal locations -- if the player tries to create one elsewhere, or to
2825 * revive one, the disoriented creature becomes a zombie
2828 cant_revive(mtype, revival, from_obj)
2831 struct obj *from_obj;
2833 /* SHOPKEEPERS can be revived now */
2834 if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival)
2835 || *mtype == PM_HIGH_PRIEST || *mtype == PM_ALIGNED_PRIEST
2836 || *mtype == PM_ANGEL) {
2837 *mtype = PM_HUMAN_ZOMBIE;
2839 } else if (*mtype == PM_LONG_WORM_TAIL) { /* for create_particular() */
2840 *mtype = PM_LONG_WORM;
2842 } else if (unique_corpstat(&mons[*mtype])
2843 && (!from_obj || !has_omonst(from_obj))) {
2844 /* unique corpses (from bones or wizard mode wish) or
2845 statues (bones or any wish) end up as shapechangers */
2846 *mtype = PM_DOPPELGANGER;
2853 * Make a new monster with the type controlled by the user.
2855 * Note: when creating a monster by class letter, specifying the
2856 * "strange object" (']') symbol produces a random monster rather
2857 * than a mimic. This behavior quirk is useful so don't "fix" it
2858 * (use 'm'--or "mimic"--to create a random mimic).
2860 * Used in wizard mode only (for ^G command and for scroll or spell
2861 * of create monster). Once upon a time, an earlier incarnation of
2862 * this code was also used for the scroll/spell in explore mode.
2867 char buf[BUFSZ], *bufp, monclass;
2868 int which, tryct, i, firstchoice = NON_PM;
2869 struct permonst *whichpm = NULL;
2871 boolean madeany = FALSE;
2872 boolean maketame, makepeaceful, makehostile;
2873 boolean randmonst = FALSE;
2877 monclass = MAXMCLASSES;
2878 which = urole.malenum; /* an arbitrary index into mons[] */
2879 maketame = makepeaceful = makehostile = FALSE;
2881 getlin("Create what kind of monster? [type the name or symbol]", buf);
2883 getlin("
\82Ç
\82Ì
\8eí
\82Ì
\89ö
\95¨
\82ð
\8dì
\82è
\82Ü
\82·
\82©
\81H[
\96¼
\91O
\82ð
\93ü
\82ê
\82Ä
\82Ë]", buf);
2884 bufp = mungspaces(buf);
2885 if (*bufp == '\033')
2887 /* allow the initial disposition to be specified */
2889 if (!strncmpi(bufp, "tame ", 5)) {
2892 if (!strncmpi(bufp, "
\8eè
\82È
\82¸
\82¯
\82ç
\82ê
\82½", 14)) {
2897 } else if (!strncmpi(bufp, "peaceful ", 9)) {
2900 } else if (!strncmpi(bufp, "
\97F
\8dD
\93I
\82È", 8)) {
2903 makepeaceful = TRUE;
2905 } else if (!strncmpi(bufp, "hostile ", 8)) {
2908 } else if (!strncmpi(bufp, "
\93G
\91Î
\93I
\82È", 8)) {
2913 /* decide whether a valid monster was chosen */
2915 if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "random"))) {
2917 if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "
\83\89\83\93\83_
\83\80"))) {
2921 which = name_to_mon(bufp);
2922 if (which >= LOW_PM)
2923 break; /* got one */
2924 monclass = name_to_monclass(bufp, &which);
2925 if (which >= LOW_PM) {
2926 monclass = MAXMCLASSES; /* matters below */
2928 } else if (monclass > 0) {
2929 which = urole.malenum; /* reset from NON_PM */
2932 /* no good; try again... */
2934 pline("I've never heard of such monsters.");
2936 pline("
\82»
\82Ì
\82æ
\82¤
\82È
\89ö
\95¨
\82Í
\95·
\82¢
\82½
\82±
\82Æ
\82ª
\82È
\82¢
\81D");
2937 } while (--tryct > 0);
2940 pline1(thats_enough_tries);
2943 firstchoice = which;
2944 if (cant_revive(&which, FALSE, (struct obj *) 0)) {
2945 /* wizard mode can override handling of special monsters */
2947 Sprintf(buf, "Creating %s instead; force %s?",
2948 mons[which].mname, mons[firstchoice].mname);
2950 Sprintf(buf, "
\91ã
\82í
\82è
\82É%s
\82ª
\8dì
\82ç
\82ê
\82Ü
\82·
\81G%s
\82É
\82·
\82é
\81H",
2951 mons[which].mname, mons[firstchoice].mname);
2954 which = firstchoice;
2956 whichpm = &mons[which];
2958 for (i = 0; i <= multi; i++) {
2959 if (monclass != MAXMCLASSES)
2960 whichpm = mkclass(monclass, 0);
2962 whichpm = rndmonst();
2963 mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS);
2965 /* quit trying if creation failed and is going to repeat */
2966 if (monclass == MAXMCLASSES && !randmonst)
2968 /* otherwise try again */
2972 (void) tamedog(mtmp, (struct obj *) 0);
2973 } else if (makepeaceful || makehostile) {
2974 mtmp->mtame = 0; /* sanity precaution */
2975 mtmp->mpeaceful = makepeaceful ? 1 : 0;
2979 /* in case we got a doppelganger instead of what was asked
2980 for, make it start out looking like what was asked for */
2981 if (mtmp->cham != NON_PM && firstchoice != NON_PM
2982 && mtmp->cham != firstchoice)
2983 (void) newcham(mtmp, &mons[firstchoice], FALSE, FALSE);