summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-util.cc
diff options
context:
space:
mode:
authorShmuale Mark <shm.mark@gmail.com>2014-06-19 16:05:04 -0400
committerShmuale Mark <shm.mark@gmail.com>2014-06-22 10:03:45 -0400
commit465957cba490a2a9d5444a64523572a90cfb837f (patch)
tree536c94ce0702e60217120aa2bb27325aff1b8f2d /crawl-ref/source/mon-util.cc
parent393eda0d444702a7eda580e6c363bbdcaba8d54e (diff)
downloadcrawl-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.cc178
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;
+}