diff options
author | dolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-12-24 00:50:31 +0000 |
---|---|---|
committer | dolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-12-24 00:50:31 +0000 |
commit | dd34bc7bf8b38a93cffba657eb2658a48c2dacff (patch) | |
tree | 8af9cbdc13945b26e90f172addc532ec2b862664 /crawl-ref | |
parent | 532d8dccff760d21593d5db61275e1d00a6af25b (diff) | |
download | crawl-ref-dd34bc7bf8b38a93cffba657eb2658a48c2dacff.tar.gz crawl-ref-dd34bc7bf8b38a93cffba657eb2658a48c2dacff.zip |
Generalize checks for spellbooks and rods of a particular class, or
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
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/religion.cc | 229 | ||||
-rw-r--r-- | crawl-ref/source/religion.h | 21 | ||||
-rw-r--r-- | crawl-ref/source/spl-book.cc | 8 |
3 files changed, 202 insertions, 56 deletions
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index c088dc7190..7b742427c0 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -3322,6 +3322,12 @@ bool is_holy_item(const item_def& item) case OBJ_SCROLLS: retval = (item.sub_type == SCR_HOLY_WORD); break; + case OBJ_BOOKS: + retval = is_holy_spellbook(item); + break; + case OBJ_STAVES: + retval = is_holy_rod(item); + break; default: break; } @@ -3363,15 +3369,10 @@ bool is_evil_item(const item_def& item) retval = is_blood_potion(item); break; case OBJ_BOOKS: - retval = (item.sub_type == BOOK_NECROMANCY - || item.sub_type == BOOK_DEATH - || item.sub_type == BOOK_UNLIFE - || item.sub_type == BOOK_NECRONOMICON - || item.sub_type == BOOK_DEMONOLOGY); + retval = is_evil_spellbook(item); break; case OBJ_STAVES: - retval = (item.sub_type == STAFF_DEATH - || item.sub_type == STAFF_DEMONOLOGY); + retval = (item.sub_type == STAFF_DEATH || is_evil_rod(item)); break; case OBJ_MISCELLANY: retval = (item.sub_type == MISC_BOTTLED_EFREET @@ -3408,6 +3409,12 @@ bool is_chaotic_item(const item_def& item) case OBJ_POTIONS: retval = (item.sub_type == POT_MUTATION); break; + case OBJ_BOOKS: + retval = is_chaotic_spellbook(item); + break; + case OBJ_STAVES: + retval = is_chaotic_rod(item); + break; default: break; } @@ -3418,6 +3425,126 @@ bool is_chaotic_item(const item_def& item) return (retval); } +bool is_holy_discipline(int discipline) +{ + return (discipline & SPTYP_HOLY); +} + +bool is_evil_discipline(int discipline) +{ + return (discipline & SPTYP_NECROMANCY); +} + +bool is_holy_spell(spell_type spell, god_type god) +{ + UNUSED(god); + + unsigned int disciplines = get_spell_disciplines(spell); + + 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)); +} + bool good_god_dislikes_item_handling(const item_def &item) { return (is_good_god(you.religion) && is_evil_item(item) @@ -3426,78 +3553,83 @@ bool good_god_dislikes_item_handling(const item_def &item) bool god_dislikes_item_handling(const item_def &item) { - if (you.religion == GOD_TROG) - { - return (item.base_type == OBJ_BOOKS - && item.sub_type != BOOK_MANUAL - && item.sub_type != BOOK_DESTRUCTION); - } - - if (you.religion == GOD_ZIN) + switch (you.religion) { + case GOD_ZIN: if (item_type_known(item) && is_chaotic_item(item)) return (true); - } + break; - if (you.religion == GOD_SHINING_ONE) + case GOD_SHINING_ONE: { if (!item_type_known(item)) return (false); - if (item.base_type == OBJ_WEAPONS) + switch (item.base_type) + { + case OBJ_WEAPONS: { const int item_brand = get_weapon_brand(item); - if (item_brand == SPWPN_VENOM) return (true); + break; } - else if (item.base_type == OBJ_MISSILES) + + case OBJ_MISSILES: { const int item_brand = get_ammo_brand(item); - if (item_brand == SPMSL_POISONED || item_brand == SPMSL_CURARE) - { return (true); - } + break; } - 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; } + break; } - if (you.religion == GOD_YREDELEMNUL) - { - if (!item_type_known(item)) - return (false); + case GOD_YREDELEMNUL: + if (item_type_known(item) && is_holy_item(item)) + return (true); + break; - if (is_holy_item(item)) + case GOD_TROG: + if (item.base_type == OBJ_BOOKS + && item.sub_type != BOOK_MANUAL + && item.sub_type != BOOK_DESTRUCTION) + { return (true); + } + break; + + default: + break; } + if (god_dislikes_spellbook(item) || god_dislikes_rod(item)) + return (true); + return (false); } bool god_dislikes_spell_type(spell_type spell, god_type god) { - if (god == GOD_NO_GOD) - return (false); + if (is_good_god(god) && is_evil_spell(spell)) + return (true); unsigned int flags = get_spell_flags(spell); unsigned int disciplines = get_spell_disciplines(spell); - if (is_good_god(god)) - { - if ((flags & SPFLAG_UNHOLY) || (disciplines & SPTYP_NECROMANCY)) - return (true); - } - - switch(god) + switch (god) { case GOD_ZIN: - if (spell == SPELL_POLYMORPH_OTHER || spell == SPELL_ALTER_SELF) + if (is_chaotic_spell(spell)) return (true); break; @@ -3522,7 +3654,7 @@ bool god_dislikes_spell_type(spell_type spell, god_type god) break; case GOD_YREDELEMNUL: - if (disciplines & SPTYP_HOLY) + if (is_holy_spell(spell)) return (true); break; @@ -3556,7 +3688,7 @@ bool god_dislikes_spell_type(spell_type spell, god_type god) // Also doesn't like battle spells of the non-conjuration type. if (flags & SPFLAG_BATTLE) - return true; + return (true); break; default: @@ -3570,13 +3702,10 @@ bool god_dislikes_spell_discipline(int discipline, god_type god) { ASSERT(discipline < (1 << (SPTYP_LAST_EXPONENT + 1))); - if (god == GOD_NO_GOD) - return (false); - - if (is_good_god(god) && (discipline & SPTYP_NECROMANCY)) + if (is_good_god(god) && is_evil_discipline(discipline)) return (true); - switch(god) + switch (god) { case GOD_SHINING_ONE: return (discipline & SPTYP_POISON); diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h index 406d3dbb31..a2019b7201 100644 --- a/crawl-ref/source/religion.h +++ b/crawl-ref/source/religion.h @@ -107,14 +107,31 @@ void beogh_convert_orc(monsters *orc, bool emergency, bool is_holy_item(const item_def& item); bool is_evil_item(const item_def& item); bool is_chaotic_item(const item_def& item); +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); bool good_god_dislikes_item_handling(const item_def &item); bool god_dislikes_item_handling(const item_def &item); // NOTE: As of now, these two functions only say if a god won't give a // spell/school when giving a gift. bool god_dislikes_spell_type(spell_type spell, god_type god = you.religion); -bool god_dislikes_spell_discipline(int discipline, - god_type god = you.religion); +bool god_dislikes_spell_discipline(int discipline, god_type god = you.religion); bool trog_burn_spellbooks(); bool ely_destroy_weapons(); diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index dfd3db7e3b..dad9800e5d 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -982,10 +982,10 @@ static unsigned char _lowest_rarity[NUM_SPELLS]; void init_spell_rarities() { - for (int i = 0; i < NUM_SPELLS; i++) + for (int i = 0; i < NUM_SPELLS; ++i) _lowest_rarity[i] = 255; - for (int i = 0; i < NUM_FIXED_BOOKS; i++) + for (int i = 0; i < NUM_FIXED_BOOKS; ++i) { const int rarity = book_rarity(i); @@ -994,14 +994,14 @@ void init_spell_rarities() if (rarity >= 20) continue; - for (int j = 0; j < SPELLBOOK_SIZE; j++) + for (int j = 0; j < SPELLBOOK_SIZE; ++j) { spell_type spell = which_spell_in_book(i, j); if (spell == SPELL_NO_SPELL) continue; #ifdef DEBUG - int unsigned flags = get_spell_flags(spell); + unsigned int flags = get_spell_flags(spell); if (flags & (SPFLAG_MONSTER | SPFLAG_TESTING)) { |