Formulas (as suggested by David) may need tweaking, feedback welcome!
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9093 c06c8d41-db1a-0410-9941-cceddc491573
MT6WFYUIJ2MA3GIQ2MEHHKIQ6QT6IECFGO4BV4SB3GCGQUIWEYNAC
BTHEX36BHZOAGTT5SNO6OPWDAZJQSUUNDXSJ77FBEFZE3NGJ7CAQC
ED7MV353FW7C4KZWLXUOEULWZZWMRCJVWMLAFC5OLCKZNPDBLQAQC
H5CSZQLEZSQJJZ44RT5J2TSQAEUACR7SOSWS27ZTA7AFI4FZUB5QC
OE3TD4J5FSIFAM37J2UPEV7QQNXLSZM6GDUMPI66LC5LW2OM2J4AC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
FCL7KOWXA5O3GLMDR22JCGMTHMZ57C4WQIJKBIIUQV3LI2CI3X7AC
QO5ZJWQ3JK3PEGBPTQSAYIPEJEHG2M2KTD74227G5VG7DVXUL3BQC
6F6OFJCUOBUP7QTVWSMSQPW25RLVRYVXO3VO5GLMFRY6K5RMOWFAC
YDWBT7CZGY33CNDPF7S4LK7YULFMDUJAKIODKMGB2IYIWHF4SJWQC
52XHD5LKS6UVLXBYUXMPTMVMTXQ6FBUFXJ2TAW6R7CSJY7OXWVJAC
CCRQESB4ADT4WA7FGLNZZXAJ6G5QMCTYCZIWORBN45P6ZPILC34AC
HDT4JHGRZEABO4FSNDRPJ3TOMGIO4UGMMO3RM7CPOT2XYQXRRTXAC
TQOJIJP5MUILKWSEC3Q6BNGVFZJOYSCUR3DR4WPJQ4GGDEVQHEMQC
}
// The weight of a spell is defined as the average of all disciplines'
// skill levels minus the doubled spell level.
static int _spell_weight(spell_type spell)
{
ASSERT(spell != SPELL_NO_SPELL);
int weight = 0;
unsigned int disciplines = get_spell_disciplines(spell);
int count = 0;
for (int i = 0; i <= SPTYP_LAST_EXPONENT; i++)
{
int disc = 1 << i;
if (disciplines & disc)
{
int skill = you.skills[spell_type2skill(disc)]
* 100 / species_skills(i, you.species);
weight += skill;
count++;
}
}
ASSERT(count > 0);
int level = spell_difficulty(spell);
return std::max(0, weight/count - 2*level);
}
// When randomly picking a book for acquirement, use the sum of the
// weights of all unknown spells in the book.
static int _book_weight(int book)
{
ASSERT(book >= 0 && book <= MAX_NORMAL_BOOK);
if (book == BOOK_HEALING)
return 0;
int total_weight = 0;
for (int i = 0; i < SPELLBOOK_SIZE; i++)
{
spell_type stype = which_spell_in_book(book, i);
if (stype == SPELL_NO_SPELL)
continue;
// Skip over spells already seen.
if (you.seen_spell[stype])
continue;
total_weight += _spell_weight(stype);
}
return (total_weight);
int choice = random_choose_weighted(
58, BOOK_RANDART_THEME,
24, book.sub_type,
level == -1 ? 0 :
agent == GOD_SIF_MUNA ? 6 : 2, BOOK_RANDART_LEVEL,
agent == GOD_XOM ? 0 : 6, BOOK_MANUAL, // too useful for Xom
0);
int choice = NUM_BOOKS;
// No changes.
if (choice == book.sub_type)
return;
bool knows_magic = false;
// Manuals are too useful for Xom, and useless when gifted from Sif Muna.
if (agent != GOD_XOM && agent != GOD_SIF_MUNA)
{
int weights[NUM_SKILLS];
int magic_weights = 0;
int other_weights = 0;
book.sub_type = choice;
for (int i = 0; i < NUM_SKILLS; i++)
{
if (i > SK_UNARMED_COMBAT && i < SK_SPELLCASTING)
{
weights[i] = 0;
continue;
}
weights[i] = you.skills[i]
* 100 / species_skills(i, you.species);
if (i >= SK_SPELLCASTING && i <= SK_POISON_MAGIC)
magic_weights += weights[i];
else
other_weights += weights[i];
}
if (x_chance_in_y(other_weights, magic_weights + other_weights))
{
choice = BOOK_MANUAL;
if (magic_weights > 0)
knows_magic = true;
}
}
weights[i - SK_CONJURATIONS] = w;
int skill = you.skills[i]
* 100 / species_skills(i, you.species);
int w = (skill < 12) ? skill + 3
: 25 - skill;
// If we don't know any magic skills, make non-magic skills
// more likely.
if (!knows_magic && i < SK_SPELLCASTING)
w *= 2;
weights[i] = w;
ASSERT(false);
{
mpr("Make book normal spellbook.");
// Pick a random spellbook according to unknown spells contained.
int weights[MAX_NORMAL_BOOK+1];
for (int bk = 0; bk <= MAX_NORMAL_BOOK; bk++)
weights[bk] = _book_weight(bk);
book.sub_type = choose_random_weighted(weights,
weights + ARRAYSZ(weights));