OSDN Git Service

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