OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / src / spell.c
1 /* NetHack 3.6  spell.c $NHDT-Date: 1508479722 2017/10/20 06:08:42 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.84 $ */
2 /*      Copyright (c) M. Stephenson 1988                          */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11
12 /* spellmenu arguments; 0 thru n-1 used as spl_book[] index when swapping */
13 #define SPELLMENU_CAST (-2)
14 #define SPELLMENU_VIEW (-1)
15 #define SPELLMENU_SORT (MAXSPELL) /* special menu entry */
16
17 /* spell retention period, in turns; at 10% of this value, player becomes
18    eligible to reread the spellbook and regain 100% retention (the threshold
19    used to be 1000 turns, which was 10% of the original 10000 turn retention
20    period but didn't get adjusted when that period got doubled to 20000) */
21 #define KEEN 20000
22 /* x: need to add 1 when used for reading a spellbook rather than for hero
23    initialization; spell memory is decremented at the end of each turn,
24    including the turn on which the spellbook is read; without the extra
25    increment, the hero used to get cheated out of 1 turn of retention */
26 #define incrnknow(spell, x) (spl_book[spell].sp_know = KEEN + (x))
27
28 #define spellev(spell) spl_book[spell].sp_lev
29 #define spellname(spell) OBJ_NAME(objects[spellid(spell)])
30 #define spellet(spell) \
31     ((char) ((spell < 26) ? ('a' + spell) : ('A' + spell - 26)))
32
33 STATIC_DCL int FDECL(spell_let_to_idx, (CHAR_P));
34 STATIC_DCL boolean FDECL(cursed_book, (struct obj * bp));
35 STATIC_DCL boolean FDECL(confused_book, (struct obj *));
36 STATIC_DCL void FDECL(deadbook, (struct obj *));
37 STATIC_PTR int NDECL(learn);
38 STATIC_DCL boolean NDECL(rejectcasting);
39 STATIC_DCL boolean FDECL(getspell, (int *));
40 STATIC_PTR int FDECL(CFDECLSPEC spell_cmp, (const genericptr,
41                                             const genericptr));
42 STATIC_DCL void NDECL(sortspells);
43 STATIC_DCL boolean NDECL(spellsortmenu);
44 STATIC_DCL boolean FDECL(dospellmenu, (const char *, int, int *));
45 STATIC_DCL int FDECL(percent_success, (int));
46 STATIC_DCL char *FDECL(spellretention, (int, char *));
47 STATIC_DCL int NDECL(throwspell);
48 STATIC_DCL void NDECL(cast_protection);
49 STATIC_DCL void FDECL(spell_backfire, (int));
50 STATIC_DCL const char *FDECL(spelltypemnemonic, (int));
51 STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
52
53 /* The roles[] table lists the role-specific values for tuning
54  * percent_success().
55  *
56  * Reasoning:
57  *   spelbase, spelheal:
58  *      Arc are aware of magic through historical research
59  *      Bar abhor magic (Conan finds it "interferes with his animal instincts")
60  *      Cav are ignorant to magic
61  *      Hea are very aware of healing magic through medical research
62  *      Kni are moderately aware of healing from Paladin training
63  *      Mon use magic to attack and defend in lieu of weapons and armor
64  *      Pri are very aware of healing magic through theological research
65  *      Ran avoid magic, preferring to fight unseen and unheard
66  *      Rog are moderately aware of magic through trickery
67  *      Sam have limited magical awareness, preferring meditation to conjuring
68  *      Tou are aware of magic from all the great films they have seen
69  *      Val have limited magical awareness, preferring fighting
70  *      Wiz are trained mages
71  *
72  *      The arms penalty is lessened for trained fighters Bar, Kni, Ran,
73  *      Sam, Val -- the penalty is its metal interference, not encumbrance.
74  *      The `spelspec' is a single spell which is fundamentally easier
75  *      for that role to cast.
76  *
77  *  spelspec, spelsbon:
78  *      Arc map masters (SPE_MAGIC_MAPPING)
79  *      Bar fugue/berserker (SPE_HASTE_SELF)
80  *      Cav born to dig (SPE_DIG)
81  *      Hea to heal (SPE_CURE_SICKNESS)
82  *      Kni to turn back evil (SPE_TURN_UNDEAD)
83  *      Mon to preserve their abilities (SPE_RESTORE_ABILITY)
84  *      Pri to bless (SPE_REMOVE_CURSE)
85  *      Ran to hide (SPE_INVISIBILITY)
86  *      Rog to find loot (SPE_DETECT_TREASURE)
87  *      Sam to be At One (SPE_CLAIRVOYANCE)
88  *      Tou to smile (SPE_CHARM_MONSTER)
89  *      Val control the cold (SPE_CONE_OF_COLD)
90  *      Wiz all really, but SPE_MAGIC_MISSILE is their party trick
91  *
92  *      See percent_success() below for more comments.
93  *
94  *  uarmbon, uarmsbon, uarmhbon, uarmgbon, uarmfbon:
95  *      Fighters find body armour & shield a little less limiting.
96  *      Headgear, Gauntlets and Footwear are not role-specific (but
97  *      still have an effect, except helm of brilliance, which is designed
98  *      to permit magic-use).
99  */
100
101 #define uarmhbon 4 /* Metal helmets interfere with the mind */
102 #define uarmgbon 6 /* Casting channels through the hands */
103 #define uarmfbon 2 /* All metal interferes to some degree */
104
105 /* since the spellbook itself doesn't blow up, don't say just "explodes" */
106 #if 0 /*JP*/
107 static const char explodes[] = "radiates explosive energy";
108 #endif
109
110 /* convert a letter into a number in the range 0..51, or -1 if not a letter */
111 STATIC_OVL int
112 spell_let_to_idx(ilet)
113 char ilet;
114 {
115     int indx;
116
117     indx = ilet - 'a';
118     if (indx >= 0 && indx < 26)
119         return indx;
120     indx = ilet - 'A';
121     if (indx >= 0 && indx < 26)
122         return indx + 26;
123     return -1;
124 }
125
126 /* TRUE: book should be destroyed by caller */
127 STATIC_OVL boolean
128 cursed_book(bp)
129 struct obj *bp;
130 {
131     boolean was_in_use;
132     int lev = objects[bp->otyp].oc_level;
133     int dmg = 0;
134
135     switch (rn2(lev)) {
136     case 0:
137 /*JP
138         You_feel("a wrenching sensation.");
139 */
140         You("\82Ë\82\82ç\82ê\82½\82æ\82¤\82È\8a´\8ao\82ð\8a´\82\82½\81D");
141         tele(); /* teleport him */
142         break;
143     case 1:
144 /*JP
145         You_feel("threatened.");
146 */
147         You("\82¨\82Ç\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
148         aggravate();
149         break;
150     case 2:
151         make_blinded(Blinded + rn1(100, 250), TRUE);
152         break;
153     case 3:
154         take_gold();
155         break;
156     case 4:
157 /*JP
158         pline("These runes were just too much to comprehend.");
159 */
160         pline("\82±\82Ì\83\8b\81[\83\93\95\8e\9a\82ð\97\9d\89ð\82·\82é\82Ì\82Í\8d¢\93ï\82¾\81D");
161         make_confused(HConfusion + rn1(7, 16), FALSE);
162         break;
163     case 5:
164 /*JP
165         pline_The("book was coated with contact poison!");
166 */
167         pline("\82±\82Ì\96{\82Í\90Ú\90G\8c^\82Ì\93Å\82Å\95¢\82í\82ê\82Ä\82¢\82é\81I");
168         if (uarmg) {
169 #if 0 /*JP*/
170             erode_obj(uarmg, "gloves", ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
171 #else
172             erode_obj(uarmg, "\8f¬\8eè", ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
173 #endif
174             break;
175         }
176         /* temp disable in_use; death should not destroy the book */
177         was_in_use = bp->in_use;
178         bp->in_use = FALSE;
179         losestr(Poison_resistance ? rn1(2, 1) : rn1(4, 3));
180 #if 0 /*JP*/
181         losehp(rnd(Poison_resistance ? 6 : 10), "contact-poisoned spellbook",
182                KILLED_BY_AN);
183 #else
184         losehp(rnd(Poison_resistance ? 6 : 10), "\90Ú\90G\93Å\82Ì\96\82\96@\8f\91\82Å",
185                KILLED_BY_AN);
186 #endif
187         bp->in_use = was_in_use;
188         break;
189     case 6:
190         if (Antimagic) {
191             shieldeff(u.ux, u.uy);
192 /*JP
193             pline_The("book %s, but you are unharmed!", explodes);
194 */
195             pline("\96{\82Í\8b­\97Í\82È\83G\83l\83\8b\83M\81[\82ð\95ú\8fo\82µ\82½\81C\82µ\82©\82µ\82 \82È\82½\82Í\8f\9d\82Â\82©\82È\82¢\81I");
196         } else {
197 /*JP
198             pline("As you read the book, it %s in your %s!", explodes,
199 */
200             pline("\96{\82Í\8b­\97Í\82È\83G\83l\83\8b\83M\81[\82ð\82 \82È\82½\82Ì%s\82É\95ú\8fo\82µ\82½\81I",
201                   body_part(FACE));
202             dmg = 2 * rnd(10) + 5;
203 /*JP
204             losehp(Maybe_Half_Phys(dmg), "exploding rune", KILLED_BY_AN);
205 */
206             losehp(Maybe_Half_Phys(dmg), "\8b­\97Í\82È\83\8b\81[\83\93\95\8e\9a\82Ì\83G\83l\83\8b\83M\81[\82Å", KILLED_BY_AN);
207         }
208         return TRUE;
209     default:
210         rndcurse();
211         break;
212     }
213     return FALSE;
214 }
215
216 /* study while confused: returns TRUE if the book is destroyed */
217 STATIC_OVL boolean
218 confused_book(spellbook)
219 struct obj *spellbook;
220 {
221     boolean gone = FALSE;
222
223     if (!rn2(3) && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
224         spellbook->in_use = TRUE; /* in case called from learn */
225         pline(
226 /*JP
227          "Being confused you have difficulties in controlling your actions.");
228 */
229          "\8d¬\97\90\82µ\82Ä\82¢\82é\82Ì\82Å\81C\82»\82¤\82¢\82¤\82±\82Æ\82ð\82·\82é\82Ì\82Í\93ï\82µ\82¢\81D");
230         display_nhwindow(WIN_MESSAGE, FALSE);
231 /*JP
232         You("accidentally tear the spellbook to pieces.");
233 */
234         You("\82¤\82Á\82©\82è\81C\96\82\96@\8f\91\82ð\88ø\82«\82³\82¢\82Ä\82µ\82Ü\82Á\82½\81D");
235         if (!objects[spellbook->otyp].oc_name_known
236             && !objects[spellbook->otyp].oc_uname)
237             docall(spellbook);
238         useup(spellbook);
239         gone = TRUE;
240     } else {
241 #if 0 /*JP*/
242         You("find yourself reading the %s line over and over again.",
243             spellbook == context.spbook.book ? "next" : "first");
244 #else
245         You("%s\82Ì\8ds\82ð\89½\93x\82à\8cJ\82è\95Ô\82µ\82Ä\93Ç\82ñ\82Å\82¢\82½\82±\82Æ\82É\8bC\95t\82¢\82½\81D",
246             spellbook == context.spbook.book ? "\8e\9f" : "\8dÅ\8f\89");
247 #endif
248     }
249     return gone;
250 }
251
252 /* special effects for The Book of the Dead */
253 STATIC_OVL void
254 deadbook(book2)
255 struct obj *book2;
256 {
257     struct monst *mtmp, *mtmp2;
258     coord mm;
259
260 /*JP
261     You("turn the pages of the Book of the Dead...");
262 */
263     You("\8e\80\8eÒ\82Ì\8f\91\82Ì\83y\81[\83W\82ð\82ß\82­\82Á\82½\81D\81D\81D");
264     makeknown(SPE_BOOK_OF_THE_DEAD);
265     /* KMH -- Need ->known to avoid "_a_ Book of the Dead" */
266     book2->known = 1;
267     if (invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
268         register struct obj *otmp;
269         register boolean arti1_primed = FALSE, arti2_primed = FALSE,
270                          arti_cursed = FALSE;
271
272         if (book2->cursed) {
273 /*JP
274             pline_The("runes appear scrambled.  You can't read them!");
275 */
276             pline("\83\8b\81[\83\93\95\8e\9a\82Í\82²\82¿\82á\82Ü\82º\82É\82È\82Á\82Ä\82¨\82è\81C\93Ç\82Þ\82±\82Æ\82ª\82Å\82«\82È\82©\82Á\82½\81I");
277             return;
278         }
279
280         if (!u.uhave.bell || !u.uhave.menorah) {
281 /*JP
282             pline("A chill runs down your %s.", body_part(SPINE));
283 */
284             Your("%s\82É\8a¦\82¯\82ª\91\96\82Á\82½\81D", body_part(SPINE));
285             if (!u.uhave.bell)
286 /*JP
287                 You_hear("a faint chime...");
288 */
289                 You_hear("\82©\82·\82©\82È\83x\83\8b\82Ì\89¹\82ð\95·\82¢\82½\81D\81D\81D");
290             if (!u.uhave.menorah)
291 /*JP
292                 pline("Vlad's doppelganger is amused.");
293 */
294                 pline("\83\94\83\89\83h\82Ì\90\97ì\82Í\8fÎ\82Á\82½\81D");
295             return;
296         }
297
298         for (otmp = invent; otmp; otmp = otmp->nobj) {
299             if (otmp->otyp == CANDELABRUM_OF_INVOCATION && otmp->spe == 7
300                 && otmp->lamplit) {
301                 if (!otmp->cursed)
302                     arti1_primed = TRUE;
303                 else
304                     arti_cursed = TRUE;
305             }
306             if (otmp->otyp == BELL_OF_OPENING
307                 && (moves - otmp->age) < 5L) { /* you rang it recently */
308                 if (!otmp->cursed)
309                     arti2_primed = TRUE;
310                 else
311                     arti_cursed = TRUE;
312             }
313         }
314
315         if (arti_cursed) {
316 /*JP
317             pline_The("invocation fails!");
318 */
319             pline("\93Á\8eê\94\\97Í\82Í\94­\8aö\82³\82ê\82È\82©\82Á\82½\81I");
320 /*JP
321             pline("At least one of your artifacts is cursed...");
322 */
323             pline("\8f­\82È\82­\82Æ\82à\90¹\8aí\82Ì\82Ð\82Æ\82Â\82ª\8eô\82í\82ê\82Ä\82¢\82é\81D\81D\81D");
324         } else if (arti1_primed && arti2_primed) {
325             unsigned soon =
326                 (unsigned) d(2, 6); /* time til next intervene() */
327
328             /* successful invocation */
329             mkinvokearea();
330             u.uevent.invoked = 1;
331             /* in case you haven't killed the Wizard yet, behave as if
332                you just did */
333             u.uevent.udemigod = 1; /* wizdead() */
334             if (!u.udg_cnt || u.udg_cnt > soon)
335                 u.udg_cnt = soon;
336         } else { /* at least one artifact not prepared properly */
337 /*JP
338             You("have a feeling that %s is amiss...", something);
339 */
340             You("\89½\82©\82ª\8aÔ\88á\82Á\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D\81D\81D");
341             goto raise_dead;
342         }
343         return;
344     }
345
346     /* when not an invocation situation */
347     if (book2->cursed) {
348     raise_dead:
349
350 /*JP
351         You("raised the dead!");
352 */
353         You("\8e\80\8eÒ\82ð\91h\82ç\82¹\82½\81I");
354         /* first maybe place a dangerous adversary */
355         if (!rn2(3) && ((mtmp = makemon(&mons[PM_MASTER_LICH], u.ux, u.uy,
356                                         NO_MINVENT)) != 0
357                         || (mtmp = makemon(&mons[PM_NALFESHNEE], u.ux, u.uy,
358                                            NO_MINVENT)) != 0)) {
359             mtmp->mpeaceful = 0;
360             set_malign(mtmp);
361         }
362         /* next handle the affect on things you're carrying */
363         (void) unturn_dead(&youmonst);
364         /* last place some monsters around you */
365         mm.x = u.ux;
366         mm.y = u.uy;
367         mkundead(&mm, TRUE, NO_MINVENT);
368     } else if (book2->blessed) {
369         for (mtmp = fmon; mtmp; mtmp = mtmp2) {
370             mtmp2 = mtmp->nmon; /* tamedog() changes chain */
371             if (DEADMONSTER(mtmp))
372                 continue;
373
374             if ((is_undead(mtmp->data) || is_vampshifter(mtmp))
375                 && cansee(mtmp->mx, mtmp->my)) {
376                 mtmp->mpeaceful = TRUE;
377                 if (sgn(mtmp->data->maligntyp) == sgn(u.ualign.type)
378                     && distu(mtmp->mx, mtmp->my) < 4)
379                     if (mtmp->mtame) {
380                         if (mtmp->mtame < 20)
381                             mtmp->mtame++;
382                     } else
383                         (void) tamedog(mtmp, (struct obj *) 0);
384                 else
385                     monflee(mtmp, 0, FALSE, TRUE);
386             }
387         }
388     } else {
389         switch (rn2(3)) {
390         case 0:
391 /*JP
392             Your("ancestors are annoyed with you!");
393 */
394             Your("\90æ\91c\82Í\82 \82È\82½\82ª\8c\99\82¢\82È\82æ\82¤\82¾\81I");
395             break;
396         case 1:
397 /*JP
398             pline_The("headstones in the cemetery begin to move!");
399 */
400             pline("\95æ\92n\82Ì\95æ\90Î\82ª\93®\82«\82Í\82\82ß\82½\81I");
401             break;
402         default:
403 /*JP
404             pline("Oh my!  Your name appears in the book!");
405 */
406             pline("\82È\82ñ\82Ä\82±\82Á\82½\82¢\81I\82 \82È\82½\82Ì\96¼\91O\82ª\96{\82É\8f\91\82¢\82Ä\82 \82é\81I");
407         }
408     }
409     return;
410 }
411
412 /* 'book' has just become cursed; if we're reading it and realize it is
413    now cursed, interrupt */
414 void
415 book_cursed(book)
416 struct obj *book;
417 {
418     if (occupation == learn && context.spbook.book == book
419         && book->cursed && book->bknown && multi >= 0)
420         stop_occupation();
421 }
422
423 STATIC_PTR int
424 learn(VOID_ARGS)
425 {
426     int i;
427     short booktype;
428     char splname[BUFSZ];
429     boolean costly = TRUE;
430     struct obj *book = context.spbook.book;
431
432     /* JDS: lenses give 50% faster reading; 33% smaller read time */
433     if (context.spbook.delay && ublindf && ublindf->otyp == LENSES && rn2(2))
434         context.spbook.delay++;
435     if (Confusion) { /* became confused while learning */
436         (void) confused_book(book);
437         context.spbook.book = 0; /* no longer studying */
438         context.spbook.o_id = 0;
439         nomul(context.spbook.delay); /* remaining delay is uninterrupted */
440 /*JP
441         multi_reason = "reading a book";
442 */
443         multi_reason = "\96{\82ð\93Ç\82ñ\82Å\82¢\82é\8e\9e\82É";
444         nomovemsg = 0;
445         context.spbook.delay = 0;
446         return 0;
447     }
448     if (context.spbook.delay) {
449         /* not if (context.spbook.delay++), so at end delay == 0 */
450         context.spbook.delay++;
451         return 1; /* still busy */
452     }
453     exercise(A_WIS, TRUE); /* you're studying. */
454     booktype = book->otyp;
455     if (booktype == SPE_BOOK_OF_THE_DEAD) {
456         deadbook(book);
457         return 0;
458     }
459
460 #if 0 /*JP*/
461     Sprintf(splname,
462             objects[booktype].oc_name_known ? "\"%s\"" : "the \"%s\" spell",
463             OBJ_NAME(objects[booktype]));
464 #else
465     Sprintf(splname,
466             objects[booktype].oc_name_known ? "\"%s\"" : "\"%s\"",
467             OBJ_NAME(objects[booktype]));
468 #endif
469     for (i = 0; i < MAXSPELL; i++)
470         if (spellid(i) == booktype || spellid(i) == NO_SPELL)
471             break;
472
473     if (i == MAXSPELL) {
474         impossible("Too many spells memorized!");
475     } else if (spellid(i) == booktype) {
476         /* normal book can be read and re-read a total of 4 times */
477         if (book->spestudied > MAX_SPELL_STUDY) {
478 /*JP
479             pline("This spellbook is too faint to be read any more.");
480 */
481             pline("\82±\82Ì\96\82\96@\8f\91\82Ì\95\8e\9a\82Í\94\96\82·\82¬\82Ä\82±\82ê\88È\8fã\93Ç\82ß\82È\82¢\81D");
482             book->otyp = booktype = SPE_BLANK_PAPER;
483             /* reset spestudied as if polymorph had taken place */
484             book->spestudied = rn2(book->spestudied);
485         } else if (spellknow(i) > KEEN / 10) {
486 /*JP
487             You("know %s quite well already.", splname);
488 */
489             You("\82·\82Å\82É%s\82ð\8fn\92m\82µ\82Ä\82¢\82é\81D", splname);
490             costly = FALSE;
491         } else { /* spellknow(i) <= KEEN/10 */
492 #if 0 /*JP*/
493             Your("knowledge of %s is %s.", splname,
494                  spellknow(i) ? "keener" : "restored");
495 #else
496             Your("%s\82É\91Î\82·\82é\92m\8e¯\82Í%s\82³\82ê\82½\81D", splname,
497                  spellknow(i) ? "\82³\82ç\82É\8c¤\82¬\82·\82Ü" : "\95\9c\8c³");
498 #endif
499             incrnknow(i, 1);
500             book->spestudied++;
501             exercise(A_WIS, TRUE); /* extra study */
502         }
503         /* make book become known even when spell is already
504            known, in case amnesia made you forget the book */
505         makeknown((int) booktype);
506     } else { /* (spellid(i) == NO_SPELL) */
507         /* for a normal book, spestudied will be zero, but for
508            a polymorphed one, spestudied will be non-zero and
509            one less reading is available than when re-learning */
510         if (book->spestudied >= MAX_SPELL_STUDY) {
511             /* pre-used due to being the product of polymorph */
512 /*JP
513             pline("This spellbook is too faint to read even once.");
514 */
515             pline("\82±\82Ì\96\82\96@\8f\91\82Ì\95\8e\9a\82Í\94\96\82·\82¬\82Ä\82±\82ê\88È\8fã\93Ç\82ß\82È\82¢\81D");
516             book->otyp = booktype = SPE_BLANK_PAPER;
517             /* reset spestudied as if polymorph had taken place */
518             book->spestudied = rn2(book->spestudied);
519         } else {
520             spl_book[i].sp_id = booktype;
521             spl_book[i].sp_lev = objects[booktype].oc_level;
522             incrnknow(i, 1);
523             book->spestudied++;
524 /*JP
525             You(i > 0 ? "add %s to your repertoire." : "learn %s.", splname);
526 */
527             You(i > 0 ? "%s\82ð\83\8c\83p\81[\83g\83\8a\81[\82É\89Á\82¦\82½\81D" : "%s\82ð\8fK\93¾\82µ\82½\81D", splname);
528         }
529         makeknown((int) booktype);
530     }
531
532     if (book->cursed) { /* maybe a demon cursed it */
533         if (cursed_book(book)) {
534             useup(book);
535             context.spbook.book = 0;
536             context.spbook.o_id = 0;
537             return 0;
538         }
539     }
540     if (costly)
541         check_unpaid(book);
542     context.spbook.book = 0;
543     context.spbook.o_id = 0;
544     return 0;
545 }
546
547 int
548 study_book(spellbook)
549 register struct obj *spellbook;
550 {
551     int booktype = spellbook->otyp;
552     boolean confused = (Confusion != 0);
553     boolean too_hard = FALSE;
554
555     /* attempting to read dull book may make hero fall asleep */
556     if (!confused && !Sleep_resistance
557 /*JP
558         && !strcmp(OBJ_DESCR(objects[booktype]), "dull")) {
559 */
560         && !strcmp(OBJ_DESCR(objects[booktype]), "\89\94\90F\82Ì\96\82\96@\8f\91")) {
561         const char *eyes;
562         int dullbook = rnd(25) - ACURR(A_WIS);
563
564         /* adjust chance if hero stayed awake, got interrupted, retries */
565         if (context.spbook.delay && spellbook == context.spbook.book)
566             dullbook -= rnd(objects[booktype].oc_level);
567
568         if (dullbook > 0) {
569             eyes = body_part(EYE);
570             if (eyecount(youmonst.data) > 1)
571                 eyes = makeplural(eyes);
572 /*JP
573             pline("This book is so dull that you can't keep your %s open.",
574 */
575             pline("\82±\82Ì\96{\82Í\91Þ\8bü\82·\82¬\82Ä%s\82ð\8aJ\82¯\82Ä\82¢\82ç\82ê\82È\82¢\81D",
576                   eyes);
577             dullbook += rnd(2 * objects[booktype].oc_level);
578             fall_asleep(-dullbook, TRUE);
579             return 1;
580         }
581     }
582
583     if (context.spbook.delay && !confused && spellbook == context.spbook.book
584         /* handle the sequence: start reading, get interrupted, have
585            context.spbook.book become erased somehow, resume reading it */
586         && booktype != SPE_BLANK_PAPER) {
587 #if 0 /*JP*/
588         You("continue your efforts to %s.",
589             (booktype == SPE_NOVEL) ? "read the novel" : "memorize the spell");
590 #else
591         You("%s\82ð\8dÄ\8aJ\82µ\82½\81D",
592             (booktype == SPE_NOVEL) ? "\93Ç\8f\91" : "\96\82\96@\82Ì\8aw\8fK");
593 #endif
594     } else {
595         /* KMH -- Simplified this code */
596         if (booktype == SPE_BLANK_PAPER) {
597 /*JP
598             pline("This spellbook is all blank.");
599 */
600             pline("\82±\82Ì\96\82\96@\8f\91\82Í\90^\82Á\94\92\82¾\81D");
601             makeknown(booktype);
602             return 1;
603         }
604
605         /* 3.6 tribute */
606         if (booktype == SPE_NOVEL) {
607             /* Obtain current Terry Pratchett book title */
608             const char *tribtitle = noveltitle(&spellbook->novelidx);
609
610             if (read_tribute("books", tribtitle, 0, (char *) 0, 0,
611                              spellbook->o_id)) {
612                 u.uconduct.literate++;
613                 check_unpaid(spellbook);
614                 makeknown(booktype);
615                 if (!u.uevent.read_tribute) {
616                     /* give bonus of 20 xp and 4*20+0 pts */
617                     more_experienced(20, 0);
618                     newexplevel();
619                     u.uevent.read_tribute = 1; /* only once */
620                 }
621             }
622             return 1;
623         }
624
625         switch (objects[booktype].oc_level) {
626         case 1:
627         case 2:
628             context.spbook.delay = -objects[booktype].oc_delay;
629             break;
630         case 3:
631         case 4:
632             context.spbook.delay = -(objects[booktype].oc_level - 1)
633                                    * objects[booktype].oc_delay;
634             break;
635         case 5:
636         case 6:
637             context.spbook.delay =
638                 -objects[booktype].oc_level * objects[booktype].oc_delay;
639             break;
640         case 7:
641             context.spbook.delay = -8 * objects[booktype].oc_delay;
642             break;
643         default:
644             impossible("Unknown spellbook level %d, book %d;",
645                        objects[booktype].oc_level, booktype);
646             return 0;
647         }
648
649         /* Books are often wiser than their readers (Rus.) */
650         spellbook->in_use = TRUE;
651         if (!spellbook->blessed && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
652             if (spellbook->cursed) {
653                 too_hard = TRUE;
654             } else {
655                 /* uncursed - chance to fail */
656                 int read_ability = ACURR(A_INT) + 4 + u.ulevel / 2
657                                    - 2 * objects[booktype].oc_level
658                              + ((ublindf && ublindf->otyp == LENSES) ? 2 : 0);
659
660                 /* only wizards know if a spell is too difficult */
661                 if (Role_if(PM_WIZARD) && read_ability < 20 && !confused) {
662                     char qbuf[QBUFSZ];
663
664 #if 0 /*JP*/
665                     Sprintf(qbuf,
666                     "This spellbook is %sdifficult to comprehend.  Continue?",
667                             (read_ability < 12 ? "very " : ""));
668 #else
669                     Sprintf(qbuf,
670                     "\82±\82Ì\96\82\96@\8f\91\82ð\97\9d\89ð\82·\82é\82Ì\82Í%s\8d¢\93ï\82¾\81D\91±\82¯\82Ü\82·\82©\81H",
671                             (read_ability < 12 ? "\82Æ\82Ä\82à" : ""));
672 #endif
673                     if (yn(qbuf) != 'y') {
674                         spellbook->in_use = FALSE;
675                         return 1;
676                     }
677                 }
678                 /* its up to random luck now */
679                 if (rnd(20) > read_ability) {
680                     too_hard = TRUE;
681                 }
682             }
683         }
684
685         if (too_hard) {
686             boolean gone = cursed_book(spellbook);
687
688             nomul(context.spbook.delay); /* study time */
689 /*JP
690             multi_reason = "reading a book";
691 */
692             multi_reason = "\96{\82ð\93Ç\82ñ\82Å\82¢\82é\8e\9e\82É";
693             nomovemsg = 0;
694             context.spbook.delay = 0;
695             if (gone || !rn2(3)) {
696                 if (!gone)
697 /*JP
698                     pline_The("spellbook crumbles to dust!");
699 */
700                     pline("\96\82\96@\8f\91\82Í\90o\82Æ\82È\82Á\82½\81I");
701                 if (!objects[spellbook->otyp].oc_name_known
702                     && !objects[spellbook->otyp].oc_uname)
703                     docall(spellbook);
704                 useup(spellbook);
705             } else
706                 spellbook->in_use = FALSE;
707             return 1;
708         } else if (confused) {
709             if (!confused_book(spellbook)) {
710                 spellbook->in_use = FALSE;
711             }
712             nomul(context.spbook.delay);
713 /*JP
714             multi_reason = "reading a book";
715 */
716             multi_reason = "\96{\82ð\93Ç\82ñ\82Å\82¢\82é\8e\9e\82É";
717             nomovemsg = 0;
718             context.spbook.delay = 0;
719             return 1;
720         }
721         spellbook->in_use = FALSE;
722
723 #if 0 /*JP*/
724         You("begin to %s the runes.",
725             spellbook->otyp == SPE_BOOK_OF_THE_DEAD ? "recite" : "memorize");
726 #else
727         You("\83\8b\81[\83\93\95\8e\9a\82ð%s\82µ\82Í\82\82ß\82½\81D",
728             spellbook->otyp == SPE_BOOK_OF_THE_DEAD ? "\88Ã\8f¥" : "\8bL\89¯");
729 #endif
730     }
731
732     context.spbook.book = spellbook;
733     if (context.spbook.book)
734         context.spbook.o_id = context.spbook.book->o_id;
735 /*JP
736     set_occupation(learn, "studying", 0);
737 */
738     set_occupation(learn, "\8aw\82Ô", 0);
739     return 1;
740 }
741
742 /* a spellbook has been destroyed or the character has changed levels;
743    the stored address for the current book is no longer valid */
744 void
745 book_disappears(obj)
746 struct obj *obj;
747 {
748     if (obj == context.spbook.book) {
749         context.spbook.book = (struct obj *) 0;
750         context.spbook.o_id = 0;
751     }
752 }
753
754 /* renaming an object usually results in it having a different address;
755    so the sequence start reading, get interrupted, name the book, resume
756    reading would read the "new" book from scratch */
757 void
758 book_substitution(old_obj, new_obj)
759 struct obj *old_obj, *new_obj;
760 {
761     if (old_obj == context.spbook.book) {
762         context.spbook.book = new_obj;
763         if (context.spbook.book)
764             context.spbook.o_id = context.spbook.book->o_id;
765     }
766 }
767
768 /* called from moveloop() */
769 void
770 age_spells()
771 {
772     int i;
773     /*
774      * The time relative to the hero (a pass through move
775      * loop) causes all spell knowledge to be decremented.
776      * The hero's speed, rest status, conscious status etc.
777      * does not alter the loss of memory.
778      */
779     for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++)
780         if (spellknow(i))
781             decrnknow(i);
782     return;
783 }
784
785 /* return True if spellcasting is inhibited;
786    only covers a small subset of reasons why casting won't work */
787 STATIC_OVL boolean
788 rejectcasting()
789 {
790     /* rejections which take place before selecting a particular spell */
791     if (Stunned) {
792 /*JP
793         You("are too impaired to cast a spell.");
794 */
795         You("\96\82\96@\82ð\8f¥\82¦\82ç\82ê\82È\82¢\81D");
796         return TRUE;
797     } else if (!can_chant(&youmonst)) {
798         You("are unable to chant the incantation.");
799         return TRUE;
800     } else if (!freehand()) {
801         /* Note: !freehand() occurs when weapon and shield (or two-handed
802          * weapon) are welded to hands, so "arms" probably doesn't need
803          * to be makeplural(bodypart(ARM)).
804          *
805          * But why isn't lack of free arms (for gesturing) an issue when
806          * poly'd hero has no limbs?
807          */
808 /*JP
809         Your("arms are not free to cast!");
810 */
811         pline("\96\82\96@\82ð\8f¥\82¦\82æ\82¤\82É\82à\98r\82Ì\8e©\97R\82ª\8cø\82©\82È\82¢\81I");
812         return TRUE;
813     }
814     return FALSE;
815 }
816
817 /*
818  * Return TRUE if a spell was picked, with the spell index in the return
819  * parameter.  Otherwise return FALSE.
820  */
821 STATIC_OVL boolean
822 getspell(spell_no)
823 int *spell_no;
824 {
825     int nspells, idx;
826     char ilet, lets[BUFSZ], qbuf[QBUFSZ];
827
828     if (spellid(0) == NO_SPELL) {
829 /*JP
830         You("don't know any spells right now.");
831 */
832         You("\8d¡\82Ì\82Æ\82±\82ë\89½\82Ì\96\82\96@\82à\92m\82ç\82È\82¢\81D");
833         return FALSE;
834     }
835     if (rejectcasting())
836         return FALSE; /* no spell chosen */
837
838     if (flags.menu_style == MENU_TRADITIONAL) {
839         /* we know there is at least 1 known spell */
840         for (nspells = 1; nspells < MAXSPELL && spellid(nspells) != NO_SPELL;
841              nspells++)
842             continue;
843
844         if (nspells == 1)
845             Strcpy(lets, "a");
846         else if (nspells < 27)
847             Sprintf(lets, "a-%c", 'a' + nspells - 1);
848         else if (nspells == 27)
849             Sprintf(lets, "a-zA");
850         /* this assumes that there are at most 52 spells... */
851         else
852             Sprintf(lets, "a-zA-%c", 'A' + nspells - 27);
853
854         for (;;) {
855 /*JP
856             Sprintf(qbuf, "Cast which spell? [%s *?]", lets);
857 */
858             Sprintf(qbuf, "\82Ç\82Ì\96\82\96@\82ð\8f¥\82¦\82é\81H[%s ?]", lets);
859             ilet = yn_function(qbuf, (char *) 0, '\0');
860             if (ilet == '*' || ilet == '?')
861                 break; /* use menu mode */
862             if (index(quitchars, ilet))
863                 return FALSE;
864
865             idx = spell_let_to_idx(ilet);
866             if (idx < 0 || idx >= nspells) {
867 /*JP
868                 You("don't know that spell.");
869 */
870                 You("\82»\82ñ\82È\96\82\96@\82Í\92m\82ç\82È\82¢\81D");
871                 continue; /* ask again */
872             }
873             *spell_no = idx;
874             return TRUE;
875         }
876     }
877 /*JP
878     return dospellmenu("Choose which spell to cast", SPELLMENU_CAST,
879 */
880     return dospellmenu("\82Ç\82Ì\96\82\96@\82ð\8f¥\82¦\82é\81H", SPELLMENU_CAST,
881                        spell_no);
882 }
883
884 /* the 'Z' command -- cast a spell */
885 int
886 docast()
887 {
888     int spell_no;
889
890     if (getspell(&spell_no))
891         return spelleffects(spell_no, FALSE);
892     return 0;
893 }
894
895 STATIC_OVL const char *
896 spelltypemnemonic(skill)
897 int skill;
898 {
899     switch (skill) {
900     case P_ATTACK_SPELL:
901 /*JP
902         return "attack";
903 */
904         return "\8dU\8c\82";
905     case P_HEALING_SPELL:
906 /*JP
907         return "healing";
908 */
909         return "\8e¡\96ü";
910     case P_DIVINATION_SPELL:
911 /*JP
912         return "divination";
913 */
914         return "\97\\92m";
915     case P_ENCHANTMENT_SPELL:
916 /*JP
917         return "enchantment";
918 */
919         return "\95â\8f\95";
920     case P_CLERIC_SPELL:
921 /*JP
922         return "clerical";
923 */
924         return "\91m\97µ";
925     case P_ESCAPE_SPELL:
926 /*JP
927         return "escape";
928 */
929         return "\92E\8fo";
930     case P_MATTER_SPELL:
931 /*JP
932         return "matter";
933 */
934         return "\95¨\8e¿";
935     default:
936         impossible("Unknown spell skill, %d;", skill);
937         return "";
938     }
939 }
940
941 int
942 spell_skilltype(booktype)
943 int booktype;
944 {
945     return objects[booktype].oc_skill;
946 }
947
948 STATIC_OVL void
949 cast_protection()
950 {
951     int l = u.ulevel, loglev = 0,
952         gain, natac = u.uac + u.uspellprot;
953     /* note: u.uspellprot is subtracted when find_ac() factors it into u.uac,
954        so adding here factors it back out
955        (versions prior to 3.6 had this backwards) */
956
957     /* loglev=log2(u.ulevel)+1 (1..5) */
958     while (l) {
959         loglev++;
960         l /= 2;
961     }
962
963     /* The more u.uspellprot you already have, the less you get,
964      * and the better your natural ac, the less you get.
965      *
966      *  LEVEL AC    SPELLPROT from successive SPE_PROTECTION casts
967      *      1     10    0,  1,  2,  3,  4
968      *      1      0    0,  1,  2,  3
969      *      1    -10    0,  1,  2
970      *      2-3   10    0,  2,  4,  5,  6,  7,  8
971      *      2-3    0    0,  2,  4,  5,  6
972      *      2-3  -10    0,  2,  3,  4
973      *      4-7   10    0,  3,  6,  8,  9, 10, 11, 12
974      *      4-7    0    0,  3,  5,  7,  8,  9
975      *      4-7  -10    0,  3,  5,  6
976      *      7-15 -10    0,  3,  5,  6
977      *      8-15  10    0,  4,  7, 10, 12, 13, 14, 15, 16
978      *      8-15   0    0,  4,  7,  9, 10, 11, 12
979      *      8-15 -10    0,  4,  6,  7,  8
980      *     16-30  10    0,  5,  9, 12, 14, 16, 17, 18, 19, 20
981      *     16-30   0    0,  5,  9, 11, 13, 14, 15
982      *     16-30 -10    0,  5,  8,  9, 10
983      */
984     natac = (10 - natac) / 10; /* convert to positive and scale down */
985     gain = loglev - (int) u.uspellprot / (4 - min(3, natac));
986
987     if (gain > 0) {
988         if (!Blind) {
989             int rmtyp;
990             const char *hgolden = hcolor(NH_GOLDEN), *atmosphere;
991
992             if (u.uspellprot) {
993 /*JP
994                 pline_The("%s haze around you becomes more dense.", hgolden);
995 */
996                 pline("\82 \82È\82½\82Ì\82Ü\82í\82è\82Ì%s\89à\82ª\94Z\82­\82È\82Á\82½\81D", hgolden);
997             } else {
998                 rmtyp = levl[u.ux][u.uy].typ;
999                 atmosphere = u.uswallow
1000                                 ? ((u.ustuck->data == &mons[PM_FOG_CLOUD])
1001 /*JP
1002                                    ? "mist"
1003 */
1004                                    ? "\96¶"
1005                                    : is_whirly(u.ustuck->data)
1006 /*JP
1007                                       ? "maelstrom"
1008 */
1009                                       ? "\89Q"
1010                                       : is_animal(u.ustuck->data)
1011 /*JP
1012                                          ? "maw"
1013 */
1014                                          ? "\88Ý"
1015 /*JP
1016                                          : "ooze")
1017 */
1018                                          : "\82Ë\82Î\82Ë\82Î")
1019                                 : (u.uinwater
1020 /*JP
1021                                    ? hliquid("water")
1022 */
1023                                    ? hliquid("\90\85")
1024                                    : (rmtyp == CLOUD)
1025 /*JP
1026                                       ? "cloud"
1027 */
1028                                       ? "\89_"
1029                                       : IS_TREE(rmtyp)
1030 /*JP
1031                                          ? "vegetation"
1032 */
1033                                          ? "\96Ø"
1034                                          : IS_STWALL(rmtyp)
1035 /*JP
1036                                             ? "stone"
1037 */
1038                                             ? "\90Î"
1039 /*JP
1040                                             : "air");
1041 */
1042                                             : "\8bó\8bC");
1043 #if 0 /*JP*/
1044                 pline_The("%s around you begins to shimmer with %s haze.",
1045                           atmosphere, an(hgolden));
1046 #else
1047                 pline("\82 \82È\82½\82Ì\82Ü\82í\82è\82Ì%s\82ª%s\96\82Å\83L\83\89\83L\83\89\82Æ\8cõ\82è\82Í\82\82ß\82½\81D",
1048                           atmosphere, hgolden);
1049 #endif
1050             }
1051         }
1052         u.uspellprot += gain;
1053         u.uspmtime = (P_SKILL(spell_skilltype(SPE_PROTECTION)) == P_EXPERT)
1054                         ? 20 : 10;
1055         if (!u.usptime)
1056             u.usptime = u.uspmtime;
1057         find_ac();
1058     } else {
1059 /*JP
1060         Your("skin feels warm for a moment.");
1061 */
1062         Your("\94§\82Í\88ê\8fu\83|\83J\83|\83J\82µ\82½\81D");
1063     }
1064 }
1065
1066 /* attempting to cast a forgotten spell will cause disorientation */
1067 STATIC_OVL void
1068 spell_backfire(spell)
1069 int spell;
1070 {
1071     long duration = (long) ((spellev(spell) + 1) * 3), /* 6..24 */
1072          old_stun = (HStun & TIMEOUT), old_conf = (HConfusion & TIMEOUT);
1073
1074     /* Prior to 3.4.1, only effect was confusion; it still predominates.
1075      *
1076      * 3.6.0: this used to override pre-existing confusion duration
1077      * (cases 0..8) and pre-existing stun duration (cases 4..9);
1078      * increase them instead.   (Hero can no longer cast spells while
1079      * Stunned, so the potential increment to stun duration here is
1080      * just hypothetical.)
1081      */
1082     switch (rn2(10)) {
1083     case 0:
1084     case 1:
1085     case 2:
1086     case 3:
1087         make_confused(old_conf + duration, FALSE); /* 40% */
1088         break;
1089     case 4:
1090     case 5:
1091     case 6:
1092         make_confused(old_conf + 2L * duration / 3L, FALSE); /* 30% */
1093         make_stunned(old_stun + duration / 3L, FALSE);
1094         break;
1095     case 7:
1096     case 8:
1097         make_stunned(old_stun + 2L * duration / 3L, FALSE); /* 20% */
1098         make_confused(old_conf + duration / 3L, FALSE);
1099         break;
1100     case 9:
1101         make_stunned(old_stun + duration, FALSE); /* 10% */
1102         break;
1103     }
1104     return;
1105 }
1106
1107 int
1108 spelleffects(spell, atme)
1109 int spell;
1110 boolean atme;
1111 {
1112     int energy, damage, chance, n, intell;
1113     int skill, role_skill, res = 0;
1114     boolean confused = (Confusion != 0);
1115     boolean physical_damage = FALSE;
1116     struct obj *pseudo;
1117     coord cc;
1118
1119     /*
1120      * Reject attempting to cast while stunned or with no free hands.
1121      * Already done in getspell() to stop casting before choosing
1122      * which spell, but duplicated here for cases where spelleffects()
1123      * gets called directly for ^T without intrinsic teleport capability
1124      * or #turn for non-priest/non-knight.
1125      * (There's no duplication of messages; when the rejection takes
1126      * place in getspell(), we don't get called.)
1127      */
1128     if (rejectcasting()) {
1129         return 0; /* no time elapses */
1130     }
1131
1132     /*
1133      * Spell casting no longer affects knowledge of the spell. A
1134      * decrement of spell knowledge is done every turn.
1135      */
1136     if (spellknow(spell) <= 0) {
1137 /*JP
1138         Your("knowledge of this spell is twisted.");
1139 */
1140         Your("\82±\82Ì\96\82\96@\82É\8aÖ\82·\82é\92m\8e¯\82Í\82æ\82\82ê\82½\81D");
1141 /*JP
1142         pline("It invokes nightmarish images in your mind...");
1143 */
1144         pline("\82»\82ê\82Í\88«\96²\82ð\90S\82É\95\82\82Î\82¹\82½\81D\81D\81D");
1145         spell_backfire(spell);
1146         return 1;
1147     } else if (spellknow(spell) <= KEEN / 200) { /* 100 turns left */
1148 /*JP
1149         You("strain to recall the spell.");
1150 */
1151         You("\96\82\96@\82ð\8ev\82¢\82¾\82·\82Ì\82É\8bê\98J\82µ\82½\81D");
1152     } else if (spellknow(spell) <= KEEN / 40) { /* 500 turns left */
1153 /*JP
1154         You("have difficulty remembering the spell.");
1155 */
1156         You("\8eô\95\82ð\8ev\82¢\8fo\82·\82Ì\82ª\93ï\82µ\82­\82È\82Á\82Ä\82«\82½\81D");
1157     } else if (spellknow(spell) <= KEEN / 20) { /* 1000 turns left */
1158 /*JP
1159         Your("knowledge of this spell is growing faint.");
1160 */
1161         Your("\82±\82Ì\96\82\96@\82É\8aÖ\82·\82é\92m\8e¯\82ª\82¨\82Ú\82ë\82°\82É\82È\82Á\82Ä\82«\82½\81D");
1162     } else if (spellknow(spell) <= KEEN / 10) { /* 2000 turns left */
1163 /*JP
1164         Your("recall of this spell is gradually fading.");
1165 */
1166         Your("\82±\82Ì\96\82\96@\82É\8aÖ\82·\82é\92m\8e¯\82ª\8f\99\81X\82É\94\96\82ê\82Ä\82«\82½\81D");
1167     }
1168     energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */
1169
1170     if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) {
1171 /*JP
1172         You("are too hungry to cast that spell.");
1173 */
1174         pline("\95 \82ª\8c¸\82è\82·\82¬\82Ä\96\82\96@\82ð\8f¥\82¦\82ç\82ê\82È\82¢\81D");
1175         return 0;
1176     } else if (ACURR(A_STR) < 4 && spellid(spell) != SPE_RESTORE_ABILITY) {
1177 /*JP
1178         You("lack the strength to cast spells.");
1179 */
1180         pline("\8b­\82³\82ª\8f­\82È\82·\82¬\82Ä\96\82\96@\82ð\8f¥\82¦\82ç\82ê\82È\82¢\81D");
1181         return 0;
1182     } else if (check_capacity(
1183 /*JP
1184                 "Your concentration falters while carrying so much stuff.")) {
1185 */
1186                 "\82½\82­\82³\82ñ\82à\82Ì\82ð\8e\9d\82¿\82·\82¬\82Ä\8fW\92\86\82Å\82«\82È\82¢\81D")){
1187         return 1;
1188     }
1189
1190     /* if the cast attempt is already going to fail due to insufficient
1191        energy (ie, u.uen < energy), the Amulet's drain effect won't kick
1192        in and no turn will be consumed; however, when it does kick in,
1193        the attempt may fail due to lack of energy after the draining, in
1194        which case a turn will be used up in addition to the energy loss */
1195     if (u.uhave.amulet && u.uen >= energy) {
1196 /*JP
1197         You_feel("the amulet draining your energy away.");
1198 */
1199         pline("\96\82\8f\9c\82¯\82ª\82 \82È\82½\82Ì\83G\83l\83\8b\83M\81[\82ð\8bz\82¢\82Æ\82Á\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1200         /* this used to be 'energy += rnd(2 * energy)' (without 'res'),
1201            so if amulet-induced cost was more than u.uen, nothing
1202            (except the "don't have enough energy" message) happened
1203            and player could just try again (and again and again...);
1204            now we drain some energy immediately, which has a
1205            side-effect of not increasing the hunger aspect of casting */
1206         u.uen -= rnd(2 * energy);
1207         if (u.uen < 0)
1208             u.uen = 0;
1209         context.botl = 1;
1210         res = 1; /* time is going to elapse even if spell doesn't get cast */
1211     }
1212
1213     if (energy > u.uen) {
1214 /*JP
1215         You("don't have enough energy to cast that spell.");
1216 */
1217         pline("\96\82\96@\82ð\8f¥\82¦\82é\82¾\82¯\82Ì\8f\\95ª\82È\83G\83l\83\8b\83M\81[\82ª\82È\82¢\81D");
1218         return res;
1219     } else {
1220         if (spellid(spell) != SPE_DETECT_FOOD) {
1221             int hungr = energy * 2;
1222
1223             /* If hero is a wizard, their current intelligence
1224              * (bonuses + temporary + current)
1225              * affects hunger reduction in casting a spell.
1226              * 1. int = 17-18 no reduction
1227              * 2. int = 16    1/4 hungr
1228              * 3. int = 15    1/2 hungr
1229              * 4. int = 1-14  normal reduction
1230              * The reason for this is:
1231              * a) Intelligence affects the amount of exertion
1232              * in thinking.
1233              * b) Wizards have spent their life at magic and
1234              * understand quite well how to cast spells.
1235              */
1236             intell = acurr(A_INT);
1237             if (!Role_if(PM_WIZARD))
1238                 intell = 10;
1239             switch (intell) {
1240             case 25:
1241             case 24:
1242             case 23:
1243             case 22:
1244             case 21:
1245             case 20:
1246             case 19:
1247             case 18:
1248             case 17:
1249                 hungr = 0;
1250                 break;
1251             case 16:
1252                 hungr /= 4;
1253                 break;
1254             case 15:
1255                 hungr /= 2;
1256                 break;
1257             }
1258             /* don't put player (quite) into fainting from
1259              * casting a spell, particularly since they might
1260              * not even be hungry at the beginning; however,
1261              * this is low enough that they must eat before
1262              * casting anything else except detect food
1263              */
1264             if (hungr > u.uhunger - 3)
1265                 hungr = u.uhunger - 3;
1266             morehungry(hungr);
1267         }
1268     }
1269
1270     chance = percent_success(spell);
1271     if (confused || (rnd(100) > chance)) {
1272 /*JP
1273         You("fail to cast the spell correctly.");
1274 */
1275         You("\96\82\96@\82ð\90³\82µ\82­\8f¥\82¦\82é\82±\82Æ\82ª\82Å\82«\82È\82©\82Á\82½\81D");
1276         u.uen -= energy / 2;
1277         context.botl = 1;
1278         return 1;
1279     }
1280
1281     u.uen -= energy;
1282     context.botl = 1;
1283     exercise(A_WIS, TRUE);
1284     /* pseudo is a temporary "false" object containing the spell stats */
1285     pseudo = mksobj(spellid(spell), FALSE, FALSE);
1286     pseudo->blessed = pseudo->cursed = 0;
1287     pseudo->quan = 20L; /* do not let useup get it */
1288     /*
1289      * Find the skill the hero has in a spell type category.
1290      * See spell_skilltype for categories.
1291      */
1292     skill = spell_skilltype(pseudo->otyp);
1293     role_skill = P_SKILL(skill);
1294
1295     switch (pseudo->otyp) {
1296     /*
1297      * At first spells act as expected.  As the hero increases in skill
1298      * with the appropriate spell type, some spells increase in their
1299      * effects, e.g. more damage, further distance, and so on, without
1300      * additional cost to the spellcaster.
1301      */
1302     case SPE_FIREBALL:
1303     case SPE_CONE_OF_COLD:
1304         if (role_skill >= P_SKILLED) {
1305             if (throwspell()) {
1306                 cc.x = u.dx;
1307                 cc.y = u.dy;
1308                 n = rnd(8) + 1;
1309                 while (n--) {
1310                     if (!u.dx && !u.dy && !u.dz) {
1311                         if ((damage = zapyourself(pseudo, TRUE)) != 0) {
1312                             char buf[BUFSZ];
1313 #if 0 /*JP*/
1314                             Sprintf(buf, "zapped %sself with a spell",
1315                                     uhim());
1316                             losehp(damage, buf, NO_KILLER_PREFIX);
1317 #else
1318                             Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82ð\97\81\82Ñ\82Ä");
1319                             losehp(damage, buf, KILLED_BY);
1320 #endif
1321                         }
1322                     } else {
1323                         explode(u.dx, u.dy,
1324                                 pseudo->otyp - SPE_MAGIC_MISSILE + 10,
1325                                 spell_damage_bonus(u.ulevel / 2 + 1), 0,
1326                                 (pseudo->otyp == SPE_CONE_OF_COLD)
1327                                    ? EXPL_FROSTY
1328                                    : EXPL_FIERY);
1329                     }
1330                     u.dx = cc.x + rnd(3) - 2;
1331                     u.dy = cc.y + rnd(3) - 2;
1332                     if (!isok(u.dx, u.dy) || !cansee(u.dx, u.dy)
1333                         || IS_STWALL(levl[u.dx][u.dy].typ) || u.uswallow) {
1334                         /* Spell is reflected back to center */
1335                         u.dx = cc.x;
1336                         u.dy = cc.y;
1337                     }
1338                 }
1339             }
1340             break;
1341         } /* else fall through... */
1342
1343     /* these spells are all duplicates of wand effects */
1344     case SPE_FORCE_BOLT:
1345         physical_damage = TRUE;
1346     /* fall through */
1347     case SPE_SLEEP:
1348     case SPE_MAGIC_MISSILE:
1349     case SPE_KNOCK:
1350     case SPE_SLOW_MONSTER:
1351     case SPE_WIZARD_LOCK:
1352     case SPE_DIG:
1353     case SPE_TURN_UNDEAD:
1354     case SPE_POLYMORPH:
1355     case SPE_TELEPORT_AWAY:
1356     case SPE_CANCELLATION:
1357     case SPE_FINGER_OF_DEATH:
1358     case SPE_LIGHT:
1359     case SPE_DETECT_UNSEEN:
1360     case SPE_HEALING:
1361     case SPE_EXTRA_HEALING:
1362     case SPE_DRAIN_LIFE:
1363     case SPE_STONE_TO_FLESH:
1364         if (!(objects[pseudo->otyp].oc_dir == NODIR)) {
1365             if (atme) {
1366                 u.dx = u.dy = u.dz = 0;
1367             } else if (!getdir((char *) 0)) {
1368                 /* getdir cancelled, re-use previous direction */
1369                 /*
1370                  * FIXME:  reusing previous direction only makes sense
1371                  * if there is an actual previous direction.  When there
1372                  * isn't one, the spell gets cast at self which is rarely
1373                  * what the player intended.  Unfortunately, the way
1374                  * spelleffects() is organized means that aborting with
1375                  * "nevermind" is not an option.
1376                  */
1377 /*JP
1378                 pline_The("magical energy is released!");
1379 */
1380                 pline("\96\82\96@\82Ì\83G\83l\83\8b\83M\81[\82ª\89ð\95ú\82³\82ê\82½\81I");
1381             }
1382             if (!u.dx && !u.dy && !u.dz) {
1383                 if ((damage = zapyourself(pseudo, TRUE)) != 0) {
1384                     char buf[BUFSZ];
1385
1386 /*JP
1387                     Sprintf(buf, "zapped %sself with a spell", uhim());
1388 */
1389                     Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82ð\97\81\82Ñ\82Ä");
1390                     if (physical_damage)
1391                         damage = Maybe_Half_Phys(damage);
1392 #if 0 /*JP*/
1393                     losehp(damage, buf, NO_KILLER_PREFIX);
1394 #else
1395                     losehp(damage, buf, KILLED_BY);
1396 #endif
1397                 }
1398             } else
1399                 weffects(pseudo);
1400         } else
1401             weffects(pseudo);
1402         update_inventory(); /* spell may modify inventory */
1403         break;
1404
1405     /* these are all duplicates of scroll effects */
1406     case SPE_REMOVE_CURSE:
1407     case SPE_CONFUSE_MONSTER:
1408     case SPE_DETECT_FOOD:
1409     case SPE_CAUSE_FEAR:
1410     case SPE_IDENTIFY:
1411         /* high skill yields effect equivalent to blessed scroll */
1412         if (role_skill >= P_SKILLED)
1413             pseudo->blessed = 1;
1414     /* fall through */
1415     case SPE_CHARM_MONSTER:
1416     case SPE_MAGIC_MAPPING:
1417     case SPE_CREATE_MONSTER:
1418         (void) seffects(pseudo);
1419         break;
1420
1421     /* these are all duplicates of potion effects */
1422     case SPE_HASTE_SELF:
1423     case SPE_DETECT_TREASURE:
1424     case SPE_DETECT_MONSTERS:
1425     case SPE_LEVITATION:
1426     case SPE_RESTORE_ABILITY:
1427         /* high skill yields effect equivalent to blessed potion */
1428         if (role_skill >= P_SKILLED)
1429             pseudo->blessed = 1;
1430     /* fall through */
1431     case SPE_INVISIBILITY:
1432         (void) peffects(pseudo);
1433         break;
1434     /* end of potion-like spells */
1435
1436     case SPE_CURE_BLINDNESS:
1437         healup(0, 0, FALSE, TRUE);
1438         break;
1439     case SPE_CURE_SICKNESS:
1440         if (Sick)
1441 /*JP
1442             You("are no longer ill.");
1443 */
1444             Your("\95a\8bC\82Í\92¼\82Á\82½\81D");
1445         if (Slimed)
1446 /*JP
1447             make_slimed(0L, "The slime disappears!");
1448 */
1449             make_slimed(0L, "\83X\83\89\83C\83\80\82Í\8fÁ\82¦\82½\81I");
1450         healup(0, 0, TRUE, FALSE);
1451         break;
1452     case SPE_CREATE_FAMILIAR:
1453         (void) make_familiar((struct obj *) 0, u.ux, u.uy, FALSE);
1454         break;
1455     case SPE_CLAIRVOYANCE:
1456         if (!BClairvoyant) {
1457             if (role_skill >= P_SKILLED)
1458                 pseudo->blessed = 1; /* detect monsters as well as map */
1459             do_vicinity_map(pseudo);
1460         /* at present, only one thing blocks clairvoyance */
1461         } else if (uarmh && uarmh->otyp == CORNUTHAUM)
1462 /*JP
1463             You("sense a pointy hat on top of your %s.", body_part(HEAD));
1464 */
1465             You("\82Æ\82ª\82Á\82½\96X\8eq\82ð%s\82Ì\8fã\82É\94­\8c©\82µ\82½\81D", body_part(HEAD));
1466         break;
1467     case SPE_PROTECTION:
1468         cast_protection();
1469         break;
1470     case SPE_JUMPING:
1471         if (!jump(max(role_skill, 1)))
1472             pline1(nothing_happens);
1473         break;
1474     default:
1475         impossible("Unknown spell %d attempted.", spell);
1476         obfree(pseudo, (struct obj *) 0);
1477         return 0;
1478     }
1479
1480     /* gain skill for successful cast */
1481     use_skill(skill, spellev(spell));
1482
1483     obfree(pseudo, (struct obj *) 0); /* now, get rid of it */
1484     return 1;
1485 }
1486
1487 /*ARGSUSED*/
1488 STATIC_OVL boolean
1489 spell_aim_step(arg, x, y)
1490 genericptr_t arg UNUSED;
1491 int x, y;
1492 {
1493     if (!isok(x,y))
1494         return FALSE;
1495     if (!ZAP_POS(levl[x][y].typ)
1496         && !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
1497         return FALSE;
1498     return TRUE;
1499 }
1500
1501 /* Choose location where spell takes effect. */
1502 STATIC_OVL int
1503 throwspell()
1504 {
1505     coord cc, uc;
1506     struct monst *mtmp;
1507
1508     if (u.uinwater) {
1509 /*JP
1510         pline("You're joking! In this weather?");
1511 */
1512         pline("\90\85\92\86\82Å\89½\82ð\82µ\82æ\82¤\82Á\82Ä\82¢\82¤\82ñ\82¾\82¢\81H");
1513         return 0;
1514     } else if (Is_waterlevel(&u.uz)) {
1515 /*JP
1516         You("had better wait for the sun to come out.");
1517 */
1518         You("\91¾\97z\82ª\8c»\82ê\82é\82Ü\82Å\91Ò\82Á\82½\82Ù\82¤\82ª\82æ\82¢\82¾\82ë\82¤\81D");
1519         return 0;
1520     }
1521
1522 /*JP
1523     pline("Where do you want to cast the spell?");
1524 */
1525     pline("\82Ç\82±\82É\8cü\82©\82Á\82Ä\96\82\96@\82ð\8f¥\82¦\82é\81H");
1526     cc.x = u.ux;
1527     cc.y = u.uy;
1528 /*JP
1529     if (getpos(&cc, TRUE, "the desired position") < 0)
1530 */
1531     if (getpos(&cc, TRUE, "\96]\82Ý\82Ì\8fê\8f\8a") < 0)
1532         return 0; /* user pressed ESC */
1533     /* The number of moves from hero to where the spell drops.*/
1534     if (distmin(u.ux, u.uy, cc.x, cc.y) > 10) {
1535 /*JP
1536         pline_The("spell dissipates over the distance!");
1537 */
1538         pline("\89\93\82·\82¬\82é\81I");
1539         return 0;
1540     } else if (u.uswallow) {
1541 /*JP
1542         pline_The("spell is cut short!");
1543 */
1544         pline("\82¾\82ß\82¾\81I\8bß\82·\82¬\82é\81I");
1545         exercise(A_WIS, FALSE); /* What were you THINKING! */
1546         u.dx = 0;
1547         u.dy = 0;
1548         return 1;
1549     } else if ((!cansee(cc.x, cc.y)
1550                 && (!(mtmp = m_at(cc.x, cc.y)) || !canspotmon(mtmp)))
1551                || IS_STWALL(levl[cc.x][cc.y].typ)) {
1552 /*JP
1553         Your("mind fails to lock onto that location!");
1554 */
1555         You("\82»\82±\82É\8cü\82©\82Á\82Ä\8fW\92\86\82µ\82½\82ª\8e¸\94s\82µ\82½\81I");
1556         return 0;
1557     }
1558
1559     uc.x = u.ux;
1560     uc.y = u.uy;
1561
1562     walk_path(&uc, &cc, spell_aim_step, (genericptr_t) 0);
1563
1564     u.dx = cc.x;
1565     u.dy = cc.y;
1566     return 1;
1567 }
1568
1569 /* forget a random selection of known spells due to amnesia;
1570    they used to be lost entirely, as if never learned, but now we
1571    just set the memory retention to zero so that they can't be cast */
1572 void
1573 losespells()
1574 {
1575     int n, nzap, i;
1576
1577     /* in case reading has been interrupted earlier, discard context */
1578     context.spbook.book = 0;
1579     context.spbook.o_id = 0;
1580     /* count the number of known spells */
1581     for (n = 0; n < MAXSPELL; ++n)
1582         if (spellid(n) == NO_SPELL)
1583             break;
1584
1585     /* lose anywhere from zero to all known spells;
1586        if confused, use the worse of two die rolls */
1587     nzap = rn2(n + 1);
1588     if (Confusion) {
1589         i = rn2(n + 1);
1590         if (i > nzap)
1591             nzap = i;
1592     }
1593     /* good Luck might ameliorate spell loss */
1594     if (nzap > 1 && !rnl(7))
1595         nzap = rnd(nzap);
1596
1597     /*
1598      * Forget 'nzap' out of 'n' known spells by setting their memory
1599      * retention to zero.  Every spell has the same probability to be
1600      * forgotten, even if its retention is already zero.
1601      *
1602      * Perhaps we should forget the corresponding book too?
1603      *
1604      * (3.4.3 removed spells entirely from the list, but always did
1605      * so from its end, so the 'nzap' most recently learned spells
1606      * were the ones lost by default.  Player had sort control over
1607      * the list, so could move the most useful spells to front and
1608      * only lose them if 'nzap' turned out to be a large value.
1609      *
1610      * Discarding from the end of the list had the virtue of making
1611      * casting letters for lost spells become invalid and retaining
1612      * the original letter for the ones which weren't lost, so there
1613      * was no risk to the player of accidentally casting the wrong
1614      * spell when using a letter that was in use prior to amnesia.
1615      * That wouldn't be the case if we implemented spell loss spread
1616      * throughout the list of known spells; every spell located past
1617      * the first lost spell would end up with new letter assigned.)
1618      */
1619     for (i = 0; nzap > 0; ++i) {
1620         /* when nzap is small relative to the number of spells left,
1621            the chance to lose spell [i] is small; as the number of
1622            remaining candidates shrinks, the chance per candidate
1623            gets bigger; overall, exactly nzap entries are affected */
1624         if (rn2(n - i) < nzap) {
1625             /* lose access to spell [i] */
1626             spellknow(i) = 0;
1627 #if 0
1628             /* also forget its book */
1629             forget_single_object(spellid(i));
1630 #endif
1631             /* and abuse wisdom */
1632             exercise(A_WIS, FALSE);
1633             /* there's now one less spell slated to be forgotten */
1634             --nzap;
1635         }
1636     }
1637 }
1638
1639 /*
1640  * Allow player to sort the list of known spells.  Manually swapping
1641  * pairs of them becomes very tedious once the list reaches two pages.
1642  *
1643  * Possible extensions:
1644  *      provide means for player to control ordering of skill classes;
1645  *      provide means to supply value N such that first N entries stick
1646  *      while rest of list is being sorted;
1647  *      make chosen sort order be persistent such that when new spells
1648  *      are learned, they get inserted into sorted order rather than be
1649  *      appended to the end of the list?
1650  */
1651 enum spl_sort_types {
1652     SORTBY_LETTER = 0,
1653     SORTBY_ALPHA,
1654     SORTBY_LVL_LO,
1655     SORTBY_LVL_HI,
1656     SORTBY_SKL_AL,
1657     SORTBY_SKL_LO,
1658     SORTBY_SKL_HI,
1659     SORTBY_CURRENT,
1660     SORTRETAINORDER,
1661
1662     NUM_SPELL_SORTBY
1663 };
1664
1665 static const char *spl_sortchoices[NUM_SPELL_SORTBY] = {
1666 /*JP
1667     "by casting letter",
1668 */
1669     "\91I\91ð\82·\82é\95\8e\9a\8f\87",
1670 /*JP
1671     "alphabetically",
1672 */
1673     "\95\8e\9a\83R\81[\83h\8f\87",
1674 /*JP
1675     "by level, low to high",
1676 */
1677     "\83\8c\83x\83\8b\8f¸\8f\87",
1678 /*JP
1679     "by level, high to low",
1680 */
1681     "\83\8c\83x\83\8b\8d~\8f\87",
1682 /*JP
1683     "by skill group, alphabetized within each group",
1684 */
1685     "\83X\83L\83\8b\83O\83\8b\81[\83v\96\88\82É\95\8e\9a\83R\81[\83h\8f\87",
1686 /*JP
1687     "by skill group, low to high level within group",
1688 */
1689     "\83X\83L\83\8b\83O\83\8b\81[\83v\96\88\82É\83\8c\83x\83\8b\8f¸\8f\87",
1690 /*JP
1691     "by skill group, high to low level within group",
1692 */
1693     "\83X\83L\83\8b\83O\83\8b\81[\83v\96\88\82É\83\8c\83x\83\8b\8d~\8f\87",
1694 /*JP
1695     "maintain current ordering",
1696 */
1697     "\8c»\8dÝ\82Ì\8f\87\8f\98\82ð\88Û\8e\9d",
1698     /* a menu choice rather than a sort choice */
1699 /*JP
1700     "reassign casting letters to retain current order",
1701 */
1702     "\8c»\8dÝ\82Ì\8f\87\8f\98\82ð\95Ï\82¦\82¸\82É\91I\91ð\82·\82é\95\8e\9a\82ð\8dÄ\8a\84\82è\93\96\82Ä",
1703 };
1704 static int spl_sortmode = 0;   /* index into spl_sortchoices[] */
1705 static int *spl_orderindx = 0; /* array of spl_book[] indices */
1706
1707 /* qsort callback routine */
1708 STATIC_PTR int CFDECLSPEC
1709 spell_cmp(vptr1, vptr2)
1710 const genericptr vptr1;
1711 const genericptr vptr2;
1712 {
1713     /*
1714      * gather up all of the possible parameters except spell name
1715      * in advance, even though some might not be needed:
1716      *  indx. = spl_orderindx[] index into spl_book[];
1717      *  otyp. = spl_book[] index into objects[];
1718      *  levl. = spell level;
1719      *  skil. = skill group aka spell class.
1720      */
1721     int indx1 = *(int *) vptr1, indx2 = *(int *) vptr2,
1722         otyp1 = spl_book[indx1].sp_id, otyp2 = spl_book[indx2].sp_id,
1723         levl1 = objects[otyp1].oc_level, levl2 = objects[otyp2].oc_level,
1724         skil1 = objects[otyp1].oc_skill, skil2 = objects[otyp2].oc_skill;
1725
1726     switch (spl_sortmode) {
1727     case SORTBY_LETTER:
1728         return indx1 - indx2;
1729     case SORTBY_ALPHA:
1730         break;
1731     case SORTBY_LVL_LO:
1732         if (levl1 != levl2)
1733             return levl1 - levl2;
1734         break;
1735     case SORTBY_LVL_HI:
1736         if (levl1 != levl2)
1737             return levl2 - levl1;
1738         break;
1739     case SORTBY_SKL_AL:
1740         if (skil1 != skil2)
1741             return skil1 - skil2;
1742         break;
1743     case SORTBY_SKL_LO:
1744         if (skil1 != skil2)
1745             return skil1 - skil2;
1746         if (levl1 != levl2)
1747             return levl1 - levl2;
1748         break;
1749     case SORTBY_SKL_HI:
1750         if (skil1 != skil2)
1751             return skil1 - skil2;
1752         if (levl1 != levl2)
1753             return levl2 - levl1;
1754         break;
1755     case SORTBY_CURRENT:
1756     default:
1757         return (vptr1 < vptr2) ? -1
1758                                : (vptr1 > vptr2); /* keep current order */
1759     }
1760     /* tie-breaker for most sorts--alphabetical by spell name */
1761     return strcmpi(OBJ_NAME(objects[otyp1]), OBJ_NAME(objects[otyp2]));
1762 }
1763
1764 /* sort the index used for display order of the "view known spells"
1765    list (sortmode == SORTBY_xxx), or sort the spellbook itself to make
1766    the current display order stick (sortmode == SORTRETAINORDER) */
1767 STATIC_OVL void
1768 sortspells()
1769 {
1770     int i;
1771 #if defined(SYSV) || defined(DGUX)
1772     unsigned n;
1773 #else
1774     int n;
1775 #endif
1776
1777     if (spl_sortmode == SORTBY_CURRENT)
1778         return;
1779     for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; ++n)
1780         continue;
1781     if (n < 2)
1782         return; /* not enough entries to need sorting */
1783
1784     if (!spl_orderindx) {
1785         /* we haven't done any sorting yet; list is in casting order */
1786         if (spl_sortmode == SORTBY_LETTER /* default */
1787             || spl_sortmode == SORTRETAINORDER)
1788             return;
1789         /* allocate enough for full spellbook rather than just N spells */
1790         spl_orderindx = (int *) alloc(MAXSPELL * sizeof(int));
1791         for (i = 0; i < MAXSPELL; i++)
1792             spl_orderindx[i] = i;
1793     }
1794
1795     if (spl_sortmode == SORTRETAINORDER) {
1796         struct spell tmp_book[MAXSPELL];
1797
1798         /* sort spl_book[] rather than spl_orderindx[];
1799            this also updates the index to reflect the new ordering (we
1800            could just free it since that ordering becomes the default) */
1801         for (i = 0; i < MAXSPELL; i++)
1802             tmp_book[i] = spl_book[spl_orderindx[i]];
1803         for (i = 0; i < MAXSPELL; i++)
1804             spl_book[i] = tmp_book[i], spl_orderindx[i] = i;
1805         spl_sortmode = SORTBY_LETTER; /* reset */
1806         return;
1807     }
1808
1809     /* usual case, sort the index rather than the spells themselves */
1810     qsort((genericptr_t) spl_orderindx, n, sizeof *spl_orderindx, spell_cmp);
1811     return;
1812 }
1813
1814 /* called if the [sort spells] entry in the view spells menu gets chosen */
1815 STATIC_OVL boolean
1816 spellsortmenu()
1817 {
1818     winid tmpwin;
1819     menu_item *selected;
1820     anything any;
1821     char let;
1822     int i, n, choice;
1823
1824     tmpwin = create_nhwindow(NHW_MENU);
1825     start_menu(tmpwin);
1826     any = zeroany; /* zero out all bits */
1827
1828     for (i = 0; i < SIZE(spl_sortchoices); i++) {
1829         if (i == SORTRETAINORDER) {
1830             let = 'z'; /* assumes fewer than 26 sort choices... */
1831             /* separate final choice from others with a blank line */
1832             any.a_int = 0;
1833             add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "",
1834                      MENU_UNSELECTED);
1835         } else {
1836             let = 'a' + i;
1837         }
1838         any.a_int = i + 1;
1839         add_menu(tmpwin, NO_GLYPH, &any, let, 0, ATR_NONE, spl_sortchoices[i],
1840                  (i == spl_sortmode) ? MENU_SELECTED : MENU_UNSELECTED);
1841     }
1842     end_menu(tmpwin, "View known spells list sorted");
1843
1844     n = select_menu(tmpwin, PICK_ONE, &selected);
1845     destroy_nhwindow(tmpwin);
1846     if (n > 0) {
1847         choice = selected[0].item.a_int - 1;
1848         /* skip preselected entry if we have more than one item chosen */
1849         if (n > 1 && choice == spl_sortmode)
1850             choice = selected[1].item.a_int - 1;
1851         free((genericptr_t) selected);
1852         spl_sortmode = choice;
1853         return TRUE;
1854     }
1855     return FALSE;
1856 }
1857
1858 /* the '+' command -- view known spells */
1859 int
1860 dovspell()
1861 {
1862     char qbuf[QBUFSZ];
1863     int splnum, othnum;
1864     struct spell spl_tmp;
1865
1866     if (spellid(0) == NO_SPELL) {
1867 /*JP
1868         You("don't know any spells right now.");
1869 */
1870         You("\96\82\96@\82ð\92m\82ç\82È\82¢\81D");
1871     } else {
1872 /*JP
1873         while (dospellmenu("Currently known spells",
1874 */
1875         while (dospellmenu("\8c»\8dÝ\92m\82Á\82Ä\82¢\82é\96\82\96@\88ê\97\97",
1876                            SPELLMENU_VIEW, &splnum)) {
1877             if (splnum == SPELLMENU_SORT) {
1878                 if (spellsortmenu())
1879                     sortspells();
1880             } else {
1881 /*JP
1882                 Sprintf(qbuf, "Reordering spells; swap '%c' with",
1883 */
1884                 Sprintf(qbuf, "'%c'\82Æ\95À\82Ñ\95Ï\82¦\82é\96\82\96@\82Í\81H",
1885                         spellet(splnum));
1886                 if (!dospellmenu(qbuf, splnum, &othnum))
1887                     break;
1888
1889                 spl_tmp = spl_book[splnum];
1890                 spl_book[splnum] = spl_book[othnum];
1891                 spl_book[othnum] = spl_tmp;
1892             }
1893         }
1894     }
1895     if (spl_orderindx) {
1896         free((genericptr_t) spl_orderindx);
1897         spl_orderindx = 0;
1898     }
1899     spl_sortmode = SORTBY_LETTER; /* 0 */
1900     return 0;
1901 }
1902
1903 STATIC_OVL boolean
1904 dospellmenu(prompt, splaction, spell_no)
1905 const char *prompt;
1906 int splaction; /* SPELLMENU_CAST, SPELLMENU_VIEW, or spl_book[] index */
1907 int *spell_no;
1908 {
1909     winid tmpwin;
1910     int i, n, how, splnum;
1911     char buf[BUFSZ], retentionbuf[24];
1912     const char *fmt;
1913     menu_item *selected;
1914     anything any;
1915
1916     tmpwin = create_nhwindow(NHW_MENU);
1917     start_menu(tmpwin);
1918     any = zeroany; /* zero out all bits */
1919
1920     /*
1921      * The correct spacing of the columns when not using
1922      * tab separation depends on the following:
1923      * (1) that the font is monospaced, and
1924      * (2) that selection letters are pre-pended to the
1925      * given string and are of the form "a - ".
1926      */
1927     if (!iflags.menu_tab_sep) {
1928 #if 0 /*JP*/
1929         Sprintf(buf, "%-20s     Level %-12s Fail Retention", "    Name",
1930                 "Category");
1931 #else
1932         Sprintf(buf, "%-20s     Level  %-12s \90¬\8c÷\97¦", "    Name", "\95ª\97Þ");
1933 #endif
1934         fmt = "%-20s  %2d   %-12s %3d%% %9s";
1935     } else {
1936 /*JP
1937         Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
1938 */
1939         Sprintf(buf, "\96¼\91O\t\83\8c\83x\83\8b\t\95ª\97Þ\t\90¬\8c÷\97¦");
1940         fmt = "%s\t%-d\t%s\t%-d%%\t%s";
1941     }
1942     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1943              MENU_UNSELECTED);
1944     for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) {
1945         splnum = !spl_orderindx ? i : spl_orderindx[i];
1946         Sprintf(buf, fmt, spellname(splnum), spellev(splnum),
1947                 spelltypemnemonic(spell_skilltype(spellid(splnum))),
1948                 100 - percent_success(splnum),
1949                 spellretention(splnum, retentionbuf));
1950
1951         any.a_int = splnum + 1; /* must be non-zero */
1952         add_menu(tmpwin, NO_GLYPH, &any, spellet(splnum), 0, ATR_NONE, buf,
1953                  (splnum == splaction) ? MENU_SELECTED : MENU_UNSELECTED);
1954     }
1955     how = PICK_ONE;
1956     if (splaction == SPELLMENU_VIEW) {
1957         if (spellid(1) == NO_SPELL) {
1958             /* only one spell => nothing to swap with */
1959             how = PICK_NONE;
1960         } else {
1961             /* more than 1 spell, add an extra menu entry */
1962             any.a_int = SPELLMENU_SORT + 1;
1963             add_menu(tmpwin, NO_GLYPH, &any, '+', 0, ATR_NONE,
1964                      "[sort spells]", MENU_UNSELECTED);
1965         }
1966     }
1967     end_menu(tmpwin, prompt);
1968
1969     n = select_menu(tmpwin, how, &selected);
1970     destroy_nhwindow(tmpwin);
1971     if (n > 0) {
1972         *spell_no = selected[0].item.a_int - 1;
1973         /* menu selection for `PICK_ONE' does not
1974            de-select any preselected entry */
1975         if (n > 1 && *spell_no == splaction)
1976             *spell_no = selected[1].item.a_int - 1;
1977         free((genericptr_t) selected);
1978         /* default selection of preselected spell means that
1979            user chose not to swap it with anything */
1980         if (*spell_no == splaction)
1981             return FALSE;
1982         return TRUE;
1983     } else if (splaction >= 0) {
1984         /* explicit de-selection of preselected spell means that
1985            user is still swapping but not for the current spell */
1986         *spell_no = splaction;
1987         return TRUE;
1988     }
1989     return FALSE;
1990 }
1991
1992 STATIC_OVL int
1993 percent_success(spell)
1994 int spell;
1995 {
1996     /* Intrinsic and learned ability are combined to calculate
1997      * the probability of player's success at cast a given spell.
1998      */
1999     int chance, splcaster, special, statused;
2000     int difficulty;
2001     int skill;
2002
2003     /* Calculate intrinsic ability (splcaster) */
2004
2005     splcaster = urole.spelbase;
2006     special = urole.spelheal;
2007     statused = ACURR(urole.spelstat);
2008
2009     if (uarm && is_metallic(uarm))
2010         splcaster += (uarmc && uarmc->otyp == ROBE) ? urole.spelarmr / 2
2011                                                     : urole.spelarmr;
2012     else if (uarmc && uarmc->otyp == ROBE)
2013         splcaster -= urole.spelarmr;
2014     if (uarms)
2015         splcaster += urole.spelshld;
2016
2017     if (uarmh && is_metallic(uarmh) && uarmh->otyp != HELM_OF_BRILLIANCE)
2018         splcaster += uarmhbon;
2019     if (uarmg && is_metallic(uarmg))
2020         splcaster += uarmgbon;
2021     if (uarmf && is_metallic(uarmf))
2022         splcaster += uarmfbon;
2023
2024     if (spellid(spell) == urole.spelspec)
2025         splcaster += urole.spelsbon;
2026
2027     /* `healing spell' bonus */
2028     if (spellid(spell) == SPE_HEALING || spellid(spell) == SPE_EXTRA_HEALING
2029         || spellid(spell) == SPE_CURE_BLINDNESS
2030         || spellid(spell) == SPE_CURE_SICKNESS
2031         || spellid(spell) == SPE_RESTORE_ABILITY
2032         || spellid(spell) == SPE_REMOVE_CURSE)
2033         splcaster += special;
2034
2035     if (splcaster > 20)
2036         splcaster = 20;
2037
2038     /* Calculate learned ability */
2039
2040     /* Players basic likelihood of being able to cast any spell
2041      * is based of their `magic' statistic. (Int or Wis)
2042      */
2043     chance = 11 * statused / 2;
2044
2045     /*
2046      * High level spells are harder.  Easier for higher level casters.
2047      * The difficulty is based on the hero's level and their skill level
2048      * in that spell type.
2049      */
2050     skill = P_SKILL(spell_skilltype(spellid(spell)));
2051     skill = max(skill, P_UNSKILLED) - 1; /* unskilled => 0 */
2052     difficulty =
2053         (spellev(spell) - 1) * 4 - ((skill * 6) + (u.ulevel / 3) + 1);
2054
2055     if (difficulty > 0) {
2056         /* Player is too low level or unskilled. */
2057         chance -= isqrt(900 * difficulty + 2000);
2058     } else {
2059         /* Player is above level.  Learning continues, but the
2060          * law of diminishing returns sets in quickly for
2061          * low-level spells.  That is, a player quickly gains
2062          * no advantage for raising level.
2063          */
2064         int learning = 15 * -difficulty / spellev(spell);
2065         chance += learning > 20 ? 20 : learning;
2066     }
2067
2068     /* Clamp the chance: >18 stat and advanced learning only help
2069      * to a limit, while chances below "hopeless" only raise the
2070      * specter of overflowing 16-bit ints (and permit wearing a
2071      * shield to raise the chances :-).
2072      */
2073     if (chance < 0)
2074         chance = 0;
2075     if (chance > 120)
2076         chance = 120;
2077
2078     /* Wearing anything but a light shield makes it very awkward
2079      * to cast a spell.  The penalty is not quite so bad for the
2080      * player's role-specific spell.
2081      */
2082     if (uarms && weight(uarms) > (int) objects[SMALL_SHIELD].oc_weight) {
2083         if (spellid(spell) == urole.spelspec) {
2084             chance /= 2;
2085         } else {
2086             chance /= 4;
2087         }
2088     }
2089
2090     /* Finally, chance (based on player intell/wisdom and level) is
2091      * combined with ability (based on player intrinsics and
2092      * encumbrances).  No matter how intelligent/wise and advanced
2093      * a player is, intrinsics and encumbrance can prevent casting;
2094      * and no matter how able, learning is always required.
2095      */
2096     chance = chance * (20 - splcaster) / 15 - splcaster;
2097
2098     /* Clamp to percentile */
2099     if (chance > 100)
2100         chance = 100;
2101     if (chance < 0)
2102         chance = 0;
2103
2104     return chance;
2105 }
2106
2107 STATIC_OVL char *
2108 spellretention(idx, outbuf)
2109 int idx;
2110 char *outbuf;
2111 {
2112     long turnsleft, percent, accuracy;
2113     int skill;
2114
2115     skill = P_SKILL(spell_skilltype(spellid(idx)));
2116     skill = max(skill, P_UNSKILLED); /* restricted same as unskilled */
2117     turnsleft = spellknow(idx);
2118     *outbuf = '\0'; /* lint suppression */
2119
2120     if (turnsleft < 1L) {
2121         /* spell has expired; hero can't successfully cast it anymore */
2122         Strcpy(outbuf, "(gone)");
2123     } else if (turnsleft >= (long) KEEN) {
2124         /* full retention, first turn or immediately after reading book */
2125         Strcpy(outbuf, "100%");
2126     } else {
2127         /*
2128          * Retention is displayed as a range of percentages of
2129          * amount of time left until memory of the spell expires;
2130          * the precision of the range depends upon hero's skill
2131          * in this spell.
2132          *    expert:  2% intervals; 1-2,   3-4,  ...,   99-100;
2133          *   skilled:  5% intervals; 1-5,   6-10, ...,   95-100;
2134          *     basic: 10% intervals; 1-10, 11-20, ...,   91-100;
2135          * unskilled: 25% intervals; 1-25, 26-50, 51-75, 76-100.
2136          *
2137          * At the low end of each range, a value of N% really means
2138          * (N-1)%+1 through N%; so 1% is "greater than 0, at most 200".
2139          * KEEN is a multiple of 100; KEEN/100 loses no precision.
2140          */
2141         percent = (turnsleft - 1L) / ((long) KEEN / 100L) + 1L;
2142         accuracy =
2143             (skill == P_EXPERT) ? 2L : (skill == P_SKILLED)
2144                                            ? 5L
2145                                            : (skill == P_BASIC) ? 10L : 25L;
2146         /* round up to the high end of this range */
2147         percent = accuracy * ((percent - 1L) / accuracy + 1L);
2148         Sprintf(outbuf, "%ld%%-%ld%%", percent - accuracy + 1L, percent);
2149     }
2150     return outbuf;
2151 }
2152
2153 /* Learn a spell during creation of the initial inventory */
2154 void
2155 initialspell(obj)
2156 struct obj *obj;
2157 {
2158     int i, otyp = obj->otyp;
2159
2160     for (i = 0; i < MAXSPELL; i++)
2161         if (spellid(i) == NO_SPELL || spellid(i) == otyp)
2162             break;
2163
2164     if (i == MAXSPELL) {
2165         impossible("Too many spells memorized!");
2166     } else if (spellid(i) != NO_SPELL) {
2167         /* initial inventory shouldn't contain duplicate spellbooks */
2168         impossible("Spell %s already known.", OBJ_NAME(objects[otyp]));
2169     } else {
2170         spl_book[i].sp_id = otyp;
2171         spl_book[i].sp_lev = objects[otyp].oc_level;
2172         incrnknow(i, 0);
2173     }
2174     return;
2175 }
2176
2177 /*spell.c*/