OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / src / read.c
1 /* NetHack 3.6  read.c  $NHDT-Date: 1515802375 2018/01/13 00:12:55 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.150 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 #define Your_Own_Role(mndx)  \
14     ((mndx) == urole.malenum \
15      || (urole.femalenum != NON_PM && (mndx) == urole.femalenum))
16 #define Your_Own_Race(mndx)  \
17     ((mndx) == urace.malenum \
18      || (urace.femalenum != NON_PM && (mndx) == urace.femalenum))
19
20 boolean known;
21
22 static NEARDATA const char readable[] = { ALL_CLASSES, SCROLL_CLASS,
23                                           SPBOOK_CLASS, 0 };
24 static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
25
26 STATIC_DCL boolean FDECL(learnscrolltyp, (SHORT_P));
27 STATIC_DCL char * FDECL(erode_obj_text, (struct obj *, char *));
28 STATIC_DCL void NDECL(do_class_genocide);
29 STATIC_DCL void FDECL(stripspe, (struct obj *));
30 STATIC_DCL void FDECL(p_glow1, (struct obj *));
31 STATIC_DCL void FDECL(p_glow2, (struct obj *, const char *));
32 STATIC_DCL void FDECL(randomize, (int *, int));
33 STATIC_DCL void FDECL(forget_single_object, (int));
34 STATIC_DCL void FDECL(forget, (int));
35 STATIC_DCL int FDECL(maybe_tame, (struct monst *, struct obj *));
36 STATIC_DCL boolean FDECL(is_valid_stinking_cloud_pos, (int, int, BOOLEAN_P));
37 STATIC_DCL void FDECL(display_stinking_cloud_positions, (int));
38 STATIC_DCL boolean FDECL(get_valid_stinking_cloud_pos, (int, int));
39 STATIC_PTR void FDECL(set_lit, (int, int, genericptr));
40
41 STATIC_OVL boolean
42 learnscrolltyp(scrolltyp)
43 short scrolltyp;
44 {
45     if (!objects[scrolltyp].oc_name_known) {
46         makeknown(scrolltyp);
47         more_experienced(0, 10);
48         return TRUE;
49     } else
50         return FALSE;
51 }
52
53 /* also called from teleport.c for scroll of teleportation */
54 void
55 learnscroll(sobj)
56 struct obj *sobj;
57 {
58     /* it's implied that sobj->dknown is set;
59        we couldn't be reading this scroll otherwise */
60     if (sobj->oclass != SPBOOK_CLASS)
61         (void) learnscrolltyp(sobj->otyp);
62 }
63
64 char *
65 erode_obj_text(otmp, buf)
66 struct obj *otmp;
67 char *buf;
68 {
69     int erosion = greatest_erosion(otmp);
70
71     if (erosion)
72         wipeout_text(buf, (int) (strlen(buf) * erosion / (2 * MAX_ERODE)),
73                      otmp->o_id ^ (unsigned) ubirthday);
74     return buf;
75 }
76
77 char *
78 tshirt_text(tshirt, buf)
79 struct obj *tshirt;
80 char *buf;
81 {
82     static const char *shirt_msgs[] = {
83         /* Scott Bigham */
84 #if 0 /*JP*/
85       "I explored the Dungeons of Doom and all I got was this lousy T-shirt!",
86         "Is that Mjollnir in your pocket or are you just happy to see me?",
87       "It's not the size of your sword, it's how #enhance'd you are with it.",
88         "Madame Elvira's House O' Succubi Lifetime Customer",
89         "Madame Elvira's House O' Succubi Employee of the Month",
90         "Ludios Vault Guards Do It In Small, Dark Rooms",
91         "Yendor Military Soldiers Do It In Large Groups",
92         "I survived Yendor Military Boot Camp",
93         "Ludios Accounting School Intra-Mural Lacrosse Team",
94         "Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest",
95         "Hey, black dragon!  Disintegrate THIS!",
96         "I'm With Stupid -->",
97         "Don't blame me, I voted for Izchak!",
98         "Don't Panic", /* HHGTTG */
99         "Furinkan High School Athletic Dept.",                /* Ranma 1/2 */
100         "Hel-LOOO, Nurse!",                                   /* Animaniacs */
101 #else
102         "\8e\84\82Í\89^\96½\82Ì\96À\8b{\82ð\92²\8d¸\82µ\82Ä\82¢\82½\82ª\81C\8eè\82É\93ü\82ê\82½\82Ì\82Í\82«\82½\82È\82¢\82s\83V\83\83\83c\82¾\82¯\82¾\82Á\82½\81I",
103         "\83|\83P\83b\83g\82É\83~\83\85\83\8b\83j\81[\83\8b\82ª\93ü\82Á\82Ä\82¢\82é\82Ì\81H\82»\82ê\82Æ\82à\8e\84\82É\89ï\82¦\82Ä\82¤\82ê\82µ\82¢\81H",
104         "\8c\95\82Ì\91å\82«\82³\82ª\96â\91è\82È\82Ì\82Å\82Í\82È\82¢\81D\82»\82ê\82ª\94@\89½\82É#enhance\82³\82ê\82Ä\82¢\82é\82©\82È\82Ì\82¾\81D",
105         "\83}\83_\83\80\81E\83G\83\8b\83o\83C\83\89\82Ì\83T\83L\83\85\83o\83X\8aÙ \89i\8bv\8cÚ\8bq",
106         "\83}\83_\83\80\81E\83G\83\8b\83o\83C\83\89\82Ì\83T\83L\83\85\83o\83X\8aÙ \8d¡\8c\8e\82Ì\8dÅ\97D\8fG\8c÷\98J\8eÒ",
107         "\83\8d\81[\83f\83B\83I\83X\8bà\8cÉ\82Ì\94Ô\90l\81C\82»\82ê\82Í\88Ã\82­\8f¬\82³\82¢\95\94\89®\82Ì\92\86",
108         "\83C\83F\83\93\83_\81[\8cR\95º\8em\81C\82»\82ê\82Í\8b\90\91å\82È\92c\91Ì\82Ì\92\86",
109         "\8e\84\82Í\83C\83F\83\93\83_\81[\8cR\82Ì\90V\95º\8cP\97û\8f\8a\82ð\8fæ\82è\89z\82¦\82Ü\82µ\82½",
110         "\83\8d\81[\83f\83B\83I\83X\89ï\8cv\8aw\8d\8eº\93à\83\89\83N\83\8d\83X\83`\81[\83\80",
111         "Oracle(TM) \82Ì\90ò \91æ\82P\82O\89ñ\94G\82ê\82s\83V\83\83\83c\83R\83\93\83e\83X\83g",
112         "\82¨\82¢\81C\8d\95\83h\83\89\83S\83\93\81I\82±\82¢\82Â\82ð\95ª\89ð\82µ\82ë\81I",
113         "\94n\8e­\82Æ\88ê\8f\8f\82É\82¢\82Ü\82· \81¨ ",
114         "\8e\84\82Í\88«\82­\82È\82¢\81IIzchak\82É\93\8a\95[\82µ\82½\82à\82Ì\81I",
115         "\82  \82í \82Ä \82é \82È", /* \8bâ\89Í\83q\83b\83`\83n\83C\83N\83K\83C\83h */
116         "\95\97\97Ñ\8aÙ\8d\82\8dZ\97¤\8fã\95\94",                                   /* Ranma 1/2 */
117         "\82g\82\85\82\8c\81|\82k\82n\82n\82n\81C\82m\82\95\82\92\82\93\82\85\81I",                     /* Animaniacs */
118 #endif
119         "=^.^=",
120 #if 0 /*JP*/
121         "100% goblin hair - do not wash",
122         "Aberzombie and Fitch",
123         "cK -- Cockatrice touches the Kop",
124         "Don't ask me, I only adventure here",
125         "Down with pants!",
126         "d, your dog or a killer?",
127         "FREE PUG AND NEWT!",
128         "Go team ant!",
129         "Got newt?",
130         "Hello, my darlings!", /* Charlie Drake */
131         "Hey!  Nymphs!  Steal This T-Shirt!",
132         "I <3 Dungeon of Doom",
133         "I <3 Maud",
134         "I am a Valkyrie.  If you see me running, try to keep up.",
135         "I am not a pack rat - I am a collector",
136         "I bounced off a rubber tree",         /* Monkey Island */
137         "Plunder Island Brimstone Beach Club", /* Monkey Island */
138 #else
139         "\83S\83u\83\8a\83\93\96Ñ100% - \90ô\82¦\82Ü\82¹\82ñ",
140         "\83A\83o\83]\83\93\83r&\83t\83B\83b\83`",
141         "cK -- \83R\83J\83g\83\8a\83X\82ª\8cx\8a¯\82É\83^\83b\83`",
142         "\8e¿\96â\82µ\82È\82¢\82Å; \8e\84\82Í\82±\82±\82ð\92T\8c\9f\82µ\82Ä\82¢\82é\82¾\82¯",
143         "Down with pants!",
144         "d\82Í\82 \82È\82½\82Ì\8c¢\82©\8eE\90l\8eÒ\82©\81H",
145         "FREE PUG AND NEWT!",
146         "Go team ant!",
147         "Got newt?",
148         "\82±\82ñ\82É\82¿\82Í\83_\81[\83\8a\83\93\81I", /* Charlie Drake */
149         "\82â\82 \81I\83j\83\93\83t\81I\82±\82Ì\82s\83V\83\83\83c\82ð\93\90\82ñ\82Å\81I",
150         "I <3 Dungeon of Doom",
151         "I <3 Maud",
152         "\8e\84\82Í\83o\83\8b\83L\83\8a\81[\82¾\81D\8e\84\82ª\91\96\82Á\82Ä\82¢\82é\82Ì\82ð\8c©\82½\82ç\81C\82Â\82¢\82Ä\82±\82¢\81D",
153         "\8e\84\82Í\83S\83~\8fW\82ß\82Å\82Í\82È\82¢\81D\8e\84\82Í\8eû\8fW\89Æ\82¾",
154         "\8e\84\82Í\83S\83\80\82Ì\96Ø\82É\92µ\82Ë\95Ô\82Á\82½",         /* Monkey Island */
155         "\97ª\92D\93\87\97°\89©\8aC\8aÝ\83N\83\89\83u", /* Monkey Island */
156 #endif
157 #if 0 /*JP*/
158         "If you can read this, I can hit you with my polearm",
159         "I'm confused!",
160         "I scored with the princess",
161         "I want to live forever or die in the attempt.",
162         "Lichen Park",
163         "LOST IN THOUGHT - please send search party",
164         "Meat is Mordor",
165         "Minetown Better Business Bureau",
166         "Minetown Watch",
167  "Ms. Palm's House of Negotiable Affection -- A Very Reputable House Of Disrepute",
168         "Protection Racketeer",
169         "Real men love Crom",
170         "Somebody stole my Mojo!",
171         "The Hellhound Gang",
172         "The Werewolves",
173 #else
174         "\82±\82ê\82ª\93Ç\82ß\82é\82È\82ç\81A\8e\84\82Ì\92·\95\80\82ª\93Í\82­\82Æ\82¢\82¤\82±\82Æ\82¾",
175         "\8e\84\82Í\8d¬\97\90\82µ\82Ä\82¢\82Ü\82·\81I",
176         "I scored with the princess",
177         "\8e\84\82Í\89i\89\93\82É\90\82«\82é\82©\81A\82»\82Ì\82½\82ß\82É\8e\80\82É\82½\82¢\81D",
178         "Lichen Park",
179         "\8dl\82¦\8d\9e\82ñ\82Å\82¢\82Ü\82· - \91{\8dõ\91à\82ð\8fo\82µ\82Ä\82­\82¾\82³\82¢",
180         "\93÷\82Í\83\82\83\8b\83h\81[\83\8b",
181         "\8dz\8eR\8aX\8f¤\8bÆ\89ü\91P\8b¦\89ï",
182         "\8dz\8eR\8aX\82Ì\8c©\92£\82è",
183  "\83p\81[\83\80\8f\97\8ej\82Ì\8cð\8fÂ\8bZ\8fp\82Ì\89Æ -- \82Æ\82Ä\82à\95]\94»\82Ì\88«\95]\82Ì\89Æ",
184         "\8dz\8eR\83_\83b\83V\83\85\92\86",
185         "\96{\95¨\82Ì\92j\82Í\83N\83\8d\83\80\82ð\88¤\82·\82é",
186         "\92N\82©\82ª\89´\82Ì\83A\83\8c\82ð\93\90\82ñ\82¾\81I",
187         "The Hellhound Gang",
188         "The Werewolves",
189 #endif
190 #if 0 /*JP*/
191         "They Might Be Storm Giants",
192         "Weapons don't kill people, I kill people",
193         "White Zombie",
194         "You're killing me!",
195         "Anhur State University - Home of the Fighting Fire Ants!",
196         "FREE HUGS",
197         "Serial Ascender",
198         "Real men are valkyries",
199         "Young Men's Cavedigging Association",
200         "Occupy Fort Ludios",
201         "I couldn't afford this T-shirt so I stole it!",
202         "Mind flayers suck",
203         "I'm not wearing any pants",
204         "Down with the living!",
205         "Pudding farmer",
206         "Vegetarian",
207         "Hello, I'm War!",
208         "It is better to light a candle than to curse the darkness",
209         "It is easier to curse the darkness than to light a candle",
210         /* expanded "rock--paper--scissors" featured in TV show "Big Bang
211            Theory" although they didn't create it (and an actual T-shirt
212            with pentagonal diagram showing which choices defeat which) */
213         "rock--paper--scissors--lizard--Spock!",
214         /* "All men must die -- all men must serve" challange and response
215            from book series _A_Song_of_Ice_and_Fire_ by George R.R. Martin,
216            TV show "Game of Thrones" (probably an actual T-shirt too...) */
217         "/Valar morghulis/ -- /Valar dohaeris/",
218 #else
219         "\83[\83C\81E\83}\83C\83g\81E\83r\81[\81E\83X\83g\81[\83\80\81E\83W\83\83\83C\83A\83\93\83c",
220         "\95\90\8aí\82ª\90l\82ð\8eE\82·\82Ì\82Å\82Í\82È\82¢\81C\8e\84\82ª\90l\82ð\8eE\82·\82Ì\82¾",
221         "White Zombie",
222         "\82¢\82¢\89Á\8c¸\82É\82µ\82Ä\81I",
223         "\83A\83\93\83t\83\8b\8fB\97§\91å\8aw - \89Î\8ba\82Æ\82Ì\90í\82¢\82Ì\96{\8b\92\92n\81I",
224         "FREE HUGS",
225         "\93Á\95Ê\8f¸\93V\8eÒ",
226         "\96{\93\96\82Ì\92j\82Í\83o\83\8b\83L\83\8a\81[\82¾",
227         "\90Â\94N\93´\8cA\8c@\8dí\98A\96¿",
228         "\83\8d\81[\83f\83B\83I\83X\8dÔ\82ð\90è\8b\92\82¹\82æ",
229         "\82±\82Ì\82s\83V\83\83\83c\82ð\94\83\82¤\82¨\8bà\82ª\82È\82©\82Á\82½\82Ì\82Å\82±\82ê\82Í\93\90\82ñ\82¾\81I",
230         "\83}\83C\83\93\83h\83t\83\8c\83\84\8e\81\82Ë",
231         "\8e\84\82Í\83p\83\93\83c\82ð\90ú\82¢\82Ä\82¢\82Ü\82¹\82ñ",
232         "Down with the living!",
233         "\83v\83\8a\83\93\94_\89Æ",
234         "\83x\83W\83^\83\8a\83A\83\93",
235         "\82â\82 \81C\8e\84\82ª\81w\90í\91\88\81x\82¾\81I",
236         "It is better to light a candle than to curse the darkness",
237         "It is easier to curse the darkness than to light a candle",
238         /* expanded "rock--paper--scissors" featured in TV show "Big Bang
239            Theory" although they didn't create it (and an actual T-shirt
240            with pentagonal diagram showing which choices defeat which) */
241         "rock--paper--scissors--lizard--Spock!",
242         /* "All men must die -- all men must serve" challange and response
243            from book series _A_Song_of_Ice_and_Fire_ by George R.R. Martin,
244            TV show "Game of Thrones" (probably an actual T-shirt too...) */
245         "/Valar morghulis/ -- /Valar dohaeris/",
246 #endif
247     };
248
249     Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]);
250     return erode_obj_text(tshirt, buf);
251 }
252
253 char *
254 apron_text(apron, buf)
255 struct obj *apron;
256 char *buf;
257 {
258     static const char *apron_msgs[] = {
259         "Kiss the cook",
260         "I'm making SCIENCE!",
261         "Don't mess with the chef",
262         "Don't make me poison you",
263         "Gehennom's Kitchen",
264         "Rat: The other white meat",
265         "If you can't stand the heat, get out of Gehennom!",
266         "If we weren't meant to eat animals, why are they made out of meat?",
267         "If you don't like the food, I'll stab you",
268     };
269
270     Strcpy(buf, apron_msgs[apron->o_id % SIZE(apron_msgs)]);
271     return erode_obj_text(apron, buf);
272 }
273
274 int
275 doread()
276 {
277     register struct obj *scroll;
278     boolean confused, nodisappear;
279
280     known = FALSE;
281     if (check_capacity((char *) 0))
282         return 0;
283     scroll = getobj(readable, "read");
284     if (!scroll)
285         return 0;
286
287     /* outrumor has its own blindness check */
288     if (scroll->otyp == FORTUNE_COOKIE) {
289         if (flags.verbose)
290 /*JP
291             You("break up the cookie and throw away the pieces.");
292 */
293             You("\83N\83b\83L\81[\82ð\8a\84\82è\81C\82©\82¯\82ç\82ð\93\8a\82°\82·\82Ä\82½\81D");
294         outrumor(bcsign(scroll), BY_COOKIE);
295         if (!Blind)
296             u.uconduct.literate++;
297         useup(scroll);
298         return 1;
299     } else if (scroll->otyp == T_SHIRT || scroll->otyp == ALCHEMY_SMOCK) {
300         char buf[BUFSZ], *mesg;
301         const char *endpunct;
302
303         if (Blind) {
304 /*JP
305             You_cant("feel any Braille writing.");
306 */
307             You("\93_\8e\9a\82Í\82Ç\82¤\82à\8f\91\82¢\82Ä\82È\82¢\82æ\82¤\82¾\81D");
308             return 0;
309         }
310         /* can't read shirt worn under suit (under cloak is ok though) */
311         if (scroll->otyp == T_SHIRT && uarm && scroll == uarmu) {
312 #if 0 /*JP*/
313             pline("%s shirt is obscured by %s%s.",
314                   scroll->unpaid ? "That" : "Your", shk_your(buf, uarm),
315                   suit_simple_name(uarm));
316 #else
317             pline("\83V\83\83\83c\82Í%s\82Å\89B\82³\82ê\82Ä\82¢\82é\81D",
318                   suit_simple_name(uarm));
319 #endif
320             return 0;
321         }
322         u.uconduct.literate++;
323         /* populate 'buf[]' */
324         mesg = (scroll->otyp == T_SHIRT) ? tshirt_text(scroll, buf)
325                                          : apron_text(scroll, buf);
326         endpunct = "";
327         if (flags.verbose) {
328             int ln = (int) strlen(mesg);
329
330             /* we will be displaying a sentence; need ending punctuation */
331             if (ln > 0 && !index(".!?", mesg[ln - 1]))
332                 endpunct = ".";
333 /*JP
334             pline("It reads:");
335 */
336             pline("\82»\82ê\82ð\93Ç\82ñ\82¾\81F");
337         }
338 #if 0 /*JP*/
339         pline("\"%s\"%s", mesg, endpunct);
340 #else
341         pline("\81u%s\81v", mesg);
342 #endif
343         return 1;
344     } else if (scroll->otyp == CREDIT_CARD) {
345         static const char *card_msgs[] = {
346 #if 0 /*JP*/
347             "Leprechaun Gold Tru$t - Shamrock Card",
348             "Magic Memory Vault Charge Card",
349             "Larn National Bank",                /* Larn */
350             "First Bank of Omega",               /* Omega */
351             "Bank of Zork - Frobozz Magic Card", /* Zork */
352             "Ankh-Morpork Merchant's Guild Barter Card",
353             "Ankh-Morpork Thieves' Guild Unlimited Transaction Card",
354             "Ransmannsby Moneylenders Association",
355             "Bank of Gehennom - 99% Interest Card",
356             "Yendorian Express - Copper Card",
357             "Yendorian Express - Silver Card",
358             "Yendorian Express - Gold Card",
359             "Yendorian Express - Mithril Card",
360             "Yendorian Express - Platinum Card", /* must be last */
361 #else
362             "\83\8c\83v\83\89\83R\81[\83\93\90M\97p\8bà\8cÉ - \83N\83\8d\81[\83o\81[\83J\81[\83h",
363             "\96\82\96@\8bL\94O\91q\8cÉ\83N\83\8c\83W\83b\83g\83J\81[\83h", "\83\89\81[\83\93\8d\91\89c\8bâ\8ds", /* Larn */
364             "\83I\83\81\83K\91æ\88ê\8bâ\8ds",               /* Omega */
365             "\83]\81[\83N\8bâ\8ds - Bank of Zork - \83t\83\8d\83{\83Y\96\82\96@\83J\81[\83h", /* Zork */
366             "\83A\83\93\83N\83\82\83\8b\83|\81[\83N\8f¤\90l\83M\83\8b\83\8cð\88Õ\83J\81[\83h",
367             "\83A\83\93\83N\83\82\83\8b\83|\81[\83N\93\90\91¯\83M\83\8b\83\96³\90§\8cÀ\8eæ\88ø\83J\81[\83h",
368             "\83\89\83\93\83X\83}\83\93\83X\83x\83C\91Ý\8bà\8bÆ\8b¦\89ï",
369             "\83Q\83w\83i\8bâ\8ds - \97\98\8eq99%\83J\81[\83h",
370             "\83C\83F\83\93\83_\81[\88ó\83G\83L\83X\83v\83\8c\83X\83J\81[\83h - \83J\83b\83p\81[\83J\81[\83h",
371             "\83C\83F\83\93\83_\81[\88ó\83G\83L\83X\83v\83\8c\83X\83J\81[\83h - \83V\83\8b\83o\81[\83J\81[\83h",
372             "\83C\83F\83\93\83_\81[\88ó\83G\83L\83X\83v\83\8c\83X\83J\81[\83h - \83S\81[\83\8b\83h\83J\81[\83h",
373             "\83C\83F\83\93\83_\81[\88ó\83G\83L\83X\83v\83\8c\83X\83J\81[\83h - \83~\83X\83\8a\83\8b\83J\81[\83h",
374             "\83C\83F\83\93\83_\81[\88ó\83G\83L\83X\83v\83\8c\83X\83J\81[\83h - \83v\83\89\83`\83i\83J\81[\83h", /* must be last */
375 #endif
376         };
377
378         if (Blind) {
379 /*JP
380             You("feel the embossed numbers:");
381 */
382             You("\95\82\82«\92¤\82è\82É\82³\82ê\82Ä\82¢\82é\94Ô\8d\86\82ð\8a´\82\82½:");
383         } else {
384             if (flags.verbose)
385 /*JP
386                 pline("It reads:");
387 */
388                 pline("\82»\82ê\82ð\93Ç\82ñ\82¾\81F");
389 /*JP
390             pline("\"%s\"",
391 */
392             pline("\81u%s\81v",
393                   scroll->oartifact
394                       ? card_msgs[SIZE(card_msgs) - 1]
395                       : card_msgs[scroll->o_id % (SIZE(card_msgs) - 1)]);
396         }
397         /* Make a credit card number */
398         pline("\"%d0%d %ld%d1 0%d%d0\"%s",
399               (((int) scroll->o_id % 89) + 10),
400               ((int) scroll->o_id % 4),
401               ((((long) scroll->o_id * 499L) % 899999L) + 100000L),
402               ((int) scroll->o_id % 10),
403               (!((int) scroll->o_id % 3)),
404               (((int) scroll->o_id * 7) % 10),
405               (flags.verbose || Blind) ? "." : "");
406         u.uconduct.literate++;
407         return 1;
408     } else if (scroll->otyp == CAN_OF_GREASE) {
409 /*JP
410         pline("This %s has no label.", singular(scroll, xname));
411 */
412         pline("\82±\82Ì%s\82É\82Í\83\89\83x\83\8b\82ª\82È\82¢\81D", singular(scroll, xname));
413         return 0;
414     } else if (scroll->otyp == MAGIC_MARKER) {
415         if (Blind) {
416 /*JP
417             You_cant("feel any Braille writing.");
418 */
419             pline("\93_\8e\9a\82Í\82Ç\82¤\82à\8f\91\82¢\82Ä\82È\82¢\82æ\82¤\82¾\81D");
420             return 0;
421         }
422         if (flags.verbose)
423 /*JP
424             pline("It reads:");
425 */
426             pline("\82»\82ê\82ð\93Ç\82ñ\82¾\81F");
427 /*JP
428         pline("\"Magic Marker(TM) Red Ink Marker Pen.  Water Soluble.\"");
429 */
430         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");
431         u.uconduct.literate++;
432         return 1;
433     } else if (scroll->oclass == COIN_CLASS) {
434         if (Blind)
435 /*JP
436             You("feel the embossed words:");
437 */
438             You("\95\82\82«\92¤\82è\82É\82³\82ê\82Ä\82¢\82é\95\8e\9a\82ð\8a´\82\82½:");
439         else if (flags.verbose)
440 /*JP
441             You("read:");
442 */
443             pline("\82»\82ê\82ð\93Ç\82ñ\82¾\81F");
444         pline("\"1 Zorkmid.  857 GUE.  In Frobs We Trust.\"");
445         u.uconduct.literate++;
446         return 1;
447     } else if (scroll->oartifact == ART_ORB_OF_FATE) {
448         if (Blind)
449 /*JP
450             You("feel the engraved signature:");
451 */
452             You("\92¤\82è\8d\9e\82Ü\82ê\82Ä\82¢\82é\83T\83C\83\93\82ð\8a´\82\82½\81F");
453         else
454 /*JP
455             pline("It is signed:");
456 */
457             pline("\83T\83C\83\93\82ª\82 \82é\81F");
458 /*JP
459         pline("\"Odin.\"");
460 */
461         pline("\81u\83I\81[\83f\83B\83\93\81v");
462         u.uconduct.literate++;
463         return 1;
464     } else if (scroll->otyp == CANDY_BAR) {
465         static const char *wrapper_msgs[] = {
466             "Apollo",       /* Lost */
467             "Moon Crunchy", /* South Park */
468             "Snacky Cake",    "Chocolate Nuggie", "The Small Bar",
469             "Crispy Yum Yum", "Nilla Crunchie",   "Berry Bar",
470             "Choco Nummer",   "Om-nom", /* Cat Macro */
471             "Fruity Oaty",              /* Serenity */
472             "Wonka Bar" /* Charlie and the Chocolate Factory */
473         };
474
475         if (Blind) {
476 /*JP
477             You_cant("feel any Braille writing.");
478 */
479             pline("\93_\8e\9a\82Í\82Ç\82¤\82à\8f\91\82¢\82Ä\82È\82¢\82æ\82¤\82¾\81D");
480             return 0;
481         }
482 #if 0 /*JP:T*/
483         pline("The wrapper reads: \"%s\".",
484               wrapper_msgs[scroll->o_id % SIZE(wrapper_msgs)]);
485 #else
486         pline("\95ï\82Ý\8e\86\82Ì\95\8e\9a\82ð\93Ç\82ñ\82¾\81F\81u%s\81v.",
487               wrapper_msgs[scroll->o_id % SIZE(wrapper_msgs)]);
488 #endif
489         u.uconduct.literate++;
490         return 1;
491     } else if (scroll->oclass != SCROLL_CLASS
492                && scroll->oclass != SPBOOK_CLASS) {
493 /*JP
494         pline(silly_thing_to, "read");
495 */
496         pline(silly_thing_to, "\93Ç\82Þ");
497         return 0;
498     } else if (Blind && (scroll->otyp != SPE_BOOK_OF_THE_DEAD)) {
499         const char *what = 0;
500         if (scroll->oclass == SPBOOK_CLASS)
501 /*JP
502             what = "mystic runes";
503 */
504             what = "\90_\94é\93I\82È\83\8b\81[\83\93\95\8e\9a";
505         else if (!scroll->dknown)
506 /*JP
507             what = "formula on the scroll";
508 */
509             what = "\8aª\95¨\82Ì\8eô\95¶";
510         if (what) {
511 /*JP
512             pline("Being blind, you cannot read the %s.", what);
513 */
514             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);
515             return 0;
516         }
517     }
518
519     confused = (Confusion != 0);
520 #ifdef MAIL
521     if (scroll->otyp == SCR_MAIL) {
522         confused = FALSE; /* override */
523         /* reading mail is a convenience for the player and takes
524            place outside the game, so shouldn't affect gameplay;
525            on the other hand, it starts by explicitly making the
526            hero actively read something, which is pretty hard
527            to simply ignore; as a compromise, if the player has
528            maintained illiterate conduct so far, and this mail
529            scroll didn't come from bones, ask for confirmation */
530         if (!u.uconduct.literate) {
531             if (!scroll->spe && yn(
532              "Reading mail will violate \"illiterate\" conduct.  Read anyway?"
533                                    ) != 'y')
534                 return 0;
535         }
536     }
537 #endif
538
539     /* Actions required to win the game aren't counted towards conduct */
540     /* Novel conduct is handled in read_tribute so exclude it too*/
541     if (scroll->otyp != SPE_BOOK_OF_THE_DEAD
542         && scroll->otyp != SPE_BLANK_PAPER && scroll->otyp != SCR_BLANK_PAPER
543         && scroll->otyp != SPE_NOVEL)
544         u.uconduct.literate++;
545
546     if (scroll->oclass == SPBOOK_CLASS) {
547         return study_book(scroll);
548     }
549     scroll->in_use = TRUE; /* scroll, not spellbook, now being read */
550     if (scroll->otyp != SCR_BLANK_PAPER) {
551         boolean silently = !can_chant(&youmonst);
552
553         /* a few scroll feedback messages describe something happening
554            to the scroll itself, so avoid "it disappears" for those */
555         nodisappear = (scroll->otyp == SCR_FIRE
556                        || (scroll->otyp == SCR_REMOVE_CURSE
557                            && scroll->cursed));
558         if (Blind)
559 #if 0 /*JP*/
560             pline(nodisappear
561                       ? "You %s the formula on the scroll."
562                       : "As you %s the formula on it, the scroll disappears.",
563                   silently ? "cogitate" : "pronounce");
564 #else
565             pline(nodisappear
566                       ? "\82 \82È\82½\82Í\8eô\95\82ð%s\82½\81D"
567                       : "\8eô\95\82ð%s\82é\82Æ\81C\8aª\95¨\82Í\8fÁ\82¦\82½\81D",
568                   silently ? "\94O\82¶" : "\8f¥\82¦");
569 #endif
570         else
571 #if 0 /*JP*/
572             pline(nodisappear ? "You read the scroll."
573                               : "As you read the scroll, it disappears.");
574 #else
575             pline(nodisappear ? "\82 \82È\82½\82Í\8aª\95¨\82ð\93Ç\82ñ\82¾\81D"
576                               : "\8aª\95¨\82ð\93Ç\82Þ\82Æ\81C\82»\82ê\82Í\8fÁ\82¦\82½\81D");
577 #endif
578         if (confused) {
579             if (Hallucination)
580 /*JP
581                 pline("Being so trippy, you screw up...");
582 */
583                 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");
584             else
585 #if 0 /*JP*/
586                 pline("Being confused, you %s the magic words...",
587                       silently ? "misunderstand" : "mispronounce");
588 #else
589                 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");
590 #endif
591         }
592     }
593     if (!seffects(scroll)) {
594         if (!objects[scroll->otyp].oc_name_known) {
595             if (known)
596                 learnscroll(scroll);
597             else if (!objects[scroll->otyp].oc_uname)
598                 docall(scroll);
599         }
600         scroll->in_use = FALSE;
601         if (scroll->otyp != SCR_BLANK_PAPER)
602             useup(scroll);
603     }
604     return 1;
605 }
606
607 STATIC_OVL void
608 stripspe(obj)
609 register struct obj *obj;
610 {
611     if (obj->blessed || obj->spe <= 0) {
612         pline1(nothing_happens);
613     } else {
614         /* order matters: message, shop handling, actual transformation */
615 /*JP
616         pline("%s briefly.", Yobjnam2(obj, "vibrate"));
617 */
618         Your("%s\82Í\8f¬\8d\8f\82Ý\82É\90U\93®\82µ\82½\81D",xname(obj));
619         costly_alteration(obj, COST_UNCHRG);
620         obj->spe = 0;
621         if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
622             obj->age = 0;
623     }
624 }
625
626 STATIC_OVL void
627 p_glow1(otmp)
628 register struct obj *otmp;
629 {
630 /*JP
631     pline("%s briefly.", Yobjnam2(otmp, Blind ? "vibrate" : "glow"));
632 */
633     Your("%s\82Í\8f¬\8d\8f\82Ý\82É%s\81D", xname(otmp), Blind ? "\90U\93®\82µ\82½" : "\8bP\82¢\82½");
634 }
635
636 STATIC_OVL void
637 p_glow2(otmp, color)
638 register struct obj *otmp;
639 register const char *color;
640 {
641 #if 0 /*JP*/
642     pline("%s%s%s for a moment.", Yobjnam2(otmp, Blind ? "vibrate" : "glow"),
643           Blind ? "" : " ", Blind ? "" : hcolor(color));
644 #else
645     Your("%s\82Í\88ê\8fu%s%s\81D", xname(otmp),
646          Blind ? "" : jconj_adj(hcolor(color)),
647          Blind ? "\90U\93®\82µ\82½" : "\8bP\82¢\82½");
648 #endif
649 }
650
651 /* Is the object chargeable?  For purposes of inventory display; it is
652    possible to be able to charge things for which this returns FALSE. */
653 boolean
654 is_chargeable(obj)
655 struct obj *obj;
656 {
657     if (obj->oclass == WAND_CLASS)
658         return TRUE;
659     /* known && !oc_name_known is possible after amnesia/mind flayer */
660     if (obj->oclass == RING_CLASS)
661         return (boolean) (objects[obj->otyp].oc_charged
662                           && (obj->known
663                               || (obj->dknown
664                                   && objects[obj->otyp].oc_name_known)));
665     if (is_weptool(obj)) /* specific check before general tools */
666         return FALSE;
667     if (obj->oclass == TOOL_CLASS)
668         return (boolean) objects[obj->otyp].oc_charged;
669     return FALSE; /* why are weapons/armor considered charged anyway? */
670 }
671
672 /* recharge an object; curse_bless is -1 if the recharging implement
673    was cursed, +1 if blessed, 0 otherwise. */
674 void
675 recharge(obj, curse_bless)
676 struct obj *obj;
677 int curse_bless;
678 {
679     register int n;
680     boolean is_cursed, is_blessed;
681
682     is_cursed = curse_bless < 0;
683     is_blessed = curse_bless > 0;
684
685     if (obj->oclass == WAND_CLASS) {
686         int lim = (obj->otyp == WAN_WISHING)
687                       ? 3
688                       : (objects[obj->otyp].oc_dir != NODIR) ? 8 : 15;
689
690         /* undo any prior cancellation, even when is_cursed */
691         if (obj->spe == -1)
692             obj->spe = 0;
693
694         /*
695          * Recharging might cause wands to explode.
696          *      v = number of previous recharges
697          *            v = percentage chance to explode on this attempt
698          *                    v = cumulative odds for exploding
699          *      0 :   0       0
700          *      1 :   0.29    0.29
701          *      2 :   2.33    2.62
702          *      3 :   7.87   10.28
703          *      4 :  18.66   27.02
704          *      5 :  36.44   53.62
705          *      6 :  62.97   82.83
706          *      7 : 100     100
707          */
708         n = (int) obj->recharged;
709         if (n > 0 && (obj->otyp == WAN_WISHING
710                       || (n * n * n > rn2(7 * 7 * 7)))) { /* recharge_limit */
711             wand_explode(obj, rnd(lim));
712             return;
713         }
714         /* didn't explode, so increment the recharge count */
715         obj->recharged = (unsigned) (n + 1);
716
717         /* now handle the actual recharging */
718         if (is_cursed) {
719             stripspe(obj);
720         } else {
721             n = (lim == 3) ? 3 : rn1(5, lim + 1 - 5);
722             if (!is_blessed)
723                 n = rnd(n);
724
725             if (obj->spe < n)
726                 obj->spe = n;
727             else
728                 obj->spe++;
729             if (obj->otyp == WAN_WISHING && obj->spe > 3) {
730                 wand_explode(obj, 1);
731                 return;
732             }
733             if (obj->spe >= lim)
734                 p_glow2(obj, NH_BLUE);
735             else
736                 p_glow1(obj);
737 #if 0 /*[shop price doesn't vary by charge count]*/
738             /* update shop bill to reflect new higher price */
739             if (obj->unpaid)
740                 alter_cost(obj, 0L);
741 #endif
742         }
743
744     } else if (obj->oclass == RING_CLASS && objects[obj->otyp].oc_charged) {
745         /* charging does not affect ring's curse/bless status */
746         int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
747         boolean is_on = (obj == uleft || obj == uright);
748
749         /* destruction depends on current state, not adjustment */
750         if (obj->spe > rn2(7) || obj->spe <= -5) {
751 #if 0 /*JP*/
752             pline("%s momentarily, then %s!", Yobjnam2(obj, "pulsate"),
753                   otense(obj, "explode"));
754 #else
755             Your("%s\82Í\88ê\8fu\96¬\93®\82µ\81C\94\9a\94­\82µ\82½\81I", xname(obj));
756 #endif
757             if (is_on)
758                 Ring_gone(obj);
759             s = rnd(3 * abs(obj->spe)); /* amount of damage */
760             useup(obj);
761 /*JP
762             losehp(Maybe_Half_Phys(s), "exploding ring", KILLED_BY_AN);
763 */
764             losehp(Maybe_Half_Phys(s), "\8ew\97Ö\82Ì\94\9a\94­\82Å", KILLED_BY_AN);
765         } else {
766             long mask = is_on ? (obj == uleft ? LEFT_RING : RIGHT_RING) : 0L;
767
768 #if 0 /*JP*/
769             pline("%s spins %sclockwise for a moment.", Yname2(obj),
770                   s < 0 ? "counter" : "");
771 #else
772             Your("%s\82Í\88ê\8fu%s\8e\9e\8cv\89ñ\82è\82É\89ñ\93]\82µ\82½\81D", xname(obj),
773                  s < 0 ? "\94½" : "");
774 #endif
775             if (s < 0)
776                 costly_alteration(obj, COST_DECHNT);
777             /* cause attributes and/or properties to be updated */
778             if (is_on)
779                 Ring_off(obj);
780             obj->spe += s; /* update the ring while it's off */
781             if (is_on)
782                 setworn(obj, mask), Ring_on(obj);
783             /* oartifact: if a touch-sensitive artifact ring is
784                ever created the above will need to be revised  */
785             /* update shop bill to reflect new higher price */
786             if (s > 0 && obj->unpaid)
787                 alter_cost(obj, 0L);
788         }
789
790     } else if (obj->oclass == TOOL_CLASS) {
791         int rechrg = (int) obj->recharged;
792
793         if (objects[obj->otyp].oc_charged) {
794             /* tools don't have a limit, but the counter used does */
795             if (rechrg < 7) /* recharge_limit */
796                 obj->recharged++;
797         }
798         switch (obj->otyp) {
799         case BELL_OF_OPENING:
800             if (is_cursed)
801                 stripspe(obj);
802             else if (is_blessed)
803                 obj->spe += rnd(3);
804             else
805                 obj->spe += 1;
806             if (obj->spe > 5)
807                 obj->spe = 5;
808             break;
809         case MAGIC_MARKER:
810         case TINNING_KIT:
811         case EXPENSIVE_CAMERA:
812             if (is_cursed)
813                 stripspe(obj);
814             else if (rechrg
815                      && obj->otyp
816                             == MAGIC_MARKER) { /* previously recharged */
817                 obj->recharged = 1; /* override increment done above */
818                 if (obj->spe < 3)
819 /*JP
820                     Your("marker seems permanently dried out.");
821 */
822                     Your("\83}\81[\83J\82Í\8a®\91S\82É\8a£\82«\82«\82Á\82Ä\82µ\82Ü\82Á\82½\81D");
823                 else
824                     pline1(nothing_happens);
825             } else if (is_blessed) {
826                 n = rn1(16, 15); /* 15..30 */
827                 if (obj->spe + n <= 50)
828                     obj->spe = 50;
829                 else if (obj->spe + n <= 75)
830                     obj->spe = 75;
831                 else {
832                     int chrg = (int) obj->spe;
833                     if ((chrg + n) > 127)
834                         obj->spe = 127;
835                     else
836                         obj->spe += n;
837                 }
838                 p_glow2(obj, NH_BLUE);
839             } else {
840                 n = rn1(11, 10); /* 10..20 */
841                 if (obj->spe + n <= 50)
842                     obj->spe = 50;
843                 else {
844                     int chrg = (int) obj->spe;
845                     if ((chrg + n) > 127)
846                         obj->spe = 127;
847                     else
848                         obj->spe += n;
849                 }
850                 p_glow2(obj, NH_WHITE);
851             }
852             break;
853         case OIL_LAMP:
854         case BRASS_LANTERN:
855             if (is_cursed) {
856                 stripspe(obj);
857                 if (obj->lamplit) {
858                     if (!Blind)
859 #if 0 /*JP*/
860                         pline("%s out!", Tobjnam(obj, "go"));
861 #else
862                         pline("%s\82Í\8fÁ\82¦\82½\81I", xname(obj));
863 #endif
864                     end_burn(obj, TRUE);
865                 }
866             } else if (is_blessed) {
867                 obj->spe = 1;
868                 obj->age = 1500;
869                 p_glow2(obj, NH_BLUE);
870             } else {
871                 obj->spe = 1;
872                 obj->age += 750;
873                 if (obj->age > 1500)
874                     obj->age = 1500;
875                 p_glow1(obj);
876             }
877             break;
878         case CRYSTAL_BALL:
879             if (is_cursed) {
880                 stripspe(obj);
881             } else if (is_blessed) {
882                 obj->spe = 6;
883                 p_glow2(obj, NH_BLUE);
884             } else {
885                 if (obj->spe < 5) {
886                     obj->spe++;
887                     p_glow1(obj);
888                 } else
889                     pline1(nothing_happens);
890             }
891             break;
892         case HORN_OF_PLENTY:
893         case BAG_OF_TRICKS:
894         case CAN_OF_GREASE:
895             if (is_cursed) {
896                 stripspe(obj);
897             } else if (is_blessed) {
898                 if (obj->spe <= 10)
899                     obj->spe += rn1(10, 6);
900                 else
901                     obj->spe += rn1(5, 6);
902                 if (obj->spe > 50)
903                     obj->spe = 50;
904                 p_glow2(obj, NH_BLUE);
905             } else {
906                 obj->spe += rnd(5);
907                 if (obj->spe > 50)
908                     obj->spe = 50;
909                 p_glow1(obj);
910             }
911             break;
912         case MAGIC_FLUTE:
913         case MAGIC_HARP:
914         case FROST_HORN:
915         case FIRE_HORN:
916         case DRUM_OF_EARTHQUAKE:
917             if (is_cursed) {
918                 stripspe(obj);
919             } else if (is_blessed) {
920                 obj->spe += d(2, 4);
921                 if (obj->spe > 20)
922                     obj->spe = 20;
923                 p_glow2(obj, NH_BLUE);
924             } else {
925                 obj->spe += rnd(4);
926                 if (obj->spe > 20)
927                     obj->spe = 20;
928                 p_glow1(obj);
929             }
930             break;
931         default:
932             goto not_chargable;
933             /*NOTREACHED*/
934             break;
935         } /* switch */
936
937     } else {
938     not_chargable:
939 /*JP
940         You("have a feeling of loss.");
941 */
942         You("\82È\82É\82©\91¹\82µ\82½\8bC\95ª\82É\82È\82Á\82½\81D");
943     }
944 }
945
946 /* Forget known information about this object type. */
947 STATIC_OVL void
948 forget_single_object(obj_id)
949 int obj_id;
950 {
951     objects[obj_id].oc_name_known = 0;
952     objects[obj_id].oc_pre_discovered = 0; /* a discovery when relearned */
953     if (objects[obj_id].oc_uname) {
954         free((genericptr_t) objects[obj_id].oc_uname);
955         objects[obj_id].oc_uname = 0;
956     }
957     undiscover_object(obj_id); /* after clearing oc_name_known */
958
959     /* clear & free object names from matching inventory items too? */
960 }
961
962 #if 0 /* here if anyone wants it.... */
963 /* Forget everything known about a particular object class. */
964 STATIC_OVL void
965 forget_objclass(oclass)
966 int oclass;
967 {
968     int i;
969
970     for (i = bases[oclass];
971          i < NUM_OBJECTS && objects[i].oc_class == oclass; i++)
972         forget_single_object(i);
973 }
974 #endif
975
976 /* randomize the given list of numbers  0 <= i < count */
977 STATIC_OVL void
978 randomize(indices, count)
979 int *indices;
980 int count;
981 {
982     int i, iswap, temp;
983
984     for (i = count - 1; i > 0; i--) {
985         if ((iswap = rn2(i + 1)) == i)
986             continue;
987         temp = indices[i];
988         indices[i] = indices[iswap];
989         indices[iswap] = temp;
990     }
991 }
992
993 /* Forget % of known objects. */
994 void
995 forget_objects(percent)
996 int percent;
997 {
998     int i, count;
999     int indices[NUM_OBJECTS];
1000
1001     if (percent == 0)
1002         return;
1003     if (percent <= 0 || percent > 100) {
1004         impossible("forget_objects: bad percent %d", percent);
1005         return;
1006     }
1007
1008     indices[0] = 0; /* lint suppression */
1009     for (count = 0, i = 1; i < NUM_OBJECTS; i++)
1010         if (OBJ_DESCR(objects[i])
1011             && (objects[i].oc_name_known || objects[i].oc_uname))
1012             indices[count++] = i;
1013
1014     if (count > 0) {
1015         randomize(indices, count);
1016
1017         /* forget first % of randomized indices */
1018         count = ((count * percent) + rn2(100)) / 100;
1019         for (i = 0; i < count; i++)
1020             forget_single_object(indices[i]);
1021     }
1022 }
1023
1024 /* Forget some or all of map (depends on parameters). */
1025 void
1026 forget_map(howmuch)
1027 int howmuch;
1028 {
1029     register int zx, zy;
1030
1031     if (Sokoban)
1032         return;
1033
1034     known = TRUE;
1035     for (zx = 0; zx < COLNO; zx++)
1036         for (zy = 0; zy < ROWNO; zy++)
1037             if (howmuch & ALL_MAP || rn2(7)) {
1038                 /* Zonk all memory of this location. */
1039                 levl[zx][zy].seenv = 0;
1040                 levl[zx][zy].waslit = 0;
1041                 levl[zx][zy].glyph = cmap_to_glyph(S_stone);
1042                 lastseentyp[zx][zy] = STONE;
1043             }
1044     /* forget overview data for this level */
1045     forget_mapseen(ledger_no(&u.uz));
1046 }
1047
1048 /* Forget all traps on the level. */
1049 void
1050 forget_traps()
1051 {
1052     register struct trap *trap;
1053
1054     /* forget all traps (except the one the hero is in :-) */
1055     for (trap = ftrap; trap; trap = trap->ntrap)
1056         if ((trap->tx != u.ux || trap->ty != u.uy) && (trap->ttyp != HOLE))
1057             trap->tseen = 0;
1058 }
1059
1060 /*
1061  * Forget given % of all levels that the hero has visited and not forgotten,
1062  * except this one.
1063  */
1064 void
1065 forget_levels(percent)
1066 int percent;
1067 {
1068     int i, count;
1069     xchar maxl, this_lev;
1070     int indices[MAXLINFO];
1071
1072     if (percent == 0)
1073         return;
1074
1075     if (percent <= 0 || percent > 100) {
1076         impossible("forget_levels: bad percent %d", percent);
1077         return;
1078     }
1079
1080     this_lev = ledger_no(&u.uz);
1081     maxl = maxledgerno();
1082
1083     /* count & save indices of non-forgotten visited levels */
1084     /* Sokoban levels are pre-mapped for the player, and should stay
1085      * so, or they become nearly impossible to solve.  But try to
1086      * shift the forgetting elsewhere by fiddling with percent
1087      * instead of forgetting fewer levels.
1088      */
1089     indices[0] = 0; /* lint suppression */
1090     for (count = 0, i = 0; i <= maxl; i++)
1091         if ((level_info[i].flags & VISITED)
1092             && !(level_info[i].flags & FORGOTTEN) && i != this_lev) {
1093             if (ledger_to_dnum(i) == sokoban_dnum)
1094                 percent += 2;
1095             else
1096                 indices[count++] = i;
1097         }
1098
1099     if (percent > 100)
1100         percent = 100;
1101
1102     if (count > 0) {
1103         randomize(indices, count);
1104
1105         /* forget first % of randomized indices */
1106         count = ((count * percent) + 50) / 100;
1107         for (i = 0; i < count; i++) {
1108             level_info[indices[i]].flags |= FORGOTTEN;
1109             forget_mapseen(indices[i]);
1110         }
1111     }
1112 }
1113
1114 /*
1115  * Forget some things (e.g. after reading a scroll of amnesia).  When called,
1116  * the following are always forgotten:
1117  *      - felt ball & chain
1118  *      - traps
1119  *      - part (6 out of 7) of the map
1120  *
1121  * Other things are subject to flags:
1122  *      howmuch & ALL_MAP       = forget whole map
1123  *      howmuch & ALL_SPELLS    = forget all spells
1124  */
1125 STATIC_OVL void
1126 forget(howmuch)
1127 int howmuch;
1128 {
1129     if (Punished)
1130         u.bc_felt = 0; /* forget felt ball&chain */
1131
1132     forget_map(howmuch);
1133     forget_traps();
1134
1135     /* 1 in 3 chance of forgetting some levels */
1136     if (!rn2(3))
1137         forget_levels(rn2(25));
1138
1139     /* 1 in 3 chance of forgetting some objects */
1140     if (!rn2(3))
1141         forget_objects(rn2(25));
1142
1143     if (howmuch & ALL_SPELLS)
1144         losespells();
1145     /*
1146      * Make sure that what was seen is restored correctly.  To do this,
1147      * we need to go blind for an instant --- turn off the display,
1148      * then restart it.  All this work is needed to correctly handle
1149      * walls which are stone on one side and wall on the other.  Turning
1150      * off the seen bits above will make the wall revert to stone,  but
1151      * there are cases where we don't want this to happen.  The easiest
1152      * thing to do is to run it through the vision system again, which
1153      * is always correct.
1154      */
1155     docrt(); /* this correctly will reset vision */
1156 }
1157
1158 /* monster is hit by scroll of taming's effect */
1159 STATIC_OVL int
1160 maybe_tame(mtmp, sobj)
1161 struct monst *mtmp;
1162 struct obj *sobj;
1163 {
1164     int was_tame = mtmp->mtame;
1165     unsigned was_peaceful = mtmp->mpeaceful;
1166
1167     if (sobj->cursed) {
1168         setmangry(mtmp, FALSE);
1169         if (was_peaceful && !mtmp->mpeaceful)
1170             return -1;
1171     } else {
1172         if (mtmp->isshk)
1173             make_happy_shk(mtmp, FALSE);
1174         else if (!resist(mtmp, sobj->oclass, 0, NOTELL))
1175             (void) tamedog(mtmp, (struct obj *) 0);
1176         if ((!was_peaceful && mtmp->mpeaceful) || (!was_tame && mtmp->mtame))
1177             return 1;
1178     }
1179     return 0;
1180 }
1181
1182 STATIC_OVL boolean
1183 get_valid_stinking_cloud_pos(x,y)
1184 int x,y;
1185 {
1186     return (!(!isok(x,y) || !cansee(x, y)
1187               || !ACCESSIBLE(levl[x][y].typ)
1188               || distu(x, y) >= 32));
1189 }
1190
1191 boolean
1192 is_valid_stinking_cloud_pos(x, y, showmsg)
1193 int x, y;
1194 boolean showmsg;
1195 {
1196     if (!get_valid_stinking_cloud_pos(x,y)) {
1197         if (showmsg)
1198 /*JP
1199             You("smell rotten eggs.");
1200 */
1201             pline("\82­\82³\82Á\82½\97\91\82Ì\82É\82¨\82¢\82ª\82µ\82½\81D");
1202         return FALSE;
1203     }
1204     return TRUE;
1205 }
1206
1207 void
1208 display_stinking_cloud_positions(state)
1209 int state;
1210 {
1211     if (state == 0) {
1212         tmp_at(DISP_BEAM, cmap_to_glyph(S_goodpos));
1213     } else if (state == 1) {
1214         int x, y, dx, dy;
1215         int dist = 6;
1216
1217         for (dx = -dist; dx <= dist; dx++)
1218             for (dy = -dist; dy <= dist; dy++) {
1219                 x = u.ux + dx;
1220                 y = u.uy + dy;
1221                 if (get_valid_stinking_cloud_pos(x,y))
1222                     tmp_at(x, y);
1223             }
1224     } else {
1225         tmp_at(DISP_END, 0);
1226     }
1227 }
1228
1229 /* scroll effects; return 1 if we use up the scroll and possibly make it
1230    become discovered, 0 if caller should take care of those side-effects */
1231 int
1232 seffects(sobj)
1233 struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
1234 {
1235     int cval, otyp = sobj->otyp;
1236     boolean confused = (Confusion != 0), sblessed = sobj->blessed,
1237             scursed = sobj->cursed, already_known, old_erodeproof,
1238             new_erodeproof;
1239     struct obj *otmp;
1240
1241     if (objects[otyp].oc_magic)
1242         exercise(A_WIS, TRUE);                       /* just for trying */
1243     already_known = (sobj->oclass == SPBOOK_CLASS /* spell */
1244                      || objects[otyp].oc_name_known);
1245
1246     switch (otyp) {
1247 #ifdef MAIL
1248     case SCR_MAIL:
1249         known = TRUE;
1250         if (sobj->spe == 2)
1251             /* "stamped scroll" created via magic marker--without a stamp */
1252             pline("This scroll is marked \"postage due\".");
1253         else if (sobj->spe)
1254             /* scroll of mail obtained from bones file or from wishing;
1255              * note to the puzzled: the game Larn actually sends you junk
1256              * mail if you win!
1257              */
1258             pline(
1259 /*JP
1260     "This seems to be junk mail addressed to the finder of the Eye of Larn.");
1261 */
1262     "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");
1263         else
1264             readmail(sobj);
1265         break;
1266 #endif
1267     case SCR_ENCHANT_ARMOR: {
1268         register schar s;
1269         boolean special_armor;
1270         boolean same_color;
1271
1272         otmp = some_armor(&youmonst);
1273         if (!otmp) {
1274 #if 0 /*JP*/
1275             strange_feeling(sobj, !Blind
1276                                       ? "Your skin glows then fades."
1277                                       : "Your skin feels warm for a moment.");
1278 #else
1279             strange_feeling(sobj, !Blind
1280                             ? "\82 \82È\82½\82Ì\91Ì\82Í\88ê\8fu\8bP\82¢\82½\81D"
1281                             : "\82 \82È\82½\82Ì\91Ì\82Í\88ê\8fu\92g\82©\82­\82È\82Á\82½\81D");
1282 #endif
1283             sobj = 0; /* useup() in strange_feeling() */
1284             exercise(A_CON, !scursed);
1285             exercise(A_STR, !scursed);
1286             break;
1287         }
1288         if (confused) {
1289             old_erodeproof = (otmp->oerodeproof != 0);
1290             new_erodeproof = !scursed;
1291             otmp->oerodeproof = 0; /* for messages */
1292             if (Blind) {
1293                 otmp->rknown = FALSE;
1294 /*JP
1295                 pline("%s warm for a moment.", Yobjnam2(otmp, "feel"));
1296 */
1297                 Your("%s\82Í\88ê\8fu\92g\82©\82­\82È\82Á\82½\81D", xname(otmp));
1298             } else {
1299                 otmp->rknown = TRUE;
1300 #if 0 /*JP*/
1301                 pline("%s covered by a %s %s %s!", Yobjnam2(otmp, "are"),
1302                       scursed ? "mottled" : "shimmering",
1303                       hcolor(scursed ? NH_BLACK : NH_GOLDEN),
1304                       scursed ? "glow"
1305                               : (is_shield(otmp) ? "layer" : "shield"));
1306 #else
1307                 Your("%s\82Í%s%s%s\82Å\95¢\82í\82ê\82½\81I", xname(otmp),
1308                      jconj_adj(hcolor(scursed ? NH_BLACK : NH_GOLDEN)),
1309                      scursed ? "\8cõ\82é\82Ü\82¾\82ç\82Ì" : "\82ä\82ç\82ß\82­",
1310                      scursed ? "\8bP\82«"
1311                              : "\83o\83\8a\83A");
1312 #endif
1313             }
1314             if (new_erodeproof && (otmp->oeroded || otmp->oeroded2)) {
1315                 otmp->oeroded = otmp->oeroded2 = 0;
1316 #if 0 /*JP*/
1317                 pline("%s as good as new!",
1318                       Yobjnam2(otmp, Blind ? "feel" : "look"));
1319 #else
1320                 Your("%s\82Í\90V\95i\93¯\97l\82É\82È\82Á\82½\81I",
1321                      xname(otmp));
1322 #endif
1323             }
1324             if (old_erodeproof && !new_erodeproof) {
1325                 /* restore old_erodeproof before shop charges */
1326                 otmp->oerodeproof = 1;
1327                 costly_alteration(otmp, COST_DEGRD);
1328             }
1329             otmp->oerodeproof = new_erodeproof ? 1 : 0;
1330             break;
1331         }
1332         /* elven armor vibrates warningly when enchanted beyond a limit */
1333         special_armor = is_elven_armor(otmp)
1334                         || (Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM);
1335         if (scursed)
1336             same_color = (otmp->otyp == BLACK_DRAGON_SCALE_MAIL
1337                           || otmp->otyp == BLACK_DRAGON_SCALES);
1338         else
1339             same_color = (otmp->otyp == SILVER_DRAGON_SCALE_MAIL
1340                           || otmp->otyp == SILVER_DRAGON_SCALES
1341                           || otmp->otyp == SHIELD_OF_REFLECTION);
1342         if (Blind)
1343             same_color = FALSE;
1344
1345         /* KMH -- catch underflow */
1346         s = scursed ? -otmp->spe : otmp->spe;
1347         if (s > (special_armor ? 5 : 3) && rn2(s)) {
1348             otmp->in_use = TRUE;
1349 #if 0 /*JP*/
1350             pline("%s violently %s%s%s for a while, then %s.", Yname2(otmp),
1351                   otense(otmp, Blind ? "vibrate" : "glow"),
1352                   (!Blind && !same_color) ? " " : "",
1353                   (Blind || same_color) ? "" : hcolor(scursed ? NH_BLACK
1354                                                               : NH_SILVER),
1355                   otense(otmp, "evaporate"));
1356 #else
1357             Your("%s\82Í\82µ\82Î\82ç\82­\82Ì\8aÔ\8c\83\82µ\82­%s%s\81C\8fö\94­\82µ\82½\81D", xname(otmp),
1358                  (Blind || same_color) ? "" : jconj_adj(hcolor(scursed ? NH_BLACK : NH_SILVER)),
1359                  Blind ? "\90U\93®\82µ" : "\8bP\82«");
1360 #endif
1361             remove_worn_item(otmp, FALSE);
1362             useup(otmp);
1363             break;
1364         }
1365         s = scursed ? -1
1366                     : (otmp->spe >= 9)
1367                        ? (rn2(otmp->spe) == 0)
1368                        : sblessed
1369                           ? rnd(3 - otmp->spe / 3)
1370                           : 1;
1371         if (s >= 0 && Is_dragon_scales(otmp)) {
1372             /* dragon scales get turned into dragon scale mail */
1373 /*JP
1374             pline("%s merges and hardens!", Yname2(otmp));
1375 */
1376             Your("%s\82Í\97Z\8d\87\82µ\8cÅ\82­\82È\82Á\82½\81I", xname(otmp));
1377             setworn((struct obj *) 0, W_ARM);
1378             /* assumes same order */
1379             otmp->otyp += GRAY_DRAGON_SCALE_MAIL - GRAY_DRAGON_SCALES;
1380             if (sblessed) {
1381                 otmp->spe++;
1382                 if (!otmp->blessed)
1383                     bless(otmp);
1384             } else if (otmp->cursed)
1385                 uncurse(otmp);
1386             otmp->known = 1;
1387             setworn(otmp, W_ARM);
1388             if (otmp->unpaid)
1389                 alter_cost(otmp, 0L); /* shop bill */
1390             break;
1391         }
1392 #if 0 /*JP*/
1393         pline("%s %s%s%s%s for a %s.", Yname2(otmp),
1394               s == 0 ? "violently " : "",
1395               otense(otmp, Blind ? "vibrate" : "glow"),
1396               (!Blind && !same_color) ? " " : "",
1397               (Blind || same_color)
1398                  ? "" : hcolor(scursed ? NH_BLACK : NH_SILVER),
1399               (s * s > 1) ? "while" : "moment");
1400 #else
1401         Your("%s\82Í%s%s%s%s\81D", xname(otmp),
1402              (s * s > 1) ? "\82µ\82Î\82ç\82­\82Ì\8aÔ" : "\88ê\8fu",
1403              s == 0 ? "\8c\83\82µ\82­" : "",
1404              (Blind || same_color) ? ""
1405                                    : jconj_adj(hcolor(sobj->cursed ? NH_BLACK : NH_SILVER)),
1406              Blind ? "\90U\93®\82µ\82½" : "\8bP\82¢\82½");
1407 #endif
1408         /* [this cost handling will need updating if shop pricing is
1409            ever changed to care about curse/bless status of armor] */
1410         if (s < 0)
1411             costly_alteration(otmp, COST_DECHNT);
1412         if (scursed && !otmp->cursed)
1413             curse(otmp);
1414         else if (sblessed && !otmp->blessed)
1415             bless(otmp);
1416         else if (!scursed && otmp->cursed)
1417             uncurse(otmp);
1418         if (s) {
1419             otmp->spe += s;
1420             adj_abon(otmp, s);
1421             known = otmp->known;
1422             /* update shop bill to reflect new higher price */
1423             if (s > 0 && otmp->unpaid)
1424                 alter_cost(otmp, 0L);
1425         }
1426
1427         if ((otmp->spe > (special_armor ? 5 : 3))
1428             && (special_armor || !rn2(7)))
1429 #if 0 /*JP*/
1430             pline("%s %s.", Yobjnam2(otmp, "suddenly vibrate"),
1431                   Blind ? "again" : "unexpectedly");
1432 #else
1433             Your("%s\82Í\93Ë\91R%s\90U\93®\82µ\82½\81D", xname(otmp),
1434                  Blind ? "\82Ü\82½" : "\8ev\82¢\82à\82æ\82ç\82¸");
1435 #endif
1436         break;
1437     }
1438     case SCR_DESTROY_ARMOR: {
1439         otmp = some_armor(&youmonst);
1440         if (confused) {
1441             if (!otmp) {
1442 /*JP
1443                 strange_feeling(sobj, "Your bones itch.");
1444 */
1445                 strange_feeling(sobj, "\8d\9c\82ª\83\80\83Y\83\80\83Y\82·\82é\81D");
1446                 sobj = 0; /* useup() in strange_feeling() */
1447                 exercise(A_STR, FALSE);
1448                 exercise(A_CON, FALSE);
1449                 break;
1450             }
1451             old_erodeproof = (otmp->oerodeproof != 0);
1452             new_erodeproof = scursed;
1453             otmp->oerodeproof = 0; /* for messages */
1454             p_glow2(otmp, NH_PURPLE);
1455             if (old_erodeproof && !new_erodeproof) {
1456                 /* restore old_erodeproof before shop charges */
1457                 otmp->oerodeproof = 1;
1458                 costly_alteration(otmp, COST_DEGRD);
1459             }
1460             otmp->oerodeproof = new_erodeproof ? 1 : 0;
1461             break;
1462         }
1463         if (!scursed || !otmp || !otmp->cursed) {
1464             if (!destroy_arm(otmp)) {
1465 /*JP
1466                 strange_feeling(sobj, "Your skin itches.");
1467 */
1468                 strange_feeling(sobj,"\94ç\95\86\82ª\83\80\83Y\83\80\83Y\82·\82é\81D");
1469                 sobj = 0; /* useup() in strange_feeling() */
1470                 exercise(A_STR, FALSE);
1471                 exercise(A_CON, FALSE);
1472                 break;
1473             } else
1474                 known = TRUE;
1475         } else { /* armor and scroll both cursed */
1476 /*JP
1477             pline("%s.", Yobjnam2(otmp, "vibrate"));
1478 */
1479             Your("%s\82Í\90U\93®\82µ\82½\81D", xname(otmp));
1480             if (otmp->spe >= -6) {
1481                 otmp->spe += -1;
1482                 adj_abon(otmp, -1);
1483             }
1484             make_stunned((HStun & TIMEOUT) + (long) rn1(10, 10), TRUE);
1485         }
1486     } break;
1487     case SCR_CONFUSE_MONSTER:
1488     case SPE_CONFUSE_MONSTER:
1489         if (youmonst.data->mlet != S_HUMAN || scursed) {
1490             if (!HConfusion)
1491 /*JP
1492                 You_feel("confused.");
1493 */
1494                 You_feel("confused.");
1495             make_confused(HConfusion + rnd(100), FALSE);
1496         } else if (confused) {
1497             if (!sblessed) {
1498 #if 0 /*JP*/
1499                 Your("%s begin to %s%s.", makeplural(body_part(HAND)),
1500                      Blind ? "tingle" : "glow ",
1501                      Blind ? "" : hcolor(NH_PURPLE));
1502 #else
1503                 Your("%s\82Í%s%s\82Í\82\82ß\82½\81D", makeplural(body_part(HAND)),
1504                      Blind ? "" : jconj_adj(hcolor(NH_PURPLE)),
1505                      Blind ? "\83q\83\8a\83q\83\8a\82µ" : "\8bP\82«");
1506 #endif
1507                 make_confused(HConfusion + rnd(100), FALSE);
1508             } else {
1509 #if 0 /*JP*/
1510                 pline("A %s%s surrounds your %s.",
1511                       Blind ? "" : hcolor(NH_RED),
1512                       Blind ? "faint buzz" : " glow", body_part(HEAD));
1513 #else
1514                 pline("%s%s\82ª\82 \82È\82½\82Ì%s\82ð\8eæ\82è\8aª\82¢\82½\81D",
1515                       Blind ? "" : jconj_adj(hcolor(NH_RED)),
1516                       Blind ? "\82©\82·\82©\82É\83u\81[\83\93\82Æ\96Â\82é\82à\82Ì" : "\8bP\82­\82à\82Ì",
1517                       body_part(HEAD));
1518 #endif
1519                 make_confused(0L, TRUE);
1520             }
1521         } else {
1522             if (!sblessed) {
1523 #if 0 /*JP*/
1524                 Your("%s%s %s%s.", makeplural(body_part(HAND)),
1525                      Blind ? "" : " begin to glow",
1526                      Blind ? (const char *) "tingle" : hcolor(NH_RED),
1527                      u.umconf ? " even more" : "");
1528 #else
1529                 Your("%s\82Í%s%s%s\81D", makeplural(body_part(HAND)),
1530                      u.umconf ? "\8f­\82µ" : "",
1531                      Blind ? (const char *) "\83q\83\8a\83q\83\8a\82µ\82½" : jconj_adj(hcolor(NH_RED)),
1532                      Blind ? "" : "\8bP\82«\82Í\82\82ß\82½");
1533 #endif
1534                 u.umconf++;
1535             } else {
1536                 if (Blind)
1537 #if 0 /*JP*/
1538                     Your("%s tingle %s sharply.", makeplural(body_part(HAND)),
1539                          u.umconf ? "even more" : "very");
1540 #else
1541                     Your("%s\82Í%s\83s\83\8a\83s\83\8a\82·\82é\81D", makeplural(body_part(HAND)),
1542                          u.umconf ? "\8f­\82µ" : "\82Æ\82Ä\82à");
1543 #endif
1544                 else
1545 #if 0 /*JP*/
1546                     Your("%s glow a%s brilliant %s.",
1547                          makeplural(body_part(HAND)),
1548                          u.umconf ? "n even more" : "", hcolor(NH_RED));
1549 #else
1550                     Your("%s\82Í%s%s\96¾\82é\82­\8bP\82¢\82½\81D",
1551                          makeplural(body_part(HAND)),
1552                          u.umconf ? "\8f­\82µ" : "", jconj_adj(hcolor(NH_RED)));
1553 #endif
1554                 /* after a while, repeated uses become less effective */
1555                 if (u.umconf >= 40)
1556                     u.umconf++;
1557                 else
1558                     u.umconf += rn1(8, 2);
1559             }
1560         }
1561         break;
1562     case SCR_SCARE_MONSTER:
1563     case SPE_CAUSE_FEAR: {
1564         register int ct = 0;
1565         register struct monst *mtmp;
1566
1567         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1568             if (DEADMONSTER(mtmp))
1569                 continue;
1570             if (cansee(mtmp->mx, mtmp->my)) {
1571                 if (confused || scursed) {
1572                     mtmp->mflee = mtmp->mfrozen = mtmp->msleeping = 0;
1573                     mtmp->mcanmove = 1;
1574                 } else if (!resist(mtmp, sobj->oclass, 0, NOTELL))
1575                     monflee(mtmp, 0, FALSE, FALSE);
1576                 if (!mtmp->mtame)
1577                     ct++; /* pets don't laugh at you */
1578             }
1579         }
1580         if (otyp == SCR_SCARE_MONSTER || !ct)
1581 #if 0 /*JP*/
1582             You_hear("%s %s.", (confused || scursed) ? "sad wailing"
1583                                                      : "maniacal laughter",
1584                      !ct ? "in the distance" : "close by");
1585 #else
1586             You_hear("\89\93\82­\82Å%s\82ð\95·\82¢\82½\81D",
1587                      (confused || sobj->cursed) ? "\94ß\82µ\82­\8b\83\82«\8b©\82Ô\90º"
1588                                                 : "\8b\82Á\82½\82æ\82¤\82É\8fÎ\82¤\90º");
1589 #endif
1590         break;
1591     }
1592     case SCR_BLANK_PAPER:
1593         if (Blind)
1594 /*JP
1595             You("don't remember there being any magic words on this scroll.");
1596 */
1597             You("\8aª\95¨\82É\8eô\95\82ª\8f\91\82¢\82Ä\82È\82©\82Á\82½\82±\82Æ\82ð\8ev\82¢\82¾\82µ\82½\81D");
1598         else
1599 /*JP
1600             pline("This scroll seems to be blank.");
1601 */
1602             pline("\82±\82Ì\8aª\95¨\82É\82Í\89½\82à\8f\91\82¢\82Ä\82È\82¢\82æ\82¤\82É\8c©\82¦\82é\81D");
1603         known = TRUE;
1604         break;
1605     case SCR_REMOVE_CURSE:
1606     case SPE_REMOVE_CURSE: {
1607         register struct obj *obj;
1608
1609 #if 0 /*JP*/
1610         You_feel(!Hallucination
1611                      ? (!confused ? "like someone is helping you."
1612                                   : "like you need some help.")
1613                      : (!confused ? "in touch with the Universal Oneness."
1614                                   : "the power of the Force against you!"));
1615 #else
1616         You(!Hallucination
1617             ? (!confused ? "\92N\82©\82ª\82 \82È\82½\82ð\8f\95\82¯\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D"
1618                          : "\8e©\95ª\82ª\8f\95\82¯\82ð\95K\97v\82Æ\82µ\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D")
1619             : (!confused ? "\89F\92\88\92²\98a\82Ì\8c´\97\9d\82É\90G\82ê\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D"
1620                          : "\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"));
1621 #endif
1622
1623         if (scursed) {
1624 /*JP
1625             pline_The("scroll disintegrates.");
1626 */
1627             pline("\8aª\95¨\82Í\95²\81X\82É\82È\82Á\82½\81D");
1628         } else {
1629             for (obj = invent; obj; obj = obj->nobj) {
1630                 long wornmask;
1631
1632                 /* gold isn't subject to cursing and blessing */
1633                 if (obj->oclass == COIN_CLASS)
1634                     continue;
1635                 wornmask = (obj->owornmask & ~(W_BALL | W_ART | W_ARTI));
1636                 if (wornmask && !sblessed) {
1637                     /* handle a couple of special cases; we don't
1638                        allow auxiliary weapon slots to be used to
1639                        artificially increase number of worn items */
1640                     if (obj == uswapwep) {
1641                         if (!u.twoweap)
1642                             wornmask = 0L;
1643                     } else if (obj == uquiver) {
1644                         if (obj->oclass == WEAPON_CLASS) {
1645                             /* mergeable weapon test covers ammo,
1646                                missiles, spears, daggers & knives */
1647                             if (!objects[obj->otyp].oc_merge)
1648                                 wornmask = 0L;
1649                         } else if (obj->oclass == GEM_CLASS) {
1650                             /* possibly ought to check whether
1651                                alternate weapon is a sling... */
1652                             if (!uslinging())
1653                                 wornmask = 0L;
1654                         } else {
1655                             /* weptools don't merge and aren't
1656                                reasonable quivered weapons */
1657                             wornmask = 0L;
1658                         }
1659                     }
1660                 }
1661                 if (sblessed || wornmask || obj->otyp == LOADSTONE
1662                     || (obj->otyp == LEASH && obj->leashmon)) {
1663                     /* water price varies by curse/bless status */
1664                     boolean shop_h2o = (obj->unpaid && obj->otyp == POT_WATER);
1665
1666                     if (confused) {
1667                         blessorcurse(obj, 2);
1668                         /* lose knowledge of this object's curse/bless
1669                            state (even if it didn't actually change) */
1670                         obj->bknown = 0;
1671                         /* blessorcurse() only affects uncursed items
1672                            so no need to worry about price of water
1673                            going down (hence no costly_alteration) */
1674                         if (shop_h2o && (obj->cursed || obj->blessed))
1675                             alter_cost(obj, 0L); /* price goes up */
1676                     } else if (obj->cursed) {
1677                         if (shop_h2o)
1678                             costly_alteration(obj, COST_UNCURS);
1679                         uncurse(obj);
1680                     }
1681                 }
1682             }
1683         }
1684         if (Punished && !confused)
1685             unpunish();
1686         if (u.utrap && u.utraptype == TT_BURIEDBALL) {
1687             buried_ball_to_freedom();
1688 /*JP
1689             pline_The("clasp on your %s vanishes.", body_part(LEG));
1690 */
1691             pline_The("%s\82Ì\8bà\8bï\82ª\8fÁ\82¦\82½\81D", body_part(LEG));
1692         }
1693         update_inventory();
1694         break;
1695     }
1696     case SCR_CREATE_MONSTER:
1697     case SPE_CREATE_MONSTER:
1698         if (create_critters(1 + ((confused || scursed) ? 12 : 0)
1699                                 + ((sblessed || rn2(73)) ? 0 : rnd(4)),
1700                             confused ? &mons[PM_ACID_BLOB]
1701                                      : (struct permonst *) 0,
1702                             FALSE))
1703             known = TRUE;
1704         /* no need to flush monsters; we ask for identification only if the
1705          * monsters are not visible
1706          */
1707         break;
1708     case SCR_ENCHANT_WEAPON:
1709         /* [What about twoweapon mode?  Proofing/repairing/enchanting both
1710            would be too powerful, but shouldn't we choose randomly between
1711            primary and secondary instead of always acting on primary?] */
1712         if (confused && uwep
1713             && erosion_matters(uwep) && uwep->oclass != ARMOR_CLASS) {
1714             old_erodeproof = (uwep->oerodeproof != 0);
1715             new_erodeproof = !scursed;
1716             uwep->oerodeproof = 0; /* for messages */
1717             if (Blind) {
1718                 uwep->rknown = FALSE;
1719 /*JP
1720                 Your("weapon feels warm for a moment.");
1721 */
1722                 pline("\95\90\8aí\82ª\88ê\8fu\92g\82©\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1723             } else {
1724                 uwep->rknown = TRUE;
1725 #if 0 /*JP*/
1726                 pline("%s covered by a %s %s %s!", Yobjnam2(uwep, "are"),
1727                       scursed ? "mottled" : "shimmering",
1728                       hcolor(scursed ? NH_PURPLE : NH_GOLDEN),
1729                       scursed ? "glow" : "shield");
1730 #else
1731                 Your("%s\82Í%s%s%s\82Å\95¢\82í\82ê\82½\81I", xname(uwep),
1732                      jconj_adj(hcolor(scursed ? NH_PURPLE : NH_GOLDEN)),
1733                      scursed ? "\8cõ\82é\82Ü\82¾\82ç\82Ì" : "\82ä\82ç\82ß\82­",
1734                      scursed ? "\8bP\82«" : "\83o\83\8a\83A");
1735 #endif
1736             }
1737             if (new_erodeproof && (uwep->oeroded || uwep->oeroded2)) {
1738                 uwep->oeroded = uwep->oeroded2 = 0;
1739 #if 0 /*JP*/
1740                 pline("%s as good as new!",
1741                       Yobjnam2(uwep, Blind ? "feel" : "look"));
1742 #else
1743                 pline("%s\82Í\90V\95i\93¯\97l\82É\82È\82Á\82½\81I", xname(uwep));
1744 #endif
1745             }
1746             if (old_erodeproof && !new_erodeproof) {
1747                 /* restore old_erodeproof before shop charges */
1748                 uwep->oerodeproof = 1;
1749                 costly_alteration(uwep, COST_DEGRD);
1750             }
1751             uwep->oerodeproof = new_erodeproof ? 1 : 0;
1752             break;
1753         }
1754         if (!chwepon(sobj, scursed ? -1
1755                              : !uwep ? 1
1756                                : (uwep->spe >= 9) ? !rn2(uwep->spe)
1757                                  : sblessed ? rnd(3 - uwep->spe / 3)
1758                                    : 1))
1759             sobj = 0; /* nothing enchanted: strange_feeling -> useup */
1760         break;
1761     case SCR_TAMING:
1762     case SPE_CHARM_MONSTER: {
1763         int candidates, res, results, vis_results;
1764
1765         if (u.uswallow) {
1766             candidates = 1;
1767             results = vis_results = maybe_tame(u.ustuck, sobj);
1768         } else {
1769             int i, j, bd = confused ? 5 : 1;
1770             struct monst *mtmp;
1771
1772             /* note: maybe_tame() can return either positive or
1773                negative values, but not both for the same scroll */
1774             candidates = results = vis_results = 0;
1775             for (i = -bd; i <= bd; i++)
1776                 for (j = -bd; j <= bd; j++) {
1777                     if (!isok(u.ux + i, u.uy + j))
1778                         continue;
1779                     if ((mtmp = m_at(u.ux + i, u.uy + j)) != 0
1780                         || (!i && !j && (mtmp = u.usteed) != 0)) {
1781                         ++candidates;
1782                         res = maybe_tame(mtmp, sobj);
1783                         results += res;
1784                         if (canspotmon(mtmp))
1785                             vis_results += res;
1786                     }
1787                 }
1788         }
1789         if (!results) {
1790 #if 0 /*JP*/
1791             pline("Nothing interesting %s.",
1792                   !candidates ? "happens" : "seems to happen");
1793 #else
1794             pline("\89½\82à\96Ê\94\92\82¢\82±\82Æ\82Í\82¨\82±\82ç\82È\82©\82Á\82½%s\81D",
1795                   !candidates ? "" : "\82æ\82¤\82¾");
1796 #endif
1797         } else {
1798 #if 0 /*JP*/
1799             pline_The("neighborhood %s %sfriendlier.",
1800                       vis_results ? "is" : "seems",
1801                       (results < 0) ? "un" : "");
1802 #else
1803             pline_The("\82¨\97×\82Æ\82Ì\92\87\82ª%s\82­\82È\82Á\82½%s\81D",
1804                       (results < 0) ? "\88«" : "\97Ç",
1805                       vis_results ? "" : "\82æ\82¤\82¾");
1806 #endif
1807             if (vis_results > 0)
1808                 known = TRUE;
1809         }
1810         break;
1811     }
1812     case SCR_GENOCIDE:
1813         if (!already_known)
1814 /*JP
1815             You("have found a scroll of genocide!");
1816 */
1817             pline("\82±\82ê\82Í\8bs\8eE\82Ì\8aª\95¨\82¾\81I");
1818         known = TRUE;
1819         if (sblessed)
1820             do_class_genocide();
1821         else
1822             do_genocide((!scursed) | (2 * !!Confusion));
1823         break;
1824     case SCR_LIGHT:
1825         if (!confused || rn2(5)) {
1826             if (!Blind)
1827                 known = TRUE;
1828             litroom(!confused && !scursed, sobj);
1829             if (!confused && !scursed) {
1830                 if (lightdamage(sobj, TRUE, 5))
1831                     known = TRUE;
1832             }
1833         } else {
1834             /* could be scroll of create monster, don't set known ...*/
1835             (void) create_critters(1, !scursed ? &mons[PM_YELLOW_LIGHT]
1836                                                : &mons[PM_BLACK_LIGHT],
1837                                    TRUE);
1838         }
1839         break;
1840     case SCR_TELEPORTATION:
1841         if (confused || scursed) {
1842             level_tele();
1843         } else {
1844             known = scrolltele(sobj);
1845         }
1846         break;
1847     case SCR_GOLD_DETECTION:
1848         if ((confused || scursed) ? trap_detect(sobj) : gold_detect(sobj))
1849             sobj = 0; /* failure: strange_feeling() -> useup() */
1850         break;
1851     case SCR_FOOD_DETECTION:
1852     case SPE_DETECT_FOOD:
1853         if (food_detect(sobj))
1854             sobj = 0; /* nothing detected: strange_feeling -> useup */
1855         break;
1856     case SCR_IDENTIFY:
1857         /* known = TRUE; -- handled inline here */
1858         /* use up the scroll first, before makeknown() performs a
1859            perm_invent update; also simplifies empty invent check */
1860         useup(sobj);
1861         sobj = 0; /* it's gone */
1862         if (confused)
1863 /*JP
1864             You("identify this as an identify scroll.");
1865 */
1866             You("\82±\82ê\82Í\8e¯\95Ê\82Ì\8aª\95¨\82¾\82Æ\8e¯\95Ê\82µ\82½\81D");
1867         else if (!already_known || !invent)
1868             /* force feedback now if invent became
1869                empty after using up this scroll */
1870 /*JP
1871             pline("This is an identify scroll.");
1872 */
1873             pline("\82±\82ê\82Í\8e¯\95Ê\82Ì\8aª\95¨\82¾\81D");
1874         if (!already_known)
1875             (void) learnscrolltyp(SCR_IDENTIFY);
1876         /*FALLTHRU*/
1877     case SPE_IDENTIFY:
1878         cval = 1;
1879         if (sblessed || (!scursed && !rn2(5))) {
1880             cval = rn2(5);
1881             /* note: if cval==0, identify all items */
1882             if (cval == 1 && sblessed && Luck > 0)
1883                 ++cval;
1884         }
1885         if (invent && !confused) {
1886             identify_pack(cval, !already_known);
1887         } else if (otyp == SPE_IDENTIFY) {
1888             /* when casting a spell we know we're not confused,
1889                so inventory must be empty (another message has
1890                already been given above if reading a scroll) */
1891 /*JP
1892             pline("You're not carrying anything to be identified.");
1893 */
1894             pline("\82 \82È\82½\82Í\8e¯\95Ê\82Å\82«\82é\82à\82Ì\82ð\82È\82É\82à\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
1895         }
1896         break;
1897     case SCR_CHARGING:
1898         if (confused) {
1899             if (scursed) {
1900 /*JP
1901                 You_feel("discharged.");
1902 */
1903                 You_feel("\95ú\8fo\82³\82ê\82½\8bC\82ª\82·\82é\81D");
1904                 u.uen = 0;
1905             } else {
1906 /*JP
1907                 You_feel("charged up!");
1908 */
1909                 You_feel("\8f[\93U\82³\82ê\82½\82æ\82¤\82È\8bC\82ª\82·\82é\81I");
1910                 u.uen += d(sblessed ? 6 : 4, 4);
1911                 if (u.uen > u.uenmax) /* if current energy is already at   */
1912                     u.uenmax = u.uen; /* or near maximum, increase maximum */
1913                 else
1914                     u.uen = u.uenmax; /* otherwise restore current to max  */
1915             }
1916             context.botl = 1;
1917             break;
1918         }
1919         /* known = TRUE; -- handled inline here */
1920         if (!already_known) {
1921 /*JP
1922             pline("This is a charging scroll.");
1923 */
1924             pline("\82±\82ê\82Í\8f[\93U\82Ì\8aª\95¨\82¾\81I");
1925             learnscroll(sobj);
1926         }
1927         /* use it up now to prevent it from showing in the
1928            getobj picklist because the "disappears" message
1929            was already delivered */
1930         useup(sobj);
1931         sobj = 0; /* it's gone */
1932         otmp = getobj(all_count, "charge");
1933         if (otmp)
1934             recharge(otmp, scursed ? -1 : sblessed ? 1 : 0);
1935         break;
1936     case SCR_MAGIC_MAPPING:
1937         if (level.flags.nommap) {
1938 /*JP
1939             Your("mind is filled with crazy lines!");
1940 */
1941             Your("\90S\82É\82½\82¾\82È\82ç\82Ê\90ü\81I\90ü\81I\90ü\81I\82ª\95\82\82Ñ\82 \82ª\82Á\82½\81I");
1942             if (Hallucination)
1943 /*JP
1944                 pline("Wow!  Modern art.");
1945 */
1946                 pline("\83\8f\83H\81I\83\82\83_\83\93\83A\81[\83g\82¾\81I");
1947             else
1948 /*JP
1949                 Your("%s spins in bewilderment.", body_part(HEAD));
1950 */
1951                 You("\93\96\98f\82µ\82Ä\96Ú\82ª\82Ü\82í\82Á\82½\81D");
1952             make_confused(HConfusion + rnd(30), FALSE);
1953             break;
1954         }
1955         if (sblessed) {
1956             register int x, y;
1957
1958             for (x = 1; x < COLNO; x++)
1959                 for (y = 0; y < ROWNO; y++)
1960                     if (levl[x][y].typ == SDOOR)
1961                         cvt_sdoor_to_door(&levl[x][y]);
1962             /* do_mapping() already reveals secret passages */
1963         }
1964         known = TRUE;
1965         /*FALLTHRU*/
1966     case SPE_MAGIC_MAPPING:
1967         if (level.flags.nommap) {
1968 #if 0 /*JP*/
1969             Your("%s spins as %s blocks the spell!", body_part(HEAD),
1970                  something);
1971 #else
1972             You("\89½\82©\82ª\8eô\95\82ð\82³\82¦\82¬\82è\81C\96Ú\82ª\82Ü\82í\82Á\82½\81I");
1973 #endif
1974             make_confused(HConfusion + rnd(30), FALSE);
1975             break;
1976         }
1977 /*JP
1978         pline("A map coalesces in your mind!");
1979 */
1980         pline("\92n\90}\82ª\82 \82È\82½\82Ì\90S\82É\97Z\8d\87\82µ\82½\81I");
1981         cval = (scursed && !confused);
1982         if (cval)
1983             HConfusion = 1; /* to screw up map */
1984         do_mapping();
1985         if (cval) {
1986             HConfusion = 0; /* restore */
1987 /*JP
1988             pline("Unfortunately, you can't grasp the details.");
1989 */
1990             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");
1991         }
1992         break;
1993     case SCR_AMNESIA:
1994         known = TRUE;
1995         forget((!sblessed ? ALL_SPELLS : 0)
1996                | (!confused || scursed ? ALL_MAP : 0));
1997         if (Hallucination) /* Ommmmmm! */
1998 /*JP
1999             Your("mind releases itself from mundane concerns.");
2000 */
2001             Your("\90S\82Í\95½\96}\82È\97\98\8aQ\8aÖ\8cW\82©\82ç\89ð\95ú\82³\82ê\82½\81D");
2002         else if (!strncmpi(plname, "Maud", 4))
2003             pline(
2004 /*JP
2005           "As your mind turns inward on itself, you forget everything else.");
2006 */
2007           "\82 \82È\82½\82Ì\90S\82Í\93à\91¤\82É\8cü\82«\81C\91S\82Ä\82ð\96Y\82ê\82Ä\82µ\82Ü\82Á\82½\81D");
2008         else if (rn2(2))
2009 /*JP
2010             pline("Who was that Maud person anyway?");
2011 */
2012             pline("Maud\82Á\82Ä\96º\82Í\82¢\82Á\82½\82¢\92N\82¾\82¢\81H");
2013         else
2014 /*JP
2015             pline("Thinking of Maud you forget everything else.");
2016 */
2017             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");
2018         exercise(A_WIS, FALSE);
2019         break;
2020     case SCR_FIRE: {
2021         coord cc;
2022         int dam;
2023
2024         cc.x = u.ux;
2025         cc.y = u.uy;
2026         cval = bcsign(sobj);
2027         dam = (2 * (rn1(3, 3) + 2 * cval) + 1) / 3;
2028         useup(sobj);
2029         sobj = 0; /* it's gone */
2030         if (!already_known)
2031             (void) learnscrolltyp(SCR_FIRE);
2032         if (confused) {
2033             if (Fire_resistance) {
2034                 shieldeff(u.ux, u.uy);
2035                 if (!Blind)
2036 /*JP
2037                     pline("Oh, look, what a pretty fire in your %s.",
2038 */
2039                     pline("\82í\82\9f\82²\82ç\82ñ\81D\8f¬\82³\82È\89Î\82ª%s\82É\82 \82é\81D",
2040                           makeplural(body_part(HAND)));
2041                 else
2042 /*JP
2043                     You_feel("a pleasant warmth in your %s.",
2044 */
2045                     You_feel("%s\82Ì\92\86\82É\89õ\93K\82È\92g\82©\82³\82ð\8a´\82\82½\81D",
2046                              makeplural(body_part(HAND)));
2047             } else {
2048 /*JP
2049                 pline_The("scroll catches fire and you burn your %s.",
2050 */
2051                 pline("\8aª\95¨\82É\89Î\82ª\94R\82¦\82¤\82Â\82è\81C\82 \82È\82½\82Ì%s\82ð\8fÄ\82¢\82½\81D",
2052                           makeplural(body_part(HAND)));
2053 /*JP
2054                 losehp(1, "scroll of fire", KILLED_BY_AN);
2055 */
2056                 losehp(1, "\89\8a\82Ì\8aª\95¨\82Å", KILLED_BY_AN);
2057             }
2058             break;
2059         }
2060         if (Underwater) {
2061 /*JP
2062             pline_The("%s around you vaporizes violently!", hliquid("water"));
2063 */
2064             pline_The("\82 \82È\82½\82Ì\89ñ\82è\82Ì%s\82Í\82Í\82°\82µ\82­\95¦\93«\82µ\82½\81I", hliquid("\90\85"));
2065         } else {
2066             if (sblessed) {
2067                 if (!already_known)
2068                     pline("This is a scroll of fire!");
2069                 dam *= 5;
2070                 pline("Where do you want to center the explosion?");
2071                 getpos_sethilite(display_stinking_cloud_positions, get_valid_stinking_cloud_pos);
2072                 (void) getpos(&cc, TRUE, "the desired position");
2073                 if (!is_valid_stinking_cloud_pos(cc.x, cc.y, FALSE)) {
2074                     /* try to reach too far, get burned */
2075                     cc.x = u.ux;
2076                     cc.y = u.uy;
2077                 }
2078             }
2079             if (cc.x == u.ux && cc.y == u.uy) {
2080 /*JP
2081             pline_The("scroll erupts in a tower of flame!");
2082 */
2083             pline("\8aª\95¨\82©\82ç\89Î\92\8c\82ª\97§\82¿\8f¸\82Á\82½\81I");
2084                 iflags.last_msg = PLNMSG_TOWER_OF_FLAME; /* for explode() */
2085                 burn_away_slime();
2086             }
2087         }
2088         explode(cc.x, cc.y, 11, dam, SCROLL_CLASS, EXPL_FIERY);
2089         break;
2090     }
2091     case SCR_EARTH:
2092         /* TODO: handle steeds */
2093         if (!Is_rogue_level(&u.uz) && has_ceiling(&u.uz)
2094             && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
2095             register int x, y;
2096             int nboulders = 0;
2097
2098             /* Identify the scroll */
2099             if (u.uswallow)
2100 /*JP
2101                 You_hear("rumbling.");
2102 */
2103                 You_hear("\83S\83\8d\83S\83\8d\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
2104             else
2105 #if 0 /*JP*/
2106                 pline_The("%s rumbles %s you!", ceiling(u.ux, u.uy),
2107                           sblessed ? "around" : "above");
2108 #else
2109                 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",
2110                       sblessed ? "\82Ü\82í\82è" : "\90^\8fã", ceiling(u.ux,u.uy));
2111 #endif
2112             known = 1;
2113             sokoban_guilt();
2114
2115             /* Loop through the surrounding squares */
2116             if (!scursed)
2117                 for (x = u.ux - 1; x <= u.ux + 1; x++) {
2118                     for (y = u.uy - 1; y <= u.uy + 1; y++) {
2119                         /* Is this a suitable spot? */
2120                         if (isok(x, y) && !closed_door(x, y)
2121                             && !IS_ROCK(levl[x][y].typ)
2122                             && !IS_AIR(levl[x][y].typ)
2123                             && (x != u.ux || y != u.uy)) {
2124                             nboulders +=
2125                                 drop_boulder_on_monster(x, y, confused, TRUE);
2126                         }
2127                     }
2128                 }
2129             /* Attack the player */
2130             if (!sblessed) {
2131                 drop_boulder_on_player(confused, !scursed, TRUE, FALSE);
2132             } else if (!nboulders)
2133 /*JP
2134                 pline("But nothing else happens.");
2135 */
2136                 pline("\82µ\82©\82µ\91¼\82É\89½\82à\82¨\82±\82ç\82È\82©\82Á\82½\81D");
2137         }
2138         break;
2139     case SCR_PUNISHMENT:
2140         known = TRUE;
2141         if (confused || sblessed) {
2142 /*JP
2143             You_feel("guilty.");
2144 */
2145             You("\8dß\82ð\8a´\82\82½\81D");
2146             break;
2147         }
2148         punish(sobj);
2149         break;
2150     case SCR_STINKING_CLOUD: {
2151         coord cc;
2152
2153         if (!already_known)
2154 /*JP
2155             You("have found a scroll of stinking cloud!");
2156 */
2157             You("\88«\8fL\89_\82Ì\8aª\95¨\82ð\94­\8c©\82µ\82½\81I");
2158         known = TRUE;
2159 #if 0 /*JP*/
2160         pline("Where do you want to center the %scloud?",
2161               already_known ? "stinking " : "");
2162 #else
2163         pline("\89_\82Ì\92\86\90S\82ð\82Ç\82±\82É\82µ\82Ü\82·\82©\81H");
2164 #endif
2165         cc.x = u.ux;
2166         cc.y = u.uy;
2167         getpos_sethilite(display_stinking_cloud_positions, get_valid_stinking_cloud_pos);
2168 /*JP
2169         if (getpos(&cc, TRUE, "the desired position") < 0) {
2170 */
2171         if (getpos(&cc, TRUE, "\91_\82¤\8fê\8f\8a") < 0) {
2172             pline1(Never_mind);
2173             break;
2174         }
2175         if (!is_valid_stinking_cloud_pos(cc.x, cc.y, TRUE))
2176             break;
2177         (void) create_gas_cloud(cc.x, cc.y, 3 + bcsign(sobj),
2178                                 8 + 4 * bcsign(sobj));
2179         break;
2180     }
2181     default:
2182         impossible("What weird effect is this? (%u)", otyp);
2183     }
2184     return sobj ? 0 : 1;
2185 }
2186
2187 void
2188 drop_boulder_on_player(confused, helmet_protects, byu, skip_uswallow)
2189 boolean confused, helmet_protects, byu, skip_uswallow;
2190 {
2191     int dmg;
2192     struct obj *otmp2;
2193
2194     /* hit monster if swallowed */
2195     if (u.uswallow && !skip_uswallow) {
2196         drop_boulder_on_monster(u.ux, u.uy, confused, byu);
2197         return;
2198     }
2199
2200     otmp2 = mksobj(confused ? ROCK : BOULDER, FALSE, FALSE);
2201     if (!otmp2)
2202         return;
2203     otmp2->quan = confused ? rn1(5, 2) : 1;
2204     otmp2->owt = weight(otmp2);
2205     if (!amorphous(youmonst.data) && !Passes_walls
2206         && !noncorporeal(youmonst.data) && !unsolid(youmonst.data)) {
2207 /*JP
2208         You("are hit by %s!", doname(otmp2));
2209 */
2210         pline("%s\82ª\96½\92\86\82µ\82½\81I", doname(otmp2));
2211         dmg = dmgval(otmp2, &youmonst) * otmp2->quan;
2212         if (uarmh && helmet_protects) {
2213             if (is_metallic(uarmh)) {
2214 /*JP
2215                 pline("Fortunately, you are wearing a hard helmet.");
2216 */
2217                 pline("\8dK\89^\82É\82à\81C\82 \82È\82½\82Í\8cÅ\82¢\8a\95\82ð\90g\82É\82Â\82¯\82Ä\82¢\82é\81D");
2218                 if (dmg > 2)
2219                     dmg = 2;
2220             } else if (flags.verbose) {
2221 /*JP
2222                 pline("%s does not protect you.", Yname2(uarmh));
2223 */
2224                 Your("%s\82Å\82Í\8eç\82ê\82È\82¢\81D", xname(uarmh));
2225             }
2226         }
2227     } else
2228         dmg = 0;
2229     wake_nearto(u.ux, u.uy, 4 * 4);
2230     /* Must be before the losehp(), for bones files */
2231 /*JP
2232     if (!flooreffects(otmp2, u.ux, u.uy, "fall")) {
2233 */
2234     if (!flooreffects(otmp2, u.ux, u.uy, "\97\8e\82¿\82é")) {
2235         place_object(otmp2, u.ux, u.uy);
2236         stackobj(otmp2);
2237         newsym(u.ux, u.uy);
2238     }
2239     if (dmg)
2240 /*JP
2241         losehp(Maybe_Half_Phys(dmg), "scroll of earth", KILLED_BY_AN);
2242 */
2243         losehp(Maybe_Half_Phys(dmg), "\91å\92n\82Ì\8aª\95¨\82Å", KILLED_BY_AN);
2244 }
2245
2246 boolean
2247 drop_boulder_on_monster(x, y, confused, byu)
2248 int x, y;
2249 boolean confused, byu;
2250 {
2251     register struct obj *otmp2;
2252     register struct monst *mtmp;
2253
2254     /* Make the object(s) */
2255     otmp2 = mksobj(confused ? ROCK : BOULDER, FALSE, FALSE);
2256     if (!otmp2)
2257         return FALSE; /* Shouldn't happen */
2258     otmp2->quan = confused ? rn1(5, 2) : 1;
2259     otmp2->owt = weight(otmp2);
2260
2261     /* Find the monster here (won't be player) */
2262     mtmp = m_at(x, y);
2263     if (mtmp && !amorphous(mtmp->data) && !passes_walls(mtmp->data)
2264         && !noncorporeal(mtmp->data) && !unsolid(mtmp->data)) {
2265         struct obj *helmet = which_armor(mtmp, W_ARMH);
2266         int mdmg;
2267
2268         if (cansee(mtmp->mx, mtmp->my)) {
2269 /*JP
2270             pline("%s is hit by %s!", Monnam(mtmp), doname(otmp2));
2271 */
2272             pline("%s\82ª%s\82É\96½\92\86\82µ\82½\81I", doname(otmp2), Monnam(mtmp));
2273             if (mtmp->minvis && !canspotmon(mtmp))
2274                 map_invisible(mtmp->mx, mtmp->my);
2275         } else if (u.uswallow && mtmp == u.ustuck)
2276 #if 0 /*JP*/
2277             You_hear("something hit %s %s over your %s!",
2278                      s_suffix(mon_nam(mtmp)), mbodypart(mtmp, STOMACH),
2279                      body_part(HEAD));
2280 #else
2281             You_hear("\89½\82©\82ª\82 \82È\82½\82Ì%s\82Ì\8fã\82Ì%s\82Ì%s\82É\93\96\82½\82Á\82½\89¹\82ð\95·\82¢\82½\81I",
2282                      body_part(HEAD),
2283                      mon_nam(mtmp), mbodypart(mtmp, STOMACH));
2284 #endif
2285
2286         mdmg = dmgval(otmp2, mtmp) * otmp2->quan;
2287         if (helmet) {
2288             if (is_metallic(helmet)) {
2289                 if (canspotmon(mtmp))
2290 /*JP
2291                     pline("Fortunately, %s is wearing a hard helmet.",
2292 */
2293                     pline("\8dK\89^\82É\82à\81C%s\82Í\8cÅ\82¢\8a\95\82ð\90g\82É\82Â\82¯\82Ä\82¢\82é\81D",
2294                           mon_nam(mtmp));
2295                 else if (!Deaf)
2296 /*JP
2297                     You_hear("a clanging sound.");
2298 */
2299                     You_hear("\83K\83\89\83\93\83K\83\89\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
2300                 if (mdmg > 2)
2301                     mdmg = 2;
2302             } else {
2303                 if (canspotmon(mtmp))
2304 #if 0 /*JP*/
2305                     pline("%s's %s does not protect %s.", Monnam(mtmp),
2306                           xname(helmet), mhim(mtmp));
2307 #else
2308                     pline("%s\82Ì%s\82Å\82Í\8eç\82ê\82È\82¢\81D", Monnam(mtmp),
2309                           xname(helmet));
2310 #endif
2311             }
2312         }
2313         mtmp->mhp -= mdmg;
2314         if (mtmp->mhp <= 0) {
2315             if (byu) {
2316                 killed(mtmp);
2317             } else {
2318 /*JP
2319                 pline("%s is killed.", Monnam(mtmp));
2320 */
2321                 pline("%s\82Í\8e\80\82ñ\82¾\81D", Monnam(mtmp));
2322                 mondied(mtmp);
2323             }
2324         } else {
2325             wakeup(mtmp, byu);
2326         }
2327         wake_nearto(x, y, 4 * 4);
2328     } else if (u.uswallow && mtmp == u.ustuck) {
2329         obfree(otmp2, (struct obj *) 0);
2330         /* fall through to player */
2331         drop_boulder_on_player(confused, TRUE, FALSE, TRUE);
2332         return 1;
2333     }
2334     /* Drop the rock/boulder to the floor */
2335 /*JP
2336     if (!flooreffects(otmp2, x, y, "fall")) {
2337 */
2338     if (!flooreffects(otmp2, x, y, "\97\8e\82¿\82é")) {
2339         place_object(otmp2, x, y);
2340         stackobj(otmp2);
2341         newsym(x, y); /* map the rock */
2342     }
2343     return TRUE;
2344 }
2345
2346 /* overcharging any wand or zapping/engraving cursed wand */
2347 void
2348 wand_explode(obj, chg)
2349 struct obj *obj;
2350 int chg; /* recharging */
2351 {
2352 /*JP
2353     const char *expl = !chg ? "suddenly" : "vibrates violently and";
2354 */
2355     const char *expl = !chg ? "\93Ë\91R" : "\8c\83\82µ\82­\90U\93®\82µ\81C";
2356     int dmg, n, k;
2357
2358     /* number of damage dice */
2359     if (!chg)
2360         chg = 2; /* zap/engrave adjustment */
2361     n = obj->spe + chg;
2362     if (n < 2)
2363         n = 2; /* arbitrary minimum */
2364     /* size of damage dice */
2365     switch (obj->otyp) {
2366     case WAN_WISHING:
2367         k = 12;
2368         break;
2369     case WAN_CANCELLATION:
2370     case WAN_DEATH:
2371     case WAN_POLYMORPH:
2372     case WAN_UNDEAD_TURNING:
2373         k = 10;
2374         break;
2375     case WAN_COLD:
2376     case WAN_FIRE:
2377     case WAN_LIGHTNING:
2378     case WAN_MAGIC_MISSILE:
2379         k = 8;
2380         break;
2381     case WAN_NOTHING:
2382         k = 4;
2383         break;
2384     default:
2385         k = 6;
2386         break;
2387     }
2388     /* inflict damage and destroy the wand */
2389     dmg = d(n, k);
2390     obj->in_use = TRUE; /* in case losehp() is fatal (or --More--^C) */
2391 #if 0 /*JP*/
2392     pline("%s %s explodes!", Yname2(obj), expl);
2393 #else
2394     pline("%s\82Í%s\94\9a\94­\82µ\82½\81I", xname(obj), expl);
2395 #endif
2396 /*JP
2397     losehp(Maybe_Half_Phys(dmg), "exploding wand", KILLED_BY_AN);
2398 */
2399     losehp(Maybe_Half_Phys(dmg), "\8fñ\82Ì\94\9a\94­\82Å", KILLED_BY_AN);
2400     useup(obj);
2401     /* obscure side-effect */
2402     exercise(A_STR, FALSE);
2403 }
2404
2405 /* used to collect gremlins being hit by light so that they can be processed
2406    after vision for the entire lit area has been brought up to date */
2407 struct litmon {
2408     struct monst *mon;
2409     struct litmon *nxt;
2410 };
2411 STATIC_VAR struct litmon *gremlins = 0;
2412
2413 /*
2414  * Low-level lit-field update routine.
2415  */
2416 STATIC_PTR void
2417 set_lit(x, y, val)
2418 int x, y;
2419 genericptr_t val;
2420 {
2421     struct monst *mtmp;
2422     struct litmon *gremlin;
2423
2424     if (val) {
2425         levl[x][y].lit = 1;
2426         if ((mtmp = m_at(x, y)) != 0 && mtmp->data == &mons[PM_GREMLIN]) {
2427             gremlin = (struct litmon *) alloc(sizeof *gremlin);
2428             gremlin->mon = mtmp;
2429             gremlin->nxt = gremlins;
2430             gremlins = gremlin;
2431         }
2432     } else {
2433         levl[x][y].lit = 0;
2434         snuff_light_source(x, y);
2435     }
2436 }
2437
2438 void
2439 litroom(on, obj)
2440 register boolean on;
2441 struct obj *obj;
2442 {
2443     char is_lit; /* value is irrelevant; we use its address
2444                     as a `not null' flag for set_lit() */
2445
2446     /* first produce the text (provided you're not blind) */
2447     if (!on) {
2448         register struct obj *otmp;
2449
2450         if (!Blind) {
2451             if (u.uswallow) {
2452 /*JP
2453                 pline("It seems even darker in here than before.");
2454 */
2455                 pline("\91O\82æ\82è\88Ã\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82é\81D");
2456             } else {
2457                 if (uwep && artifact_light(uwep) && uwep->lamplit)
2458 /*JP
2459                     pline("Suddenly, the only light left comes from %s!",
2460 */
2461                     pline("\93Ë\91R\81C\96¾\82©\82è\82ª%s\82¾\82¯\82É\82È\82Á\82½\81I",
2462                           the(xname(uwep)));
2463                 else
2464 /*JP
2465                     You("are surrounded by darkness!");
2466 */
2467                     You("\88Ã\88Å\82É\95¢\82í\82ê\82½\81I");
2468             }
2469         }
2470
2471         /* the magic douses lamps, et al, too */
2472         for (otmp = invent; otmp; otmp = otmp->nobj)
2473             if (otmp->lamplit)
2474                 (void) snuff_lit(otmp);
2475     } else { /* on */
2476         if (u.uswallow) {
2477             if (Blind)
2478                 ; /* no feedback */
2479             else if (is_animal(u.ustuck->data))
2480 #if 0 /*JP*/
2481                 pline("%s %s is lit.", s_suffix(Monnam(u.ustuck)),
2482                       mbodypart(u.ustuck, STOMACH));
2483 #else
2484                 pline("%s\82Ì%s\82Í\96¾\82é\82­\82È\82Á\82½\81D", Monnam(u.ustuck),
2485                       mbodypart(u.ustuck, STOMACH));
2486 #endif
2487             else if (is_whirly(u.ustuck->data))
2488 /*JP
2489                 pline("%s shines briefly.", Monnam(u.ustuck));
2490 */
2491                 pline("%s\82Í\82¿\82å\82Á\82Æ\8bP\82¢\82½\81D", Monnam(u.ustuck));
2492             else
2493 /*JP
2494                 pline("%s glistens.", Monnam(u.ustuck));
2495 */
2496                 pline("%s\82Í\82«\82ç\82«\82ç\8bP\82¢\82½\81D", Monnam(u.ustuck));
2497         } else if (!Blind)
2498 /*JP
2499             pline("A lit field surrounds you!");
2500 */
2501             pline("\93\94\82è\82ª\82 \82È\82½\82ð\8eæ\82è\88Í\82ñ\82¾\81I");
2502     }
2503
2504     /* No-op when swallowed or in water */
2505     if (u.uswallow || Underwater || Is_waterlevel(&u.uz))
2506         return;
2507     /*
2508      *  If we are darkening the room and the hero is punished but not
2509      *  blind, then we have to pick up and replace the ball and chain so
2510      *  that we don't remember them if they are out of sight.
2511      */
2512     if (Punished && !on && !Blind)
2513         move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
2514
2515     if (Is_rogue_level(&u.uz)) {
2516         /* Can't use do_clear_area because MAX_RADIUS is too small */
2517         /* rogue lighting must light the entire room */
2518         int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
2519         int rx, ry;
2520
2521         if (rnum >= 0) {
2522             for (rx = rooms[rnum].lx - 1; rx <= rooms[rnum].hx + 1; rx++)
2523                 for (ry = rooms[rnum].ly - 1; ry <= rooms[rnum].hy + 1; ry++)
2524                     set_lit(rx, ry,
2525                             (genericptr_t) (on ? &is_lit : (char *) 0));
2526             rooms[rnum].rlit = on;
2527         }
2528         /* hallways remain dark on the rogue level */
2529     } else
2530         do_clear_area(u.ux, u.uy,
2531                       (obj && obj->oclass == SCROLL_CLASS && obj->blessed)
2532                          ? 9 : 5,
2533                       set_lit, (genericptr_t) (on ? &is_lit : (char *) 0));
2534
2535     /*
2536      *  If we are not blind, then force a redraw on all positions in sight
2537      *  by temporarily blinding the hero.  The vision recalculation will
2538      *  correctly update all previously seen positions *and* correctly
2539      *  set the waslit bit [could be messed up from above].
2540      */
2541     if (!Blind) {
2542         vision_recalc(2);
2543
2544         /* replace ball&chain */
2545         if (Punished && !on)
2546             move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
2547     }
2548
2549     vision_full_recalc = 1; /* delayed vision recalculation */
2550     if (gremlins) {
2551         struct litmon *gremlin;
2552
2553         /* can't delay vision recalc after all */
2554         vision_recalc(0);
2555         /* after vision has been updated, monsters who are affected
2556            when hit by light can now be hit by it */
2557         do {
2558             gremlin = gremlins;
2559             gremlins = gremlin->nxt;
2560             light_hits_gremlin(gremlin->mon, rnd(5));
2561             free((genericptr_t) gremlin);
2562         } while (gremlins);
2563     }
2564 }
2565
2566 STATIC_OVL void
2567 do_class_genocide()
2568 {
2569     int i, j, immunecnt, gonecnt, goodcnt, class, feel_dead = 0;
2570     char buf[BUFSZ] = DUMMY;
2571     boolean gameover = FALSE; /* true iff killed self */
2572
2573     for (j = 0;; j++) {
2574         if (j >= 5) {
2575             pline1(thats_enough_tries);
2576             return;
2577         }
2578         do {
2579 /*JP
2580             getlin("What class of monsters do you wish to genocide?", buf);
2581 */
2582             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);
2583             (void) mungspaces(buf);
2584         } while (!*buf);
2585         /* choosing "none" preserves genocideless conduct */
2586 #if 0 /*JP*/
2587         if (*buf == '\033' || !strcmpi(buf, "none")
2588             || !strcmpi(buf, "nothing"))
2589 #else
2590         if (*buf == '\033' || !strcmpi(buf, "\82È\82µ")
2591             || !strcmpi(buf, "\96³\82µ"))
2592 #endif
2593             return;
2594
2595         class = name_to_monclass(buf, (int *) 0);
2596         if (class == 0 && (i = name_to_mon(buf)) != NON_PM)
2597             class = mons[i].mlet;
2598         immunecnt = gonecnt = goodcnt = 0;
2599         for (i = LOW_PM; i < NUMMONS; i++) {
2600             if (mons[i].mlet == class) {
2601                 if (!(mons[i].geno & G_GENO))
2602                     immunecnt++;
2603                 else if (mvitals[i].mvflags & G_GENOD)
2604                     gonecnt++;
2605                 else
2606                     goodcnt++;
2607             }
2608         }
2609         if (!goodcnt && class != mons[urole.malenum].mlet
2610             && class != mons[urace.malenum].mlet) {
2611             if (gonecnt)
2612 /*JP
2613                 pline("All such monsters are already nonexistent.");
2614 */
2615                 pline("\82»\82Ì\89ö\95¨\82Í\82à\82¤\82¢\82È\82¢\81D");
2616             else if (immunecnt || class == S_invisible)
2617 /*JP
2618                 You("aren't permitted to genocide such monsters.");
2619 */
2620                 You("\82»\82Ì\89ö\95¨\82ð\8bs\8eE\82·\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
2621             else if (wizard && buf[0] == '*') {
2622                 register struct monst *mtmp, *mtmp2;
2623
2624                 gonecnt = 0;
2625                 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
2626                     mtmp2 = mtmp->nmon;
2627                     if (DEADMONSTER(mtmp))
2628                         continue;
2629                     mongone(mtmp);
2630                     gonecnt++;
2631                 }
2632 /*JP
2633                 pline("Eliminated %d monster%s.", gonecnt, plur(gonecnt));
2634 */
2635                 pline("%d\82Ì\89ö\95¨\82ð\8f\9c\82¢\82½\81D", gonecnt);
2636                 return;
2637             } else
2638 #if 0 /*JP*/
2639                 pline("That %s does not represent any monster.",
2640                       strlen(buf) == 1 ? "symbol" : "response");
2641 #else
2642                 pline("\82»\82Ì\82æ\82¤\82È\89ö\95¨\82Í\82¢\82È\82¢\81D");
2643 #endif
2644             continue;
2645         }
2646
2647         for (i = LOW_PM; i < NUMMONS; i++) {
2648             if (mons[i].mlet == class) {
2649                 char nam[BUFSZ];
2650
2651                 Strcpy(nam, makeplural(mons[i].mname));
2652                 /* Although "genus" is Latin for race, the hero benefits
2653                  * from both race and role; thus genocide affects either.
2654                  */
2655                 if (Your_Own_Role(i) || Your_Own_Race(i)
2656                     || ((mons[i].geno & G_GENO)
2657                         && !(mvitals[i].mvflags & G_GENOD))) {
2658                     /* This check must be first since player monsters might
2659                      * have G_GENOD or !G_GENO.
2660                      */
2661                     mvitals[i].mvflags |= (G_GENOD | G_NOCORPSE);
2662                     reset_rndmonst(i);
2663                     kill_genocided_monsters();
2664                     update_inventory(); /* eggs & tins */
2665 /*JP
2666                     pline("Wiped out all %s.", nam);
2667 */
2668                     pline("%s\82ð\91S\82Ä\94r\8f\9c\82µ\82½\81D", nam);
2669                     if (Upolyd && i == u.umonnum) {
2670                         u.mh = -1;
2671                         if (Unchanging) {
2672                             if (!feel_dead++)
2673 /*JP
2674                                 You("die.");
2675 */
2676                                 You("\8e\80\82É\82Ü\82µ\82½\81D\81D\81D");
2677                             /* finish genociding this class of
2678                                monsters before ultimately dying */
2679                             gameover = TRUE;
2680                         } else
2681                             rehumanize();
2682                     }
2683                     /* Self-genocide if it matches either your race
2684                        or role.  Assumption:  male and female forms
2685                        share same monster class. */
2686                     if (i == urole.malenum || i == urace.malenum) {
2687                         u.uhp = -1;
2688                         if (Upolyd) {
2689                             if (!feel_dead++)
2690 /*JP
2691                                 You_feel("%s inside.", udeadinside());
2692 */
2693                                 You("\8d°\82ª%s\82æ\82¤\82È\8bC\82ª\82µ\82½\81D", udeadinside());
2694                         } else {
2695                             if (!feel_dead++)
2696 /*JP
2697                                 You("die.");
2698 */
2699                                 You("\8e\80\82É\82Ü\82µ\82½\81D\81D\81D");
2700                             gameover = TRUE;
2701                         }
2702                     }
2703                 } else if (mvitals[i].mvflags & G_GENOD) {
2704                     if (!gameover)
2705 /*JP
2706                         pline("All %s are already nonexistent.", nam);
2707 */
2708                         pline("%s\82Í\8aù\82É\82¢\82È\82¢\81D", nam);
2709                 } else if (!gameover) {
2710                     /* suppress feedback about quest beings except
2711                        for those applicable to our own role */
2712                     if ((mons[i].msound != MS_LEADER
2713                          || quest_info(MS_LEADER) == i)
2714                         && (mons[i].msound != MS_NEMESIS
2715                             || quest_info(MS_NEMESIS) == i)
2716                         && (mons[i].msound != MS_GUARDIAN
2717                             || quest_info(MS_GUARDIAN) == i)
2718                         /* non-leader/nemesis/guardian role-specific monster
2719                            */
2720                         && (i != PM_NINJA /* nuisance */
2721                             || Role_if(PM_SAMURAI))) {
2722                         boolean named, uniq;
2723
2724                         named = type_is_pname(&mons[i]) ? TRUE : FALSE;
2725                         uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE;
2726                         /* one special case */
2727                         if (i == PM_HIGH_PRIEST)
2728                             uniq = FALSE;
2729
2730 #if 0 /*JP*/
2731                         You("aren't permitted to genocide %s%s.",
2732                             (uniq && !named) ? "the " : "",
2733                             (uniq || named) ? mons[i].mname : nam);
2734 #else
2735                         You("%s\82ð\8bs\8eE\82Å\82«\82È\82¢\81D",
2736                             (uniq || named) ? mons[i].mname : nam);
2737 #endif
2738                     }
2739                 }
2740             }
2741         }
2742         if (gameover || u.uhp == -1) {
2743             killer.format = KILLED_BY_AN;
2744 /*JP
2745             Strcpy(killer.name, "scroll of genocide");
2746 */
2747             Strcpy(killer.name, "\8bs\8eE\82Ì\8aª\95¨\82Å");
2748             if (gameover)
2749                 done(GENOCIDED);
2750         }
2751         return;
2752     }
2753 }
2754
2755 #define REALLY 1
2756 #define PLAYER 2
2757 #define ONTHRONE 4
2758 void
2759 do_genocide(how)
2760 int how;
2761 /* 0 = no genocide; create monsters (cursed scroll) */
2762 /* 1 = normal genocide */
2763 /* 3 = forced genocide of player */
2764 /* 5 (4 | 1) = normal genocide from throne */
2765 {
2766     char buf[BUFSZ] = DUMMY;
2767     register int i, killplayer = 0;
2768     register int mndx;
2769     register struct permonst *ptr;
2770     const char *which;
2771
2772     if (how & PLAYER) {
2773         mndx = u.umonster; /* non-polymorphed mon num */
2774         ptr = &mons[mndx];
2775         Strcpy(buf, ptr->mname);
2776         killplayer++;
2777     } else {
2778         for (i = 0;; i++) {
2779             if (i >= 5) {
2780                 /* cursed effect => no free pass (unless rndmonst() fails) */
2781                 if (!(how & REALLY) && (ptr = rndmonst()) != 0)
2782                     break;
2783
2784                 pline1(thats_enough_tries);
2785                 return;
2786             }
2787 /*JP
2788             getlin("What monster do you want to genocide? [type the name]",
2789 */
2790             getlin("\82Ç\82Ì\89ö\95¨\82ð\8bs\8eE\82µ\82Ü\82·\82©\81H[\96¼\91O\82ð\93ú\96{\8cê\82Å\93ü\82ê\82Ä\82Ë]",
2791                    buf);
2792             (void) mungspaces(buf);
2793             /* choosing "none" preserves genocideless conduct */
2794 #if 0 /*JP:T*/
2795             if (*buf == '\033' || !strcmpi(buf, "none")
2796                 || !strcmpi(buf, "nothing")) {
2797 #else
2798             if (*buf == '\033' || !strcmpi(buf, "\82È\82µ")
2799                 || !strcmpi(buf, "\96³\82µ")) {
2800 #endif
2801                 /* ... but no free pass if cursed */
2802                 if (!(how & REALLY) && (ptr = rndmonst()) != 0)
2803                     break; /* remaining checks don't apply */
2804
2805                 return;
2806             }
2807
2808             mndx = name_to_mon(buf);
2809             if (mndx == NON_PM || (mvitals[mndx].mvflags & G_GENOD)) {
2810 #if 0 /*JP*/
2811                 pline("Such creatures %s exist in this world.",
2812                       (mndx == NON_PM) ? "do not" : "no longer");
2813 #else
2814                 pline("\82»\82Ì\82æ\82¤\82È\90\82«\95¨\82Í%s\82±\82Ì\90¢\8aE\82É\91\8dÝ\82µ\82È\82¢\81D",
2815                       (mndx == NON_PM) ? "" : "\82à\82Í\82â");
2816 #endif
2817                 continue;
2818             }
2819             ptr = &mons[mndx];
2820             /* Although "genus" is Latin for race, the hero benefits
2821              * from both race and role; thus genocide affects either.
2822              */
2823             if (Your_Own_Role(mndx) || Your_Own_Race(mndx)) {
2824                 killplayer++;
2825                 break;
2826             }
2827             if (is_human(ptr))
2828                 adjalign(-sgn(u.ualign.type));
2829             if (is_demon(ptr))
2830                 adjalign(sgn(u.ualign.type));
2831
2832             if (!(ptr->geno & G_GENO)) {
2833                 if (!Deaf) {
2834                     /* FIXME: unconditional "caverns" will be silly in some
2835                      * circumstances.  Who's speaking?  Divine pronouncements
2836                      * aren't supposed to be hampered by deafness....
2837                      */
2838                     if (flags.verbose)
2839 /*JP
2840                         pline("A thunderous voice booms through the caverns:");
2841 */
2842                         pline("\97\8b\82Ì\82æ\82¤\82È\90º\82ª\93´\8cA\82É\8b¿\82¢\82½\81F");
2843 /*JP
2844                     verbalize("No, mortal!  That will not be done.");
2845 */
2846                     pline("\81u\92è\96½\82Ì\8eÒ\82æ\81I\82»\82Ì\96]\82Ý\82Í\82©\82È\82¤\82Ü\82¢\81D\81v");
2847                 }
2848                 continue;
2849             }
2850             /* KMH -- Unchanging prevents rehumanization */
2851             if (Unchanging && ptr == youmonst.data)
2852                 killplayer++;
2853             break;
2854         }
2855         mndx = monsndx(ptr); /* needed for the 'no free pass' cases */
2856     }
2857
2858 /*JP
2859     which = "all ";
2860 */
2861     which = "\91S\82Ä";
2862     if (Hallucination) {
2863         if (Upolyd)
2864             Strcpy(buf, youmonst.data->mname);
2865         else {
2866             Strcpy(buf, (flags.female && urole.name.f) ? urole.name.f
2867                                                        : urole.name.m);
2868             buf[0] = lowc(buf[0]);
2869         }
2870     } else {
2871         Strcpy(buf, ptr->mname); /* make sure we have standard singular */
2872         if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST])
2873 #if 0 /*JP*/
2874             which = !type_is_pname(ptr) ? "the " : "";
2875 #else
2876             which = "";
2877 #endif
2878     }
2879     if (how & REALLY) {
2880         /* setting no-corpse affects wishing and random tin generation */
2881         mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE);
2882 #if 0 /*JP*/
2883         pline("Wiped out %s%s.", which,
2884               (*which != 'a') ? buf : makeplural(buf));
2885 #else
2886         pline("%s\82ð%s\88ê\91|\82µ\82½\81D", buf, which);
2887 #endif
2888
2889         if (killplayer) {
2890             /* might need to wipe out dual role */
2891             if (urole.femalenum != NON_PM && mndx == urole.malenum)
2892                 mvitals[urole.femalenum].mvflags |= (G_GENOD | G_NOCORPSE);
2893             if (urole.femalenum != NON_PM && mndx == urole.femalenum)
2894                 mvitals[urole.malenum].mvflags |= (G_GENOD | G_NOCORPSE);
2895             if (urace.femalenum != NON_PM && mndx == urace.malenum)
2896                 mvitals[urace.femalenum].mvflags |= (G_GENOD | G_NOCORPSE);
2897             if (urace.femalenum != NON_PM && mndx == urace.femalenum)
2898                 mvitals[urace.malenum].mvflags |= (G_GENOD | G_NOCORPSE);
2899
2900             u.uhp = -1;
2901             if (how & PLAYER) {
2902                 killer.format = KILLED_BY;
2903 /*JP
2904                 Strcpy(killer.name, "genocidal confusion");
2905 */
2906                 Strcpy(killer.name, "\8d¬\97\90\82É\82æ\82é\8e©\8bs\93I\8bs\8eE\82Å");
2907             } else if (how & ONTHRONE) {
2908                 /* player selected while on a throne */
2909                 killer.format = KILLED_BY_AN;
2910 /*JP
2911                 Strcpy(killer.name, "imperious order");
2912 */
2913                 Strcpy(killer.name, "\98ü\96\9d\82È\96½\97ß\82Å");
2914             } else { /* selected player deliberately, not confused */
2915                 killer.format = KILLED_BY_AN;
2916 /*JP
2917                 Strcpy(killer.name, "scroll of genocide");
2918 */
2919                 Strcpy(killer.name, "\8bs\8eE\82Ì\8aª\95¨\82Å");
2920             }
2921
2922             /* Polymorphed characters will die as soon as they're rehumanized.
2923              */
2924             /* KMH -- Unchanging prevents rehumanization */
2925             if (Upolyd && ptr != youmonst.data) {
2926                 delayed_killer(POLYMORPH, killer.format, killer.name);
2927 /*JP
2928                 You_feel("%s inside.", udeadinside());
2929 */
2930                 You_feel("\8d°\82ª%s\82æ\82¤\82È\8bC\82ª\82µ\82½\81D", udeadinside());
2931             } else
2932                 done(GENOCIDED);
2933         } else if (ptr == youmonst.data) {
2934             rehumanize();
2935         }
2936         reset_rndmonst(mndx);
2937         kill_genocided_monsters();
2938         update_inventory(); /* in case identified eggs were affected */
2939     } else {
2940         int cnt = 0, census = monster_census(FALSE);
2941
2942         if (!(mons[mndx].geno & G_UNIQ)
2943             && !(mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT)))
2944             for (i = rn1(3, 4); i > 0; i--) {
2945                 if (!makemon(ptr, u.ux, u.uy, NO_MINVENT))
2946                     break; /* couldn't make one */
2947                 ++cnt;
2948                 if (mvitals[mndx].mvflags & G_EXTINCT)
2949                     break; /* just made last one */
2950             }
2951         if (cnt) {
2952             /* accumulated 'cnt' doesn't take groups into account;
2953                assume bringing in new mon(s) didn't remove any old ones */
2954             cnt = monster_census(FALSE) - census;
2955 #if 0 /*JP*/
2956             pline("Sent in %s%s.", (cnt > 1) ? "some " : "",
2957                   (cnt > 1) ? makeplural(buf) : an(buf));
2958 #else
2959             pline("%s\82ª\91\97\82ç\82ê\82Ä\82«\82½\81D", buf);
2960 #endif
2961         } else
2962             pline1(nothing_happens);
2963     }
2964 }
2965
2966 void
2967 punish(sobj)
2968 struct obj *sobj;
2969 {
2970     struct obj *reuse_ball = (sobj && sobj->otyp == HEAVY_IRON_BALL)
2971                                 ? sobj : (struct obj *) 0;
2972
2973     /* KMH -- Punishment is still okay when you are riding */
2974     if (!reuse_ball)
2975 /*JP
2976         You("are being punished for your misbehavior!");
2977 */
2978         You("\95s\8dì\96@\82Ì\82½\82ß\94±\82ð\8eó\82¯\82½\81I");
2979     if (Punished) {
2980 /*JP
2981         Your("iron ball gets heavier.");
2982 */
2983         Your("\93S\8b\85\82Í\82³\82ç\82É\8fd\82­\82È\82Á\82½\81D");
2984         uball->owt += IRON_BALL_W_INCR * (1 + sobj->cursed);
2985         return;
2986     }
2987     if (amorphous(youmonst.data) || is_whirly(youmonst.data)
2988         || unsolid(youmonst.data)) {
2989         if (!reuse_ball) {
2990 /*JP
2991             pline("A ball and chain appears, then falls away.");
2992 */
2993             pline("\93S\8b\85\82Æ\8d½\82ª\8c»\82í\82ê\82½\82ª\81C\82·\82é\82Á\82Æ\94²\82¯\82½\81D");
2994             dropy(mkobj(BALL_CLASS, TRUE));
2995         } else {
2996             dropy(reuse_ball);
2997         }
2998         return;
2999     }
3000     setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
3001     if (!reuse_ball)
3002         setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
3003     else
3004         setworn(reuse_ball, W_BALL);
3005     uball->spe = 1; /* special ball (see save) */
3006
3007     /*
3008      *  Place ball & chain if not swallowed.  If swallowed, the ball &
3009      *  chain variables will be set at the next call to placebc().
3010      */
3011     if (!u.uswallow) {
3012         placebc();
3013         if (Blind)
3014             set_bc(1);      /* set up ball and chain variables */
3015         newsym(u.ux, u.uy); /* see ball&chain if can't see self */
3016     }
3017 }
3018
3019 /* remove the ball and chain */
3020 void
3021 unpunish()
3022 {
3023     struct obj *savechain = uchain;
3024
3025     obj_extract_self(uchain);
3026     newsym(uchain->ox, uchain->oy);
3027     setworn((struct obj *) 0, W_CHAIN);
3028     dealloc_obj(savechain);
3029     uball->spe = 0;
3030     setworn((struct obj *) 0, W_BALL);
3031 }
3032
3033 /* some creatures have special data structures that only make sense in their
3034  * normal locations -- if the player tries to create one elsewhere, or to
3035  * revive one, the disoriented creature becomes a zombie
3036  */
3037 boolean
3038 cant_revive(mtype, revival, from_obj)
3039 int *mtype;
3040 boolean revival;
3041 struct obj *from_obj;
3042 {
3043     /* SHOPKEEPERS can be revived now */
3044     if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival)
3045         || *mtype == PM_HIGH_PRIEST || *mtype == PM_ALIGNED_PRIEST
3046         || *mtype == PM_ANGEL) {
3047         *mtype = PM_HUMAN_ZOMBIE;
3048         return TRUE;
3049     } else if (*mtype == PM_LONG_WORM_TAIL) { /* for create_particular() */
3050         *mtype = PM_LONG_WORM;
3051         return TRUE;
3052     } else if (unique_corpstat(&mons[*mtype])
3053                && (!from_obj || !has_omonst(from_obj))) {
3054         /* unique corpses (from bones or wizard mode wish) or
3055            statues (bones or any wish) end up as shapechangers */
3056         *mtype = PM_DOPPELGANGER;
3057         return TRUE;
3058     }
3059     return FALSE;
3060 }
3061
3062 /*
3063  * Make a new monster with the type controlled by the user.
3064  *
3065  * Note:  when creating a monster by class letter, specifying the
3066  * "strange object" (']') symbol produces a random monster rather
3067  * than a mimic.  This behavior quirk is useful so don't "fix" it
3068  * (use 'm'--or "mimic"--to create a random mimic).
3069  *
3070  * Used in wizard mode only (for ^G command and for scroll or spell
3071  * of create monster).  Once upon a time, an earlier incarnation of
3072  * this code was also used for the scroll/spell in explore mode.
3073  */
3074 boolean
3075 create_particular()
3076 {
3077     char buf[BUFSZ] = DUMMY, *bufp, monclass;
3078     char *tmpp;
3079     int which, tryct, i, firstchoice = NON_PM;
3080     struct permonst *whichpm = NULL;
3081     struct monst *mtmp;
3082     boolean madeany = FALSE, randmonst = FALSE,
3083         maketame, makepeaceful, makehostile, saddled, invisible,
3084         sleeping;
3085     int fem;
3086
3087     tryct = 5;
3088     do {
3089         monclass = MAXMCLASSES;
3090         which = urole.malenum; /* an arbitrary index into mons[] */
3091         maketame = makepeaceful = makehostile = FALSE;
3092         sleeping = saddled = invisible = FALSE;
3093         fem = -1; /* gender not specified */
3094 /*JP
3095         getlin("Create what kind of monster? [type the name or symbol]", buf);
3096 */
3097         getlin("\82Ç\82Ì\8eí\82Ì\89ö\95¨\82ð\8dì\82è\82Ü\82·\82©\81H[\96¼\91O\82ð\93ü\82ê\82Ä\82Ë]", buf);
3098         bufp = mungspaces(buf);
3099         if (*bufp == '\033')
3100             return FALSE;
3101         if ((tmpp = strstri(bufp, "saddled ")) != 0) {
3102             saddled = TRUE;
3103             (void) memset(tmpp, ' ', sizeof "saddled " - 1);
3104         }
3105         if ((tmpp = strstri(bufp, "sleeping ")) != 0) {
3106             sleeping = TRUE;
3107             (void) memset(tmpp, ' ', sizeof "sleeping " - 1);
3108         }
3109         if ((tmpp = strstri(bufp, "invisible ")) != 0) {
3110             invisible = TRUE;
3111             (void) memset(tmpp, ' ', sizeof "invisible " - 1);
3112         }
3113         /* check "female" before "male" to avoid false hit mid-word */
3114         if ((tmpp = strstri(bufp, "female ")) != 0) {
3115             fem = 1;
3116             (void) memset(tmpp, ' ', sizeof "female " - 1);
3117         }
3118         if ((tmpp = strstri(bufp, "male ")) != 0) {
3119             fem = 0;
3120             (void) memset(tmpp, ' ', sizeof "male " - 1);
3121         }
3122         bufp = mungspaces(bufp); /* after potential memset(' ') */
3123         /* allow the initial disposition to be specified */
3124 #if 0 /*JP*/
3125         if (!strncmpi(bufp, "tame ", 5)) {
3126             bufp += 5;
3127 #else
3128         if (!strncmpi(bufp, "\8eè\82È\82¸\82¯\82ç\82ê\82½", 14)) {
3129             bufp += 14;
3130 #endif
3131             maketame = TRUE;
3132 #if 0 /*JP*/
3133         } else if (!strncmpi(bufp, "peaceful ", 9)) {
3134             bufp += 9;
3135 #else
3136         } else if (!strncmpi(bufp, "\97F\8dD\93I\82È", 8)) {
3137             bufp += 8;
3138 #endif
3139             makepeaceful = TRUE;
3140 #if 0 /*JP*/
3141         } else if (!strncmpi(bufp, "hostile ", 8)) {
3142             bufp += 8;
3143 #else
3144         } else if (!strncmpi(bufp, "\93G\91Î\93I\82È", 8)) {
3145             bufp += 8;
3146 #endif
3147             makehostile = TRUE;
3148         }
3149         /* decide whether a valid monster was chosen */
3150 /*JP
3151         if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "random"))) {
3152 */
3153         if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "\83\89\83\93\83_\83\80"))) {
3154             randmonst = TRUE;
3155             break;
3156         }
3157         which = name_to_mon(bufp);
3158         if (which >= LOW_PM)
3159             break; /* got one */
3160         monclass = name_to_monclass(bufp, &which);
3161         if (which >= LOW_PM) {
3162             monclass = MAXMCLASSES; /* matters below */
3163             break;
3164         } else if (monclass > 0) {
3165             which = urole.malenum; /* reset from NON_PM */
3166             break;
3167         }
3168         /* no good; try again... */
3169 /*JP
3170         pline("I've never heard of such monsters.");
3171 */
3172         pline("\82»\82Ì\82æ\82¤\82È\89ö\95¨\82Í\95·\82¢\82½\82±\82Æ\82ª\82È\82¢\81D");
3173     } while (--tryct > 0);
3174
3175     if (!tryct) {
3176         pline1(thats_enough_tries);
3177     } else {
3178         if (!randmonst) {
3179             firstchoice = which;
3180             if (cant_revive(&which, FALSE, (struct obj *) 0)) {
3181                 /* wizard mode can override handling of special monsters */
3182 #if 0 /*JP*/
3183                 Sprintf(buf, "Creating %s instead; force %s?",
3184                         mons[which].mname, mons[firstchoice].mname);
3185 #else
3186                 Sprintf(buf, "\91ã\82í\82è\82É%s\82ª\8dì\82ç\82ê\82Ü\82·\81G%s\82É\82·\82é\81H",
3187                         mons[which].mname, mons[firstchoice].mname);
3188 #endif
3189                 if (yn(buf) == 'y')
3190                     which = firstchoice;
3191             }
3192             whichpm = &mons[which];
3193         }
3194         for (i = 0; i <= multi; i++) {
3195             if (monclass != MAXMCLASSES)
3196                 whichpm = mkclass(monclass, 0);
3197             else if (randmonst)
3198                 whichpm = rndmonst();
3199             mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS);
3200             if (!mtmp) {
3201                 /* quit trying if creation failed and is going to repeat */
3202                 if (monclass == MAXMCLASSES && !randmonst)
3203                     break;
3204                 /* otherwise try again */
3205                 continue;
3206             }
3207             /* 'is_FOO()' ought to be called 'always_FOO()' */
3208             if (fem != -1 && !is_male(mtmp->data) && !is_female(mtmp->data))
3209                 mtmp->female = fem; /* ignored for is_neuter() */
3210             if (maketame) {
3211                 (void) tamedog(mtmp, (struct obj *) 0);
3212             } else if (makepeaceful || makehostile) {
3213                 mtmp->mtame = 0; /* sanity precaution */
3214                 mtmp->mpeaceful = makepeaceful ? 1 : 0;
3215                 set_malign(mtmp);
3216             }
3217             if (saddled && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
3218                 struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);
3219
3220                 put_saddle_on_mon(otmp, mtmp);
3221             }
3222             if (invisible)
3223                 mon_set_minvis(mtmp);
3224             if (sleeping)
3225                 mtmp->msleeping = 1;
3226             madeany = TRUE;
3227             /* in case we got a doppelganger instead of what was asked
3228                for, make it start out looking like what was asked for */
3229             if (mtmp->cham != NON_PM && firstchoice != NON_PM
3230                 && mtmp->cham != firstchoice)
3231                 (void) newcham(mtmp, &mons[firstchoice], FALSE, FALSE);
3232         }
3233     }
3234     return madeany;
3235 }
3236
3237 /*read.c*/