summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/mon-util.cc')
-rw-r--r--crawl-ref/source/mon-util.cc162
1 files changed, 125 insertions, 37 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index b0733fe0c9..7dc536835a 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -31,6 +31,7 @@
#include "debug.h"
#include "itemname.h"
#include "itemprop.h"
+#include "misc.h"
#include "monplace.h"
#include "mstuff2.h"
#include "player.h"
@@ -635,7 +636,6 @@ bool check_mons_resist_magic( const monsters *monster, int pow )
return ((mrch2 < mrchance) ? true : false);
} // end check_mons_resist_magic()
-
int mons_res_elec( const monsters *mon )
{
int mc = mon->type;
@@ -712,7 +712,6 @@ int mons_res_poison( const monsters *mon )
return (u);
} // end mons_res_poison()
-
int mons_res_fire( const monsters *mon )
{
int mc = mon->type;
@@ -1642,47 +1641,14 @@ int mons_offhand_weapon_index(const monsters *m)
return (m->inv[1]);
}
-int mons_weapon_index(const monsters *m)
-{
- // This randomly picks one of the wielded weapons for monsters that can use
- // two weapons. Not ideal, but better than nothing. fight.cc does it right,
- // for various values of right.
- int weap = m->inv[MSLOT_WEAPON];
-
- if (mons_wields_two_weapons(m))
- {
- const int offhand = mons_offhand_weapon_index(m);
- if (offhand != NON_ITEM && (weap == NON_ITEM || coinflip()))
- weap = offhand;
- }
-
- return (weap);
-}
-
int mons_base_damage_type(const monsters *m)
{
return (mons_class_flag(m->type, M_CLAWS)? DVORP_CLAWING : DVORP_CRUSHING);
}
-int mons_damage_type(const monsters *m)
+int mons_size(const monsters *m)
{
- const int mweap = mons_weapon_index(m);
-
- if (mweap == NON_ITEM)
- return (mons_base_damage_type(m));
-
- return (get_vorpal_type(mitm[mweap]));
-}
-
-int mons_damage_brand(const monsters *m)
-{
- const int mweap = mons_weapon_index(m);
-
- if (mweap == NON_ITEM)
- return (SPWPN_NORMAL);
-
- const item_def &weap = mitm[mweap];
- return (!is_range_weapon(weap)? get_weapon_brand(weap) : SPWPN_NORMAL);
+ return m->body_size();
}
bool mons_friendly(const monsters *m)
@@ -2500,3 +2466,125 @@ bool monster_senior(const monsters *m1, const monsters *m2)
return (mchar1 == mchar2 && m1->hit_dice > m2->hit_dice);
}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// monsters methods
+
+coord_def monsters::pos() const
+{
+ return coord_def(x, y);
+}
+
+bool monsters::swimming() const
+{
+ const int grid = grd[x][y];
+ return (grid_is_watery(grid) && monster_habitat(type) == DNGN_DEEP_WATER);
+}
+
+bool monsters::floundering() const
+{
+ const int grid = grd[x][y];
+ return (grid_is_water(grid)
+ // Can't use monster_habitable_grid because that'll return true
+ // for non-water monsters in shallow water.
+ && monster_habitat(type) != DNGN_DEEP_WATER
+ && !mons_class_flag(type, M_AMPHIBIOUS)
+ && !mons_flies(this));
+}
+
+size_type monsters::body_size(int /* psize */, bool /* base */) const
+{
+ const monsterentry *e = seekmonster(type);
+ return (e? e->size : SIZE_MEDIUM);
+}
+
+int monsters::damage_type(int which_attack)
+{
+ const item_def *mweap = weapon(which_attack);
+
+ if (!mweap)
+ return (mons_base_damage_type(this));
+
+ return (get_vorpal_type(*mweap));
+}
+
+int monsters::damage_brand(int which_attack)
+{
+ const item_def *mweap = weapon(which_attack);
+
+ if (!mweap)
+ return (SPWPN_NORMAL);
+
+ return (!is_range_weapon(*mweap)? get_weapon_brand(*mweap) : SPWPN_NORMAL);
+}
+
+item_def *monsters::weapon(int which_attack)
+{
+ if (which_attack > 1)
+ which_attack &= 1;
+
+ // This randomly picks one of the wielded weapons for monsters that can use
+ // two weapons. Not ideal, but better than nothing. fight.cc does it right,
+ // for various values of right.
+ int weap = inv[MSLOT_WEAPON];
+
+ if (which_attack && mons_wields_two_weapons(this))
+ {
+ const int offhand = mons_offhand_weapon_index(this);
+ if (offhand != NON_ITEM
+ && (weap == NON_ITEM || which_attack == 1 || coinflip()))
+ {
+ weap = offhand;
+ }
+ }
+
+ return (weap == NON_ITEM? NULL : &mitm[weap]);
+}
+
+item_def *monsters::shield()
+{
+ return (NULL);
+}
+
+std::string monsters::name(description_level_type desc) const
+{
+ return (ptr_monam(this, desc));
+}
+
+std::string monsters::conj_verb(const std::string &verb) const
+{
+ return (verb + "s");
+}
+
+int monsters::id() const
+{
+ return (type);
+}
+
+bool monsters::fumbles_attack(bool verbose)
+{
+ if (floundering() && one_chance_in(4))
+ {
+ if (verbose && !silenced(you.x_pos, you.y_pos)
+ && !silenced(x, y))
+ {
+ mprf(MSGCH_SOUND, "You hear a splashing noise.");
+ }
+ }
+ return (false);
+}
+
+bool monsters::cannot_fight() const
+{
+ return mons_class_flag(type, M_NO_EXP_GAIN)
+ || mons_is_statue(type);
+}
+
+void monsters::attacking(actor * /* other */)
+{
+}
+
+void monsters::go_berserk(bool /* intentional */)
+{
+}