forgetting spells due to amnesia (trunk only)
From the newsgroup, losing spells to amnesia always took away the
last 'N' spells after choosing a random N. That kept casting letters
sane, since letters for lost spells became invalid and those for non-lost
ones stayed the same as they were before amnesia. But 3.4.x gave the
player the ability to swap pairs of spells, so he could make his favorites
to be the first spells, and only lose them if the random number of spells
being affected was as large as the whole list. (Also, divine spellbook
gifts give preference to books for unknown spells; in theory, you could
use spell letter manipulation plus deliberate amnesia to make a particular
spell revert to unknown in order to improve the chance of getting a new
spellbook for it. A bit of cleverness by a determined player but it
makes the game and/or its patron deities seem a bit dumb in the process.)
I first implemented losing spells throughout the list, with later
spells moved forward to fill any gaps. But that results in new casting
letters for every spell past the first lost one, potentially wreaking
havoc if a player chooses a casting letter from his own memory of the
pre-amnesia list. So, instead of losing some spells entirely, either
from the end of the list or spread throughout, I've changed amnesia to
set the retention amount (of N spells from throughout the list) to zero,
the same as happens when it's been 20000 turns since the spell was last
learned. Letters for all known spells stay unchanged, and forgetting
due to amnesia becomes the same as the other way of forgetting spells.
(So now a different potential clever use of amnesia occurs; a player who's
trying to a make speed ascension could get access to expired spells--to
cast in order to become confused--without waiting for 20000 turns after
reading the first book.)
This commit is contained in:
@@ -331,6 +331,8 @@ grammar fixes for vault guard messages given after player assigns guard a name
|
||||
wearing cloak of displacement auto-discovered it even when hero couldn't see
|
||||
wearing elven cloak auto-discovered it even when already stealthy
|
||||
putting on ring of stealth never auto-discovered it
|
||||
forgetting spells due to amnesia now sets memory retention to zero instead
|
||||
of removing them from hero's list of known spells
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
74
src/spell.c
74
src/spell.c
@@ -1083,24 +1083,72 @@ throwspell()
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* forget a random selection of known spells due to amnesia;
|
||||
they used to be lost entirely, as if never learned, but now we
|
||||
just set the memory retention to zero so that they can't be cast */
|
||||
void
|
||||
losespells()
|
||||
{
|
||||
boolean confused = (Confusion != 0);
|
||||
int n, nzap, i;
|
||||
int n, nzap, i;
|
||||
|
||||
context.spbook.book = 0;
|
||||
context.spbook.o_id = 0;
|
||||
for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++)
|
||||
continue;
|
||||
if (n) {
|
||||
nzap = rnd(n) + confused ? 1 : 0;
|
||||
if (nzap > n) nzap = n;
|
||||
for (i = n - nzap; i < n; i++) {
|
||||
spellid(i) = NO_SPELL;
|
||||
exercise(A_WIS, FALSE); /* ouch! */
|
||||
}
|
||||
/* in case reading has been interrupted earlier, discard context */
|
||||
context.spbook.book = 0;
|
||||
context.spbook.o_id = 0;
|
||||
/* count the number of known spells */
|
||||
for (n = 0; n < MAXSPELL; ++n)
|
||||
if (spellid(n) == NO_SPELL) break;
|
||||
|
||||
/* lose anywhere from zero to all known spells;
|
||||
if confused, use the worse of two die rolls */
|
||||
nzap = rn2(n + 1);
|
||||
if (Confusion) {
|
||||
i = rn2(n + 1);
|
||||
if (i > nzap) nzap = i;
|
||||
}
|
||||
/* good Luck might ameliorate spell loss */
|
||||
if (nzap > 1 && !rnl(7))
|
||||
nzap = rnd(nzap);
|
||||
|
||||
/*
|
||||
* Forget 'nzap' out of 'n' known spells by setting their memory
|
||||
* retention to zero. Every spell has the same probability to be
|
||||
* forgotten, even if its retention is already zero.
|
||||
*
|
||||
* Perhaps we should forget the corresponding book too?
|
||||
*
|
||||
* (3.4.3 removed spells entirely from the list, but always did
|
||||
* so from its end, so the 'nzap' most recently learned spells
|
||||
* were the ones lost by default. Player had sort control over
|
||||
* the list, so could move the most useful spells to front and
|
||||
* only lose them if 'nzap' turned out to be a large value.
|
||||
*
|
||||
* Discarding from the end of the list had the virtue of making
|
||||
* casting letters for lost spells become invalid and retaining
|
||||
* the original letter for the ones which weren't lost, so there
|
||||
* was no risk to the player of accidentally casting the wrong
|
||||
* spell when using a letter that was in use prior to amnesia.
|
||||
* That wouldn't be the case if we implemented spell loss spread
|
||||
* throughout the list of known spells; every spell located past
|
||||
* the first lost spell would end up with new letter assigned.)
|
||||
*/
|
||||
for (i = 0; nzap > 0; ++i) {
|
||||
/* when nzap is small relative to the number of spells left,
|
||||
the chance to lose spell [i] is small; as the number of
|
||||
remaining candidates shrinks, the chance per candidate
|
||||
gets bigger; overall, exactly nzap entries are affected */
|
||||
if (rn2(n - i) < nzap) {
|
||||
/* lose access to spell [i] */
|
||||
spellknow(i) = 0;
|
||||
#if 0
|
||||
/* also forget its book */
|
||||
forget_single_object(spellid(i));
|
||||
#endif
|
||||
/* and abuse wisdom */
|
||||
exercise(A_WIS, FALSE);
|
||||
/* there's now one less spell slated to be forgotten */
|
||||
--nzap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user