OSDN Git Service

168def71597c82999b280d40faea2fee7e869266
[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-2019            */
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("\82­\82ç\82­\82ç\82µ\82Ä\82¢\82Ä\96\82\96@\82ð\8eg\82¦\82È\82¢\81D");
796         return TRUE;
797     } else if (!can_chant(&youmonst)) {
798 /*JP
799         You("are unable to chant the incantation.");
800 */
801         You("\8eô\95\82ð\8f¥\82¦\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\81D");
802         return TRUE;
803     } else if (!freehand()) {
804         /* Note: !freehand() occurs when weapon and shield (or two-handed
805          * weapon) are welded to hands, so "arms" probably doesn't need
806          * to be makeplural(bodypart(ARM)).
807          *
808          * But why isn't lack of free arms (for gesturing) an issue when
809          * poly'd hero has no limbs?
810          */
811 /*JP
812         Your("arms are not free to cast!");
813 */
814         pline("\96\82\96@\82ð\8f¥\82¦\82æ\82¤\82É\82à\98r\82Ì\8e©\97R\82ª\8cø\82©\82È\82¢\81I");
815         return TRUE;
816     }
817     return FALSE;
818 }
819
820 /*
821  * Return TRUE if a spell was picked, with the spell index in the return
822  * parameter.  Otherwise return FALSE.
823  */
824 STATIC_OVL boolean
825 getspell(spell_no)
826 int *spell_no;
827 {
828     int nspells, idx;
829     char ilet, lets[BUFSZ], qbuf[QBUFSZ];
830
831     if (spellid(0) == NO_SPELL) {
832 /*JP
833         You("don't know any spells right now.");
834 */
835         You("\8d¡\82Ì\82Æ\82±\82ë\89½\82Ì\96\82\96@\82à\92m\82ç\82È\82¢\81D");
836         return FALSE;
837     }
838     if (rejectcasting())
839         return FALSE; /* no spell chosen */
840
841     if (flags.menu_style == MENU_TRADITIONAL) {
842         /* we know there is at least 1 known spell */
843         for (nspells = 1; nspells < MAXSPELL && spellid(nspells) != NO_SPELL;
844              nspells++)
845             continue;
846
847         if (nspells == 1)
848             Strcpy(lets, "a");
849         else if (nspells < 27)
850             Sprintf(lets, "a-%c", 'a' + nspells - 1);
851         else if (nspells == 27)
852             Sprintf(lets, "a-zA");
853         /* this assumes that there are at most 52 spells... */
854         else
855             Sprintf(lets, "a-zA-%c", 'A' + nspells - 27);
856
857         for (;;) {
858 /*JP
859             Sprintf(qbuf, "Cast which spell? [%s *?]", lets);
860 */
861             Sprintf(qbuf, "\82Ç\82Ì\96\82\96@\82ð\8f¥\82¦\82é\81H[%s ?]", lets);
862             ilet = yn_function(qbuf, (char *) 0, '\0');
863             if (ilet == '*' || ilet == '?')
864                 break; /* use menu mode */
865             if (index(quitchars, ilet))
866                 return FALSE;
867
868             idx = spell_let_to_idx(ilet);
869             if (idx < 0 || idx >= nspells) {
870 /*JP
871                 You("don't know that spell.");
872 */
873                 You("\82»\82ñ\82È\96\82\96@\82Í\92m\82ç\82È\82¢\81D");
874                 continue; /* ask again */
875             }
876             *spell_no = idx;
877             return TRUE;
878         }
879     }
880 /*JP
881     return dospellmenu("Choose which spell to cast", SPELLMENU_CAST,
882 */
883     return dospellmenu("\82Ç\82Ì\96\82\96@\82ð\8f¥\82¦\82é\81H", SPELLMENU_CAST,
884                        spell_no);
885 }
886
887 /* the 'Z' command -- cast a spell */
888 int
889 docast()
890 {
891     int spell_no;
892
893     if (getspell(&spell_no))
894         return spelleffects(spell_no, FALSE);
895     return 0;
896 }
897
898 STATIC_OVL const char *
899 spelltypemnemonic(skill)
900 int skill;
901 {
902     switch (skill) {
903     case P_ATTACK_SPELL:
904 /*JP
905         return "attack";
906 */
907         return "\8dU\8c\82";
908     case P_HEALING_SPELL:
909 /*JP
910         return "healing";
911 */
912         return "\8e¡\96ü";
913     case P_DIVINATION_SPELL:
914 /*JP
915         return "divination";
916 */
917         return "\97\\92m";
918     case P_ENCHANTMENT_SPELL:
919 /*JP
920         return "enchantment";
921 */
922         return "\95â\8f\95";
923     case P_CLERIC_SPELL:
924 /*JP
925         return "clerical";
926 */
927         return "\91m\97µ";
928     case P_ESCAPE_SPELL:
929 /*JP
930         return "escape";
931 */
932         return "\92E\8fo";
933     case P_MATTER_SPELL:
934 /*JP
935         return "matter";
936 */
937         return "\95¨\8e¿";
938     default:
939         impossible("Unknown spell skill, %d;", skill);
940         return "";
941     }
942 }
943
944 int
945 spell_skilltype(booktype)
946 int booktype;
947 {
948     return objects[booktype].oc_skill;
949 }
950
951 STATIC_OVL void
952 cast_protection()
953 {
954     int l = u.ulevel, loglev = 0,
955         gain, natac = u.uac + u.uspellprot;
956     /* note: u.uspellprot is subtracted when find_ac() factors it into u.uac,
957        so adding here factors it back out
958        (versions prior to 3.6 had this backwards) */
959
960     /* loglev=log2(u.ulevel)+1 (1..5) */
961     while (l) {
962         loglev++;
963         l /= 2;
964     }
965
966     /* The more u.uspellprot you already have, the less you get,
967      * and the better your natural ac, the less you get.
968      *
969      *  LEVEL AC    SPELLPROT from successive SPE_PROTECTION casts
970      *      1     10    0,  1,  2,  3,  4
971      *      1      0    0,  1,  2,  3
972      *      1    -10    0,  1,  2
973      *      2-3   10    0,  2,  4,  5,  6,  7,  8
974      *      2-3    0    0,  2,  4,  5,  6
975      *      2-3  -10    0,  2,  3,  4
976      *      4-7   10    0,  3,  6,  8,  9, 10, 11, 12
977      *      4-7    0    0,  3,  5,  7,  8,  9
978      *      4-7  -10    0,  3,  5,  6
979      *      7-15 -10    0,  3,  5,  6
980      *      8-15  10    0,  4,  7, 10, 12, 13, 14, 15, 16
981      *      8-15   0    0,  4,  7,  9, 10, 11, 12
982      *      8-15 -10    0,  4,  6,  7,  8
983      *     16-30  10    0,  5,  9, 12, 14, 16, 17, 18, 19, 20
984      *     16-30   0    0,  5,  9, 11, 13, 14, 15
985      *     16-30 -10    0,  5,  8,  9, 10
986      */
987     natac = (10 - natac) / 10; /* convert to positive and scale down */
988     gain = loglev - (int) u.uspellprot / (4 - min(3, natac));
989
990     if (gain > 0) {
991         if (!Blind) {
992             int rmtyp;
993             const char *hgolden = hcolor(NH_GOLDEN), *atmosphere;
994
995             if (u.uspellprot) {
996 /*JP
997                 pline_The("%s haze around you becomes more dense.", hgolden);
998 */
999                 pline("\82 \82È\82½\82Ì\82Ü\82í\82è\82Ì%s\89à\82ª\94Z\82­\82È\82Á\82½\81D", hgolden);
1000             } else {
1001                 rmtyp = levl[u.ux][u.uy].typ;
1002                 atmosphere = u.uswallow
1003                                 ? ((u.ustuck->data == &mons[PM_FOG_CLOUD])
1004 /*JP
1005                                    ? "mist"
1006 */
1007                                    ? "\96¶"
1008                                    : is_whirly(u.ustuck->data)
1009 /*JP
1010                                       ? "maelstrom"
1011 */
1012                                       ? "\89Q"
1013                                       : is_animal(u.ustuck->data)
1014 /*JP
1015                                          ? "maw"
1016 */
1017                                          ? "\88Ý"
1018 /*JP
1019                                          : "ooze")
1020 */
1021                                          : "\82Ë\82Î\82Ë\82Î")
1022                                 : (u.uinwater
1023 /*JP
1024                                    ? hliquid("water")
1025 */
1026                                    ? hliquid("\90\85")
1027                                    : (rmtyp == CLOUD)
1028 /*JP
1029                                       ? "cloud"
1030 */
1031                                       ? "\89_"
1032                                       : IS_TREE(rmtyp)
1033 /*JP
1034                                          ? "vegetation"
1035 */
1036                                          ? "\96Ø"
1037                                          : IS_STWALL(rmtyp)
1038 /*JP
1039                                             ? "stone"
1040 */
1041                                             ? "\90Î"
1042 /*JP
1043                                             : "air");
1044 */
1045                                             : "\8bó\8bC");
1046 #if 0 /*JP*/
1047                 pline_The("%s around you begins to shimmer with %s haze.",
1048                           atmosphere, an(hgolden));
1049 #else
1050                 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",
1051                           atmosphere, hgolden);
1052 #endif
1053             }
1054         }
1055         u.uspellprot += gain;
1056         u.uspmtime = (P_SKILL(spell_skilltype(SPE_PROTECTION)) == P_EXPERT)
1057                         ? 20 : 10;
1058         if (!u.usptime)
1059             u.usptime = u.uspmtime;
1060         find_ac();
1061     } else {
1062 /*JP
1063         Your("skin feels warm for a moment.");
1064 */
1065         Your("\94§\82Í\88ê\8fu\83|\83J\83|\83J\82µ\82½\81D");
1066     }
1067 }
1068
1069 /* attempting to cast a forgotten spell will cause disorientation */
1070 STATIC_OVL void
1071 spell_backfire(spell)
1072 int spell;
1073 {
1074     long duration = (long) ((spellev(spell) + 1) * 3), /* 6..24 */
1075          old_stun = (HStun & TIMEOUT), old_conf = (HConfusion & TIMEOUT);
1076
1077     /* Prior to 3.4.1, only effect was confusion; it still predominates.
1078      *
1079      * 3.6.0: this used to override pre-existing confusion duration
1080      * (cases 0..8) and pre-existing stun duration (cases 4..9);
1081      * increase them instead.   (Hero can no longer cast spells while
1082      * Stunned, so the potential increment to stun duration here is
1083      * just hypothetical.)
1084      */
1085     switch (rn2(10)) {
1086     case 0:
1087     case 1:
1088     case 2:
1089     case 3:
1090         make_confused(old_conf + duration, FALSE); /* 40% */
1091         break;
1092     case 4:
1093     case 5:
1094     case 6:
1095         make_confused(old_conf + 2L * duration / 3L, FALSE); /* 30% */
1096         make_stunned(old_stun + duration / 3L, FALSE);
1097         break;
1098     case 7:
1099     case 8:
1100         make_stunned(old_stun + 2L * duration / 3L, FALSE); /* 20% */
1101         make_confused(old_conf + duration / 3L, FALSE);
1102         break;
1103     case 9:
1104         make_stunned(old_stun + duration, FALSE); /* 10% */
1105         break;
1106     }
1107     return;
1108 }
1109
1110 int
1111 spelleffects(spell, atme)
1112 int spell;
1113 boolean atme;
1114 {
1115     int energy, damage, chance, n, intell;
1116     int skill, role_skill, res = 0;
1117     boolean confused = (Confusion != 0);
1118     boolean physical_damage = FALSE;
1119     struct obj *pseudo;
1120     coord cc;
1121
1122     /*
1123      * Reject attempting to cast while stunned or with no free hands.
1124      * Already done in getspell() to stop casting before choosing
1125      * which spell, but duplicated here for cases where spelleffects()
1126      * gets called directly for ^T without intrinsic teleport capability
1127      * or #turn for non-priest/non-knight.
1128      * (There's no duplication of messages; when the rejection takes
1129      * place in getspell(), we don't get called.)
1130      */
1131     if (rejectcasting()) {
1132         return 0; /* no time elapses */
1133     }
1134
1135     /*
1136      * Spell casting no longer affects knowledge of the spell. A
1137      * decrement of spell knowledge is done every turn.
1138      */
1139     if (spellknow(spell) <= 0) {
1140 /*JP
1141         Your("knowledge of this spell is twisted.");
1142 */
1143         Your("\82±\82Ì\96\82\96@\82É\8aÖ\82·\82é\92m\8e¯\82Í\82æ\82\82ê\82½\81D");
1144 /*JP
1145         pline("It invokes nightmarish images in your mind...");
1146 */
1147         pline("\82»\82ê\82Í\88«\96²\82ð\90S\82É\95\82\82Î\82¹\82½\81D\81D\81D");
1148         spell_backfire(spell);
1149         return 1;
1150     } else if (spellknow(spell) <= KEEN / 200) { /* 100 turns left */
1151 /*JP
1152         You("strain to recall the spell.");
1153 */
1154         You("\96\82\96@\82ð\8ev\82¢\82¾\82·\82Ì\82É\8bê\98J\82µ\82½\81D");
1155     } else if (spellknow(spell) <= KEEN / 40) { /* 500 turns left */
1156 /*JP
1157         You("have difficulty remembering the spell.");
1158 */
1159         You("\8eô\95\82ð\8ev\82¢\8fo\82·\82Ì\82ª\93ï\82µ\82­\82È\82Á\82Ä\82«\82½\81D");
1160     } else if (spellknow(spell) <= KEEN / 20) { /* 1000 turns left */
1161 /*JP
1162         Your("knowledge of this spell is growing faint.");
1163 */
1164         Your("\82±\82Ì\96\82\96@\82É\8aÖ\82·\82é\92m\8e¯\82ª\82¨\82Ú\82ë\82°\82É\82È\82Á\82Ä\82«\82½\81D");
1165     } else if (spellknow(spell) <= KEEN / 10) { /* 2000 turns left */
1166 /*JP
1167         Your("recall of this spell is gradually fading.");
1168 */
1169         Your("\82±\82Ì\96\82\96@\82É\8aÖ\82·\82é\92m\8e¯\82ª\8f\99\81X\82É\94\96\82ê\82Ä\82«\82½\81D");
1170     }
1171     energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */
1172
1173     if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) {
1174 /*JP
1175         You("are too hungry to cast that spell.");
1176 */
1177         pline("\95 \82ª\8c¸\82è\82·\82¬\82Ä\96\82\96@\82ð\8f¥\82¦\82ç\82ê\82È\82¢\81D");
1178         return 0;
1179     } else if (ACURR(A_STR) < 4 && spellid(spell) != SPE_RESTORE_ABILITY) {
1180 /*JP
1181         You("lack the strength to cast spells.");
1182 */
1183         pline("\8b­\82³\82ª\8f­\82È\82·\82¬\82Ä\96\82\96@\82ð\8f¥\82¦\82ç\82ê\82È\82¢\81D");
1184         return 0;
1185     } else if (check_capacity(
1186 /*JP
1187                 "Your concentration falters while carrying so much stuff.")) {
1188 */
1189                 "\82½\82­\82³\82ñ\82à\82Ì\82ð\8e\9d\82¿\82·\82¬\82Ä\8fW\92\86\82Å\82«\82È\82¢\81D")){
1190         return 1;
1191     }
1192
1193     /* if the cast attempt is already going to fail due to insufficient
1194        energy (ie, u.uen < energy), the Amulet's drain effect won't kick
1195        in and no turn will be consumed; however, when it does kick in,
1196        the attempt may fail due to lack of energy after the draining, in
1197        which case a turn will be used up in addition to the energy loss */
1198     if (u.uhave.amulet && u.uen >= energy) {
1199 /*JP
1200         You_feel("the amulet draining your energy away.");
1201 */
1202         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");
1203         /* this used to be 'energy += rnd(2 * energy)' (without 'res'),
1204            so if amulet-induced cost was more than u.uen, nothing
1205            (except the "don't have enough energy" message) happened
1206            and player could just try again (and again and again...);
1207            now we drain some energy immediately, which has a
1208            side-effect of not increasing the hunger aspect of casting */
1209         u.uen -= rnd(2 * energy);
1210         if (u.uen < 0)
1211             u.uen = 0;
1212         context.botl = 1;
1213         res = 1; /* time is going to elapse even if spell doesn't get cast */
1214     }
1215
1216     if (energy > u.uen) {
1217 /*JP
1218         You("don't have enough energy to cast that spell.");
1219 */
1220         pline("\96\82\96@\82ð\8f¥\82¦\82é\82¾\82¯\82Ì\8f\\95ª\82È\83G\83l\83\8b\83M\81[\82ª\82È\82¢\81D");
1221         return res;
1222     } else {
1223         if (spellid(spell) != SPE_DETECT_FOOD) {
1224             int hungr = energy * 2;
1225
1226             /* If hero is a wizard, their current intelligence
1227              * (bonuses + temporary + current)
1228              * affects hunger reduction in casting a spell.
1229              * 1. int = 17-18 no reduction
1230              * 2. int = 16    1/4 hungr
1231              * 3. int = 15    1/2 hungr
1232              * 4. int = 1-14  normal reduction
1233              * The reason for this is:
1234              * a) Intelligence affects the amount of exertion
1235              * in thinking.
1236              * b) Wizards have spent their life at magic and
1237              * understand quite well how to cast spells.
1238              */
1239             intell = acurr(A_INT);
1240             if (!Role_if(PM_WIZARD))
1241                 intell = 10;
1242             switch (intell) {
1243             case 25:
1244             case 24:
1245             case 23:
1246             case 22:
1247             case 21:
1248             case 20:
1249             case 19:
1250             case 18:
1251             case 17:
1252                 hungr = 0;
1253                 break;
1254             case 16:
1255                 hungr /= 4;
1256                 break;
1257             case 15:
1258                 hungr /= 2;
1259                 break;
1260             }
1261             /* don't put player (quite) into fainting from
1262              * casting a spell, particularly since they might
1263              * not even be hungry at the beginning; however,
1264              * this is low enough that they must eat before
1265              * casting anything else except detect food
1266              */
1267             if (hungr > u.uhunger - 3)
1268                 hungr = u.uhunger - 3;
1269             morehungry(hungr);
1270         }
1271     }
1272
1273     chance = percent_success(spell);
1274     if (confused || (rnd(100) > chance)) {
1275 /*JP
1276         You("fail to cast the spell correctly.");
1277 */
1278         You("\96\82\96@\82ð\90³\82µ\82­\8f¥\82¦\82é\82±\82Æ\82ª\82Å\82«\82È\82©\82Á\82½\81D");
1279         u.uen -= energy / 2;
1280         context.botl = 1;
1281         return 1;
1282     }
1283
1284     u.uen -= energy;
1285     context.botl = 1;
1286     exercise(A_WIS, TRUE);
1287     /* pseudo is a temporary "false" object containing the spell stats */
1288     pseudo = mksobj(spellid(spell), FALSE, FALSE);
1289     pseudo->blessed = pseudo->cursed = 0;
1290     pseudo->quan = 20L; /* do not let useup get it */
1291     /*
1292      * Find the skill the hero has in a spell type category.
1293      * See spell_skilltype for categories.
1294      */
1295     skill = spell_skilltype(pseudo->otyp);
1296     role_skill = P_SKILL(skill);
1297
1298     switch (pseudo->otyp) {
1299     /*
1300      * At first spells act as expected.  As the hero increases in skill
1301      * with the appropriate spell type, some spells increase in their
1302      * effects, e.g. more damage, further distance, and so on, without
1303      * additional cost to the spellcaster.
1304      */
1305     case SPE_FIREBALL:
1306     case SPE_CONE_OF_COLD:
1307         if (role_skill >= P_SKILLED) {
1308             if (throwspell()) {
1309                 cc.x = u.dx;
1310                 cc.y = u.dy;
1311                 n = rnd(8) + 1;
1312                 while (n--) {
1313                     if (!u.dx && !u.dy && !u.dz) {
1314                         if ((damage = zapyourself(pseudo, TRUE)) != 0) {
1315                             char buf[BUFSZ];
1316 #if 0 /*JP*/
1317                             Sprintf(buf, "zapped %sself with a spell",
1318                                     uhim());
1319                             losehp(damage, buf, NO_KILLER_PREFIX);
1320 #else
1321                             Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82ð\97\81\82Ñ\82Ä");
1322                             losehp(damage, buf, KILLED_BY);
1323 #endif
1324                         }
1325                     } else {
1326                         explode(u.dx, u.dy,
1327                                 pseudo->otyp - SPE_MAGIC_MISSILE + 10,
1328                                 spell_damage_bonus(u.ulevel / 2 + 1), 0,
1329                                 (pseudo->otyp == SPE_CONE_OF_COLD)
1330                                    ? EXPL_FROSTY
1331                                    : EXPL_FIERY);
1332                     }
1333                     u.dx = cc.x + rnd(3) - 2;
1334                     u.dy = cc.y + rnd(3) - 2;
1335                     if (!isok(u.dx, u.dy) || !cansee(u.dx, u.dy)
1336                         || IS_STWALL(levl[u.dx][u.dy].typ) || u.uswallow) {
1337                         /* Spell is reflected back to center */
1338                         u.dx = cc.x;
1339                         u.dy = cc.y;
1340                     }
1341                 }
1342             }
1343             break;
1344         } /* else fall through... */
1345
1346     /* these spells are all duplicates of wand effects */
1347     case SPE_FORCE_BOLT:
1348         physical_damage = TRUE;
1349     /* fall through */
1350     case SPE_SLEEP:
1351     case SPE_MAGIC_MISSILE:
1352     case SPE_KNOCK:
1353     case SPE_SLOW_MONSTER:
1354     case SPE_WIZARD_LOCK:
1355     case SPE_DIG:
1356     case SPE_TURN_UNDEAD:
1357     case SPE_POLYMORPH:
1358     case SPE_TELEPORT_AWAY:
1359     case SPE_CANCELLATION:
1360     case SPE_FINGER_OF_DEATH:
1361     case SPE_LIGHT:
1362     case SPE_DETECT_UNSEEN:
1363     case SPE_HEALING:
1364     case SPE_EXTRA_HEALING:
1365     case SPE_DRAIN_LIFE:
1366     case SPE_STONE_TO_FLESH:
1367         if (!(objects[pseudo->otyp].oc_dir == NODIR)) {
1368             if (atme) {
1369                 u.dx = u.dy = u.dz = 0;
1370             } else if (!getdir((char *) 0)) {
1371                 /* getdir cancelled, re-use previous direction */
1372                 /*
1373                  * FIXME:  reusing previous direction only makes sense
1374                  * if there is an actual previous direction.  When there
1375                  * isn't one, the spell gets cast at self which is rarely
1376                  * what the player intended.  Unfortunately, the way
1377                  * spelleffects() is organized means that aborting with
1378                  * "nevermind" is not an option.
1379                  */
1380 /*JP
1381                 pline_The("magical energy is released!");
1382 */
1383                 pline("\96\82\96@\82Ì\83G\83l\83\8b\83M\81[\82ª\89ð\95ú\82³\82ê\82½\81I");
1384             }
1385             if (!u.dx && !u.dy && !u.dz) {
1386                 if ((damage = zapyourself(pseudo, TRUE)) != 0) {
1387                     char buf[BUFSZ];
1388
1389 /*JP
1390                     Sprintf(buf, "zapped %sself with a spell", uhim());
1391 */
1392                     Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82ð\97\81\82Ñ\82Ä");
1393                     if (physical_damage)
1394                         damage = Maybe_Half_Phys(damage);
1395 #if 0 /*JP*/
1396                     losehp(damage, buf, NO_KILLER_PREFIX);
1397 #else
1398                     losehp(damage, buf, KILLED_BY);
1399 #endif
1400                 }
1401             } else
1402                 weffects(pseudo);
1403         } else
1404             weffects(pseudo);
1405         update_inventory(); /* spell may modify inventory */
1406         break;
1407
1408     /* these are all duplicates of scroll effects */
1409     case SPE_REMOVE_CURSE:
1410     case SPE_CONFUSE_MONSTER:
1411     case SPE_DETECT_FOOD:
1412     case SPE_CAUSE_FEAR:
1413     case SPE_IDENTIFY:
1414         /* high skill yields effect equivalent to blessed scroll */
1415         if (role_skill >= P_SKILLED)
1416             pseudo->blessed = 1;
1417     /* fall through */
1418     case SPE_CHARM_MONSTER:
1419     case SPE_MAGIC_MAPPING:
1420     case SPE_CREATE_MONSTER:
1421         (void) seffects(pseudo);
1422         break;
1423
1424     /* these are all duplicates of potion effects */
1425     case SPE_HASTE_SELF:
1426     case SPE_DETECT_TREASURE:
1427     case SPE_DETECT_MONSTERS:
1428     case SPE_LEVITATION:
1429     case SPE_RESTORE_ABILITY:
1430         /* high skill yields effect equivalent to blessed potion */
1431         if (role_skill >= P_SKILLED)
1432             pseudo->blessed = 1;
1433     /* fall through */
1434     case SPE_INVISIBILITY:
1435         (void) peffects(pseudo);
1436         break;
1437     /* end of potion-like spells */
1438
1439     case SPE_CURE_BLINDNESS:
1440         healup(0, 0, FALSE, TRUE);
1441         break;
1442     case SPE_CURE_SICKNESS:
1443         if (Sick)
1444 /*JP
1445             You("are no longer ill.");
1446 */
1447             Your("\95a\8bC\82Í\92¼\82Á\82½\81D");
1448         if (Slimed)
1449 /*JP
1450             make_slimed(0L, "The slime disappears!");
1451 */
1452             make_slimed(0L, "\83X\83\89\83C\83\80\82Í\8fÁ\82¦\82½\81I");
1453         healup(0, 0, TRUE, FALSE);
1454         break;
1455     case SPE_CREATE_FAMILIAR:
1456         (void) make_familiar((struct obj *) 0, u.ux, u.uy, FALSE);
1457         break;
1458     case SPE_CLAIRVOYANCE:
1459         if (!BClairvoyant) {
1460             if (role_skill >= P_SKILLED)
1461                 pseudo->blessed = 1; /* detect monsters as well as map */
1462             do_vicinity_map(pseudo);
1463         /* at present, only one thing blocks clairvoyance */
1464         } else if (uarmh && uarmh->otyp == CORNUTHAUM)
1465 /*JP
1466             You("sense a pointy hat on top of your %s.", body_part(HEAD));
1467 */
1468             You("\82Æ\82ª\82Á\82½\96X\8eq\82ð%s\82Ì\8fã\82É\94­\8c©\82µ\82½\81D", body_part(HEAD));
1469         break;
1470     case SPE_PROTECTION:
1471         cast_protection();
1472         break;
1473     case SPE_JUMPING:
1474         if (!jump(max(role_skill, 1)))
1475             pline1(nothing_happens);
1476         break;
1477     default:
1478         impossible("Unknown spell %d attempted.", spell);
1479         obfree(pseudo, (struct obj *) 0);
1480         return 0;
1481     }
1482
1483     /* gain skill for successful cast */
1484     use_skill(skill, spellev(spell));
1485
1486     obfree(pseudo, (struct obj *) 0); /* now, get rid of it */
1487     return 1;
1488 }
1489
1490 /*ARGSUSED*/
1491 STATIC_OVL boolean
1492 spell_aim_step(arg, x, y)
1493 genericptr_t arg UNUSED;
1494 int x, y;
1495 {
1496     if (!isok(x,y))
1497         return FALSE;
1498     if (!ZAP_POS(levl[x][y].typ)
1499         && !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
1500         return FALSE;
1501     return TRUE;
1502 }
1503
1504 /* Choose location where spell takes effect. */
1505 STATIC_OVL int
1506 throwspell()
1507 {
1508     coord cc, uc;
1509     struct monst *mtmp;
1510
1511     if (u.uinwater) {
1512 /*JP
1513         pline("You're joking! In this weather?");
1514 */
1515         pline("\90\85\92\86\82Å\89½\82ð\82µ\82æ\82¤\82Á\82Ä\82¢\82¤\82ñ\82¾\82¢\81H");
1516         return 0;
1517     } else if (Is_waterlevel(&u.uz)) {
1518 /*JP
1519         You("had better wait for the sun to come out.");
1520 */
1521         You("\91¾\97z\82ª\8c»\82ê\82é\82Ü\82Å\91Ò\82Á\82½\82Ù\82¤\82ª\82æ\82¢\82¾\82ë\82¤\81D");
1522         return 0;
1523     }
1524
1525 /*JP
1526     pline("Where do you want to cast the spell?");
1527 */
1528     pline("\82Ç\82±\82É\8cü\82©\82Á\82Ä\96\82\96@\82ð\8f¥\82¦\82é\81H");
1529     cc.x = u.ux;
1530     cc.y = u.uy;
1531 /*JP
1532     if (getpos(&cc, TRUE, "the desired position") < 0)
1533 */
1534     if (getpos(&cc, TRUE, "\96]\82Ý\82Ì\8fê\8f\8a") < 0)
1535         return 0; /* user pressed ESC */
1536     /* The number of moves from hero to where the spell drops.*/
1537     if (distmin(u.ux, u.uy, cc.x, cc.y) > 10) {
1538 /*JP
1539         pline_The("spell dissipates over the distance!");
1540 */
1541         pline("\89\93\82·\82¬\82é\81I");
1542         return 0;
1543     } else if (u.uswallow) {
1544 /*JP
1545         pline_The("spell is cut short!");
1546 */
1547         pline("\82¾\82ß\82¾\81I\8bß\82·\82¬\82é\81I");
1548         exercise(A_WIS, FALSE); /* What were you THINKING! */
1549         u.dx = 0;
1550         u.dy = 0;
1551         return 1;
1552     } else if ((!cansee(cc.x, cc.y)
1553                 && (!(mtmp = m_at(cc.x, cc.y)) || !canspotmon(mtmp)))
1554                || IS_STWALL(levl[cc.x][cc.y].typ)) {
1555 /*JP
1556         Your("mind fails to lock onto that location!");
1557 */
1558         You("\82»\82±\82É\8cü\82©\82Á\82Ä\8fW\92\86\82µ\82½\82ª\8e¸\94s\82µ\82½\81I");
1559         return 0;
1560     }
1561
1562     uc.x = u.ux;
1563     uc.y = u.uy;
1564
1565     walk_path(&uc, &cc, spell_aim_step, (genericptr_t) 0);
1566
1567     u.dx = cc.x;
1568     u.dy = cc.y;
1569     return 1;
1570 }
1571
1572 /* forget a random selection of known spells due to amnesia;
1573    they used to be lost entirely, as if never learned, but now we
1574    just set the memory retention to zero so that they can't be cast */
1575 void
1576 losespells()
1577 {
1578     int n, nzap, i;
1579
1580     /* in case reading has been interrupted earlier, discard context */
1581     context.spbook.book = 0;
1582     context.spbook.o_id = 0;
1583     /* count the number of known spells */
1584     for (n = 0; n < MAXSPELL; ++n)
1585         if (spellid(n) == NO_SPELL)
1586             break;
1587
1588     /* lose anywhere from zero to all known spells;
1589        if confused, use the worse of two die rolls */
1590     nzap = rn2(n + 1);
1591     if (Confusion) {
1592         i = rn2(n + 1);
1593         if (i > nzap)
1594             nzap = i;
1595     }
1596     /* good Luck might ameliorate spell loss */
1597     if (nzap > 1 && !rnl(7))
1598         nzap = rnd(nzap);
1599
1600     /*
1601      * Forget 'nzap' out of 'n' known spells by setting their memory
1602      * retention to zero.  Every spell has the same probability to be
1603      * forgotten, even if its retention is already zero.
1604      *
1605      * Perhaps we should forget the corresponding book too?
1606      *
1607      * (3.4.3 removed spells entirely from the list, but always did
1608      * so from its end, so the 'nzap' most recently learned spells
1609      * were the ones lost by default.  Player had sort control over
1610      * the list, so could move the most useful spells to front and
1611      * only lose them if 'nzap' turned out to be a large value.
1612      *
1613      * Discarding from the end of the list had the virtue of making
1614      * casting letters for lost spells become invalid and retaining
1615      * the original letter for the ones which weren't lost, so there
1616      * was no risk to the player of accidentally casting the wrong
1617      * spell when using a letter that was in use prior to amnesia.
1618      * That wouldn't be the case if we implemented spell loss spread
1619      * throughout the list of known spells; every spell located past
1620      * the first lost spell would end up with new letter assigned.)
1621      */
1622     for (i = 0; nzap > 0; ++i) {
1623         /* when nzap is small relative to the number of spells left,
1624            the chance to lose spell [i] is small; as the number of
1625            remaining candidates shrinks, the chance per candidate
1626            gets bigger; overall, exactly nzap entries are affected */
1627         if (rn2(n - i) < nzap) {
1628             /* lose access to spell [i] */
1629             spellknow(i) = 0;
1630 #if 0
1631             /* also forget its book */
1632             forget_single_object(spellid(i));
1633 #endif
1634             /* and abuse wisdom */
1635             exercise(A_WIS, FALSE);
1636             /* there's now one less spell slated to be forgotten */
1637             --nzap;
1638         }
1639     }
1640 }
1641
1642 /*
1643  * Allow player to sort the list of known spells.  Manually swapping
1644  * pairs of them becomes very tedious once the list reaches two pages.
1645  *
1646  * Possible extensions:
1647  *      provide means for player to control ordering of skill classes;
1648  *      provide means to supply value N such that first N entries stick
1649  *      while rest of list is being sorted;
1650  *      make chosen sort order be persistent such that when new spells
1651  *      are learned, they get inserted into sorted order rather than be
1652  *      appended to the end of the list?
1653  */
1654 enum spl_sort_types {
1655     SORTBY_LETTER = 0,
1656     SORTBY_ALPHA,
1657     SORTBY_LVL_LO,
1658     SORTBY_LVL_HI,
1659     SORTBY_SKL_AL,
1660     SORTBY_SKL_LO,
1661     SORTBY_SKL_HI,
1662     SORTBY_CURRENT,
1663     SORTRETAINORDER,
1664
1665     NUM_SPELL_SORTBY
1666 };
1667
1668 static const char *spl_sortchoices[NUM_SPELL_SORTBY] = {
1669 /*JP
1670     "by casting letter",
1671 */
1672     "\91I\91ð\82·\82é\95\8e\9a\8f\87",
1673 /*JP
1674     "alphabetically",
1675 */
1676     "\95\8e\9a\83R\81[\83h\8f\87",
1677 /*JP
1678     "by level, low to high",
1679 */
1680     "\83\8c\83x\83\8b\8f¸\8f\87",
1681 /*JP
1682     "by level, high to low",
1683 */
1684     "\83\8c\83x\83\8b\8d~\8f\87",
1685 /*JP
1686     "by skill group, alphabetized within each group",
1687 */
1688     "\83X\83L\83\8b\83O\83\8b\81[\83v\96\88\82É\95\8e\9a\83R\81[\83h\8f\87",
1689 /*JP
1690     "by skill group, low to high level within group",
1691 */
1692     "\83X\83L\83\8b\83O\83\8b\81[\83v\96\88\82É\83\8c\83x\83\8b\8f¸\8f\87",
1693 /*JP
1694     "by skill group, high to low level within group",
1695 */
1696     "\83X\83L\83\8b\83O\83\8b\81[\83v\96\88\82É\83\8c\83x\83\8b\8d~\8f\87",
1697 /*JP
1698     "maintain current ordering",
1699 */
1700     "\8c»\8dÝ\82Ì\8f\87\8f\98\82ð\88Û\8e\9d",
1701     /* a menu choice rather than a sort choice */
1702 /*JP
1703     "reassign casting letters to retain current order",
1704 */
1705     "\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Ä",
1706 };
1707 static int spl_sortmode = 0;   /* index into spl_sortchoices[] */
1708 static int *spl_orderindx = 0; /* array of spl_book[] indices */
1709
1710 /* qsort callback routine */
1711 STATIC_PTR int CFDECLSPEC
1712 spell_cmp(vptr1, vptr2)
1713 const genericptr vptr1;
1714 const genericptr vptr2;
1715 {
1716     /*
1717      * gather up all of the possible parameters except spell name
1718      * in advance, even though some might not be needed:
1719      *  indx. = spl_orderindx[] index into spl_book[];
1720      *  otyp. = spl_book[] index into objects[];
1721      *  levl. = spell level;
1722      *  skil. = skill group aka spell class.
1723      */
1724     int indx1 = *(int *) vptr1, indx2 = *(int *) vptr2,
1725         otyp1 = spl_book[indx1].sp_id, otyp2 = spl_book[indx2].sp_id,
1726         levl1 = objects[otyp1].oc_level, levl2 = objects[otyp2].oc_level,
1727         skil1 = objects[otyp1].oc_skill, skil2 = objects[otyp2].oc_skill;
1728
1729     switch (spl_sortmode) {
1730     case SORTBY_LETTER:
1731         return indx1 - indx2;
1732     case SORTBY_ALPHA:
1733         break;
1734     case SORTBY_LVL_LO:
1735         if (levl1 != levl2)
1736             return levl1 - levl2;
1737         break;
1738     case SORTBY_LVL_HI:
1739         if (levl1 != levl2)
1740             return levl2 - levl1;
1741         break;
1742     case SORTBY_SKL_AL:
1743         if (skil1 != skil2)
1744             return skil1 - skil2;
1745         break;
1746     case SORTBY_SKL_LO:
1747         if (skil1 != skil2)
1748             return skil1 - skil2;
1749         if (levl1 != levl2)
1750             return levl1 - levl2;
1751         break;
1752     case SORTBY_SKL_HI:
1753         if (skil1 != skil2)
1754             return skil1 - skil2;
1755         if (levl1 != levl2)
1756             return levl2 - levl1;
1757         break;
1758     case SORTBY_CURRENT:
1759     default:
1760         return (vptr1 < vptr2) ? -1
1761                                : (vptr1 > vptr2); /* keep current order */
1762     }
1763     /* tie-breaker for most sorts--alphabetical by spell name */
1764     return strcmpi(OBJ_NAME(objects[otyp1]), OBJ_NAME(objects[otyp2]));
1765 }
1766
1767 /* sort the index used for display order of the "view known spells"
1768    list (sortmode == SORTBY_xxx), or sort the spellbook itself to make
1769    the current display order stick (sortmode == SORTRETAINORDER) */
1770 STATIC_OVL void
1771 sortspells()
1772 {
1773     int i;
1774 #if defined(SYSV) || defined(DGUX)
1775     unsigned n;
1776 #else
1777     int n;
1778 #endif
1779
1780     if (spl_sortmode == SORTBY_CURRENT)
1781         return;
1782     for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; ++n)
1783         continue;
1784     if (n < 2)
1785         return; /* not enough entries to need sorting */
1786
1787     if (!spl_orderindx) {
1788         /* we haven't done any sorting yet; list is in casting order */
1789         if (spl_sortmode == SORTBY_LETTER /* default */
1790             || spl_sortmode == SORTRETAINORDER)
1791             return;
1792         /* allocate enough for full spellbook rather than just N spells */
1793         spl_orderindx = (int *) alloc(MAXSPELL * sizeof(int));
1794         for (i = 0; i < MAXSPELL; i++)
1795             spl_orderindx[i] = i;
1796     }
1797
1798     if (spl_sortmode == SORTRETAINORDER) {
1799         struct spell tmp_book[MAXSPELL];
1800
1801         /* sort spl_book[] rather than spl_orderindx[];
1802            this also updates the index to reflect the new ordering (we
1803            could just free it since that ordering becomes the default) */
1804         for (i = 0; i < MAXSPELL; i++)
1805             tmp_book[i] = spl_book[spl_orderindx[i]];
1806         for (i = 0; i < MAXSPELL; i++)
1807             spl_book[i] = tmp_book[i], spl_orderindx[i] = i;
1808         spl_sortmode = SORTBY_LETTER; /* reset */
1809         return;
1810     }
1811
1812     /* usual case, sort the index rather than the spells themselves */
1813     qsort((genericptr_t) spl_orderindx, n, sizeof *spl_orderindx, spell_cmp);
1814     return;
1815 }
1816
1817 /* called if the [sort spells] entry in the view spells menu gets chosen */
1818 STATIC_OVL boolean
1819 spellsortmenu()
1820 {
1821     winid tmpwin;
1822     menu_item *selected;
1823     anything any;
1824     char let;
1825     int i, n, choice;
1826
1827     tmpwin = create_nhwindow(NHW_MENU);
1828     start_menu(tmpwin);
1829     any = zeroany; /* zero out all bits */
1830
1831     for (i = 0; i < SIZE(spl_sortchoices); i++) {
1832         if (i == SORTRETAINORDER) {
1833             let = 'z'; /* assumes fewer than 26 sort choices... */
1834             /* separate final choice from others with a blank line */
1835             any.a_int = 0;
1836             add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "",
1837                      MENU_UNSELECTED);
1838         } else {
1839             let = 'a' + i;
1840         }
1841         any.a_int = i + 1;
1842         add_menu(tmpwin, NO_GLYPH, &any, let, 0, ATR_NONE, spl_sortchoices[i],
1843                  (i == spl_sortmode) ? MENU_SELECTED : MENU_UNSELECTED);
1844     }
1845     end_menu(tmpwin, "View known spells list sorted");
1846
1847     n = select_menu(tmpwin, PICK_ONE, &selected);
1848     destroy_nhwindow(tmpwin);
1849     if (n > 0) {
1850         choice = selected[0].item.a_int - 1;
1851         /* skip preselected entry if we have more than one item chosen */
1852         if (n > 1 && choice == spl_sortmode)
1853             choice = selected[1].item.a_int - 1;
1854         free((genericptr_t) selected);
1855         spl_sortmode = choice;
1856         return TRUE;
1857     }
1858     return FALSE;
1859 }
1860
1861 /* the '+' command -- view known spells */
1862 int
1863 dovspell()
1864 {
1865     char qbuf[QBUFSZ];
1866     int splnum, othnum;
1867     struct spell spl_tmp;
1868
1869     if (spellid(0) == NO_SPELL) {
1870 /*JP
1871         You("don't know any spells right now.");
1872 */
1873         You("\96\82\96@\82ð\92m\82ç\82È\82¢\81D");
1874     } else {
1875 /*JP
1876         while (dospellmenu("Currently known spells",
1877 */
1878         while (dospellmenu("\8c»\8dÝ\92m\82Á\82Ä\82¢\82é\96\82\96@\88ê\97\97",
1879                            SPELLMENU_VIEW, &splnum)) {
1880             if (splnum == SPELLMENU_SORT) {
1881                 if (spellsortmenu())
1882                     sortspells();
1883             } else {
1884 /*JP
1885                 Sprintf(qbuf, "Reordering spells; swap '%c' with",
1886 */
1887                 Sprintf(qbuf, "'%c'\82Æ\95À\82Ñ\95Ï\82¦\82é\96\82\96@\82Í\81H",
1888                         spellet(splnum));
1889                 if (!dospellmenu(qbuf, splnum, &othnum))
1890                     break;
1891
1892                 spl_tmp = spl_book[splnum];
1893                 spl_book[splnum] = spl_book[othnum];
1894                 spl_book[othnum] = spl_tmp;
1895             }
1896         }
1897     }
1898     if (spl_orderindx) {
1899         free((genericptr_t) spl_orderindx);
1900         spl_orderindx = 0;
1901     }
1902     spl_sortmode = SORTBY_LETTER; /* 0 */
1903     return 0;
1904 }
1905
1906 STATIC_OVL boolean
1907 dospellmenu(prompt, splaction, spell_no)
1908 const char *prompt;
1909 int splaction; /* SPELLMENU_CAST, SPELLMENU_VIEW, or spl_book[] index */
1910 int *spell_no;
1911 {
1912     winid tmpwin;
1913     int i, n, how, splnum;
1914     char buf[BUFSZ], retentionbuf[24];
1915     const char *fmt;
1916     menu_item *selected;
1917     anything any;
1918
1919     tmpwin = create_nhwindow(NHW_MENU);
1920     start_menu(tmpwin);
1921     any = zeroany; /* zero out all bits */
1922
1923     /*
1924      * The correct spacing of the columns when not using
1925      * tab separation depends on the following:
1926      * (1) that the font is monospaced, and
1927      * (2) that selection letters are pre-pended to the
1928      * given string and are of the form "a - ".
1929      */
1930     if (!iflags.menu_tab_sep) {
1931 #if 0 /*JP*/
1932         Sprintf(buf, "%-20s     Level %-12s Fail Retention", "    Name",
1933                 "Category");
1934 #else
1935         Sprintf(buf, "%-20s     Level  %-12s \90¬\8c÷\97¦", "    Name", "\95ª\97Þ");
1936 #endif
1937         fmt = "%-20s  %2d   %-12s %3d%% %9s";
1938     } else {
1939 /*JP
1940         Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
1941 */
1942         Sprintf(buf, "\96¼\91O\t\83\8c\83x\83\8b\t\95ª\97Þ\t\90¬\8c÷\97¦");
1943         fmt = "%s\t%-d\t%s\t%-d%%\t%s";
1944     }
1945     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1946              MENU_UNSELECTED);
1947     for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) {
1948         splnum = !spl_orderindx ? i : spl_orderindx[i];
1949         Sprintf(buf, fmt, spellname(splnum), spellev(splnum),
1950                 spelltypemnemonic(spell_skilltype(spellid(splnum))),
1951                 100 - percent_success(splnum),
1952                 spellretention(splnum, retentionbuf));
1953
1954         any.a_int = splnum + 1; /* must be non-zero */
1955         add_menu(tmpwin, NO_GLYPH, &any, spellet(splnum), 0, ATR_NONE, buf,
1956                  (splnum == splaction) ? MENU_SELECTED : MENU_UNSELECTED);
1957     }
1958     how = PICK_ONE;
1959     if (splaction == SPELLMENU_VIEW) {
1960         if (spellid(1) == NO_SPELL) {
1961             /* only one spell => nothing to swap with */
1962             how = PICK_NONE;
1963         } else {
1964             /* more than 1 spell, add an extra menu entry */
1965             any.a_int = SPELLMENU_SORT + 1;
1966             add_menu(tmpwin, NO_GLYPH, &any, '+', 0, ATR_NONE,
1967                      "[sort spells]", MENU_UNSELECTED);
1968         }
1969     }
1970     end_menu(tmpwin, prompt);
1971
1972     n = select_menu(tmpwin, how, &selected);
1973     destroy_nhwindow(tmpwin);
1974     if (n > 0) {
1975         *spell_no = selected[0].item.a_int - 1;
1976         /* menu selection for `PICK_ONE' does not
1977            de-select any preselected entry */
1978         if (n > 1 && *spell_no == splaction)
1979             *spell_no = selected[1].item.a_int - 1;
1980         free((genericptr_t) selected);
1981         /* default selection of preselected spell means that
1982            user chose not to swap it with anything */
1983         if (*spell_no == splaction)
1984             return FALSE;
1985         return TRUE;
1986     } else if (splaction >= 0) {
1987         /* explicit de-selection of preselected spell means that
1988            user is still swapping but not for the current spell */
1989         *spell_no = splaction;
1990         return TRUE;
1991     }
1992     return FALSE;
1993 }
1994
1995 STATIC_OVL int
1996 percent_success(spell)
1997 int spell;
1998 {
1999     /* Intrinsic and learned ability are combined to calculate
2000      * the probability of player's success at cast a given spell.
2001      */
2002     int chance, splcaster, special, statused;
2003     int difficulty;
2004     int skill;
2005
2006     /* Calculate intrinsic ability (splcaster) */
2007
2008     splcaster = urole.spelbase;
2009     special = urole.spelheal;
2010     statused = ACURR(urole.spelstat);
2011
2012     if (uarm && is_metallic(uarm))
2013         splcaster += (uarmc && uarmc->otyp == ROBE) ? urole.spelarmr / 2
2014                                                     : urole.spelarmr;
2015     else if (uarmc && uarmc->otyp == ROBE)
2016         splcaster -= urole.spelarmr;
2017     if (uarms)
2018         splcaster += urole.spelshld;
2019
2020     if (uarmh && is_metallic(uarmh) && uarmh->otyp != HELM_OF_BRILLIANCE)
2021         splcaster += uarmhbon;
2022     if (uarmg && is_metallic(uarmg))
2023         splcaster += uarmgbon;
2024     if (uarmf && is_metallic(uarmf))
2025         splcaster += uarmfbon;
2026
2027     if (spellid(spell) == urole.spelspec)
2028         splcaster += urole.spelsbon;
2029
2030     /* `healing spell' bonus */
2031     if (spellid(spell) == SPE_HEALING || spellid(spell) == SPE_EXTRA_HEALING
2032         || spellid(spell) == SPE_CURE_BLINDNESS
2033         || spellid(spell) == SPE_CURE_SICKNESS
2034         || spellid(spell) == SPE_RESTORE_ABILITY
2035         || spellid(spell) == SPE_REMOVE_CURSE)
2036         splcaster += special;
2037
2038     if (splcaster > 20)
2039         splcaster = 20;
2040
2041     /* Calculate learned ability */
2042
2043     /* Players basic likelihood of being able to cast any spell
2044      * is based of their `magic' statistic. (Int or Wis)
2045      */
2046     chance = 11 * statused / 2;
2047
2048     /*
2049      * High level spells are harder.  Easier for higher level casters.
2050      * The difficulty is based on the hero's level and their skill level
2051      * in that spell type.
2052      */
2053     skill = P_SKILL(spell_skilltype(spellid(spell)));
2054     skill = max(skill, P_UNSKILLED) - 1; /* unskilled => 0 */
2055     difficulty =
2056         (spellev(spell) - 1) * 4 - ((skill * 6) + (u.ulevel / 3) + 1);
2057
2058     if (difficulty > 0) {
2059         /* Player is too low level or unskilled. */
2060         chance -= isqrt(900 * difficulty + 2000);
2061     } else {
2062         /* Player is above level.  Learning continues, but the
2063          * law of diminishing returns sets in quickly for
2064          * low-level spells.  That is, a player quickly gains
2065          * no advantage for raising level.
2066          */
2067         int learning = 15 * -difficulty / spellev(spell);
2068         chance += learning > 20 ? 20 : learning;
2069     }
2070
2071     /* Clamp the chance: >18 stat and advanced learning only help
2072      * to a limit, while chances below "hopeless" only raise the
2073      * specter of overflowing 16-bit ints (and permit wearing a
2074      * shield to raise the chances :-).
2075      */
2076     if (chance < 0)
2077         chance = 0;
2078     if (chance > 120)
2079         chance = 120;
2080
2081     /* Wearing anything but a light shield makes it very awkward
2082      * to cast a spell.  The penalty is not quite so bad for the
2083      * player's role-specific spell.
2084      */
2085     if (uarms && weight(uarms) > (int) objects[SMALL_SHIELD].oc_weight) {
2086         if (spellid(spell) == urole.spelspec) {
2087             chance /= 2;
2088         } else {
2089             chance /= 4;
2090         }
2091     }
2092
2093     /* Finally, chance (based on player intell/wisdom and level) is
2094      * combined with ability (based on player intrinsics and
2095      * encumbrances).  No matter how intelligent/wise and advanced
2096      * a player is, intrinsics and encumbrance can prevent casting;
2097      * and no matter how able, learning is always required.
2098      */
2099     chance = chance * (20 - splcaster) / 15 - splcaster;
2100
2101     /* Clamp to percentile */
2102     if (chance > 100)
2103         chance = 100;
2104     if (chance < 0)
2105         chance = 0;
2106
2107     return chance;
2108 }
2109
2110 STATIC_OVL char *
2111 spellretention(idx, outbuf)
2112 int idx;
2113 char *outbuf;
2114 {
2115     long turnsleft, percent, accuracy;
2116     int skill;
2117
2118     skill = P_SKILL(spell_skilltype(spellid(idx)));
2119     skill = max(skill, P_UNSKILLED); /* restricted same as unskilled */
2120     turnsleft = spellknow(idx);
2121     *outbuf = '\0'; /* lint suppression */
2122
2123     if (turnsleft < 1L) {
2124         /* spell has expired; hero can't successfully cast it anymore */
2125         Strcpy(outbuf, "(gone)");
2126     } else if (turnsleft >= (long) KEEN) {
2127         /* full retention, first turn or immediately after reading book */
2128         Strcpy(outbuf, "100%");
2129     } else {
2130         /*
2131          * Retention is displayed as a range of percentages of
2132          * amount of time left until memory of the spell expires;
2133          * the precision of the range depends upon hero's skill
2134          * in this spell.
2135          *    expert:  2% intervals; 1-2,   3-4,  ...,   99-100;
2136          *   skilled:  5% intervals; 1-5,   6-10, ...,   95-100;
2137          *     basic: 10% intervals; 1-10, 11-20, ...,   91-100;
2138          * unskilled: 25% intervals; 1-25, 26-50, 51-75, 76-100.
2139          *
2140          * At the low end of each range, a value of N% really means
2141          * (N-1)%+1 through N%; so 1% is "greater than 0, at most 200".
2142          * KEEN is a multiple of 100; KEEN/100 loses no precision.
2143          */
2144         percent = (turnsleft - 1L) / ((long) KEEN / 100L) + 1L;
2145         accuracy =
2146             (skill == P_EXPERT) ? 2L : (skill == P_SKILLED)
2147                                            ? 5L
2148                                            : (skill == P_BASIC) ? 10L : 25L;
2149         /* round up to the high end of this range */
2150         percent = accuracy * ((percent - 1L) / accuracy + 1L);
2151         Sprintf(outbuf, "%ld%%-%ld%%", percent - accuracy + 1L, percent);
2152     }
2153     return outbuf;
2154 }
2155
2156 /* Learn a spell during creation of the initial inventory */
2157 void
2158 initialspell(obj)
2159 struct obj *obj;
2160 {
2161     int i, otyp = obj->otyp;
2162
2163     for (i = 0; i < MAXSPELL; i++)
2164         if (spellid(i) == NO_SPELL || spellid(i) == otyp)
2165             break;
2166
2167     if (i == MAXSPELL) {
2168         impossible("Too many spells memorized!");
2169     } else if (spellid(i) != NO_SPELL) {
2170         /* initial inventory shouldn't contain duplicate spellbooks */
2171         impossible("Spell %s already known.", OBJ_NAME(objects[otyp]));
2172     } else {
2173         spl_book[i].sp_id = otyp;
2174         spl_book[i].sp_lev = objects[otyp].oc_level;
2175         incrnknow(i, 0);
2176     }
2177     return;
2178 }
2179
2180 /*spell.c*/