diff options
author | Shmuale Mark <shm.mark@gmail.com> | 2014-06-19 16:05:04 -0400 |
---|---|---|
committer | Shmuale Mark <shm.mark@gmail.com> | 2014-06-22 10:03:45 -0400 |
commit | 465957cba490a2a9d5444a64523572a90cfb837f (patch) | |
tree | 536c94ce0702e60217120aa2bb27325aff1b8f2d /crawl-ref/source/mon-util.cc | |
parent | 393eda0d444702a7eda580e6c363bbdcaba8d54e (diff) | |
download | crawl-ref-465957cba490a2a9d5444a64523572a90cfb837f.tar.gz crawl-ref-465957cba490a2a9d5444a64523572a90cfb837f.zip |
The great mon-stuff migration.
A good deal of functions move to the two new files, mon-poly and
mon-message. Of the others, some go to where they are used, some to
mon-util, and a few are made member methods of monster.
This probably breaks Xcode compilation, and I'm not able to test
the changes I made to MSVC that will (hopefully) keep it working.
Diffstat (limited to 'crawl-ref/source/mon-util.cc')
-rw-r--r-- | crawl-ref/source/mon-util.cc | 178 |
1 files changed, 129 insertions, 49 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index cdded8861d..8b6cfd753f 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -12,6 +12,7 @@ #include "act-iter.h" #include "areas.h" #include "artefact.h" +#include "attitude-change.h" #include "beam.h" #include "colour.h" #include "coordit.h" @@ -39,7 +40,7 @@ #include "mon-chimera.h" #include "mon-death.h" #include "mon-place.h" -#include "mon-stuff.h" +#include "mon-poly.h" #include "notes.h" #include "options.h" #include "random.h" @@ -315,33 +316,6 @@ void init_monster_symbols() monster_symbols[i].glyph = mons_base_char(i); } -static bool _get_tentacle_head(const monster*& mon) -{ - // For tentacle segments, find the associated tentacle. - if (mon->is_child_tentacle_segment()) - { - if (invalid_monster_index(mon->number)) - return false; - if (invalid_monster(&menv[mon->number])) - return false; - - mon = &menv[mon->number]; - } - - // For tentacles, find the associated head. - if (mon->is_child_tentacle()) - { - if (invalid_monster_index(mon->number)) - return false; - if (invalid_monster(&menv[mon->number])) - return false; - - mon = &menv[mon->number]; - } - - return true; -} - void set_resist(resists_t &all, mon_resist_flags res, int lev) { if (res > MR_LAST_MULTI) @@ -366,7 +340,7 @@ resists_t get_mons_class_resists(monster_type mc) resists_t get_mons_resists(const monster* mon) { - _get_tentacle_head(mon); + get_tentacle_head(mon); resists_t resists = get_mons_class_resists(mon->type); @@ -1440,36 +1414,46 @@ bool mons_class_can_regenerate(monster_type mc) return !mons_class_flag(mc, M_NO_REGEN); } -bool mons_can_regenerate(const monster* mon) +bool get_tentacle_head(const monster*& mon) { - _get_tentacle_head(mon); + // For tentacle segments, find the associated tentacle. + if (mon->is_child_tentacle_segment()) + { + if (invalid_monster_index(mon->number)) + return false; + if (invalid_monster(&menv[mon->number])) + return false; - if (testbits(mon->flags, MF_NO_REGEN)) - return false; + mon = &menv[mon->number]; + } - return mons_class_can_regenerate(mon->type); -} + // For tentacles, find the associated head. + if (mon->is_child_tentacle()) + { + if (invalid_monster_index(mon->number)) + return false; + if (invalid_monster(&menv[mon->number])) + return false; -bool mons_class_fast_regen(monster_type mc) -{ - return mons_class_flag(mc, M_FAST_REGEN); + mon = &menv[mon->number]; + } + + return true; } -bool mons_class_can_display_wounds(monster_type mc) +bool mons_can_regenerate(const monster* mon) { - // Zombified monsters other than spectral things don't show - // wounds. - if (mons_class_is_zombified(mc) && mc != MONS_SPECTRAL_THING) + get_tentacle_head(mon); + + if (testbits(mon->flags, MF_NO_REGEN)) return false; - return true; + return mons_class_can_regenerate(mon->type); } -bool mons_can_display_wounds(const monster* mon) +bool mons_class_fast_regen(monster_type mc) { - _get_tentacle_head(mon); - - return mons_class_can_display_wounds(mon->type); + return mons_class_flag(mc, M_FAST_REGEN); } bool mons_class_leaves_hide(monster_type mc) @@ -1702,7 +1686,7 @@ mon_attack_def mons_attack_spec(const monster* mon, int attk_number, bool base_f { monster_type mc = mon->type; - _get_tentacle_head(mon); + get_tentacle_head(mon); const bool zombified = mons_is_zombified(mon); @@ -2910,7 +2894,7 @@ mon_intel_type mons_class_intel(monster_type mc) mon_intel_type mons_intel(const monster* mon) { - _get_tentacle_head(mon); + get_tentacle_head(mon); if (mons_enslaved_soul(mon)) return mons_class_intel(mons_zombie_base(mon)); @@ -4838,6 +4822,34 @@ vector<monster* > get_on_level_followers() return mon_list; } +// Return the number of monsters of the specified type. +// If friendly_only is true, only count friendly +// monsters, otherwise all of them +int count_monsters(monster_type mtyp, bool friendly_only) +{ + int count = 0; + for (int mon = 0; mon < MAX_MONSTERS; mon++) + { + monster *mons = &menv[mon]; + if (mons->alive() && mons->type == mtyp + && (!friendly_only || mons->friendly())) + { + count++; + } + } + return count; +} + +int count_allies() +{ + int count = 0; + for (int mon = 0; mon < MAX_MONSTERS; mon++) + if (menv[mon].alive() && menv[mon].friendly()) + count++; + + return count; +} + bool mons_stores_tracking_data(const monster* mons) { return mons->type == MONS_THORN_HUNTER @@ -4884,3 +4896,71 @@ bool mons_antimagic_affected(const monster* mons) && !mons->is_priest() && !mons_class_flag(mons->type, M_FAKE_SPELLS); } + +// The default suitable() function for choose_random_nearby_monster(). +bool choose_any_monster(const monster* mon) +{ + return !mons_is_projectile(mon->type); +} + +// Find a nearby monster and return its index, including you as a +// possibility with probability weight. suitable() should return true +// for the type of monster wanted. +// If prefer_named is true, named monsters (including uniques) are twice +// as likely to get chosen compared to non-named ones. +// If prefer_priest is true, priestly monsters (including uniques) are +// twice as likely to get chosen compared to non-priestly ones. +monster* choose_random_nearby_monster(int weight, + bool (*suitable)(const monster* mon), + bool prefer_named_or_priest) +{ + monster* chosen = NULL; + for (radius_iterator ri(you.pos(), LOS_NO_TRANS); ri; ++ri) + { + monster* mon = monster_at(*ri); + if (!mon || !suitable(mon)) + continue; + + // FIXME: if the intent is to favour monsters + // named by $DEITY, we should set a flag on the + // monster (something like MF_DEITY_PREFERRED) and + // use that instead of checking the name, given + // that other monsters can also have names. + + // True, but it's currently only used for orcs, and + // Blork and Urug also being preferred to non-named orcs + // is fine, I think. Once more gods name followers (and + // prefer them) that should be changed, of course. (jpeg) + int mon_weight = 1; + + if (prefer_named_or_priest) + mon_weight += mon->is_named() + mon->is_priest(); + + if (x_chance_in_y(mon_weight, weight += mon_weight)) + chosen = mon; + } + + return chosen; +} + +monster* choose_random_monster_on_level(int weight, + bool (*suitable)(const monster* mon)) +{ + monster* chosen = NULL; + + for (rectangle_iterator ri(1); ri; ++ri) + { + monster* mon = monster_at(*ri); + if (!mon || !suitable(mon)) + continue; + + // Named or priestly monsters have doubled chances. + int mon_weight = 1 + + mon->is_named() + mon->is_priest(); + + if (x_chance_in_y(mon_weight, weight += mon_weight)) + chosen = mon; + } + + return chosen; +} |