From e6525c83826d150eb2a283ce5bf23218cb75f82e Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Tue, 13 Nov 2007 15:57:55 +0000 Subject: * Add Cannibalism to list of forbidded actions for good gods. * Add simple warning message (god "did not appreciate that!") when using unID'd items that would otherwise be penalized. * Change protection from harm to be independent of prayer. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2849 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 12 +++---- crawl-ref/source/delay.cc | 4 +++ crawl-ref/source/enum.h | 1 + crawl-ref/source/food.cc | 13 ++++--- crawl-ref/source/it_use2.cc | 6 ++-- crawl-ref/source/item_use.cc | 7 ++-- crawl-ref/source/itemname.cc | 9 +++++ crawl-ref/source/itemname.h | 1 + crawl-ref/source/mon-data.h | 6 ++-- crawl-ref/source/monstuff.cc | 2 +- crawl-ref/source/ouch.cc | 4 +-- crawl-ref/source/player.cc | 82 +++++++++++++++++++++++++++++++++++++++++++- crawl-ref/source/player.h | 1 + crawl-ref/source/religion.cc | 53 ++++++++++++++++++++++------ crawl-ref/source/religion.h | 2 +- crawl-ref/source/spells1.cc | 1 + crawl-ref/source/spells2.cc | 3 +- 17 files changed, 170 insertions(+), 37 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 64c8c2d22e..6a497e9aba 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1670,8 +1670,8 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt, simple_monster_message(monster, " is drained."); pbolt.obvious_effect = true; - if (YOU_KILL(pbolt.thrower) && pbolt.effect_known) - did_god_conduct(DID_NECROMANCY, 2 + random2(3)); + if (YOU_KILL(pbolt.thrower)) + did_god_conduct(DID_NECROMANCY, 2 + random2(3), pbolt.effect_known); if (one_chance_in(5)) { @@ -3675,10 +3675,10 @@ static int affect_monster(bolt &beam, monsters *mon) if (YOU_KILL( beam.thrower )) { if (mons_friendly( mon )) - did_god_conduct( DID_ATTACK_FRIEND, 5, mon ); + did_god_conduct( DID_ATTACK_FRIEND, 5, true, mon ); if (mons_holiness( mon ) == MH_HOLY) - did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice, mon ); + did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice, true, mon ); if (you.religion == GOD_BEOGH && mons_species(mon->type) == MONS_ORC && mon->behaviour == BEH_SLEEP && you.species == SP_HILL_ORC @@ -3831,10 +3831,10 @@ static int affect_monster(bolt &beam, monsters *mon) if (YOU_KILL(beam.thrower) && hurt_final > 0) { if (mons_friendly(mon)) - did_god_conduct( DID_ATTACK_FRIEND, 5, mon ); + did_god_conduct( DID_ATTACK_FRIEND, 5, true, mon ); if (mons_holiness( mon ) == MH_HOLY) - did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice, mon ); + did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice, true, mon ); } if (you.religion == GOD_BEOGH && mons_species(mon->type) == MONS_ORC diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index a2c627f6b1..40de644ec4 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -637,6 +637,10 @@ static void finish_delay(const delay_queue_item &delay) (you.has_usable_claws() || you.mutation[MUT_FANGS] == 3) ? "ripping" : "chopping"); + if (is_good_god(you.religion) && is_player_same_species(item.plus)) + simple_god_message(" expects more respect for your departed " + "relatives."); + if (you.species == SP_VAMPIRE && (!god_likes_butchery(you.religion) || !you.duration[DUR_PRAYER])) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index a7cecf10c4..12b7cdf79d 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -632,6 +632,7 @@ enum conduct_type DID_CARDS, DID_STIMULANTS, // unused DID_DRINK_BLOOD, + DID_CANNIBALISM, DID_EAT_MEAT, // unused DID_CREATED_LIFE, // unused diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc index 3ee75ea83d..43d8e18915 100644 --- a/crawl-ref/source/food.cc +++ b/crawl-ref/source/food.cc @@ -55,7 +55,7 @@ #include "xom.h" static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk); -static void eat_chunk( int chunk_effect ); +static void eat_chunk( int chunk_effect, bool cannibal ); static void eating(unsigned char item_class, int item_type); static void describe_food_change(int hunger_increment); static bool food_change(bool suppress_message); @@ -670,13 +670,14 @@ void eat_from_inventory(int which_inventory_slot) // this is a bit easier to read... most compilers should // handle this the same -- bwr const int mons_type = you.inv[ which_inventory_slot ].plus; + const bool cannibal = is_player_same_species(mons_type); const int chunk_type = mons_corpse_effect( mons_type ); const bool rotten = (you.inv[which_inventory_slot].special < 100); if (!prompt_eat_chunk(you.inv[which_inventory_slot], rotten)) return; - eat_chunk( determine_chunk_effect( chunk_type, rotten ) ); + eat_chunk( determine_chunk_effect( chunk_type, rotten ), cannibal ); } else { @@ -718,10 +719,11 @@ void eat_floor_item(int item_link) else if (mitm[item_link].sub_type == FOOD_CHUNK) { const int chunk_type = mons_corpse_effect( mitm[item_link].plus ); + const bool cannibal = is_player_same_species( mitm[item_link].plus ); const bool rotten = (mitm[item_link].special < 100); if (!prompt_eat_chunk(mitm[item_link], rotten)) return; - eat_chunk( determine_chunk_effect( chunk_type, rotten ) ); + eat_chunk( determine_chunk_effect( chunk_type, rotten ), cannibal ); } else { @@ -854,7 +856,7 @@ static void say_chunk_flavour(bool likes_chunks) // never called directly - chunk_effect values must pass // through food::determine_chunk_effect() first {dlb}: -static void eat_chunk( int chunk_effect ) +static void eat_chunk( int chunk_effect, bool cannibal ) { bool likes_chunks = (you.omnivorous() || @@ -936,6 +938,9 @@ static void eat_chunk( int chunk_effect ) } } + if (cannibal) + did_god_conduct( DID_CANNIBALISM, 10 ); + if (do_eat) { start_delay( DELAY_EAT, 2, (suppress_msg) ? 0 : nutrition ); diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index e129ba8de3..e78f3375e6 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -47,7 +47,7 @@ bool potion_effect( potion_type pot_eff, int pow ) { bool effect = true; // current behaviour is all potions id on quaffing - + bool was_known = item_type_known(OBJ_POTIONS, (int) pot_eff); int new_value = 0; if (pow > 150) @@ -120,7 +120,7 @@ bool potion_effect( potion_type pot_eff, int pow ) if (you.duration[DUR_MIGHT] > 80) you.duration[DUR_MIGHT] = 80; - did_god_conduct( DID_STIMULANTS, 4 + random2(4) ); + did_god_conduct( DID_STIMULANTS, 4 + random2(4), was_known ); break; } @@ -335,7 +335,7 @@ bool potion_effect( potion_type pot_eff, int pow ) xom_is_stimulated(32); } } - did_god_conduct(DID_DRINK_BLOOD, 1 + random2(3)); + did_god_conduct(DID_DRINK_BLOOD, 1 + random2(3), was_known); break; case POT_RESISTANCE: diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index b90e378e7a..522b130787 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -3451,8 +3451,8 @@ static bool affix_weapon_enchantment() success = false; // is only naughty if you know you're doing it - if (get_ident_type(OBJ_SCROLLS, SCR_ENCHANT_WEAPON_III)==ID_KNOWN_TYPE) - did_god_conduct(DID_UNHOLY, 10); + did_god_conduct(DID_UNHOLY, 10, + get_ident_type(OBJ_SCROLLS, SCR_ENCHANT_WEAPON_III)==ID_KNOWN_TYPE); break; @@ -3900,8 +3900,7 @@ void read_scroll(void) torment( TORMENT_SCROLL, you.x_pos, you.y_pos ); // is only naughty if you know you're doing it - if (item_type_known(scroll)) - did_god_conduct(DID_UNHOLY, 10); + did_god_conduct(DID_UNHOLY, 10, item_type_known(scroll)); break; case SCR_IMMOLATION: diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 26210874c8..eaacf8c987 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -1605,6 +1605,15 @@ bool item_type_known( const item_def& item ) return false; } +bool item_type_known(const object_class_type base_type, const int sub_type) +{ + const item_type_id_type idt = objtype_to_idtype(base_type); + if ( idt != NUM_IDTYPE && sub_type < 50 ) + return ( type_ids[idt][sub_type] == ID_KNOWN_TYPE ); + else + return false; +} + bool item_type_tried( const item_def& item ) { if ( item_type_known(item) ) diff --git a/crawl-ref/source/itemname.h b/crawl-ref/source/itemname.h index d0b47d9c0a..a885693cf5 100644 --- a/crawl-ref/source/itemname.h +++ b/crawl-ref/source/itemname.h @@ -94,6 +94,7 @@ std::string quant_name( const item_def &item, int quant, description_level_type des, bool terse = false ); bool item_type_known( const item_def &item ); +bool item_type_known( const object_class_type base_type, const int sub_type ); bool item_type_tried( const item_def &item ); bool is_interesting_item( const item_def& item ); diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index e176e6a8e8..0c8b71c8e1 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -3586,7 +3586,7 @@ 300, 10, MONS_QUOKKA, MONS_QUOKKA, MH_NATURAL, -1, { {AT_BITE, AF_PLAIN, 5}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 1, 3, 5, 0 }, - 2, 13, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_NORMAL, + 2, 13, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_TINY }, @@ -4007,7 +4007,7 @@ 500, 10, MONS_MERFOLK, MONS_MERFOLK, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 14}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 2, 4, 0 }, - 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, + 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -4019,7 +4019,7 @@ 500, 10, MONS_MERMAID, MONS_MERMAID, MH_NATURAL, -5, { {AT_HIT, AF_PLAIN, 10}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 2, 4, 0 }, - 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, + 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index ea537946a2..71e832426f 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -713,7 +713,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) // no piety loss if god gifts killed by other monsters if (mons_friendly(monster) && !testbits(monster->flags,MF_GOD_GIFT)) did_god_conduct(DID_FRIEND_DIES, 1 + (monster->hit_dice / 2), - monster); + true, monster); // Trying to prevent summoning abuse here, so we're trying to // prevent summoned creatures from being being done_good kills. diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 2297d3d170..8a86114499 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -791,8 +791,8 @@ void ouch( int dam, int death_source, kill_method_type death_type, case GOD_SHINING_ONE: case GOD_ELYVILON: case GOD_YREDELEMNUL: - if (dam >= you.hp && you.duration[DUR_PRAYER] - && random2(you.piety) >= 30) + if (dam >= you.hp + && (one_chance_in(10) || you.piety > random2(1000))) { simple_god_message( " protects you from harm!" ); return; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index eeb0a796e2..39a33acc47 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -408,6 +408,86 @@ bool player_genus(genus_type which_genus, species_type species) return (false); } // end player_genus() +bool is_player_same_species(const int mon) +{ + switch (you.species) + { + case SP_HUMAN: + if (mons_species(mon) == MONS_HUMAN) + return (true); + return (false); + case SP_CENTAUR: + if (mons_species(mon) == MONS_CENTAUR) + return (true); + return (false); + case SP_OGRE: + case SP_OGRE_MAGE: + if (mons_species(mon) == MONS_OGRE) + return (true); + return (false); + case SP_TROLL: + if (mons_species(mon) == MONS_TROLL) + return (true); + return (false); + case SP_MUMMY: + if (mons_species(mon) == MONS_MUMMY) + return (true); + return (false); + case SP_VAMPIRE: + if (mons_species(mon) == MONS_VAMPIRE) + return (true); + return (false); + case SP_MINOTAUR: + if (mons_species(mon) == MONS_MINOTAUR) + return (true); + return (false); + case SP_NAGA: + if (mons_species(mon) == MONS_NAGA) + return (true); + return (false); + case SP_HILL_ORC: + if (mons_species(mon) == MONS_ORC) + return (true); + return (false); + case SP_MERFOLK: + if (mons_species(mon) == MONS_MERFOLK + || mons_species(mon) == MONS_MERMAID) + { + return (true); + } + return (false); + + case SP_GREY_ELF: + case SP_HIGH_ELF: + case SP_DEEP_ELF: + case SP_SLUDGE_ELF: + if (mons_species(mon) == MONS_ELF) + return (true); + return (false); + + case SP_RED_DRACONIAN: + case SP_WHITE_DRACONIAN: + case SP_GREEN_DRACONIAN: + case SP_GOLDEN_DRACONIAN: + case SP_GREY_DRACONIAN: + case SP_BLACK_DRACONIAN: + case SP_PURPLE_DRACONIAN: + case SP_MOTTLED_DRACONIAN: + case SP_PALE_DRACONIAN: + if (mons_species(mon) == MONS_DRACONIAN) + return (true); + return (false); + + case SP_KOBOLD: + if (mons_species(mon) == MONS_KOBOLD) + return (true); + return (false); + default: // no monster equivalent + return (false); + + } +} + // checks whether the player's current species can // use (usually wear) a given piece of equipment // Note that EQ_BODY_ARMOUR and EQ_HELMET only check @@ -5670,7 +5750,7 @@ void player::attacking(actor *other) { const monsters *mons = dynamic_cast(other); if (mons_friendly(mons)) - did_god_conduct(DID_ATTACK_FRIEND, 5, mons); + did_god_conduct(DID_ATTACK_FRIEND, 5, true, mons); else pet_target = monster_index(mons); } diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 3e3b8c172f..a012a4b470 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -326,6 +326,7 @@ void redraw_skill(const std::string &your_name, const std::string &class_name); * *********************************************************************** */ bool player_genus( genus_type which_genus, species_type species = SP_UNKNOWN ); +bool is_player_same_species( const int mon ); bool you_can_wear( int eq, bool special_armour = false ); bool player_has_feet(void); diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index b55cc393f2..93b59a40d3 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -1205,7 +1205,8 @@ void god_speaks( god_type god, const char *mesg ) // This function is the merger of done_good() and naughty(). // Returns true if god was interested (good or bad) in conduct. -bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) +bool did_god_conduct( conduct_type thing_done, int level, bool known, + const actor *victim ) { bool ret = false; int piety_change = 0; @@ -1221,10 +1222,21 @@ bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) case DID_DRINK_BLOOD: switch (you.religion) { - case GOD_ZIN: case GOD_SHINING_ONE: + if (!known) + { + simple_god_message(" did not appreciate that!"); + break; + } + penance = level; + // deliberate fall-through + case GOD_ZIN: case GOD_ELYVILON: - // no penance as this can happen accidentally + if (!known) + { + simple_god_message(" did not appreciate that!"); + break; + } piety_change = -2*level; ret = true; break; @@ -1233,7 +1245,22 @@ bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) } break; - // If you make some god like these acts, modify did_god_conduct call + case DID_CANNIBALISM: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + piety_change = -level; + penance = level; + ret = true; + break; + default: + break; + } + break; + + // If you make some god like these acts, modify did_god_conduct call // in beam.cc with god_likes_necromancy check or something similar case DID_NECROMANCY: case DID_UNHOLY: @@ -1243,8 +1270,13 @@ bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) case GOD_ZIN: case GOD_SHINING_ONE: case GOD_ELYVILON: + if (!known) + { + simple_god_message(" did not appreciate that!"); + break; + } piety_change = -level; - penance = level * ((you.religion == GOD_ZIN) ? 2 : 1); + penance = level * ((you.religion == GOD_SHINING_ONE) ? 2 : 1); ret = true; break; default: @@ -1656,13 +1688,12 @@ bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) "Necromancy", "Unholy", "Attack Holy", "Attack Friend", "Friend Died", "Stab", "Poison", "Field Sacrifice", "Kill Living", "Kill Undead", "Kill Demon", "Kill Natural Evil", - "Kill Wizard", - "Kill Priest", "Kill Angel", "Undead Slave Kill Living", - "Servant Kill Living", "Servant Kill Undead", - "Servant Kill Demon", "Servant Kill Natural Evil", - "Servant Kill Angel", + "Kill Wizard", "Kill Priest", "Kill Angel", "Undead Slave Kill Living", + "Servant Kill Living", "Servant Kill Undead", "Servant Kill Demon", + "Servant Kill Natural Evil", "Servant Kill Angel", "Spell Memorise", "Spell Cast", "Spell Practise", "Spell Nonutility", - "Cards", "Stimulants", "Drink Blood", "Eat Meat", "Create Life" + "Cards", "Stimulants", "Drink Blood", "Cannibalism", "Eat Meat", + "Create Life" }; ASSERT(ARRAYSIZE(conducts) == NUM_CONDUCTS); diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h index 092de3edd0..e07975a4e1 100644 --- a/crawl-ref/source/religion.h +++ b/crawl-ref/source/religion.h @@ -27,7 +27,7 @@ int piety_breakpoint(int i); const char *god_name(god_type which_god, bool long_name = false); //mv void dec_penance(int val); void dec_penance(god_type god, int val); -bool did_god_conduct(conduct_type thing_done, int pgain, +bool did_god_conduct(conduct_type thing_done, int pgain, bool known = true, const actor *victim = NULL); void excommunication(void); void gain_piety(int pgn); diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 85063e76ec..ddf1983f16 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -1,6 +1,7 @@ /* * File: spells1.cc * Summary: Implementations of some additional spells. + * Mostly Translocations. * Written by: Linley Henzell * * Modified for Crawl Reference by $Author$ on $Date$ diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 5ea9631a95..5b1f6b5350 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -1,6 +1,7 @@ /* * File: spells2.cc * Summary: Implementations of some additional spells. + * Mostly Necromancy and Summoning. * Written by: Linley Henzell * * Modified for Crawl Reference by $Author$ on $Date$ @@ -1138,7 +1139,7 @@ char burn_freeze(int pow, char flavour) { if (mons_friendly( monster )) { - did_god_conduct( DID_ATTACK_FRIEND, 5, monster ); + did_god_conduct( DID_ATTACK_FRIEND, 5, true, monster ); } if (mons_holiness( monster ) == MH_HOLY) -- cgit v1.2.3-54-g00ecf