Wizards learn about spellbooks as they enhance their spell skills

Previously, Wizards got a boost to the chance of writing unknown
spellbooks based purely on being a Wizard (with the chance still
luck-based), leading to a very large power spike when the Wizard
gained access to a luckstone and the ability to max out luck.
This had two main issues: this power spike came *after* the major
early-game difficulty spike, often leaving Wizards forced to deal
with it without having appropriate spells; and it promotes
grinding (for Luck and for Magicbane) at an early point in the
game, meaning that the Wizard early game effectively followed a
sequence of extreme difficulty -> grinding -> minimal difficulty,
which isn't very good balance-wise.

With this commit, Wizards lose their advantage to writing unknown
spellbooks by guessing, and instead learn spellbook IDs based on
their spell skills (advancing a skill gives knowledge of higher-
level spellbooks). This means that writing unknown spellbooks
becomes guaranteed with sufficient skill, but has no advantage
over non-Wizards in schools where the Wixard does not have
sufficient skill.

Due to Wizards' skill caps, there are two spells which they can't
ever write guaranteed: create familiar and charm monster. Create
familiar is a fairly niche spell (that doesn't match the Wizard
playstyle that well) and being unable to write it is not a major
problem. The inability to easily write charm monster is
intentional.
This commit is contained in:
Alex Smith
2023-12-02 03:46:55 +00:00
parent a30a205c45
commit 319dfbdaa3
5 changed files with 47 additions and 4 deletions
+4 -1
View File
@@ -1292,7 +1292,10 @@ if hero destroys a shop wall by breaking a wand of digging or applying a drum
of earthquake, have shopkeeper demand payment of earthquake, have shopkeeper demand payment
mimics sometimes woke up and came out of hiding when they shouldn't have if mimics sometimes woke up and came out of hiding when they shouldn't have if
hero without protection from shape changers returned to a previously hero without protection from shape changers returned to a previously
visitied level (though they would usually rehide so it wasn't obvious) visited level (though they would usually rehide so it wasn't obvious)
Wizards no longer have a bonus to writing unknown spellbooks, but now
learn what spellbooks look like as they gain skill in their
spell schools (allowing a guaranteed write with enough skill)
Fixes to 3.7.0-x General Problems Exposed Via git Repository Fixes to 3.7.0-x General Problems Exposed Via git Repository
+1
View File
@@ -2760,6 +2760,7 @@ extern int known_spell(short);
extern int spell_idx(short); extern int spell_idx(short);
extern char force_learn_spell(short); extern char force_learn_spell(short);
extern int num_spells(void); extern int num_spells(void);
extern void skill_based_spellbook_id(void);
/* ### steal.c ### */ /* ### steal.c ### */
+34
View File
@@ -831,6 +831,40 @@ spell_skilltype(int booktype)
return objects[booktype].oc_skill; return objects[booktype].oc_skill;
} }
/* Wizards learn what spellbooks look like based on their skill in the
spell's school */
void
skill_based_spellbook_id(void)
{
if (!Role_if(PM_WIZARD))
return;
int booktype;
const uchar spbook_class = (uchar) SPBOOK_CLASS;
for (booktype = gb.bases[spbook_class];
booktype < gb.bases[spbook_class + 1];
booktype++) {
int skill = spell_skilltype(booktype);
if (skill == P_NONE) continue;
int known_up_to_level;
switch (P_SKILL(skill)) {
case P_BASIC:
known_up_to_level = 2; break;
case P_SKILLED:
known_up_to_level = 4; break;
case P_EXPERT: case P_MASTER: case P_GRAND_MASTER:
known_up_to_level = 7; break;
case P_UNSKILLED: default:
known_up_to_level = 0; break;
}
if (objects[booktype].oc_level <= known_up_to_level)
makeknown(booktype);
}
}
static void static void
cast_protection(void) cast_protection(void)
{ {
+4
View File
@@ -1136,6 +1136,8 @@ skill_advance(int skill)
You("are now %s skilled in %s.", You("are now %s skilled in %s.",
P_SKILL(skill) >= P_MAX_SKILL(skill) ? "most" : "more", P_SKILL(skill) >= P_MAX_SKILL(skill) ? "most" : "more",
P_NAME(skill)); P_NAME(skill));
skill_based_spellbook_id();
} }
static const struct skill_range { static const struct skill_range {
@@ -1689,6 +1691,8 @@ skill_init(const struct def_skill *class_skill)
/* each role has a special spell; allow at least basic for its type /* each role has a special spell; allow at least basic for its type
(despite the function name, this works for spell skills too) */ (despite the function name, this works for spell skills too) */
unrestrict_weapon_skill(spell_skilltype(gu.urole.spelspec)); unrestrict_weapon_skill(spell_skilltype(gu.urole.spelspec));
skill_based_spellbook_id();
} }
void void
+4 -3
View File
@@ -313,8 +313,8 @@ dowrite(struct obj *pen)
/* /*
* Writing by name requires that the hero knows the scroll or * Writing by name requires that the hero knows the scroll or
* book type. One has previously been read (and its effect * book type. One has previously been read (and its effect
* was evident) or been ID'd via scroll/spell/throne and it * was evident) or been ID'd via scroll/spell/throne (or skill
* will be on the discoveries list. * for Wizards) and it will be on the discoveries list.
* Unknown spellbooks can also be written by name if the hero * Unknown spellbooks can also be written by name if the hero
* has fresh knowledge of the spell, or if the spell is almost * has fresh knowledge of the spell, or if the spell is almost
* forgotten and the hero is Lucky (with a greater chance than * forgotten and the hero is Lucky (with a greater chance than
@@ -349,7 +349,8 @@ dowrite(struct obj *pen)
/* else fresh knowledge of the spell works */ /* else fresh knowledge of the spell works */
&& spell_knowledge != spe_Fresh && spell_knowledge != spe_Fresh
/* and Luck might override after previous checks have failed */ /* and Luck might override after previous checks have failed */
&& rnl((Role_if(PM_WIZARD) || spell_knowledge == spe_GoingStale) && rnl(((Role_if(PM_WIZARD) && paper->oclass != SPBOOK_CLASS) ||
spell_knowledge == spe_GoingStale)
? 5 : 15)) { ? 5 : 15)) {
You("%s to write that.", by_descr ? "fail" : "don't know how"); You("%s to write that.", by_descr ? "fail" : "don't know how");
/* scrolls disappear, spellbooks don't */ /* scrolls disappear, spellbooks don't */