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. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* 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 */
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) */
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))
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)))
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,
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));
53 /* The roles[] table lists the role-specific values for tuning
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
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.
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
92 * See percent_success() below for more comments.
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).
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 */
105 /* since the spellbook itself doesn't blow up, don't say just "explodes" */
107 static const char explodes[] = "radiates explosive energy";
110 /* convert a letter into a number in the range 0..51, or -1 if not a letter */
112 spell_let_to_idx(ilet)
118 if (indx >= 0 && indx < 26)
121 if (indx >= 0 && indx < 26)
126 /* TRUE: book should be destroyed by caller */
132 int lev = objects[bp->otyp].oc_level;
138 You_feel("a wrenching sensation.");
140 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
141 tele(); /* teleport him */
145 You_feel("threatened.");
147 You("
\82¨
\82Ç
\82³
\82ê
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
151 make_blinded(Blinded + rn1(100, 250), TRUE);
158 pline("These runes were just too much to comprehend.");
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);
165 pline_The("book was coated with contact poison!");
167 pline("
\82±
\82Ì
\96{
\82Í
\90Ú
\90G
\8c^
\82Ì
\93Å
\82Å
\95¢
\82í
\82ê
\82Ä
\82¢
\82é
\81I");
170 erode_obj(uarmg, "gloves", ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
172 erode_obj(uarmg, "
\8f¬
\8eè", ERODE_CORRODE, EF_GREASE | EF_VERBOSE);
176 /* temp disable in_use; death should not destroy the book */
177 was_in_use = bp->in_use;
179 losestr(Poison_resistance ? rn1(2, 1) : rn1(4, 3));
181 losehp(rnd(Poison_resistance ? 6 : 10), "contact-poisoned spellbook",
184 losehp(rnd(Poison_resistance ? 6 : 10), "
\90Ú
\90G
\93Å
\82Ì
\96\82\96@
\8f\91\82Å",
187 bp->in_use = was_in_use;
191 shieldeff(u.ux, u.uy);
193 pline_The("book %s, but you are unharmed!", explodes);
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");
198 pline("As you read the book, it %s in your %s!", explodes,
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",
202 dmg = 2 * rnd(10) + 5;
204 losehp(Maybe_Half_Phys(dmg), "exploding rune", KILLED_BY_AN);
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);
216 /* study while confused: returns TRUE if the book is destroyed */
218 confused_book(spellbook)
219 struct obj *spellbook;
221 boolean gone = FALSE;
223 if (!rn2(3) && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
224 spellbook->in_use = TRUE; /* in case called from learn */
227 "Being confused you have difficulties in controlling your actions.");
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);
232 You("accidentally tear the spellbook to pieces.");
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)
242 You("find yourself reading the %s line over and over again.",
243 spellbook == context.spbook.book ? "next" : "first");
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");
252 /* special effects for The Book of the Dead */
257 struct monst *mtmp, *mtmp2;
261 You("turn the pages of the Book of the Dead...");
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" */
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,
274 pline_The("runes appear scrambled. You can't read them!");
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");
280 if (!u.uhave.bell || !u.uhave.menorah) {
282 pline("A chill runs down your %s.", body_part(SPINE));
284 Your("%s
\82É
\8a¦
\82¯
\82ª
\91\96\82Á
\82½
\81D", body_part(SPINE));
287 You_hear("a faint chime...");
289 You_hear("
\82©
\82·
\82©
\82È
\83x
\83\8b\82Ì
\89¹
\82ð
\95·
\82¢
\82½
\81D
\81D
\81D");
290 if (!u.uhave.menorah)
292 pline("Vlad's doppelganger is amused.");
294 pline("
\83\94\83\89\83h
\82Ì
\90¶
\97ì
\82Í
\8fÎ
\82Á
\82½
\81D");
298 for (otmp = invent; otmp; otmp = otmp->nobj) {
299 if (otmp->otyp == CANDELABRUM_OF_INVOCATION && otmp->spe == 7
306 if (otmp->otyp == BELL_OF_OPENING
307 && (moves - otmp->age) < 5L) { /* you rang it recently */
317 pline_The("invocation fails!");
319 pline("
\93Á
\8eê
\94\
\97Í
\82Í
\94
\8aö
\82³
\82ê
\82È
\82©
\82Á
\82½
\81I");
321 pline("At least one of your artifacts is cursed...");
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) {
326 (unsigned) d(2, 6); /* time til next intervene() */
328 /* successful invocation */
330 u.uevent.invoked = 1;
331 /* in case you haven't killed the Wizard yet, behave as if
333 u.uevent.udemigod = 1; /* wizdead() */
334 if (!u.udg_cnt || u.udg_cnt > soon)
336 } else { /* at least one artifact not prepared properly */
338 You("have a feeling that %s is amiss...", something);
340 You("
\89½
\82©
\82ª
\8aÔ
\88á
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D
\81D
\81D");
346 /* when not an invocation situation */
351 You("raised the dead!");
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,
357 || (mtmp = makemon(&mons[PM_NALFESHNEE], u.ux, u.uy,
358 NO_MINVENT)) != 0)) {
362 /* next handle the affect on things you're carrying */
363 (void) unturn_dead(&youmonst);
364 /* last place some monsters around you */
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))
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)
380 if (mtmp->mtame < 20)
383 (void) tamedog(mtmp, (struct obj *) 0);
385 monflee(mtmp, 0, FALSE, TRUE);
392 Your("ancestors are annoyed with you!");
394 Your("
\90æ
\91c
\82Í
\82 \82È
\82½
\82ª
\8c\99\82¢
\82È
\82æ
\82¤
\82¾
\81I");
398 pline_The("headstones in the cemetery begin to move!");
400 pline("
\95æ
\92n
\82Ì
\95æ
\90Î
\82ª
\93®
\82«
\82Í
\82¶
\82ß
\82½
\81I");
404 pline("Oh my! Your name appears in the book!");
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");
412 /* 'book' has just become cursed; if we're reading it and realize it is
413 now cursed, interrupt */
418 if (occupation == learn && context.spbook.book == book
419 && book->cursed && book->bknown && multi >= 0)
429 boolean costly = TRUE;
430 struct obj *book = context.spbook.book;
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 */
441 multi_reason = "reading a book";
443 multi_reason = "
\96{
\82ð
\93Ç
\82ñ
\82Å
\82¢
\82é
\8e\9e\82É";
445 context.spbook.delay = 0;
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 */
453 exercise(A_WIS, TRUE); /* you're studying. */
454 booktype = book->otyp;
455 if (booktype == SPE_BOOK_OF_THE_DEAD) {
462 objects[booktype].oc_name_known ? "\"%s\"" : "the \"%s\" spell",
463 OBJ_NAME(objects[booktype]));
466 objects[booktype].oc_name_known ? "\"%s\"" : "\"%s\"",
467 OBJ_NAME(objects[booktype]));
469 for (i = 0; i < MAXSPELL; i++)
470 if (spellid(i) == booktype || spellid(i) == NO_SPELL)
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) {
479 pline("This spellbook is too faint to be read any more.");
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) {
487 You("know %s quite well already.", splname);
489 You("
\82·
\82Å
\82É%s
\82ð
\8fn
\92m
\82µ
\82Ä
\82¢
\82é
\81D", splname);
491 } else { /* spellknow(i) <= KEEN/10 */
493 Your("knowledge of %s is %s.", splname,
494 spellknow(i) ? "keener" : "restored");
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³");
501 exercise(A_WIS, TRUE); /* extra study */
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 */
513 pline("This spellbook is too faint to read even once.");
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);
520 spl_book[i].sp_id = booktype;
521 spl_book[i].sp_lev = objects[booktype].oc_level;
525 You(i > 0 ? "add %s to your repertoire." : "learn %s.", splname);
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);
529 makeknown((int) booktype);
532 if (book->cursed) { /* maybe a demon cursed it */
533 if (cursed_book(book)) {
535 context.spbook.book = 0;
536 context.spbook.o_id = 0;
542 context.spbook.book = 0;
543 context.spbook.o_id = 0;
548 study_book(spellbook)
549 register struct obj *spellbook;
551 int booktype = spellbook->otyp;
552 boolean confused = (Confusion != 0);
553 boolean too_hard = FALSE;
555 /* attempting to read dull book may make hero fall asleep */
556 if (!confused && !Sleep_resistance
558 && !strcmp(OBJ_DESCR(objects[booktype]), "dull")) {
560 && !strcmp(OBJ_DESCR(objects[booktype]), "
\89\94\90F
\82Ì
\96\82\96@
\8f\91")) {
562 int dullbook = rnd(25) - ACURR(A_WIS);
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);
569 eyes = body_part(EYE);
570 if (eyecount(youmonst.data) > 1)
571 eyes = makeplural(eyes);
573 pline("This book is so dull that you can't keep your %s open.",
575 pline("
\82±
\82Ì
\96{
\82Í
\91Þ
\8bü
\82·
\82¬
\82Ä%s
\82ð
\8aJ
\82¯
\82Ä
\82¢
\82ç
\82ê
\82È
\82¢
\81D",
577 dullbook += rnd(2 * objects[booktype].oc_level);
578 fall_asleep(-dullbook, TRUE);
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) {
588 You("continue your efforts to %s.",
589 (booktype == SPE_NOVEL) ? "read the novel" : "memorize the spell");
591 You("%s
\82ð
\8dÄ
\8aJ
\82µ
\82½
\81D",
592 (booktype == SPE_NOVEL) ? "
\93Ç
\8f\91" : "
\96\82\96@
\82Ì
\8aw
\8fK");
595 /* KMH -- Simplified this code */
596 if (booktype == SPE_BLANK_PAPER) {
598 pline("This spellbook is all blank.");
600 pline("
\82±
\82Ì
\96\82\96@
\8f\91\82Í
\90^
\82Á
\94\92\82¾
\81D");
606 if (booktype == SPE_NOVEL) {
607 /* Obtain current Terry Pratchett book title */
608 const char *tribtitle = noveltitle(&spellbook->novelidx);
610 if (read_tribute("books", tribtitle, 0, (char *) 0, 0,
612 u.uconduct.literate++;
613 check_unpaid(spellbook);
615 if (!u.uevent.read_tribute) {
616 /* give bonus of 20 xp and 4*20+0 pts */
617 more_experienced(20, 0);
619 u.uevent.read_tribute = 1; /* only once */
625 switch (objects[booktype].oc_level) {
628 context.spbook.delay = -objects[booktype].oc_delay;
632 context.spbook.delay = -(objects[booktype].oc_level - 1)
633 * objects[booktype].oc_delay;
637 context.spbook.delay =
638 -objects[booktype].oc_level * objects[booktype].oc_delay;
641 context.spbook.delay = -8 * objects[booktype].oc_delay;
644 impossible("Unknown spellbook level %d, book %d;",
645 objects[booktype].oc_level, booktype);
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) {
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);
660 /* only wizards know if a spell is too difficult */
661 if (Role_if(PM_WIZARD) && read_ability < 20 && !confused) {
666 "This spellbook is %sdifficult to comprehend. Continue?",
667 (read_ability < 12 ? "very " : ""));
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à" : ""));
673 if (yn(qbuf) != 'y') {
674 spellbook->in_use = FALSE;
678 /* its up to random luck now */
679 if (rnd(20) > read_ability) {
686 boolean gone = cursed_book(spellbook);
688 nomul(context.spbook.delay); /* study time */
690 multi_reason = "reading a book";
692 multi_reason = "
\96{
\82ð
\93Ç
\82ñ
\82Å
\82¢
\82é
\8e\9e\82É";
694 context.spbook.delay = 0;
695 if (gone || !rn2(3)) {
698 pline_The("spellbook crumbles to dust!");
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)
706 spellbook->in_use = FALSE;
708 } else if (confused) {
709 if (!confused_book(spellbook)) {
710 spellbook->in_use = FALSE;
712 nomul(context.spbook.delay);
714 multi_reason = "reading a book";
716 multi_reason = "
\96{
\82ð
\93Ç
\82ñ
\82Å
\82¢
\82é
\8e\9e\82É";
718 context.spbook.delay = 0;
721 spellbook->in_use = FALSE;
724 You("begin to %s the runes.",
725 spellbook->otyp == SPE_BOOK_OF_THE_DEAD ? "recite" : "memorize");
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¯");
732 context.spbook.book = spellbook;
733 if (context.spbook.book)
734 context.spbook.o_id = context.spbook.book->o_id;
736 set_occupation(learn, "studying", 0);
738 set_occupation(learn, "
\8aw
\82Ô", 0);
742 /* a spellbook has been destroyed or the character has changed levels;
743 the stored address for the current book is no longer valid */
748 if (obj == context.spbook.book) {
749 context.spbook.book = (struct obj *) 0;
750 context.spbook.o_id = 0;
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 */
758 book_substitution(old_obj, new_obj)
759 struct obj *old_obj, *new_obj;
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;
768 /* called from moveloop() */
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.
779 for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++)
785 /* return True if spellcasting is inhibited;
786 only covers a small subset of reasons why casting won't work */
790 /* rejections which take place before selecting a particular spell */
793 You("are too impaired to cast a spell.");
795 You("
\96\82\96@
\82ð
\8f¥
\82¦
\82ç
\82ê
\82È
\82¢
\81D");
797 } else if (!can_chant(&youmonst)) {
798 You("are unable to chant the incantation.");
800 } else if (!freehand()) {
801 /* Note: !freehand() occurs when weapon and shield (or two-handed
802 * weapon) are welded to hands, so "arms" probably doesn't need
803 * to be makeplural(bodypart(ARM)).
805 * But why isn't lack of free arms (for gesturing) an issue when
806 * poly'd hero has no limbs?
809 Your("arms are not free to cast!");
811 pline("
\96\82\96@
\82ð
\8f¥
\82¦
\82æ
\82¤
\82É
\82à
\98r
\82Ì
\8e©
\97R
\82ª
\8cø
\82©
\82È
\82¢
\81I");
818 * Return TRUE if a spell was picked, with the spell index in the return
819 * parameter. Otherwise return FALSE.
826 char ilet, lets[BUFSZ], qbuf[QBUFSZ];
828 if (spellid(0) == NO_SPELL) {
830 You("don't know any spells right now.");
832 You("
\8d¡
\82Ì
\82Æ
\82±
\82ë
\89½
\82Ì
\96\82\96@
\82à
\92m
\82ç
\82È
\82¢
\81D");
836 return FALSE; /* no spell chosen */
838 if (flags.menu_style == MENU_TRADITIONAL) {
839 /* we know there is at least 1 known spell */
840 for (nspells = 1; nspells < MAXSPELL && spellid(nspells) != NO_SPELL;
846 else if (nspells < 27)
847 Sprintf(lets, "a-%c", 'a' + nspells - 1);
848 else if (nspells == 27)
849 Sprintf(lets, "a-zA");
850 /* this assumes that there are at most 52 spells... */
852 Sprintf(lets, "a-zA-%c", 'A' + nspells - 27);
856 Sprintf(qbuf, "Cast which spell? [%s *?]", lets);
858 Sprintf(qbuf, "
\82Ç
\82Ì
\96\82\96@
\82ð
\8f¥
\82¦
\82é
\81H[%s ?]", lets);
859 ilet = yn_function(qbuf, (char *) 0, '\0');
860 if (ilet == '*' || ilet == '?')
861 break; /* use menu mode */
862 if (index(quitchars, ilet))
865 idx = spell_let_to_idx(ilet);
866 if (idx < 0 || idx >= nspells) {
868 You("don't know that spell.");
870 You("
\82»
\82ñ
\82È
\96\82\96@
\82Í
\92m
\82ç
\82È
\82¢
\81D");
871 continue; /* ask again */
878 return dospellmenu("Choose which spell to cast", SPELLMENU_CAST,
880 return dospellmenu("
\82Ç
\82Ì
\96\82\96@
\82ð
\8f¥
\82¦
\82é
\81H", SPELLMENU_CAST,
884 /* the 'Z' command -- cast a spell */
890 if (getspell(&spell_no))
891 return spelleffects(spell_no, FALSE);
895 STATIC_OVL const char *
896 spelltypemnemonic(skill)
905 case P_HEALING_SPELL:
910 case P_DIVINATION_SPELL:
915 case P_ENCHANTMENT_SPELL:
917 return "enchantment";
936 impossible("Unknown spell skill, %d;", skill);
942 spell_skilltype(booktype)
945 return objects[booktype].oc_skill;
951 int l = u.ulevel, loglev = 0,
952 gain, natac = u.uac + u.uspellprot;
953 /* note: u.uspellprot is subtracted when find_ac() factors it into u.uac,
954 so adding here factors it back out
955 (versions prior to 3.6 had this backwards) */
957 /* loglev=log2(u.ulevel)+1 (1..5) */
963 /* The more u.uspellprot you already have, the less you get,
964 * and the better your natural ac, the less you get.
966 * LEVEL AC SPELLPROT from successive SPE_PROTECTION casts
970 * 2-3 10 0, 2, 4, 5, 6, 7, 8
971 * 2-3 0 0, 2, 4, 5, 6
973 * 4-7 10 0, 3, 6, 8, 9, 10, 11, 12
974 * 4-7 0 0, 3, 5, 7, 8, 9
976 * 7-15 -10 0, 3, 5, 6
977 * 8-15 10 0, 4, 7, 10, 12, 13, 14, 15, 16
978 * 8-15 0 0, 4, 7, 9, 10, 11, 12
979 * 8-15 -10 0, 4, 6, 7, 8
980 * 16-30 10 0, 5, 9, 12, 14, 16, 17, 18, 19, 20
981 * 16-30 0 0, 5, 9, 11, 13, 14, 15
982 * 16-30 -10 0, 5, 8, 9, 10
984 natac = (10 - natac) / 10; /* convert to positive and scale down */
985 gain = loglev - (int) u.uspellprot / (4 - min(3, natac));
990 const char *hgolden = hcolor(NH_GOLDEN), *atmosphere;
994 pline_The("%s haze around you becomes more dense.", hgolden);
996 pline("
\82 \82È
\82½
\82Ì
\82Ü
\82í
\82è
\82Ì%s
\89à
\82ª
\94Z
\82
\82È
\82Á
\82½
\81D", hgolden);
998 rmtyp = levl[u.ux][u.uy].typ;
999 atmosphere = u.uswallow
1000 ? ((u.ustuck->data == &mons[PM_FOG_CLOUD])
1005 : is_whirly(u.ustuck->data)
1010 : is_animal(u.ustuck->data)
1018 : "
\82Ë
\82Î
\82Ë
\82Î")
1044 pline_The("%s around you begins to shimmer with %s haze.",
1045 atmosphere, an(hgolden));
1047 pline("
\82 \82È
\82½
\82Ì
\82Ü
\82í
\82è
\82Ì%s
\82ª%s
\96¶
\82Å
\83L
\83\89\83L
\83\89\82Æ
\8cõ
\82è
\82Í
\82¶
\82ß
\82½
\81D",
1048 atmosphere, hgolden);
1052 u.uspellprot += gain;
1053 u.uspmtime = (P_SKILL(spell_skilltype(SPE_PROTECTION)) == P_EXPERT)
1056 u.usptime = u.uspmtime;
1060 Your("skin feels warm for a moment.");
1062 Your("
\94§
\82Í
\88ê
\8fu
\83|
\83J
\83|
\83J
\82µ
\82½
\81D");
1066 /* attempting to cast a forgotten spell will cause disorientation */
1068 spell_backfire(spell)
1071 long duration = (long) ((spellev(spell) + 1) * 3), /* 6..24 */
1072 old_stun = (HStun & TIMEOUT), old_conf = (HConfusion & TIMEOUT);
1074 /* Prior to 3.4.1, only effect was confusion; it still predominates.
1076 * 3.6.0: this used to override pre-existing confusion duration
1077 * (cases 0..8) and pre-existing stun duration (cases 4..9);
1078 * increase them instead. (Hero can no longer cast spells while
1079 * Stunned, so the potential increment to stun duration here is
1080 * just hypothetical.)
1087 make_confused(old_conf + duration, FALSE); /* 40% */
1092 make_confused(old_conf + 2L * duration / 3L, FALSE); /* 30% */
1093 make_stunned(old_stun + duration / 3L, FALSE);
1097 make_stunned(old_stun + 2L * duration / 3L, FALSE); /* 20% */
1098 make_confused(old_conf + duration / 3L, FALSE);
1101 make_stunned(old_stun + duration, FALSE); /* 10% */
1108 spelleffects(spell, atme)
1112 int energy, damage, chance, n, intell;
1113 int skill, role_skill, res = 0;
1114 boolean confused = (Confusion != 0);
1115 boolean physical_damage = FALSE;
1120 * Reject attempting to cast while stunned or with no free hands.
1121 * Already done in getspell() to stop casting before choosing
1122 * which spell, but duplicated here for cases where spelleffects()
1123 * gets called directly for ^T without intrinsic teleport capability
1124 * or #turn for non-priest/non-knight.
1125 * (There's no duplication of messages; when the rejection takes
1126 * place in getspell(), we don't get called.)
1128 if (rejectcasting()) {
1129 return 0; /* no time elapses */
1133 * Spell casting no longer affects knowledge of the spell. A
1134 * decrement of spell knowledge is done every turn.
1136 if (spellknow(spell) <= 0) {
1138 Your("knowledge of this spell is twisted.");
1140 Your("
\82±
\82Ì
\96\82\96@
\82É
\8aÖ
\82·
\82é
\92m
\8e¯
\82Í
\82æ
\82¶
\82ê
\82½
\81D");
1142 pline("It invokes nightmarish images in your mind...");
1144 pline("
\82»
\82ê
\82Í
\88«
\96²
\82ð
\90S
\82É
\95\82\82Î
\82¹
\82½
\81D
\81D
\81D");
1145 spell_backfire(spell);
1147 } else if (spellknow(spell) <= KEEN / 200) { /* 100 turns left */
1149 You("strain to recall the spell.");
1151 You("
\96\82\96@
\82ð
\8ev
\82¢
\82¾
\82·
\82Ì
\82É
\8bê
\98J
\82µ
\82½
\81D");
1152 } else if (spellknow(spell) <= KEEN / 40) { /* 500 turns left */
1154 You("have difficulty remembering the spell.");
1156 You("
\8eô
\95¶
\82ð
\8ev
\82¢
\8fo
\82·
\82Ì
\82ª
\93ï
\82µ
\82
\82È
\82Á
\82Ä
\82«
\82½
\81D");
1157 } else if (spellknow(spell) <= KEEN / 20) { /* 1000 turns left */
1159 Your("knowledge of this spell is growing faint.");
1161 Your("
\82±
\82Ì
\96\82\96@
\82É
\8aÖ
\82·
\82é
\92m
\8e¯
\82ª
\82¨
\82Ú
\82ë
\82°
\82É
\82È
\82Á
\82Ä
\82«
\82½
\81D");
1162 } else if (spellknow(spell) <= KEEN / 10) { /* 2000 turns left */
1164 Your("recall of this spell is gradually fading.");
1166 Your("
\82±
\82Ì
\96\82\96@
\82É
\8aÖ
\82·
\82é
\92m
\8e¯
\82ª
\8f\99\81X
\82É
\94\96\82ê
\82Ä
\82«
\82½
\81D");
1168 energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */
1170 if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) {
1172 You("are too hungry to cast that spell.");
1174 pline("
\95 \82ª
\8c¸
\82è
\82·
\82¬
\82Ä
\96\82\96@
\82ð
\8f¥
\82¦
\82ç
\82ê
\82È
\82¢
\81D");
1176 } else if (ACURR(A_STR) < 4 && spellid(spell) != SPE_RESTORE_ABILITY) {
1178 You("lack the strength to cast spells.");
1180 pline("
\8b
\82³
\82ª
\8f
\82È
\82·
\82¬
\82Ä
\96\82\96@
\82ð
\8f¥
\82¦
\82ç
\82ê
\82È
\82¢
\81D");
1182 } else if (check_capacity(
1184 "Your concentration falters while carrying so much stuff.")) {
1186 "
\82½
\82
\82³
\82ñ
\82à
\82Ì
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\8fW
\92\86\82Å
\82«
\82È
\82¢
\81D")){
1190 /* if the cast attempt is already going to fail due to insufficient
1191 energy (ie, u.uen < energy), the Amulet's drain effect won't kick
1192 in and no turn will be consumed; however, when it does kick in,
1193 the attempt may fail due to lack of energy after the draining, in
1194 which case a turn will be used up in addition to the energy loss */
1195 if (u.uhave.amulet && u.uen >= energy) {
1197 You_feel("the amulet draining your energy away.");
1199 pline("
\96\82\8f\9c\82¯
\82ª
\82 \82È
\82½
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ð
\8bz
\82¢
\82Æ
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1200 /* this used to be 'energy += rnd(2 * energy)' (without 'res'),
1201 so if amulet-induced cost was more than u.uen, nothing
1202 (except the "don't have enough energy" message) happened
1203 and player could just try again (and again and again...);
1204 now we drain some energy immediately, which has a
1205 side-effect of not increasing the hunger aspect of casting */
1206 u.uen -= rnd(2 * energy);
1210 res = 1; /* time is going to elapse even if spell doesn't get cast */
1213 if (energy > u.uen) {
1215 You("don't have enough energy to cast that spell.");
1217 pline("
\96\82\96@
\82ð
\8f¥
\82¦
\82é
\82¾
\82¯
\82Ì
\8f\
\95ª
\82È
\83G
\83l
\83\8b\83M
\81[
\82ª
\82È
\82¢
\81D");
1220 if (spellid(spell) != SPE_DETECT_FOOD) {
1221 int hungr = energy * 2;
1223 /* If hero is a wizard, their current intelligence
1224 * (bonuses + temporary + current)
1225 * affects hunger reduction in casting a spell.
1226 * 1. int = 17-18 no reduction
1227 * 2. int = 16 1/4 hungr
1228 * 3. int = 15 1/2 hungr
1229 * 4. int = 1-14 normal reduction
1230 * The reason for this is:
1231 * a) Intelligence affects the amount of exertion
1233 * b) Wizards have spent their life at magic and
1234 * understand quite well how to cast spells.
1236 intell = acurr(A_INT);
1237 if (!Role_if(PM_WIZARD))
1258 /* don't put player (quite) into fainting from
1259 * casting a spell, particularly since they might
1260 * not even be hungry at the beginning; however,
1261 * this is low enough that they must eat before
1262 * casting anything else except detect food
1264 if (hungr > u.uhunger - 3)
1265 hungr = u.uhunger - 3;
1270 chance = percent_success(spell);
1271 if (confused || (rnd(100) > chance)) {
1273 You("fail to cast the spell correctly.");
1275 You("
\96\82\96@
\82ð
\90³
\82µ
\82
\8f¥
\82¦
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D");
1276 u.uen -= energy / 2;
1283 exercise(A_WIS, TRUE);
1284 /* pseudo is a temporary "false" object containing the spell stats */
1285 pseudo = mksobj(spellid(spell), FALSE, FALSE);
1286 pseudo->blessed = pseudo->cursed = 0;
1287 pseudo->quan = 20L; /* do not let useup get it */
1289 * Find the skill the hero has in a spell type category.
1290 * See spell_skilltype for categories.
1292 skill = spell_skilltype(pseudo->otyp);
1293 role_skill = P_SKILL(skill);
1295 switch (pseudo->otyp) {
1297 * At first spells act as expected. As the hero increases in skill
1298 * with the appropriate spell type, some spells increase in their
1299 * effects, e.g. more damage, further distance, and so on, without
1300 * additional cost to the spellcaster.
1303 case SPE_CONE_OF_COLD:
1304 if (role_skill >= P_SKILLED) {
1310 if (!u.dx && !u.dy && !u.dz) {
1311 if ((damage = zapyourself(pseudo, TRUE)) != 0) {
1314 Sprintf(buf, "zapped %sself with a spell",
1316 losehp(damage, buf, NO_KILLER_PREFIX);
1318 Strcpy(buf, "
\8e©
\95ª
\8e©
\90g
\82Ì
\96\82\96@
\82ð
\97\81\82Ñ
\82Ä");
1319 losehp(damage, buf, KILLED_BY);
1324 pseudo->otyp - SPE_MAGIC_MISSILE + 10,
1325 spell_damage_bonus(u.ulevel / 2 + 1), 0,
1326 (pseudo->otyp == SPE_CONE_OF_COLD)
1330 u.dx = cc.x + rnd(3) - 2;
1331 u.dy = cc.y + rnd(3) - 2;
1332 if (!isok(u.dx, u.dy) || !cansee(u.dx, u.dy)
1333 || IS_STWALL(levl[u.dx][u.dy].typ) || u.uswallow) {
1334 /* Spell is reflected back to center */
1341 } /* else fall through... */
1343 /* these spells are all duplicates of wand effects */
1344 case SPE_FORCE_BOLT:
1345 physical_damage = TRUE;
1348 case SPE_MAGIC_MISSILE:
1350 case SPE_SLOW_MONSTER:
1351 case SPE_WIZARD_LOCK:
1353 case SPE_TURN_UNDEAD:
1355 case SPE_TELEPORT_AWAY:
1356 case SPE_CANCELLATION:
1357 case SPE_FINGER_OF_DEATH:
1359 case SPE_DETECT_UNSEEN:
1361 case SPE_EXTRA_HEALING:
1362 case SPE_DRAIN_LIFE:
1363 case SPE_STONE_TO_FLESH:
1364 if (!(objects[pseudo->otyp].oc_dir == NODIR)) {
1366 u.dx = u.dy = u.dz = 0;
1367 } else if (!getdir((char *) 0)) {
1368 /* getdir cancelled, re-use previous direction */
1370 * FIXME: reusing previous direction only makes sense
1371 * if there is an actual previous direction. When there
1372 * isn't one, the spell gets cast at self which is rarely
1373 * what the player intended. Unfortunately, the way
1374 * spelleffects() is organized means that aborting with
1375 * "nevermind" is not an option.
1378 pline_The("magical energy is released!");
1380 pline("
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ª
\89ð
\95ú
\82³
\82ê
\82½
\81I");
1382 if (!u.dx && !u.dy && !u.dz) {
1383 if ((damage = zapyourself(pseudo, TRUE)) != 0) {
1387 Sprintf(buf, "zapped %sself with a spell", uhim());
1389 Strcpy(buf, "
\8e©
\95ª
\8e©
\90g
\82Ì
\96\82\96@
\82ð
\97\81\82Ñ
\82Ä");
1390 if (physical_damage)
1391 damage = Maybe_Half_Phys(damage);
1393 losehp(damage, buf, NO_KILLER_PREFIX);
1395 losehp(damage, buf, KILLED_BY);
1402 update_inventory(); /* spell may modify inventory */
1405 /* these are all duplicates of scroll effects */
1406 case SPE_REMOVE_CURSE:
1407 case SPE_CONFUSE_MONSTER:
1408 case SPE_DETECT_FOOD:
1409 case SPE_CAUSE_FEAR:
1411 /* high skill yields effect equivalent to blessed scroll */
1412 if (role_skill >= P_SKILLED)
1413 pseudo->blessed = 1;
1415 case SPE_CHARM_MONSTER:
1416 case SPE_MAGIC_MAPPING:
1417 case SPE_CREATE_MONSTER:
1418 (void) seffects(pseudo);
1421 /* these are all duplicates of potion effects */
1422 case SPE_HASTE_SELF:
1423 case SPE_DETECT_TREASURE:
1424 case SPE_DETECT_MONSTERS:
1425 case SPE_LEVITATION:
1426 case SPE_RESTORE_ABILITY:
1427 /* high skill yields effect equivalent to blessed potion */
1428 if (role_skill >= P_SKILLED)
1429 pseudo->blessed = 1;
1431 case SPE_INVISIBILITY:
1432 (void) peffects(pseudo);
1434 /* end of potion-like spells */
1436 case SPE_CURE_BLINDNESS:
1437 healup(0, 0, FALSE, TRUE);
1439 case SPE_CURE_SICKNESS:
1442 You("are no longer ill.");
1444 Your("
\95a
\8bC
\82Í
\92¼
\82Á
\82½
\81D");
1447 make_slimed(0L, "The slime disappears!");
1449 make_slimed(0L, "
\83X
\83\89\83C
\83\80\82Í
\8fÁ
\82¦
\82½
\81I");
1450 healup(0, 0, TRUE, FALSE);
1452 case SPE_CREATE_FAMILIAR:
1453 (void) make_familiar((struct obj *) 0, u.ux, u.uy, FALSE);
1455 case SPE_CLAIRVOYANCE:
1456 if (!BClairvoyant) {
1457 if (role_skill >= P_SKILLED)
1458 pseudo->blessed = 1; /* detect monsters as well as map */
1459 do_vicinity_map(pseudo);
1460 /* at present, only one thing blocks clairvoyance */
1461 } else if (uarmh && uarmh->otyp == CORNUTHAUM)
1463 You("sense a pointy hat on top of your %s.", body_part(HEAD));
1465 You("
\82Æ
\82ª
\82Á
\82½
\96X
\8eq
\82ð%s
\82Ì
\8fã
\82É
\94
\8c©
\82µ
\82½
\81D", body_part(HEAD));
1467 case SPE_PROTECTION:
1471 if (!jump(max(role_skill, 1)))
1472 pline1(nothing_happens);
1475 impossible("Unknown spell %d attempted.", spell);
1476 obfree(pseudo, (struct obj *) 0);
1480 /* gain skill for successful cast */
1481 use_skill(skill, spellev(spell));
1483 obfree(pseudo, (struct obj *) 0); /* now, get rid of it */
1489 spell_aim_step(arg, x, y)
1490 genericptr_t arg UNUSED;
1495 if (!ZAP_POS(levl[x][y].typ)
1496 && !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
1501 /* Choose location where spell takes effect. */
1510 pline("You're joking! In this weather?");
1512 pline("
\90\85\92\86\82Å
\89½
\82ð
\82µ
\82æ
\82¤
\82Á
\82Ä
\82¢
\82¤
\82ñ
\82¾
\82¢
\81H");
1514 } else if (Is_waterlevel(&u.uz)) {
1516 You("had better wait for the sun to come out.");
1518 You("
\91¾
\97z
\82ª
\8c»
\82ê
\82é
\82Ü
\82Å
\91Ò
\82Á
\82½
\82Ù
\82¤
\82ª
\82æ
\82¢
\82¾
\82ë
\82¤
\81D");
1523 pline("Where do you want to cast the spell?");
1525 pline("
\82Ç
\82±
\82É
\8cü
\82©
\82Á
\82Ä
\96\82\96@
\82ð
\8f¥
\82¦
\82é
\81H");
1529 if (getpos(&cc, TRUE, "the desired position") < 0)
1531 if (getpos(&cc, TRUE, "
\96]
\82Ý
\82Ì
\8fê
\8f\8a") < 0)
1532 return 0; /* user pressed ESC */
1533 /* The number of moves from hero to where the spell drops.*/
1534 if (distmin(u.ux, u.uy, cc.x, cc.y) > 10) {
1536 pline_The("spell dissipates over the distance!");
1538 pline("
\89\93\82·
\82¬
\82é
\81I");
1540 } else if (u.uswallow) {
1542 pline_The("spell is cut short!");
1544 pline("
\82¾
\82ß
\82¾
\81I
\8bß
\82·
\82¬
\82é
\81I");
1545 exercise(A_WIS, FALSE); /* What were you THINKING! */
1549 } else if ((!cansee(cc.x, cc.y)
1550 && (!(mtmp = m_at(cc.x, cc.y)) || !canspotmon(mtmp)))
1551 || IS_STWALL(levl[cc.x][cc.y].typ)) {
1553 Your("mind fails to lock onto that location!");
1555 You("
\82»
\82±
\82É
\8cü
\82©
\82Á
\82Ä
\8fW
\92\86\82µ
\82½
\82ª
\8e¸
\94s
\82µ
\82½
\81I");
1562 walk_path(&uc, &cc, spell_aim_step, (genericptr_t) 0);
1569 /* forget a random selection of known spells due to amnesia;
1570 they used to be lost entirely, as if never learned, but now we
1571 just set the memory retention to zero so that they can't be cast */
1577 /* in case reading has been interrupted earlier, discard context */
1578 context.spbook.book = 0;
1579 context.spbook.o_id = 0;
1580 /* count the number of known spells */
1581 for (n = 0; n < MAXSPELL; ++n)
1582 if (spellid(n) == NO_SPELL)
1585 /* lose anywhere from zero to all known spells;
1586 if confused, use the worse of two die rolls */
1593 /* good Luck might ameliorate spell loss */
1594 if (nzap > 1 && !rnl(7))
1598 * Forget 'nzap' out of 'n' known spells by setting their memory
1599 * retention to zero. Every spell has the same probability to be
1600 * forgotten, even if its retention is already zero.
1602 * Perhaps we should forget the corresponding book too?
1604 * (3.4.3 removed spells entirely from the list, but always did
1605 * so from its end, so the 'nzap' most recently learned spells
1606 * were the ones lost by default. Player had sort control over
1607 * the list, so could move the most useful spells to front and
1608 * only lose them if 'nzap' turned out to be a large value.
1610 * Discarding from the end of the list had the virtue of making
1611 * casting letters for lost spells become invalid and retaining
1612 * the original letter for the ones which weren't lost, so there
1613 * was no risk to the player of accidentally casting the wrong
1614 * spell when using a letter that was in use prior to amnesia.
1615 * That wouldn't be the case if we implemented spell loss spread
1616 * throughout the list of known spells; every spell located past
1617 * the first lost spell would end up with new letter assigned.)
1619 for (i = 0; nzap > 0; ++i) {
1620 /* when nzap is small relative to the number of spells left,
1621 the chance to lose spell [i] is small; as the number of
1622 remaining candidates shrinks, the chance per candidate
1623 gets bigger; overall, exactly nzap entries are affected */
1624 if (rn2(n - i) < nzap) {
1625 /* lose access to spell [i] */
1628 /* also forget its book */
1629 forget_single_object(spellid(i));
1631 /* and abuse wisdom */
1632 exercise(A_WIS, FALSE);
1633 /* there's now one less spell slated to be forgotten */
1640 * Allow player to sort the list of known spells. Manually swapping
1641 * pairs of them becomes very tedious once the list reaches two pages.
1643 * Possible extensions:
1644 * provide means for player to control ordering of skill classes;
1645 * provide means to supply value N such that first N entries stick
1646 * while rest of list is being sorted;
1647 * make chosen sort order be persistent such that when new spells
1648 * are learned, they get inserted into sorted order rather than be
1649 * appended to the end of the list?
1651 enum spl_sort_types {
1665 static const char *spl_sortchoices[NUM_SPELL_SORTBY] = {
1667 "by casting letter",
1669 "
\91I
\91ð
\82·
\82é
\95¶
\8e\9a\8f\87",
1673 "
\95¶
\8e\9a\83R
\81[
\83h
\8f\87",
1675 "by level, low to high",
1677 "
\83\8c\83x
\83\8b\8f¸
\8f\87",
1679 "by level, high to low",
1681 "
\83\8c\83x
\83\8b\8d~
\8f\87",
1683 "by skill group, alphabetized within each group",
1685 "
\83X
\83L
\83\8b\83O
\83\8b\81[
\83v
\96\88\82É
\95¶
\8e\9a\83R
\81[
\83h
\8f\87",
1687 "by skill group, low to high level within group",
1689 "
\83X
\83L
\83\8b\83O
\83\8b\81[
\83v
\96\88\82É
\83\8c\83x
\83\8b\8f¸
\8f\87",
1691 "by skill group, high to low level within group",
1693 "
\83X
\83L
\83\8b\83O
\83\8b\81[
\83v
\96\88\82É
\83\8c\83x
\83\8b\8d~
\8f\87",
1695 "maintain current ordering",
1697 "
\8c»
\8dÝ
\82Ì
\8f\87\8f\98\82ð
\88Û
\8e\9d",
1698 /* a menu choice rather than a sort choice */
1700 "reassign casting letters to retain current order",
1702 "
\8c»
\8dÝ
\82Ì
\8f\87\8f\98\82ð
\95Ï
\82¦
\82¸
\82É
\91I
\91ð
\82·
\82é
\95¶
\8e\9a\82ð
\8dÄ
\8a\84\82è
\93\96\82Ä",
1704 static int spl_sortmode = 0; /* index into spl_sortchoices[] */
1705 static int *spl_orderindx = 0; /* array of spl_book[] indices */
1707 /* qsort callback routine */
1708 STATIC_PTR int CFDECLSPEC
1709 spell_cmp(vptr1, vptr2)
1710 const genericptr vptr1;
1711 const genericptr vptr2;
1714 * gather up all of the possible parameters except spell name
1715 * in advance, even though some might not be needed:
1716 * indx. = spl_orderindx[] index into spl_book[];
1717 * otyp. = spl_book[] index into objects[];
1718 * levl. = spell level;
1719 * skil. = skill group aka spell class.
1721 int indx1 = *(int *) vptr1, indx2 = *(int *) vptr2,
1722 otyp1 = spl_book[indx1].sp_id, otyp2 = spl_book[indx2].sp_id,
1723 levl1 = objects[otyp1].oc_level, levl2 = objects[otyp2].oc_level,
1724 skil1 = objects[otyp1].oc_skill, skil2 = objects[otyp2].oc_skill;
1726 switch (spl_sortmode) {
1728 return indx1 - indx2;
1733 return levl1 - levl2;
1737 return levl2 - levl1;
1741 return skil1 - skil2;
1745 return skil1 - skil2;
1747 return levl1 - levl2;
1751 return skil1 - skil2;
1753 return levl2 - levl1;
1755 case SORTBY_CURRENT:
1757 return (vptr1 < vptr2) ? -1
1758 : (vptr1 > vptr2); /* keep current order */
1760 /* tie-breaker for most sorts--alphabetical by spell name */
1761 return strcmpi(OBJ_NAME(objects[otyp1]), OBJ_NAME(objects[otyp2]));
1764 /* sort the index used for display order of the "view known spells"
1765 list (sortmode == SORTBY_xxx), or sort the spellbook itself to make
1766 the current display order stick (sortmode == SORTRETAINORDER) */
1771 #if defined(SYSV) || defined(DGUX)
1777 if (spl_sortmode == SORTBY_CURRENT)
1779 for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; ++n)
1782 return; /* not enough entries to need sorting */
1784 if (!spl_orderindx) {
1785 /* we haven't done any sorting yet; list is in casting order */
1786 if (spl_sortmode == SORTBY_LETTER /* default */
1787 || spl_sortmode == SORTRETAINORDER)
1789 /* allocate enough for full spellbook rather than just N spells */
1790 spl_orderindx = (int *) alloc(MAXSPELL * sizeof(int));
1791 for (i = 0; i < MAXSPELL; i++)
1792 spl_orderindx[i] = i;
1795 if (spl_sortmode == SORTRETAINORDER) {
1796 struct spell tmp_book[MAXSPELL];
1798 /* sort spl_book[] rather than spl_orderindx[];
1799 this also updates the index to reflect the new ordering (we
1800 could just free it since that ordering becomes the default) */
1801 for (i = 0; i < MAXSPELL; i++)
1802 tmp_book[i] = spl_book[spl_orderindx[i]];
1803 for (i = 0; i < MAXSPELL; i++)
1804 spl_book[i] = tmp_book[i], spl_orderindx[i] = i;
1805 spl_sortmode = SORTBY_LETTER; /* reset */
1809 /* usual case, sort the index rather than the spells themselves */
1810 qsort((genericptr_t) spl_orderindx, n, sizeof *spl_orderindx, spell_cmp);
1814 /* called if the [sort spells] entry in the view spells menu gets chosen */
1819 menu_item *selected;
1824 tmpwin = create_nhwindow(NHW_MENU);
1826 any = zeroany; /* zero out all bits */
1828 for (i = 0; i < SIZE(spl_sortchoices); i++) {
1829 if (i == SORTRETAINORDER) {
1830 let = 'z'; /* assumes fewer than 26 sort choices... */
1831 /* separate final choice from others with a blank line */
1833 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "",
1839 add_menu(tmpwin, NO_GLYPH, &any, let, 0, ATR_NONE, spl_sortchoices[i],
1840 (i == spl_sortmode) ? MENU_SELECTED : MENU_UNSELECTED);
1842 end_menu(tmpwin, "View known spells list sorted");
1844 n = select_menu(tmpwin, PICK_ONE, &selected);
1845 destroy_nhwindow(tmpwin);
1847 choice = selected[0].item.a_int - 1;
1848 /* skip preselected entry if we have more than one item chosen */
1849 if (n > 1 && choice == spl_sortmode)
1850 choice = selected[1].item.a_int - 1;
1851 free((genericptr_t) selected);
1852 spl_sortmode = choice;
1858 /* the '+' command -- view known spells */
1864 struct spell spl_tmp;
1866 if (spellid(0) == NO_SPELL) {
1868 You("don't know any spells right now.");
1870 You("
\96\82\96@
\82ð
\92m
\82ç
\82È
\82¢
\81D");
1873 while (dospellmenu("Currently known spells",
1875 while (dospellmenu("
\8c»
\8dÝ
\92m
\82Á
\82Ä
\82¢
\82é
\96\82\96@
\88ê
\97\97",
1876 SPELLMENU_VIEW, &splnum)) {
1877 if (splnum == SPELLMENU_SORT) {
1878 if (spellsortmenu())
1882 Sprintf(qbuf, "Reordering spells; swap '%c' with",
1884 Sprintf(qbuf, "'%c'
\82Æ
\95À
\82Ñ
\95Ï
\82¦
\82é
\96\82\96@
\82Í
\81H",
1886 if (!dospellmenu(qbuf, splnum, &othnum))
1889 spl_tmp = spl_book[splnum];
1890 spl_book[splnum] = spl_book[othnum];
1891 spl_book[othnum] = spl_tmp;
1895 if (spl_orderindx) {
1896 free((genericptr_t) spl_orderindx);
1899 spl_sortmode = SORTBY_LETTER; /* 0 */
1904 dospellmenu(prompt, splaction, spell_no)
1906 int splaction; /* SPELLMENU_CAST, SPELLMENU_VIEW, or spl_book[] index */
1910 int i, n, how, splnum;
1911 char buf[BUFSZ], retentionbuf[24];
1913 menu_item *selected;
1916 tmpwin = create_nhwindow(NHW_MENU);
1918 any = zeroany; /* zero out all bits */
1921 * The correct spacing of the columns when not using
1922 * tab separation depends on the following:
1923 * (1) that the font is monospaced, and
1924 * (2) that selection letters are pre-pended to the
1925 * given string and are of the form "a - ".
1927 if (!iflags.menu_tab_sep) {
1929 Sprintf(buf, "%-20s Level %-12s Fail Retention", " Name",
1932 Sprintf(buf, "%-20s Level %-12s
\90¬
\8c÷
\97¦", " Name", "
\95ª
\97Þ");
1934 fmt = "%-20s %2d %-12s %3d%% %9s";
1937 Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
1939 Sprintf(buf, "
\96¼
\91O\t
\83\8c\83x
\83\8b\t
\95ª
\97Þ\t
\90¬
\8c÷
\97¦");
1940 fmt = "%s\t%-d\t%s\t%-d%%\t%s";
1942 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1944 for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) {
1945 splnum = !spl_orderindx ? i : spl_orderindx[i];
1946 Sprintf(buf, fmt, spellname(splnum), spellev(splnum),
1947 spelltypemnemonic(spell_skilltype(spellid(splnum))),
1948 100 - percent_success(splnum),
1949 spellretention(splnum, retentionbuf));
1951 any.a_int = splnum + 1; /* must be non-zero */
1952 add_menu(tmpwin, NO_GLYPH, &any, spellet(splnum), 0, ATR_NONE, buf,
1953 (splnum == splaction) ? MENU_SELECTED : MENU_UNSELECTED);
1956 if (splaction == SPELLMENU_VIEW) {
1957 if (spellid(1) == NO_SPELL) {
1958 /* only one spell => nothing to swap with */
1961 /* more than 1 spell, add an extra menu entry */
1962 any.a_int = SPELLMENU_SORT + 1;
1963 add_menu(tmpwin, NO_GLYPH, &any, '+', 0, ATR_NONE,
1964 "[sort spells]", MENU_UNSELECTED);
1967 end_menu(tmpwin, prompt);
1969 n = select_menu(tmpwin, how, &selected);
1970 destroy_nhwindow(tmpwin);
1972 *spell_no = selected[0].item.a_int - 1;
1973 /* menu selection for `PICK_ONE' does not
1974 de-select any preselected entry */
1975 if (n > 1 && *spell_no == splaction)
1976 *spell_no = selected[1].item.a_int - 1;
1977 free((genericptr_t) selected);
1978 /* default selection of preselected spell means that
1979 user chose not to swap it with anything */
1980 if (*spell_no == splaction)
1983 } else if (splaction >= 0) {
1984 /* explicit de-selection of preselected spell means that
1985 user is still swapping but not for the current spell */
1986 *spell_no = splaction;
1993 percent_success(spell)
1996 /* Intrinsic and learned ability are combined to calculate
1997 * the probability of player's success at cast a given spell.
1999 int chance, splcaster, special, statused;
2003 /* Calculate intrinsic ability (splcaster) */
2005 splcaster = urole.spelbase;
2006 special = urole.spelheal;
2007 statused = ACURR(urole.spelstat);
2009 if (uarm && is_metallic(uarm))
2010 splcaster += (uarmc && uarmc->otyp == ROBE) ? urole.spelarmr / 2
2012 else if (uarmc && uarmc->otyp == ROBE)
2013 splcaster -= urole.spelarmr;
2015 splcaster += urole.spelshld;
2017 if (uarmh && is_metallic(uarmh) && uarmh->otyp != HELM_OF_BRILLIANCE)
2018 splcaster += uarmhbon;
2019 if (uarmg && is_metallic(uarmg))
2020 splcaster += uarmgbon;
2021 if (uarmf && is_metallic(uarmf))
2022 splcaster += uarmfbon;
2024 if (spellid(spell) == urole.spelspec)
2025 splcaster += urole.spelsbon;
2027 /* `healing spell' bonus */
2028 if (spellid(spell) == SPE_HEALING || spellid(spell) == SPE_EXTRA_HEALING
2029 || spellid(spell) == SPE_CURE_BLINDNESS
2030 || spellid(spell) == SPE_CURE_SICKNESS
2031 || spellid(spell) == SPE_RESTORE_ABILITY
2032 || spellid(spell) == SPE_REMOVE_CURSE)
2033 splcaster += special;
2038 /* Calculate learned ability */
2040 /* Players basic likelihood of being able to cast any spell
2041 * is based of their `magic' statistic. (Int or Wis)
2043 chance = 11 * statused / 2;
2046 * High level spells are harder. Easier for higher level casters.
2047 * The difficulty is based on the hero's level and their skill level
2048 * in that spell type.
2050 skill = P_SKILL(spell_skilltype(spellid(spell)));
2051 skill = max(skill, P_UNSKILLED) - 1; /* unskilled => 0 */
2053 (spellev(spell) - 1) * 4 - ((skill * 6) + (u.ulevel / 3) + 1);
2055 if (difficulty > 0) {
2056 /* Player is too low level or unskilled. */
2057 chance -= isqrt(900 * difficulty + 2000);
2059 /* Player is above level. Learning continues, but the
2060 * law of diminishing returns sets in quickly for
2061 * low-level spells. That is, a player quickly gains
2062 * no advantage for raising level.
2064 int learning = 15 * -difficulty / spellev(spell);
2065 chance += learning > 20 ? 20 : learning;
2068 /* Clamp the chance: >18 stat and advanced learning only help
2069 * to a limit, while chances below "hopeless" only raise the
2070 * specter of overflowing 16-bit ints (and permit wearing a
2071 * shield to raise the chances :-).
2078 /* Wearing anything but a light shield makes it very awkward
2079 * to cast a spell. The penalty is not quite so bad for the
2080 * player's role-specific spell.
2082 if (uarms && weight(uarms) > (int) objects[SMALL_SHIELD].oc_weight) {
2083 if (spellid(spell) == urole.spelspec) {
2090 /* Finally, chance (based on player intell/wisdom and level) is
2091 * combined with ability (based on player intrinsics and
2092 * encumbrances). No matter how intelligent/wise and advanced
2093 * a player is, intrinsics and encumbrance can prevent casting;
2094 * and no matter how able, learning is always required.
2096 chance = chance * (20 - splcaster) / 15 - splcaster;
2098 /* Clamp to percentile */
2108 spellretention(idx, outbuf)
2112 long turnsleft, percent, accuracy;
2115 skill = P_SKILL(spell_skilltype(spellid(idx)));
2116 skill = max(skill, P_UNSKILLED); /* restricted same as unskilled */
2117 turnsleft = spellknow(idx);
2118 *outbuf = '\0'; /* lint suppression */
2120 if (turnsleft < 1L) {
2121 /* spell has expired; hero can't successfully cast it anymore */
2122 Strcpy(outbuf, "(gone)");
2123 } else if (turnsleft >= (long) KEEN) {
2124 /* full retention, first turn or immediately after reading book */
2125 Strcpy(outbuf, "100%");
2128 * Retention is displayed as a range of percentages of
2129 * amount of time left until memory of the spell expires;
2130 * the precision of the range depends upon hero's skill
2132 * expert: 2% intervals; 1-2, 3-4, ..., 99-100;
2133 * skilled: 5% intervals; 1-5, 6-10, ..., 95-100;
2134 * basic: 10% intervals; 1-10, 11-20, ..., 91-100;
2135 * unskilled: 25% intervals; 1-25, 26-50, 51-75, 76-100.
2137 * At the low end of each range, a value of N% really means
2138 * (N-1)%+1 through N%; so 1% is "greater than 0, at most 200".
2139 * KEEN is a multiple of 100; KEEN/100 loses no precision.
2141 percent = (turnsleft - 1L) / ((long) KEEN / 100L) + 1L;
2143 (skill == P_EXPERT) ? 2L : (skill == P_SKILLED)
2145 : (skill == P_BASIC) ? 10L : 25L;
2146 /* round up to the high end of this range */
2147 percent = accuracy * ((percent - 1L) / accuracy + 1L);
2148 Sprintf(outbuf, "%ld%%-%ld%%", percent - accuracy + 1L, percent);
2153 /* Learn a spell during creation of the initial inventory */
2158 int i, otyp = obj->otyp;
2160 for (i = 0; i < MAXSPELL; i++)
2161 if (spellid(i) == NO_SPELL || spellid(i) == otyp)
2164 if (i == MAXSPELL) {
2165 impossible("Too many spells memorized!");
2166 } else if (spellid(i) != NO_SPELL) {
2167 /* initial inventory shouldn't contain duplicate spellbooks */
2168 impossible("Spell %s already known.", OBJ_NAME(objects[otyp]));
2170 spl_book[i].sp_id = otyp;
2171 spl_book[i].sp_lev = objects[otyp].oc_level;