From 0fb28d6c1b82e6c10e00c4cc9b946eb010d65017 Mon Sep 17 00:00:00 2001 From: dolorous Date: Mon, 6 Oct 2008 02:51:44 +0000 Subject: Expand handling of monster intelligence and zombifiability to work on the level of individual monsters. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7148 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 2 +- crawl-ref/source/delay.cc | 4 ++-- crawl-ref/source/describe.cc | 2 +- crawl-ref/source/food.cc | 16 ++++++++-------- crawl-ref/source/itemname.cc | 2 +- crawl-ref/source/mgrow.cc | 2 +- crawl-ref/source/mon-util.cc | 29 +++++++++++++++++++++-------- crawl-ref/source/mon-util.h | 6 +++++- crawl-ref/source/monplace.cc | 2 +- crawl-ref/source/monspeak.cc | 4 ++-- crawl-ref/source/monstuff.cc | 32 ++++++++++++++++---------------- crawl-ref/source/mstuff2.cc | 2 +- crawl-ref/source/spells1.cc | 4 ++-- crawl-ref/source/spells2.cc | 6 +++--- crawl-ref/source/spells3.cc | 2 +- crawl-ref/source/spells4.cc | 2 +- crawl-ref/source/traps.cc | 2 +- crawl-ref/source/view.cc | 2 +- 18 files changed, 69 insertions(+), 52 deletions(-) diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 8ede85386e..539e532440 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -2603,7 +2603,7 @@ void fire_tracer(const monsters *monster, bolt &pbolt, bool explode_only) pbolt.source = monster->pos(); pbolt.beam_source = monster_index(monster); pbolt.can_see_invis = mons_see_invis(monster); - pbolt.smart_monster = (mons_intel(monster->type) >= I_NORMAL); + pbolt.smart_monster = (mons_intel(monster) >= I_NORMAL); pbolt.attitude = mons_attitude(monster); // Init tracer variables. diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index 7f4d7d0612..45ec98497d 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -62,7 +62,7 @@ static bool _recite_mons_useless(const monsters *mon) { const mon_holy_type holiness = mons_holiness(mon); - return (mons_intel(mon->type) < I_NORMAL + return (mons_intel(mon) < I_NORMAL || holiness != MH_HOLY && holiness != MH_NATURAL && holiness != MH_UNDEAD @@ -1110,7 +1110,7 @@ static void _finish_delay(const delay_queue_item &delay) "relatives."); } else if (you.religion == GOD_ZIN - && mons_intel(item.plus) >= I_NORMAL) + && mons_class_intel(item.plus) >= I_NORMAL) { simple_god_message(" expects more respect for this departed " "soul."); diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index d0ad01ac01..9fb205ab45 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1831,7 +1831,7 @@ std::string get_item_description( const item_def &item, bool verbose, if (is_good_god(you.religion) && is_player_same_species(item.plus) || you.religion == GOD_ZIN - && mons_intel(item.plus) >= I_NORMAL) + && mons_class_intel(item.plus) >= I_NORMAL) { description << "$$" << god_name(you.religion) << " disapproves " "of eating such meat."; diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc index aec2c1f25b..8a73d1aa84 100644 --- a/crawl-ref/source/food.cc +++ b/crawl-ref/source/food.cc @@ -53,7 +53,7 @@ #include "xom.h" static int _determine_chunk_effect(int which_chunk_type, bool rotten_chunk); -static void _eat_chunk( int chunk_effect, bool cannibal, int mon_intel = 0); +static void _eat_chunk(int chunk_effect, bool cannibal, int mon_intel = 0); 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); @@ -1100,8 +1100,8 @@ void eat_from_inventory(int which_inventory_slot) { const int mons_type = food.plus; const bool cannibal = is_player_same_species(mons_type); - const int intel = mons_intel(mons_type) - I_ANIMAL; - const int chunk_type = mons_corpse_effect( mons_type ); + const int intel = mons_class_intel(mons_type) - I_ANIMAL; + const int chunk_type = mons_corpse_effect(mons_type); const bool rotten = food_is_rotten(food); if (rotten && !_player_can_eat_rotten_meat(true)) @@ -1131,16 +1131,16 @@ void eat_floor_item(int item_link) } else if (food.sub_type == FOOD_CHUNK) { - const int chunk_type = mons_corpse_effect( food.plus ); - const int intel = mons_intel( food.plus ) - I_ANIMAL; - const bool cannibal = is_player_same_species( food.plus ); + const int chunk_type = mons_corpse_effect(food.plus); + const int intel = mons_class_intel(food.plus) - I_ANIMAL; + const bool cannibal = is_player_same_species(food.plus); const bool rotten = food_is_rotten(food); if (rotten && !_player_can_eat_rotten_meat(true)) return; _eat_chunk(_determine_chunk_effect(chunk_type, rotten), cannibal, - intel); + intel); } else _eating( food.base_type, food.sub_type ); @@ -1352,7 +1352,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, bool cannibal, int mon_intel ) +static void _eat_chunk(int chunk_effect, bool cannibal, int mon_intel) { bool likes_chunks = (you.omnivorous() || diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 13900e0556..a43573dc27 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -2594,7 +2594,7 @@ const std::string menu_colour_item_prefix(const item_def &item, bool temp) if ((item.base_type == OBJ_CORPSES || item.sub_type == FOOD_CHUNK) && (is_good_god(you.religion) && is_player_same_species(item.plus) || you.religion == GOD_ZIN - && mons_intel(item.plus) >= I_NORMAL)) + && mons_class_intel(item.plus) >= I_NORMAL)) { prefixes.push_back("evil_eating"); } diff --git a/crawl-ref/source/mgrow.cc b/crawl-ref/source/mgrow.cc index 40025ee814..d7f275d219 100644 --- a/crawl-ref/source/mgrow.cc +++ b/crawl-ref/source/mgrow.cc @@ -218,7 +218,7 @@ bool monsters::gain_exp(int exp) if (levels_gained) { - if (mons_intel(type) >= I_NORMAL) + if (mons_intel(this) >= I_NORMAL) simple_monster_message(&mcopy, " looks more experienced."); else simple_monster_message(&mcopy, " looks stronger."); diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 16dfa071c6..7855bbf11e 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -789,9 +789,19 @@ bool mons_class_is_zombified(int mc) || mc == MONS_SPECTRAL_THING); } -bool mons_is_zombified(const monsters *monster) +bool mons_is_zombified(const monsters *mon) { - return mons_class_is_zombified(monster->type); + return mons_class_is_zombified(mon->type); +} + +bool mons_class_can_be_zombified(int mc) +{ + return (mons_zombie_size(mc) == Z_NOZOMBIE); +} + +bool mons_can_be_zombified(const monsters *mon) +{ + return (mons_class_can_be_zombified(mon->type)); } int downscale_zombie_damage(int damage) @@ -1243,7 +1253,7 @@ bool mons_has_lifeforce(const monsters *mon) bool mons_skeleton(int mc) { - if (mons_zombie_size(mc) == Z_NOZOMBIE + if (!mons_class_can_be_zombified(mc) || mons_weight(mc) == 0 || (mons_class_flag(mc, M_NO_SKELETON))) { return (false); @@ -2002,20 +2012,23 @@ static int _mons_exp_mod(int mc) return (smc->exp_mod); } - int mons_speed(int mc) { ASSERT(smc); return (smc->speed); } - -mon_intel_type mons_intel(int mc) +mon_intel_type mons_class_intel(int mc) { ASSERT(smc); return (smc->intel); } +mon_intel_type mons_intel(const monsters *mon) +{ + return (mons_class_intel(mon->type)); +} + habitat_type mons_class_habitat(int mc) { const monsterentry *me = get_monster_data(mc); @@ -2062,7 +2075,7 @@ habitat_type mons_secondary_habitat(const monsters *mon) bool intelligent_ally(const monsters *mon) { - return (mon->attitude == ATT_FRIENDLY && mons_intel(mon->type) >= I_NORMAL); + return (mon->attitude == ATT_FRIENDLY && mons_intel(mon) >= I_NORMAL); } int mons_power(int mc) @@ -2611,7 +2624,7 @@ bool ms_waste_of_time( const monsters *mon, spell_type monspell ) return (false); // Only intelligent monsters estimate. - intel = mons_intel( mon->type ); + intel = mons_intel(mon); if (intel != I_NORMAL && intel != I_HIGH) return (false); diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index e4f6a510b7..9fcc37aca8 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -545,7 +545,8 @@ bool mons_is_shapeshifter(const monsters *m); /* *********************************************************************** * called from: monstuff - spells4 - view * *********************************************************************** */ -mon_intel_type mons_intel(int mc); +mon_intel_type mons_class_intel(int mc); +mon_intel_type mons_intel(const monsters *mon); // Use mons_habitat() and mons_primary_habitat() wherever possible, // since the class variants do not handle zombies correctly. @@ -600,6 +601,9 @@ int mons_zombie_size(int mc); monster_type mons_zombie_base(const monsters *monster); bool mons_class_is_zombified(int mc); bool mons_is_zombified(const monsters *monster); +bool mons_class_can_be_zombified(int mc); +bool mons_can_be_zombified(const monsters *mon); + // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 5f780f9bad..8c37ee2931 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -2665,7 +2665,7 @@ bool monster_pathfind::traversable(coord_def p) // Your friends only know about doors you know about, unless they feel // at home in this branch. if (grd(p) == DNGN_SECRET_DOOR && mons_friendly(mons) - && (mons_intel(mons->type) < I_NORMAL + && (mons_intel(mons) < I_NORMAL || !mons_is_native_in_branch(mons))) { return (false); diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc index a25720569b..71bf3fef1e 100644 --- a/crawl-ref/source/monspeak.cc +++ b/crawl-ref/source/monspeak.cc @@ -267,7 +267,7 @@ bool mons_speaks(const monsters *monster) // animals only look at the current player form, // smart monsters at the actual player genus if (is_player_same_species(monster->type, - mons_intel(monster->type) <= I_ANIMAL)) + mons_intel(monster) <= I_ANIMAL)) { prefixes.push_back("related"); // maybe overkill for Beogh? } @@ -373,7 +373,7 @@ bool mons_speaks(const monsters *monster) // include info on if the monster's intelligence is at odds with // its shape. mon_body_shape shape = get_mon_shape(monster); - mon_intel_type intel = mons_intel(monster->type); + mon_intel_type intel = mons_intel(monster); if (shape >= MON_SHAPE_HUMANOID && shape <= MON_SHAPE_NAGA && intel < I_NORMAL) { diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 0380716a15..475b1fc68f 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -2010,7 +2010,7 @@ void behaviour_event(monsters *mon, int event, int src, { beh_type old_behaviour = mon->behaviour; - bool isSmart = (mons_intel(mon->type) > I_ANIMAL); + bool isSmart = (mons_intel(mon) > I_ANIMAL); bool wontAttack = mons_wont_attack(mon); bool sourceWontAttack = false; bool setTarget = false; @@ -2189,7 +2189,7 @@ void behaviour_event(monsters *mon, int event, int src, static bool _choose_random_patrol_target_grid(monsters *mon) { - const int intel = mons_intel(mon->type); + const int intel = mons_intel(mon); // Zombies will occasionally just stand around. // This does not mean that they don't move every second turn. Rather, @@ -2345,7 +2345,7 @@ static void _mark_neighbours_target_unreachable(monsters *mon) { // Highly intelligent monsters are perfectly capable of pathfinding // and don't need their neighbour's advice. - const mon_intel_type intel = mons_intel(mon->type); + const mon_intel_type intel = mons_intel(mon); if (intel > I_NORMAL) return; @@ -2370,7 +2370,7 @@ static void _mark_neighbours_target_unreachable(monsters *mon) // Don't restrict smarter monsters as they might find a path // a dumber monster wouldn't. - if (mons_intel(m->type) > intel) + if (mons_intel(m) > intel) continue; // Monsters of differing habitats might prefer different routes. @@ -2517,7 +2517,7 @@ static void _handle_behaviour(monsters *mon) bool proxFoe; bool isHurt = (mon->hit_points <= mon->max_hit_points / 4 - 1); bool isHealthy = (mon->hit_points > mon->max_hit_points / 2); - bool isSmart = (mons_intel(mon->type) > I_ANIMAL); + bool isSmart = (mons_intel(mon) > I_ANIMAL); bool isScared = mon->has_ench(ENCH_FEAR); bool isMobile = !mons_is_stationary(mon); bool isPacified = mons_is_pacified(mon); @@ -2551,7 +2551,7 @@ static void _handle_behaviour(monsters *mon) else if (!see_grid(mon->pos())) proxPlayer = false; - const int intel = mons_intel(mon->type); + const int intel = mons_intel(mon); // Now, the corollary to that is that sometimes, if a // player is right next to a monster, they will 'see'. if (grid_distance( you.pos(), mon->pos() ) == 1 @@ -2585,7 +2585,7 @@ static void _handle_behaviour(monsters *mon) { // Intelligent monsters prefer to attack the player, // even when berserking. - if (!isFriendly && proxPlayer && mons_intel(mon->type) >= I_NORMAL) + if (!isFriendly && proxPlayer && mons_intel(mon) >= I_NORMAL) mon->foe = MHITYOU; else _set_nearest_monster_foe(mon); @@ -2751,7 +2751,7 @@ static void _handle_behaviour(monsters *mon) // Hack: smarter monsters will tend to pursue the player longer. int memory = 0; - switch (mons_intel(monster_index(mon))) + switch (mons_intel(mon)) { case I_HIGH: memory = 100 + random2(200); @@ -2802,7 +2802,7 @@ static void _handle_behaviour(monsters *mon) // Smart monsters that can fire through walls won't use // pathfinding, and it's also not necessary if the monster // is already adjacent to you. - if (potentially_blocking && mons_intel(mon->type) >= I_NORMAL + if (potentially_blocking && mons_intel(mon) >= I_NORMAL && mons_has_los_ability(mon->type) || grid_distance(mon->pos(), you.pos()) == 1) { @@ -2820,7 +2820,7 @@ static void _handle_behaviour(monsters *mon) // across the blocking terrain, and is smart enough to // realize that. if (!potentially_blocking && !mons_flies(mon) - && (mons_intel(mon->type) < I_NORMAL + && (mons_intel(mon) < I_NORMAL || !mons_has_ranged_spell(mon) && !mons_has_ranged_attack(mon))) { @@ -2893,7 +2893,7 @@ static void _handle_behaviour(monsters *mon) const bool native = mons_is_native_in_branch(mon); int range = 0; - switch (mons_intel(mon->type)) + switch (mons_intel(mon)) { case I_PLANT: range = 2; @@ -3212,7 +3212,7 @@ static void _handle_behaviour(monsters *mon) // * forget about patrolling // * head back to patrol point - if (mons_intel(mon->type) == I_PLANT) + if (mons_intel(mon) == I_PLANT) { // Really stupid monsters forget where they're // supposed to be. @@ -6467,7 +6467,7 @@ static int _estimated_trap_damage(trap_type trap) static bool _is_trap_safe(const monsters *monster, const coord_def& where, bool just_check) { - const int intel = mons_intel(monster->type); + const int intel = mons_intel(monster); // Dumb monsters don't care at all. if (intel == I_PLANT) @@ -6817,7 +6817,7 @@ static bool _mon_can_move_to_pos(const monsters *monster, case CLOUD_GREY_SMOKE: // This isn't harmful, but dumb critters might think so. - if (mons_intel(monster->type) > I_ANIMAL || coinflip()) + if (mons_intel(monster) > I_ANIMAL || coinflip()) return (true); if (mons_res_fire(monster) > 0) @@ -6833,7 +6833,7 @@ static bool _mon_can_move_to_pos(const monsters *monster, // If we get here, the cloud is potentially harmful. // Exceedingly dumb creatures will still wander in. - if (mons_intel(monster->type) != I_PLANT) + if (mons_intel(monster) != I_PLANT) return (false); } @@ -6946,7 +6946,7 @@ static bool _monster_move(monsters *monster) // (they _live_ in the dungeon!) if (grd(newpos) == DNGN_CLOSED_DOOR || grd(newpos) == DNGN_SECRET_DOOR - && mons_intel(monster_index(monster)) >= I_NORMAL) + && mons_intel(monster) >= I_NORMAL) { if (mons_is_zombified(monster)) { diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 7d827de14c..caf554bdfd 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -1062,7 +1062,7 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) } // monster intelligence bonus - if (mons_intel(monster->type) == I_HIGH) + if (mons_intel(monster) == I_HIGH) exHitBonus += 10; // Now, if a monster is, for some reason, throwing something really diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 4666e8f176..56a49cff5c 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -652,7 +652,7 @@ static bool _can_pacify_monster(const monsters *mon, const int healed) // I was thinking of jellies when I wrote this, but maybe we shouldn't // exclude zombies and such... (jpeg) - if (mons_intel(mon->type) <= I_PLANT) // no self-awareness + if (mons_intel(mon) <= I_PLANT) // no self-awareness return (false); const mon_holy_type holiness = mons_holiness(mon); @@ -671,7 +671,7 @@ static bool _can_pacify_monster(const monsters *mon, const int healed) if (mons_is_sleeping(mon)) // not aware of what is happening return (false); - const int factor = (mons_intel(mon->type) <= I_ANIMAL) ? 3 : // animals + const int factor = (mons_intel(mon) <= I_ANIMAL) ? 3 : // animals (is_player_same_species(mon->type)) ? 2 // same species : 1; // other diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index d14b52057c..9935e216f8 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -211,10 +211,10 @@ int detect_creatures( int pow, bool telepathic ) // Assuming that highly intelligent spellcasters can // detect scrying. -- bwr - if (mons_intel( mon->type ) == I_HIGH - && mons_class_flag( mon->type, M_SPELLCASTER )) + if (mons_intel(mon) == I_HIGH + && mons_class_flag(mon->type, M_SPELLCASTER)) { - behaviour_event( mon, ME_DISTURB, MHITYOU, you.pos() ); + behaviour_event(mon, ME_DISTURB, MHITYOU, you.pos()); } } } diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index a968f7de85..5535607f41 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -633,7 +633,7 @@ bool cast_summon_horrible_things(int pow, god_type god) static bool _is_animatable_corpse(const item_def& item) { return (item.base_type == OBJ_CORPSES - && mons_zombie_size(item.plus) != Z_NOZOMBIE); + && mons_class_can_be_zombified(item.plus)); } // Try to equip the zombie/skeleton with the objects it died with. diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 10fc85342c..24e3f8edf5 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -1169,7 +1169,7 @@ static int _intoxicate_monsters(coord_def where, int pow, int garbage) int mon = mgrd(where); if (mon == NON_MONSTER - || mons_intel(menv[mon].type) < I_NORMAL + || mons_intel(&menv[mon]) < I_NORMAL || mons_holiness(&menv[mon]) != MH_NATURAL || mons_res_poison(&menv[mon]) > 0) { diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc index a66b9fb40f..c162ed6e3a 100644 --- a/crawl-ref/source/traps.cc +++ b/crawl-ref/source/traps.cc @@ -150,7 +150,7 @@ bool trap_def::is_known(const actor* act) const { const monsters* monster = static_cast(act); const bool mechanical = (this->category() == DNGN_TRAP_MECHANICAL); - const int intel = mons_intel(monster->type); + const int intel = mons_intel(monster); // Smarter trap handling for intelligent monsters // * monsters native to a branch can be assumed to know the trap diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index fe4c69b8c3..8c2dc69d5c 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1307,7 +1307,7 @@ bool check_awaken(monsters* monster) return (true); // I assume that creatures who can sense invisible are very perceptive. - mons_perc = 10 + (mons_intel(monster->type) * 4) + monster->hit_dice + mons_perc = 10 + (mons_intel(monster) * 4) + monster->hit_dice + mons_sense_invis(monster) * 5; bool unnatural_stealthy = false; // "stealthy" only because of invisibility? -- cgit v1.2.3-54-g00ecf