divine gift of spell knowledge
Remove the conduct-specific aspect of receiving spells as prayer boon. Anyone now has a 25% chance of having the spell directly implanted into their head, not just characters who have maintained illiterate conduct. It can now also restore a forgotten spell or refresh one that is nearly forgotten. It still tries to choose a spell which isn't already known (new: or was known but has been forgotten) but if it picks one that is known and doesn't need refreshing, a redundant book will be given, same as the behavior in earlier versions. The chance for receiving a blank spellbook is higher when that item is undiscovered. When given as a prayer reward, make it become discovered even if hero doesn't read it so that it will be less likely to be given again. There's a 1% chance for that auto-discovery to happen with other bestowed books. Unlike blank boots, having the book be discovered doesn't lessen their chance of being repeat gifts. Minor bug fix: for a spell implanted from scratch, the book remains unknown. That's ok; it's actually more interesting than discovering a book you haven't seen yet. But after acquiring and reading the book you could get "you know <spell> quite well already" and the book would stay undiscovered even though you were just told what spell it's for.
This commit is contained in:
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 extern.h $NHDT-Date: 1646255373 2022/03/02 21:09:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1064 $ */
|
/* NetHack 3.7 extern.h $NHDT-Date: 1646838387 2022/03/09 15:06:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1068 $ */
|
||||||
/* Copyright (c) Steve Creps, 1988. */
|
/* Copyright (c) Steve Creps, 1988. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -2543,9 +2543,9 @@ extern int tport_spell(int);
|
|||||||
extern void losespells(void);
|
extern void losespells(void);
|
||||||
extern int dovspell(void);
|
extern int dovspell(void);
|
||||||
extern void initialspell(struct obj *);
|
extern void initialspell(struct obj *);
|
||||||
extern boolean known_spell(short);
|
extern int known_spell(short);
|
||||||
extern int spell_idx(short);
|
extern int spell_idx(short);
|
||||||
extern boolean force_learn_spell(short);
|
extern char force_learn_spell(short);
|
||||||
extern int num_spells(void);
|
extern int num_spells(void);
|
||||||
|
|
||||||
/* ### steal.c ### */
|
/* ### steal.c ### */
|
||||||
|
|||||||
+8
-1
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 spell.h $NHDT-Date: 1596498560 2020/08/03 23:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */
|
/* NetHack 3.7 spell.h $NHDT-Date: 1646838388 2022/03/09 15:06:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */
|
||||||
/* Copyright 1986, M. Stephenson */
|
/* Copyright 1986, M. Stephenson */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -17,6 +17,13 @@ struct spell {
|
|||||||
int sp_know; /* knowlege of spell */
|
int sp_know; /* knowlege of spell */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum spellknowledge {
|
||||||
|
spe_Forgotten = -1, /* known but no longer castable */
|
||||||
|
spe_Unknown = 0, /* not yet known */
|
||||||
|
spe_Fresh = 1, /* castable if various casting criteria are met */
|
||||||
|
spe_GoingStale = 2 /* still castable but nearly forgotten */
|
||||||
|
};
|
||||||
|
|
||||||
/* levels of memory destruction with a scroll of amnesia */
|
/* levels of memory destruction with a scroll of amnesia */
|
||||||
#define ALL_MAP 0x1
|
#define ALL_MAP 0x1
|
||||||
#define ALL_SPELLS 0x2
|
#define ALL_SPELLS 0x2
|
||||||
|
|||||||
+3
-2
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 apply.c $NHDT-Date: 1629242800 2021/08/17 23:26:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ */
|
/* NetHack 3.7 apply.c $NHDT-Date: 1646838388 2022/03/09 15:06:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.369 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -1756,7 +1756,7 @@ jump(int magic) /* 0=Physical, otherwise skill level */
|
|||||||
coord cc;
|
coord cc;
|
||||||
|
|
||||||
/* attempt "jumping" spell if hero has no innate jumping ability */
|
/* attempt "jumping" spell if hero has no innate jumping ability */
|
||||||
if (!magic && !Jumping && known_spell(SPE_JUMPING))
|
if (!magic && !Jumping && known_spell(SPE_JUMPING) >= spe_Fresh)
|
||||||
return spelleffects(SPE_JUMPING, FALSE);
|
return spelleffects(SPE_JUMPING, FALSE);
|
||||||
|
|
||||||
if (!magic && (nolimbs(g.youmonst.data) || slithy(g.youmonst.data))) {
|
if (!magic && (nolimbs(g.youmonst.data) || slithy(g.youmonst.data))) {
|
||||||
@@ -1767,6 +1767,7 @@ jump(int magic) /* 0=Physical, otherwise skill level */
|
|||||||
} else if (!magic && !Jumping) {
|
} else if (!magic && !Jumping) {
|
||||||
You_cant("jump very far.");
|
You_cant("jump very far.");
|
||||||
return ECMD_OK;
|
return ECMD_OK;
|
||||||
|
|
||||||
/* if steed is immobile, can't do physical jump but can do spell one */
|
/* if steed is immobile, can't do physical jump but can do spell one */
|
||||||
} else if (!magic && u.usteed && stucksteed(FALSE)) {
|
} else if (!magic && u.usteed && stucksteed(FALSE)) {
|
||||||
/* stucksteed gave "<steed> won't move" message */
|
/* stucksteed gave "<steed> won't move" message */
|
||||||
|
|||||||
+85
-34
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 pray.c $NHDT-Date: 1621208529 2021/05/16 23:42:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.147 $ */
|
/* NetHack 3.7 pray.c $NHDT-Date: 1646838389 2022/03/09 15:06:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */
|
||||||
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
|
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@ static void fix_worst_trouble(int);
|
|||||||
static void angrygods(aligntyp);
|
static void angrygods(aligntyp);
|
||||||
static void at_your_feet(const char *);
|
static void at_your_feet(const char *);
|
||||||
static void gcrownu(void);
|
static void gcrownu(void);
|
||||||
|
static void give_spell(void);
|
||||||
static void pleased(aligntyp);
|
static void pleased(aligntyp);
|
||||||
static void godvoice(aligntyp, const char *);
|
static void godvoice(aligntyp, const char *);
|
||||||
static void god_zaps_you(aligntyp);
|
static void god_zaps_you(aligntyp);
|
||||||
@@ -838,7 +839,7 @@ gcrownu(void)
|
|||||||
|
|
||||||
/* when getting a new book for known spell, enhance
|
/* when getting a new book for known spell, enhance
|
||||||
currently wielded weapon rather than the book */
|
currently wielded weapon rather than the book */
|
||||||
if (known_spell(class_gift) && ok_wep(uwep))
|
if (known_spell(class_gift) != spe_Unknown && ok_wep(uwep))
|
||||||
obj = uwep; /* to be blessed,&c */
|
obj = uwep; /* to be blessed,&c */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,6 +939,86 @@ gcrownu(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
give_spell(void)
|
||||||
|
{
|
||||||
|
struct obj *otmp;
|
||||||
|
char spe_let;
|
||||||
|
int spe_knowledge, trycnt = u.ulevel + 1;
|
||||||
|
|
||||||
|
/* not yet known spells and forgotten spells are given preference over
|
||||||
|
usable ones; also, try to grant spell that hero could gain skill in
|
||||||
|
(even though being restricted doesn't prevent learning and casting) */
|
||||||
|
otmp = mkobj(SPBOOK_no_NOVEL, TRUE);
|
||||||
|
while (--trycnt > 0) {
|
||||||
|
if (otmp->otyp != SPE_BLANK_PAPER) {
|
||||||
|
if (known_spell(otmp->otyp) <= spe_Unknown
|
||||||
|
&& !P_RESTRICTED(spell_skilltype(otmp->otyp)))
|
||||||
|
break; /* forgotten or not yet known */
|
||||||
|
} else {
|
||||||
|
/* blank paper is acceptable if not discovered yet or
|
||||||
|
if hero has a magic marker to write something on it
|
||||||
|
(doesn't matter if marker is out of charges); it will
|
||||||
|
become discovered (below) without needing to be read */
|
||||||
|
if (!objects[SPE_BLANK_PAPER].oc_name_known
|
||||||
|
|| carrying(MAGIC_MARKER))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
otmp->otyp = rnd_class(g.bases[SPBOOK_CLASS], SPE_BLANK_PAPER);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 25% chance of learning the spell directly instead of
|
||||||
|
* receiving the book for it, unless it's already well known.
|
||||||
|
* The chance is not influenced by whether hero is illiterate.
|
||||||
|
*/
|
||||||
|
if (otmp->otyp != SPE_BLANK_PAPER && !rn2(4)
|
||||||
|
&& (spe_knowledge = known_spell(otmp->otyp)) != spe_Fresh) {
|
||||||
|
/* force_learn_spell() should only return '\0' if the book
|
||||||
|
is blank paper or the spell is known and has retention
|
||||||
|
of spe_Fresh, so no 'else' case is needed here */
|
||||||
|
if ((spe_let = force_learn_spell(otmp->otyp)) != '\0') {
|
||||||
|
/* for spellbook class, OBJ_NAME() yields the name of
|
||||||
|
the spell rather than "spellbook of <spell-name>" */
|
||||||
|
const char *spe_name = OBJ_NAME(objects[otmp->otyp]);
|
||||||
|
|
||||||
|
if (spe_knowledge == spe_Unknown) /* prior to learning */
|
||||||
|
/* appending "spell 'a'" seems slightly silly but
|
||||||
|
is similar to "added to your repertoire, as 'a'"
|
||||||
|
and without any spellbook on hand a novice player
|
||||||
|
might not recognize that 'spe_name' is a spell */
|
||||||
|
pline("Divine knowledge of %s fills your mind! Spell '%c'.",
|
||||||
|
spe_name, spe_let);
|
||||||
|
else
|
||||||
|
Your("knowledge of spell '%c' - %s is %s.",
|
||||||
|
spe_let, spe_name,
|
||||||
|
(spe_knowledge == spe_Forgotten) ? "restored"
|
||||||
|
: "refreshed");
|
||||||
|
}
|
||||||
|
obfree(otmp, (struct obj *) 0); /* discard the book */
|
||||||
|
} else {
|
||||||
|
otmp->dknown = 1; /* not bknown */
|
||||||
|
/* discovering blank paper will make it less likely to
|
||||||
|
be given again; small chance to arbitrarily discover
|
||||||
|
some other book type without having to read it first */
|
||||||
|
if (otmp->otyp == SPE_BLANK_PAPER || !rn2(100))
|
||||||
|
makeknown(otmp->otyp);
|
||||||
|
bless(otmp);
|
||||||
|
/* note: Hallucination case can't happen because we only get
|
||||||
|
called for a boon and boons are only bestowed if all troubles
|
||||||
|
(including hallucination) have been cured/repaired; might
|
||||||
|
apply in variants that offer "always high" as a play option
|
||||||
|
and classify hallucinating as not trouble or not fixable */
|
||||||
|
at_your_feet(Hallucination ? "A thesarus"
|
||||||
|
: Blind ? "A spellbook"
|
||||||
|
/* "An orange spellbook" or "A spellbook of knock"
|
||||||
|
depending on discoveries */
|
||||||
|
: upstart(ansimpleoname(otmp)));
|
||||||
|
place_object(otmp, u.ux, u.uy);
|
||||||
|
newsym(u.ux, u.uy);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pleased(aligntyp g_align)
|
pleased(aligntyp g_align)
|
||||||
{
|
{
|
||||||
@@ -1204,39 +1285,9 @@ pleased(aligntyp g_align)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*FALLTHRU*/
|
/*FALLTHRU*/
|
||||||
case 6: {
|
case 6:
|
||||||
struct obj *otmp;
|
give_spell();
|
||||||
int trycnt = u.ulevel + 1;
|
|
||||||
|
|
||||||
/* not yet known spells given preference over already known ones;
|
|
||||||
also, try to grant a spell for which there is a skill slot */
|
|
||||||
otmp = mkobj(SPBOOK_no_NOVEL, TRUE);
|
|
||||||
while (--trycnt > 0) {
|
|
||||||
if (otmp->otyp != SPE_BLANK_PAPER) {
|
|
||||||
if (!known_spell(otmp->otyp)
|
|
||||||
&& !P_RESTRICTED(spell_skilltype(otmp->otyp)))
|
|
||||||
break; /* usable, but not yet known */
|
|
||||||
} else {
|
|
||||||
if ((!objects[SPE_BLANK_PAPER].oc_name_known
|
|
||||||
|| carrying(MAGIC_MARKER)) && u.uconduct.literate)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
otmp->otyp = rnd_class(g.bases[SPBOOK_CLASS], SPE_BLANK_PAPER);
|
|
||||||
}
|
|
||||||
if (!u.uconduct.literate && (otmp->otyp != SPE_BLANK_PAPER)
|
|
||||||
&& !known_spell(otmp->otyp)) {
|
|
||||||
if (force_learn_spell(otmp->otyp))
|
|
||||||
pline("Divine knowledge of %s fills your mind!",
|
|
||||||
OBJ_NAME(objects[otmp->otyp]));
|
|
||||||
obfree(otmp, (struct obj *) 0);
|
|
||||||
} else {
|
|
||||||
bless(otmp);
|
|
||||||
at_your_feet("A spellbook");
|
|
||||||
place_object(otmp, u.ux, u.uy);
|
|
||||||
newsym(u.ux, u.uy);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
impossible("Confused deity!");
|
impossible("Confused deity!");
|
||||||
break;
|
break;
|
||||||
|
|||||||
+45
-27
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 spell.c $NHDT-Date: 1638499998 2021/12/03 02:53:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */
|
/* NetHack 3.7 spell.c $NHDT-Date: 1646838390 2022/03/09 15:06:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.131 $ */
|
||||||
/* Copyright (c) M. Stephenson 1988 */
|
/* Copyright (c) M. Stephenson 1988 */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -538,7 +538,11 @@ study_book(register struct obj* spellbook)
|
|||||||
if (spellid(i) == booktype || spellid(i) == NO_SPELL)
|
if (spellid(i) == booktype || spellid(i) == NO_SPELL)
|
||||||
break;
|
break;
|
||||||
if (spellid(i) == booktype && spellknow(i) > KEEN / 10) {
|
if (spellid(i) == booktype && spellknow(i) > KEEN / 10) {
|
||||||
You("know \"%s\" quite well already.", OBJ_NAME(objects[booktype]));
|
You("know \"%s\" quite well already.",
|
||||||
|
OBJ_NAME(objects[booktype]));
|
||||||
|
/* hero has just been told what spell this book is for; it may
|
||||||
|
have been undiscovered if spell was learned via divine gift */
|
||||||
|
makeknown(booktype);
|
||||||
if (yn("Refresh your memory anyway?") == 'n')
|
if (yn("Refresh your memory anyway?") == 'n')
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1668,7 +1672,7 @@ dospellmenu(
|
|||||||
{
|
{
|
||||||
winid tmpwin;
|
winid tmpwin;
|
||||||
int i, n, how, splnum;
|
int i, n, how, splnum;
|
||||||
char buf[BUFSZ], retentionbuf[24];
|
char buf[BUFSZ], retentionbuf[24], sep;
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
menu_item *selected;
|
menu_item *selected;
|
||||||
anything any;
|
anything any;
|
||||||
@@ -1685,13 +1689,18 @@ dospellmenu(
|
|||||||
* given string and are of the form "a - ".
|
* given string and are of the form "a - ".
|
||||||
*/
|
*/
|
||||||
if (!iflags.menu_tab_sep) {
|
if (!iflags.menu_tab_sep) {
|
||||||
Sprintf(buf, "%-20s Level %-12s Fail Retention", " Name",
|
Sprintf(buf, "%-20s Level %-12s Fail Retention",
|
||||||
"Category");
|
" Name", "Category");
|
||||||
fmt = "%-20s %2d %-12s %3d%% %9s";
|
fmt = "%-20s %2d %-12s %3d%% %9s";
|
||||||
|
sep = ' ';
|
||||||
} else {
|
} else {
|
||||||
Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
|
Sprintf(buf, "Name\tLevel\tCategory\tFail\tRetention");
|
||||||
fmt = "%s\t%-d\t%s\t%-d%%\t%s";
|
fmt = "%s\t%-d\t%s\t%-d%%\t%s";
|
||||||
|
sep = '\t';
|
||||||
}
|
}
|
||||||
|
if (wizard)
|
||||||
|
Sprintf(eos(buf), "%c%6s", sep, "turns");
|
||||||
|
|
||||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
||||||
iflags.menu_headings, buf, MENU_ITEMFLAGS_NONE);
|
iflags.menu_headings, buf, MENU_ITEMFLAGS_NONE);
|
||||||
for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) {
|
for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) {
|
||||||
@@ -1700,6 +1709,8 @@ dospellmenu(
|
|||||||
spelltypemnemonic(spell_skilltype(spellid(splnum))),
|
spelltypemnemonic(spell_skilltype(spellid(splnum))),
|
||||||
100 - percent_success(splnum),
|
100 - percent_success(splnum),
|
||||||
spellretention(splnum, retentionbuf));
|
spellretention(splnum, retentionbuf));
|
||||||
|
if (wizard)
|
||||||
|
Sprintf(eos(buf), "%c%6d", sep, spellknow(i));
|
||||||
|
|
||||||
any.a_int = splnum + 1; /* must be non-zero */
|
any.a_int = splnum + 1; /* must be non-zero */
|
||||||
add_menu(tmpwin, &nul_glyphinfo, &any, spellet(splnum), 0,
|
add_menu(tmpwin, &nul_glyphinfo, &any, spellet(splnum), 0,
|
||||||
@@ -1898,10 +1909,10 @@ spellretention(int idx, char * outbuf)
|
|||||||
* KEEN is a multiple of 100; KEEN/100 loses no precision.
|
* KEEN is a multiple of 100; KEEN/100 loses no precision.
|
||||||
*/
|
*/
|
||||||
percent = (turnsleft - 1L) / ((long) KEEN / 100L) + 1L;
|
percent = (turnsleft - 1L) / ((long) KEEN / 100L) + 1L;
|
||||||
accuracy =
|
accuracy = (skill == P_EXPERT) ? 2L
|
||||||
(skill == P_EXPERT) ? 2L : (skill == P_SKILLED)
|
: (skill == P_SKILLED) ? 5L
|
||||||
? 5L
|
: (skill == P_BASIC) ? 10L
|
||||||
: (skill == P_BASIC) ? 10L : 25L;
|
: 25L;
|
||||||
/* round up to the high end of this range */
|
/* round up to the high end of this range */
|
||||||
percent = accuracy * ((percent - 1L) / accuracy + 1L);
|
percent = accuracy * ((percent - 1L) / accuracy + 1L);
|
||||||
Sprintf(outbuf, "%ld%%-%ld%%", percent - accuracy + 1L, percent);
|
Sprintf(outbuf, "%ld%%-%ld%%", percent - accuracy + 1L, percent);
|
||||||
@@ -1932,16 +1943,20 @@ initialspell(struct obj* obj)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return TRUE if hero knows spell otyp, FALSE otherwise */
|
/* returns one of spe_Unknown, spe_Fresh, spe_GoingStale, spe_Forgotten */
|
||||||
boolean
|
int
|
||||||
known_spell(short otyp)
|
known_spell(short otyp)
|
||||||
{
|
{
|
||||||
int i;
|
int i, k;
|
||||||
|
|
||||||
for (i = 0; (i < MAXSPELL) && (spellid(i) != NO_SPELL); i++)
|
for (i = 0; (i < MAXSPELL) && (spellid(i) != NO_SPELL); i++)
|
||||||
if (spellid(i) == otyp)
|
if (spellid(i) == otyp) {
|
||||||
return TRUE;
|
k = spellknow(i);
|
||||||
return FALSE;
|
return (k > KEEN / 10) ? spe_Fresh
|
||||||
|
: (k > 0) ? spe_GoingStale
|
||||||
|
: spe_Forgotten;
|
||||||
|
}
|
||||||
|
return spe_Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return index for spell otyp, or UNKNOWN_SPELL if not found */
|
/* return index for spell otyp, or UNKNOWN_SPELL if not found */
|
||||||
@@ -1956,27 +1971,30 @@ spell_idx(short otyp)
|
|||||||
return UNKNOWN_SPELL;
|
return UNKNOWN_SPELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* forcibly learn spell otyp, if possible */
|
/* learn or refresh spell otyp, if feasible; return casting letter or '\0' */
|
||||||
boolean
|
char
|
||||||
force_learn_spell(short otyp)
|
force_learn_spell(short otyp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (known_spell(otyp))
|
if (otyp == SPE_BLANK_PAPER || otyp == SPE_BOOK_OF_THE_DEAD
|
||||||
return FALSE;
|
|| known_spell(otyp) == spe_Fresh)
|
||||||
|
return '\0';
|
||||||
|
|
||||||
for (i = 0; i < MAXSPELL; i++)
|
for (i = 0; i < MAXSPELL; i++)
|
||||||
if (spellid(i) == NO_SPELL)
|
if (spellid(i) == NO_SPELL || spellid(i) == otyp)
|
||||||
break;
|
break;
|
||||||
if (i == MAXSPELL)
|
if (i == MAXSPELL) {
|
||||||
impossible("Too many spells memorized");
|
impossible("Too many spells memorized");
|
||||||
else {
|
return '\0';
|
||||||
g.spl_book[i].sp_id = otyp;
|
|
||||||
g.spl_book[i].sp_lev = objects[otyp].oc_level;
|
|
||||||
incrnknow(i, 1);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
/* for a going-stale or forgotten spell the sp_id and sp_lev assignments
|
||||||
|
are redundant but harmless; for an unknown spell, they're essential */
|
||||||
|
g.spl_book[i].sp_id = otyp;
|
||||||
|
g.spl_book[i].sp_lev = objects[otyp].oc_level;
|
||||||
|
incrnknow(i, 0); /* set spl_book[i].sp_know to KEEN; unlike when learning
|
||||||
|
* a spell by reading its book, we don't need to add 1 */
|
||||||
|
return spellet(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* number of spells hero knows */
|
/* number of spells hero knows */
|
||||||
|
|||||||
+7
-8
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 teleport.c $NHDT-Date: 1605305493 2020/11/13 22:11:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */
|
/* NetHack 3.7 teleport.c $NHDT-Date: 1646838392 2022/03/09 15:06:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -713,16 +713,15 @@ dotele(
|
|||||||
if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
|
if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
|
||||||
&& !can_teleport(g.youmonst.data))) {
|
&& !can_teleport(g.youmonst.data))) {
|
||||||
/* Try to use teleport away spell. */
|
/* Try to use teleport away spell. */
|
||||||
boolean knownsp = known_spell(SPE_TELEPORT_AWAY);
|
int knownsp = known_spell(SPE_TELEPORT_AWAY);
|
||||||
|
|
||||||
/* casting isn't inhibited by being Stunned (...it ought to be) */
|
/* casting isn't inhibited by being Stunned (...it ought to be) */
|
||||||
castit = (knownsp && !Confusion);
|
castit = (knownsp >= spe_Fresh && !Confusion);
|
||||||
if (!castit && !break_the_rules) {
|
if (!castit && !break_the_rules) {
|
||||||
You("%s.",
|
You("%s.", (!Teleportation ? ((knownsp != spe_Unknown)
|
||||||
!Teleportation ? (knownsp
|
? "can't cast that spell"
|
||||||
? "can't cast that spell"
|
: "don't know that spell")
|
||||||
: "don't know that spell")
|
: "are not able to teleport at will"));
|
||||||
: "are not able to teleport at will");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user