which your god disapproves of. Now, if at least half of the spells in a spellbook or rod are in a particular class (this threshold may need adjustment; it's in is_spellbook_type()), the entire item is considered to be, too. This means that artefact spellbooks containing many evil spells may be considered evil items by good gods, as will artefact rods if/when they're implemented.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7927 c06c8d41-db1a-0410-9941-cceddc491573
KVMJCPD4RM6YUWIMO4LDHEIB5W62MTOCGBWAEFBHNOUDYLGKXQ3QC
JUKQIMBJHAYSBUZIEHLQ6UBQXLMESF4PPIA5CEHBYMYP73RJINNAC
CCRQESB4ADT4WA7FGLNZZXAJ6G5QMCTYCZIWORBN45P6ZPILC34AC
QO5ZJWQ3JK3PEGBPTQSAYIPEJEHG2M2KTD74227G5VG7DVXUL3BQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
JYEEOUYQ7ZPKOGWUV7VCORBVSOLF2UCBFBH3TR75RGOSS6PNKYUAC
3ZT5EQNS5KXWEXAKV7C3TTFZ6QHOCR57LTFTETPKIVZGTXHZKRQAC
FWNNTOEERPUKXPE4OC52UABFZLKIU3O5GRNNLDK4QI4HR2IOU36QC
NDKS43E4XVAU3FDY276OF5JW7E5SF6F5EJD2XLV5JLKZ5W6N554QC
OWGIMHN3XYFWT7G24XCDK5VWM7I3TOOJO4HVN6UQEZ55C6T2BG7QC
NRIZKLUO26UHNKB4IERXI6ECMD2IJYZACQNIUU3SH6BPLGHAJYVAC
PBKRKGKARGZSLVFVDTK5NWDXQD26NHNN67LDSSB75CLEWBR6TLEQC
VCQYSNAWZZHOZMARWQ4AJBDNFSS7T7CZBQISSPZ2YIIK5PVAWPRQC
V4F3SDV2H4HBH6G6W5M3REN3BDSSE4IDF2RNM7PJMKRW3IDJ7PNAC
4GYZYBY7FFORRNPIEFTV4ZM2C7Z6D2KTQOM537ZCC2YBXT2TNSHAC
JBZ7NU4BB5PGQWCOSZHD5OQUHQIVOD4XGJLSJQ7BUGQEGPRTVGZQC
M2X33JKIB2O27DLCUPSH7LSHEFDN76TUCLGWFNU5LSSR767JSTUQC
KK5IGMPS7OBB2LA7SMGWVR534Q4LYKUD2MESO5IAMOKLNBBDWOMQC
KAGCUOULIUHCPZSOSC6EJGOTH4PMEWCTMA4KGT7F5GQOQY5QX32QC
5SKXI22WN2Y4SWUG634WDB7QXLBNV54RPN5OHAXRI55OFM5YBF5QC
LRNJ7O6FCNZ6TWEEQLXB6ZTKSDJNZ6HXV6T6RFVW5VU6E73MX4AQC
H62KGV237ZWD6HV7U7DRE5JYAJVKQ2LOQ4I7OVH6NJ6DB3U7N5CQC
bool is_holy_discipline(int discipline);
bool is_evil_discipline(int discipline);
bool is_holy_spell(spell_type spell, god_type god = GOD_NO_GOD);
bool is_evil_spell(spell_type spell, god_type god = GOD_NO_GOD);
bool is_chaotic_spell(spell_type spell, god_type god = GOD_NO_GOD);
bool is_any_spell(spell_type spell, god_type god = GOD_NO_GOD);
bool is_spellbook_type(const item_def& item, bool book_or_rod,
bool (*suitable)(spell_type spell, god_type god) =
is_any_spell,
god_type god = you.religion);
bool is_holy_spellbook(const item_def& item);
bool is_evil_spellbook(const item_def& item);
bool is_chaotic_spellbook(const item_def& item);
bool god_dislikes_spellbook(const item_def& item);
bool is_holy_rod(const item_def& item);
bool is_evil_rod(const item_def& item);
bool is_chaotic_rod(const item_def& item);
bool god_dislikes_rod(const item_def& item);
return (is_holy_discipline(disciplines));
}
bool is_evil_spell(spell_type spell, god_type god)
{
UNUSED(god);
unsigned int flags = get_spell_flags(spell);
unsigned int disciplines = get_spell_disciplines(spell);
return ((flags & SPFLAG_UNHOLY) || (is_evil_discipline(disciplines)));
}
bool is_chaotic_spell(spell_type spell, god_type god)
{
UNUSED(god);
return (spell == SPELL_POLYMORPH_OTHER || spell == SPELL_ALTER_SELF);
}
// The default suitable() function for is_spellbook_type().
bool is_any_spell(spell_type spell, god_type god)
{
UNUSED(god);
return (true);
}
// If book_or_rod is false, only look at actual spellbooks. Otherwise,
// only look at rods.
bool is_spellbook_type(const item_def& item, bool book_or_rod,
bool (*suitable)(spell_type spell, god_type god),
god_type god)
{
const bool is_spellbook = (item.base_type == OBJ_BOOKS
&& item.sub_type != BOOK_MANUAL
&& item.sub_type != BOOK_DESTRUCTION);
const bool is_rod = item_is_rod(item);
if (!is_spellbook && !is_rod)
return (false);
if (!book_or_rod && is_rod)
return (false);
int total = 0;
int total_liked = 0;
for (int i = 0; i < SPELLBOOK_SIZE; ++i)
{
spell_type spell = which_spell_in_book(item, i);
if (spell == SPELL_NO_SPELL)
continue;
total++;
if (suitable(spell, god))
total_liked++;
}
// If at least half of the available spells are suitable, the whole
// spellbook or rod is, too.
return (total_liked >= (total / 2) + 1);
}
bool is_holy_spellbook(const item_def& item)
{
return (is_spellbook_type(item, false, is_holy_spell));
}
bool is_evil_spellbook(const item_def& item)
{
return (is_spellbook_type(item, false, is_evil_spell));
}
bool is_chaotic_spellbook(const item_def& item)
{
return (is_spellbook_type(item, false, is_chaotic_spell));
}
bool god_dislikes_spellbook(const item_def& item)
{
return (is_spellbook_type(item, false, god_dislikes_spell_type));
}
bool is_holy_rod(const item_def& item)
{
return (is_spellbook_type(item, true, is_holy_spell));
}
bool is_evil_rod(const item_def& item)
{
return (is_spellbook_type(item, true, is_evil_spell));
}
bool is_chaotic_rod(const item_def& item)
{
return (is_spellbook_type(item, true, is_chaotic_spell));
}
bool god_dislikes_rod(const item_def& item)
{
return (is_spellbook_type(item, true, god_dislikes_spell_type));
}
else if (item.base_type == OBJ_STAVES
&& (item.sub_type == STAFF_POISON
|| item.sub_type == STAFF_VENOM))
{
return (true);
case OBJ_STAVES:
if (item.sub_type == STAFF_POISON)
return (true);
break;
default:
break;