From d209dced6edfec770b03610e54a2836fb2bc0f30 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Tue, 10 Nov 2009 21:30:42 -0600 Subject: Properly split up unholy and evil items, reworking is_(unholy|evil)(). This is mainly for Fedhas, who hates the latter but not the former. --- crawl-ref/source/art-data.h | 4 +-- crawl-ref/source/artefact.h | 5 +-- crawl-ref/source/attitude-change.cc | 16 +++++---- crawl-ref/source/attitude-change.h | 2 +- crawl-ref/source/goditem.cc | 71 +++++++++++++++++++++++++++++++------ crawl-ref/source/goditem.h | 4 +++ crawl-ref/source/monster.cc | 19 ++++++++-- crawl-ref/source/monster.h | 1 + crawl-ref/source/player.cc | 6 ++-- crawl-ref/source/religion.cc | 43 +++++++++++++--------- crawl-ref/source/spl-cast.cc | 7 +--- crawl-ref/source/wiz-mon.cc | 1 + 12 files changed, 127 insertions(+), 52 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/art-data.h b/crawl-ref/source/art-data.h index e7fdec34a3..abf00dfaee 100644 --- a/crawl-ref/source/art-data.h +++ b/crawl-ref/source/art-data.h @@ -255,7 +255,7 @@ { "Sword of Cerebov", "great serpentine sword", OBJ_WEAPONS, WPN_GREAT_SWORD, +6, +6, ETC_FIRE, 2000, - UNRAND_FLAG_SPECIAL | UNRAND_FLAG_EVIL, + UNRAND_FLAG_SPECIAL | UNRAND_FLAG_UNHOLY, { SPWPN_FLAMING, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -274,7 +274,7 @@ { "Staff of Dispater", "golden staff", OBJ_WEAPONS, WPN_QUARTERSTAFF, +4, +4, ETC_GOLD, 1200, - UNRAND_FLAG_SPECIAL | UNRAND_FLAG_EVIL, + UNRAND_FLAG_SPECIAL | UNRAND_FLAG_UNHOLY, { SPWPN_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/crawl-ref/source/artefact.h b/crawl-ref/source/artefact.h index 8f1d7d65f2..9b19c03a06 100644 --- a/crawl-ref/source/artefact.h +++ b/crawl-ref/source/artefact.h @@ -122,8 +122,9 @@ enum unrand_flag_type UNRAND_FLAG_NONE = 0x00, UNRAND_FLAG_SPECIAL = 0x01, UNRAND_FLAG_HOLY = 0x02, - UNRAND_FLAG_EVIL = 0x04, - UNRAND_FLAG_CHAOTIC = 0x08 + UNRAND_FLAG_UNHOLY = 0x04, + UNRAND_FLAG_EVIL = 0x08, + UNRAND_FLAG_CHAOTIC = 0x10 }; enum setup_missile_type diff --git a/crawl-ref/source/attitude-change.cc b/crawl-ref/source/attitude-change.cc index 56d0d27b90..509525fb65 100644 --- a/crawl-ref/source/attitude-change.cc +++ b/crawl-ref/source/attitude-change.cc @@ -48,7 +48,8 @@ void good_god_follower_attitude_change(monsters *monster) const item_def* wpn = you.weapon(); if (wpn && wpn->base_type == OBJ_WEAPONS - && is_evil_item(*wpn) + && (is_unholy_item(*wpn) + || is_evil_item(*wpn)) && coinflip()) // 50% chance of conversion failing { msg::stream << monster->name(DESC_CAP_THE) @@ -192,7 +193,7 @@ bool holy_beings_attitude_change() return (apply_to_all_dungeons(_holy_beings_on_level_attitude_change)); } -static bool _evil_beings_on_level_attitude_change() +static bool _unholy_and_evil_beings_on_level_attitude_change() { bool success = false; @@ -200,10 +201,11 @@ static bool _evil_beings_on_level_attitude_change() { monsters *monster = &menv[i]; if (monster->alive() - && monster->is_evil()) + && (monster->is_unholy() + || monster->is_evil())) { #ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Evil attitude changing: %s " + mprf(MSGCH_DIAGNOSTICS, "Unholy/evil attitude changing: %s " "on level %d, branch %d", monster->name(DESC_PLAIN, true).c_str(), static_cast(you.your_level), @@ -211,7 +213,7 @@ static bool _evil_beings_on_level_attitude_change() #endif // If you worship a good god, you make all friendly and good - // neutral evil and unholy beings hostile. + // neutral unholy and evil beings hostile. if (is_good_god(you.religion) && monster->wont_attack()) { monster->attitude = ATT_HOSTILE; @@ -227,9 +229,9 @@ static bool _evil_beings_on_level_attitude_change() return (success); } -bool evil_beings_attitude_change() +bool unholy_and_evil_beings_attitude_change() { - return (apply_to_all_dungeons(_evil_beings_on_level_attitude_change)); + return (apply_to_all_dungeons(_unholy_and_evil_beings_on_level_attitude_change)); } static bool _chaotic_beings_on_level_attitude_change() diff --git a/crawl-ref/source/attitude-change.h b/crawl-ref/source/attitude-change.h index a7433689c5..c422ac9a7c 100644 --- a/crawl-ref/source/attitude-change.h +++ b/crawl-ref/source/attitude-change.h @@ -7,7 +7,7 @@ bool fedhas_plants_hostile(); void beogh_follower_convert(monsters *monster, bool orc_hit = false); void slime_convert(monsters *monster); bool holy_beings_attitude_change(); -bool evil_beings_attitude_change(); +bool unholy_and_evil_beings_attitude_change(); bool chaotic_beings_attitude_change(); bool spellcasters_attitude_change(); bool yred_slaves_abandon_you(); diff --git a/crawl-ref/source/goditem.cc b/crawl-ref/source/goditem.cc index 24eb5f1e28..f5c6e8976b 100644 --- a/crawl-ref/source/goditem.cc +++ b/crawl-ref/source/goditem.cc @@ -51,6 +51,42 @@ bool is_holy_item(const item_def& item) return (retval); } +bool is_unholy_item(const item_def& item) +{ + bool retval = false; + + if (is_unrandom_artefact(item)) + { + unrandart_entry* entry = get_unrand_entry(item.special); + + if (entry->flags & UNRAND_FLAG_UNHOLY) + return (true); + } + + switch (item.base_type) + { + case OBJ_WEAPONS: + retval = is_demonic(item); + break; + case OBJ_SCROLLS: + retval = (item.sub_type == SCR_SUMMONING); + break; + case OBJ_BOOKS: + retval = is_unholy_spellbook(item); + break; + case OBJ_STAVES: + retval = is_unholy_rod(item); + break; + case OBJ_MISCELLANY: + retval = (item.sub_type == MISC_BOTTLED_EFREET); + break; + default: + break; + } + + return (retval); +} + bool is_potentially_evil_item(const item_def& item) { switch (item.base_type) @@ -97,8 +133,7 @@ bool is_evil_item(const item_def& item) case OBJ_WEAPONS: { const int item_brand = get_weapon_brand(item); - retval = (is_demonic(item) - || item_brand == SPWPN_DRAINING + retval = (item_brand == SPWPN_DRAINING || item_brand == SPWPN_PAIN || item_brand == SPWPN_VAMPIRICISM || item_brand == SPWPN_REAPING); @@ -117,8 +152,7 @@ bool is_evil_item(const item_def& item) retval = is_blood_potion(item); break; case OBJ_SCROLLS: - retval = (item.sub_type == SCR_SUMMONING - || item.sub_type == SCR_TORMENT); + retval = (item.sub_type == SCR_TORMENT); break; case OBJ_BOOKS: retval = is_evil_spellbook(item); @@ -127,8 +161,7 @@ bool is_evil_item(const item_def& item) retval = (item.sub_type == STAFF_DEATH || is_evil_rod(item)); break; case OBJ_MISCELLANY: - retval = (item.sub_type == MISC_BOTTLED_EFREET - || item.sub_type == MISC_LANTERN_OF_SHADOWS); + retval = (item.sub_type == MISC_LANTERN_OF_SHADOWS); break; default: break; @@ -254,14 +287,22 @@ bool is_holy_spell(spell_type spell, god_type god) return (is_holy_discipline(disciplines)); } -bool is_evil_spell(spell_type spell, god_type god) +bool is_unholy_spell(spell_type spell, god_type god) { UNUSED(god); unsigned int flags = get_spell_flags(spell); + + return (flags & SPFLAG_UNHOLY); +} + +bool is_evil_spell(spell_type spell, god_type god) +{ + UNUSED(god); + unsigned int disciplines = get_spell_disciplines(spell); - return ((flags & SPFLAG_UNHOLY) || (is_evil_discipline(disciplines))); + return (is_evil_discipline(disciplines)); } bool is_chaotic_spell(spell_type spell, god_type god) @@ -331,6 +372,11 @@ bool is_holy_spellbook(const item_def& item) return (is_spellbook_type(item, false, is_holy_spell)); } +bool is_unholy_spellbook(const item_def& item) +{ + return (is_spellbook_type(item, false, is_unholy_spell)); +} + bool is_evil_spellbook(const item_def& item) { return (is_spellbook_type(item, false, is_evil_spell)); @@ -356,6 +402,11 @@ bool is_holy_rod(const item_def& item) return (is_spellbook_type(item, true, is_holy_spell)); } +bool is_unholy_rod(const item_def& item) +{ + return (is_spellbook_type(item, true, is_unholy_spell)); +} + bool is_evil_rod(const item_def& item) { return (is_spellbook_type(item, true, is_evil_spell)); @@ -481,7 +532,7 @@ conduct_type god_hates_item_handling(const item_def &item) bool god_hates_spell_type(spell_type spell, god_type god) { - if (is_good_god(god) && is_evil_spell(spell)) + if (is_good_god(god) && (is_unholy_spell(spell) || is_evil_spell(spell))) return (true); unsigned int disciplines = get_spell_disciplines(spell); @@ -508,7 +559,7 @@ bool god_hates_spell_type(spell_type spell, god_type god) break; case GOD_FEDHAS: - if (is_evil_discipline(disciplines)) + if (is_evil_spell(spell)) return (true); break; diff --git a/crawl-ref/source/goditem.h b/crawl-ref/source/goditem.h index 8503b9d204..e08c09b43b 100644 --- a/crawl-ref/source/goditem.h +++ b/crawl-ref/source/goditem.h @@ -12,12 +12,14 @@ #include "spl-util.h" bool is_holy_item(const item_def& item); +bool is_unholy_item(const item_def& item); bool is_potentially_evil_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_unholy_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_hasty_spell(spell_type spell, god_type god = GOD_NO_GOD); @@ -27,11 +29,13 @@ bool is_spellbook_type(const item_def& item, bool book_or_rod, is_any_spell, god_type god = you.religion); bool is_holy_spellbook(const item_def& item); +bool is_unholy_spellbook(const item_def& item); bool is_evil_spellbook(const item_def& item); bool is_chaotic_spellbook(const item_def& item); bool is_hasty_spellbook(const item_def& item); bool god_hates_spellbook(const item_def& item); bool is_holy_rod(const item_def& item); +bool is_unholy_rod(const item_def& item); bool is_evil_rod(const item_def& item); bool is_chaotic_rod(const item_def& item); bool is_hasty_rod(const item_def& item); diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 14020cb7f3..ab8dc0dba3 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -2757,6 +2757,15 @@ bool monsters::has_holy_spell() const return (false); } +bool monsters::has_unholy_spell() const +{ + for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; ++i) + if (is_unholy_spell(spells[i])) + return (true); + + return (false); +} + bool monsters::has_evil_spell() const { for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; ++i) @@ -3005,14 +3014,18 @@ bool monsters::is_holy() const bool monsters::is_unholy() const { - const mon_holy_type holi = holiness(); + if (holiness() == MH_DEMONIC) + return (true); - return (holi == MH_UNDEAD || holi == MH_DEMONIC); + if (has_unholy_spell()) + return (true); + + return (false); } bool monsters::is_evil() const { - if (is_unholy()) + if (holiness() == MH_UNDEAD) return (true); // Assume that all unknown gods (GOD_NAMELESS) are evil. diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h index 2f76628541..26b266ee37 100644 --- a/crawl-ref/source/monster.h +++ b/crawl-ref/source/monster.h @@ -350,6 +350,7 @@ public: bool has_spells() const; bool has_spell(spell_type spell) const; bool has_holy_spell() const; + bool has_unholy_spell() const; bool has_evil_spell() const; bool has_chaotic_spell() const; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 28cac3250c..b3d7218db1 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6382,14 +6382,12 @@ bool player::is_holy() const bool player::is_unholy() const { - const mon_holy_type holi = holiness(); - - return (holi == MH_UNDEAD || holi == MH_DEMONIC); + return (holiness() == MH_DEMONIC); } bool player::is_evil() const { - if (is_unholy()) + if (holiness() == MH_UNDEAD) return (true); if (is_evil_god(religion)) diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index f2bbc08c9f..6a4c05fee1 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -209,7 +209,7 @@ const char* god_gain_power_messages[NUM_GODS][MAX_GOD_ABILITIES] = "", "call upon Zin to create a sanctuary" }, // TSO - { "You and your allies can gain power from killing evil.", + { "You and your allies can gain power from killing the unholy and evil.", "call upon the Shining One for a divine shield", "", "channel blasts of cleansing flame", @@ -316,7 +316,7 @@ const char* god_lose_power_messages[NUM_GODS][MAX_GOD_ABILITIES] = "", "call upon Zin to create a sanctuary" }, // TSO - { "You and your allies can no longer gain power from killing evil.", + { "You and your allies can no longer gain power from killing the unholy and evil.", "call upon the Shining One for a divine shield", "", "channel blasts of cleansing flame", @@ -541,7 +541,8 @@ std::string get_god_likes(god_type which_god, bool verbose) break; case GOD_ELYVILON: - snprintf(info, INFO_SIZE, "you destroy weapons (especially evil ones)%s", + snprintf(info, INFO_SIZE, "you destroy weapons (especially unholy and " + "evil ones)%s", verbose ? " via the a command (inscribe items with " "!D to prevent their accidental destruction)" : ""); @@ -576,7 +577,7 @@ std::string get_god_likes(god_type which_god, bool verbose) break; case GOD_SHINING_ONE: - snprintf(info, INFO_SIZE, "you sacrifice evil items%s", + snprintf(info, INFO_SIZE, "you sacrifice unholy and evil items%s", verbose ? " (by dropping them on an altar and praying)" : ""); likes.push_back(info); @@ -1432,13 +1433,14 @@ bool _has_jelly() bool is_good_lawful_follower(const monsters* mon) { - return (mon->alive() && !mon->is_evil() && !mon->is_chaotic() - && mon->friendly()); + return (mon->alive() && !mon->is_unholy() && !mon->is_evil() + && !mon->is_chaotic() && mon->friendly()); } bool is_good_follower(const monsters* mon) { - return (mon->alive() && !mon->is_evil() && mon->friendly()); + return (mon->alive() && !mon->is_unholy() && !mon->is_evil() + && mon->friendly()); } bool is_follower(const monsters* mon) @@ -3780,7 +3782,7 @@ void gain_piety(int pgn) } // Is the destroyed weapon valuable enough to gain piety by doing so? -// Evil weapons are handled specially. +// Unholy and evil weapons are handled specially. static bool _destroyed_valuable_weapon(int value, int type) { // Artefacts, including most randarts. @@ -3838,10 +3840,14 @@ bool ely_destroy_weapons() #endif piety_gain_t pgain = PIETY_NONE; - const bool is_evil_weapon = is_evil_item(item); + const bool unholy_weapon = is_unholy_item(item); + const bool evil_weapon = is_evil_item(item); - if (is_evil_weapon || _destroyed_valuable_weapon(value, item.base_type)) + if (unholy_weapon || evil_weapon + || _destroyed_valuable_weapon(value, item.base_type)) + { pgain = PIETY_SOME; + } if (get_weapon_brand(item) == SPWPN_HOLY_WRATH) { @@ -3858,13 +3864,16 @@ bool ely_destroy_weapons() // Elyvilon doesn't care about item sacrifices at altars, so // I'm stealing _Sacrifice_Messages. _print_sacrifice_message(GOD_ELYVILON, item, pgain); - if (is_evil_weapon) + if (unholy_weapon || evil_weapon) { + const char *desc_weapon = evil_weapon ? "evil" : "unholy"; + // Print this in addition to the above! simple_god_message( - make_stringf(" welcomes the destruction of %s evil " + make_stringf(" welcomes the destruction of %s %s " "weapon%s.", item.quantity == 1 ? "this" : "these", + desc_weapon, item.quantity == 1 ? "" : "s").c_str(), GOD_ELYVILON); } @@ -4533,7 +4542,7 @@ static bool _god_likes_item(god_type god, const item_def& item) return (item.base_type == OBJ_GOLD); case GOD_SHINING_ONE: - return (is_evil_item(item)); + return (is_unholy_item(item) || is_evil_item(item)); case GOD_BEOGH: return (item.base_type == OBJ_CORPSES @@ -4857,7 +4866,7 @@ void offer_items() if (god_likes_fresh_corpses(you.religion)) simple_god_message(" only cares about fresh corpses!"); else if (you.religion == GOD_SHINING_ONE) - simple_god_message(" only cares about evil items!"); + simple_god_message(" only cares about unholy and evil items!"); else if (you.religion == GOD_BEOGH) simple_god_message(" only cares about orcish remains!"); else if (you.religion == GOD_NEMELEX_XOBEH) @@ -4970,8 +4979,8 @@ void god_pitch(god_type which_god) // you make all non-hostile chaotic beings hostile; and when you // start worshipping Trog, you make all non-hostile magic users // hostile. - if (is_good_god(you.religion) && evil_beings_attitude_change()) - mpr("Your evil allies forsake you.", MSGCH_MONSTER_ENCHANT); + if (is_good_god(you.religion) && unholy_and_evil_beings_attitude_change()) + mpr("Your unholy and evil allies forsake you.", MSGCH_MONSTER_ENCHANT); if (you.religion == GOD_ZIN && chaotic_beings_attitude_change()) mpr("Your chaotic allies forsake you.", MSGCH_MONSTER_ENCHANT); @@ -5426,7 +5435,7 @@ bool tso_unchivalric_attack_safe_monster(const monsters *mon) { const mon_holy_type holiness = mon->holiness(); return (mons_intel(mon) < I_NORMAL - || mon->is_evil() + || mon->undead_or_demonic() || !mon->is_holy() && holiness != MH_NATURAL); } diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index c9bfabc9fe..9a48b2ad31 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -825,11 +825,6 @@ static bool _spell_is_utility_spell(spell_type spell_id) SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION | SPTYP_DIVINATION)); } -static bool _spell_is_unholy(spell_type spell_id) -{ - return (testbits(get_spell_flags(spell_id), SPFLAG_UNHOLY)); -} - bool maybe_identify_staff(item_def &item, spell_type spell) { if (item_type_known(item)) @@ -946,7 +941,7 @@ static void _spellcasting_side_effects(spell_type spell, bool idonly = false) // Self-banishment gets a special exemption - you're there to spread // light. - if (_spell_is_unholy(spell) + if (is_unholy_spell(spell) && !you.banished && !crawl_state.is_god_acting()) { diff --git a/crawl-ref/source/wiz-mon.cc b/crawl-ref/source/wiz-mon.cc index bee9d14427..eaccf8346e 100644 --- a/crawl-ref/source/wiz-mon.cc +++ b/crawl-ref/source/wiz-mon.cc @@ -14,6 +14,7 @@ #include "delay.h" #include "map_knowledge.h" #include "ghost.h" +#include "goditem.h" #include "invent.h" #include "items.h" #include "jobs.h" -- cgit v1.2.3-54-g00ecf