summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/beam.cc3
-rw-r--r--crawl-ref/source/debug.cc8
-rw-r--r--crawl-ref/source/delay.cc4
-rw-r--r--crawl-ref/source/dungeon.cc5
-rw-r--r--crawl-ref/source/effects.cc4
-rw-r--r--crawl-ref/source/fight.cc2
-rw-r--r--crawl-ref/source/mon-data.h88
-rw-r--r--crawl-ref/source/mon-util.cc101
-rw-r--r--crawl-ref/source/mon-util.h30
-rw-r--r--crawl-ref/source/monplace.cc47
-rw-r--r--crawl-ref/source/monstuff.cc14
11 files changed, 178 insertions, 128 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 0d577edc56..0e1f9e7ef0 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -1507,8 +1507,7 @@ static bool _affect_mon_in_wall(bolt &pbolt, item_def *item,
&& (grd(where) == DNGN_METAL_WALL
|| pbolt.flavour != BEAM_ELECTRICITY)))
{
- monsters *mon = &menv[mid];
- if (!mons_is_wall_shielded(mon->type))
+ if (!mons_wall_shielded(&menv[mid]))
return (true);
}
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index e38d6233d9..09e2a5e45e 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -1839,14 +1839,16 @@ void debug_stethoscope(int mon)
mons.number, mons.flags );
// Print habitat and behaviour information.
- const habitat_type hab = mons_habitat( &mons );
+ const habitat_type hab = mons_habitat(&mons);
mprf(MSGCH_DIAGNOSTICS,
"hab=%s beh=%s(%d) foe=%s(%d) mem=%d target=(%d,%d) god=%s",
- ((hab == HT_WATER) ? "water" :
+ ((hab == HT_LAND) ? "land" :
+ (hab == HT_LAND_AMPHIBIOUS) ? "land (amphibious)" :
+ (hab == HT_WATER_AMPHIBIOUS) ? "water (amphibious)" :
+ (hab == HT_WATER) ? "water" :
(hab == HT_LAVA) ? "lava" :
(hab == HT_ROCK) ? "rock" :
- (hab == HT_LAND) ? "floor"
: "unknown"),
(mons_is_sleeping(&mons) ? "sleep" :
mons_is_wandering(&mons) ? "wander" :
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index eea7f5820a..7f4d7d0612 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -1681,9 +1681,9 @@ inline static void _monster_warning(activity_interrupt_type ai,
else if (at.context.find("bursts forth") != std::string::npos)
{
text += " bursts forth from the ";
- if (mons_habitat(mon) == HT_LAVA)
+ if (mons_primary_habitat(mon) == HT_LAVA)
text += "lava";
- else if (mons_habitat(mon) == HT_WATER)
+ else if (mons_primary_habitat(mon) == HT_WATER)
text += "water";
else
text += "realm of bugdom";
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index fc35399d36..cc9f37b7bd 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -4654,10 +4654,11 @@ bool dgn_place_monster(mons_spec &mspec,
const int montype = mons_class_is_zombified(mid) ? mspec.monbase
: mid;
- const habitat_type habitat = mons_habitat_by_type(montype);
+ const habitat_type habitat = mons_class_primary_habitat(montype);
if (habitat != HT_LAND
- && (habitat != HT_WATER || !mons_class_amphibious(montype)))
+ && (habitat != HT_WATER || !mons_class_amphibious(montype))
+ && (habitat != HT_ROCK || !mons_class_wall_shielded(montype)))
{
grd(where) = habitat2grid(habitat);
}
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index 07538c1c81..1519bcdb09 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -2644,9 +2644,9 @@ static void _catchup_monster_moves(monsters *mon, int turns)
return;
// Don't move non-land or stationary monsters around.
- if (mons_habitat(mon) != HT_LAND
+ if (mons_primary_habitat(mon) != HT_LAND
|| mons_is_zombified(mon)
- && mons_habitat_by_type(mon->base_monster) != HT_LAND
+ && mons_class_primary_habitat(mon->base_monster) != HT_LAND
|| mons_is_stationary(mon))
{
return;
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 6ad428c609..6518045d02 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -554,7 +554,7 @@ bool melee_attack::attack()
// Defending monster protects itself from attacks using the
// wall it's in.
if (defender->atype() == ACT_MONSTER && grid_is_solid(def->pos())
- && mons_is_wall_shielded(def->type))
+ && mons_wall_shielded(def))
{
std::string feat_name = raw_feature_description(grd(def->pos()));
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index d4bd6d269f..175165f7bc 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -802,24 +802,24 @@ static monsterentry mondata[] = {
{
MONS_GIANT_SLUG, 'j', GREEN, "giant slug",
- M_NO_SKELETON | M_AMPHIBIOUS,
+ M_NO_SKELETON,
MR_NO_FLAGS,
700, 10, MONS_GIANT_SLUG, MONS_GIANT_SLUG, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 23}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 10, 5, 3, 0 },
0, 2, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- HT_LAND, 6, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE
+ HT_AMPHIBIOUS_LAND, 6, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE
},
{
MONS_GIANT_SNAIL, 'j', LIGHTGREEN, "giant snail",
- M_NO_SKELETON | M_AMPHIBIOUS,
+ M_NO_SKELETON,
MR_NO_FLAGS,
900, 10, MONS_GIANT_SLUG, MONS_GIANT_SNAIL, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 18}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 14, 5, 3, 0 },
7, 2, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- HT_LAND, 4, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE
+ HT_AMPHIBIOUS_LAND, 4, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE
},
// killer bees 'k'
@@ -848,13 +848,13 @@ static monsterentry mondata[] = {
// lizards 'l'
{
MONS_GIANT_NEWT, 'l', GREEN, "giant newt",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_NO_FLAGS,
150, 10, MONS_GIANT_LIZARD, MONS_GIANT_NEWT, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 3}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 1, 1, 2, 0 },
0, 15, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_TINY
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_TINY
},
{
@@ -904,13 +904,13 @@ static monsterentry mondata[] = {
{
MONS_KOMODO_DRAGON, 'l', LIGHTRED, "komodo dragon",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_NO_FLAGS,
800, 10, MONS_GIANT_LIZARD, MONS_KOMODO_DRAGON, MH_NATURAL, -3,
{ {AT_BITE, AF_DISEASE, 30}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 8, 3, 5, 0 },
7, 8, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_HISS, I_INSECT,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
},
// drakes (also 'l', but dragon type)
@@ -967,24 +967,24 @@ static monsterentry mondata[] = {
// merfolk ('m')
{
MONS_MERFOLK, 'm', LIGHTBLUE, "merfolk",
- M_WARM_BLOOD | M_AMPHIBIOUS | M_SPEAKS,
+ M_WARM_BLOOD | M_SPEAKS,
MR_RES_POISON | MR_RES_COLD,
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_NORMAL,
- HT_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM
+ HT_AMPHIBIOUS_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM
},
{
MONS_MERMAID, 'm', LIGHTCYAN, "mermaid",
- M_SPELLCASTER | M_WARM_BLOOD | M_AMPHIBIOUS | M_SPEAKS,
+ M_SPELLCASTER | M_WARM_BLOOD | M_SPEAKS,
MR_RES_POISON | MR_RES_COLD,
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_NORMAL,
- HT_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM
+ HT_AMPHIBIOUS_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM
},
// rotting monsters ('n')
@@ -1311,24 +1311,24 @@ static monsterentry mondata[] = {
// ugly things ('u')
{
MONS_UGLY_THING, 'u', BROWN, "ugly thing",
- M_WARM_BLOOD | M_AMPHIBIOUS,
+ M_WARM_BLOOD,
mrd(MR_RES_COLD, 2),
600, 10, MONS_UGLY_THING, MONS_UGLY_THING, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 12}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 8, 3, 5, 0 },
3, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_ANIMAL,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_MEDIUM
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_MEDIUM
},
{
MONS_VERY_UGLY_THING, 'u', RED, "very ugly thing",
- M_WARM_BLOOD | M_AMPHIBIOUS,
+ M_WARM_BLOOD,
mrd(MR_RES_COLD, 2),
750, 10, MONS_UGLY_THING, MONS_VERY_UGLY_THING, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 17}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 12, 3, 5, 0 },
4, 8, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_BIG, S_ROAR, I_ANIMAL,
- HT_LAND, 8, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_LARGE
+ HT_AMPHIBIOUS_LAND, 8, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_LARGE
},
// vortices ('v')
@@ -1390,13 +1390,13 @@ static monsterentry mondata[] = {
{
MONS_WATER_ELEMENTAL, '{', LIGHTBLUE, "water elemental",
- M_FLIES | M_AMPHIBIOUS,
+ M_FLIES,
MR_RES_POISON | MR_VUL_FIRE | MR_RES_ELEC,
0, 10, MONS_EARTH_ELEMENTAL, MONS_WATER_ELEMENTAL, MH_NONLIVING, MAG_IMMUNE,
{ {AT_HIT, AF_PLAIN, 25}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 6, 5, 3, 0 },
0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- HT_WATER, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG
+ HT_AMPHIBIOUS_WATER, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG
},
// worms and larvae ('w')
@@ -1793,13 +1793,13 @@ static monsterentry mondata[] = {
{
MONS_HYDRA, 'D', LIGHTGREEN, "hydra",
- M_AMPHIBIOUS | M_WARM_BLOOD, // because it likes the swamp -- bwr
+ M_WARM_BLOOD,
MR_RES_POISON,
1800, 11, MONS_HYDRA, MONS_HYDRA, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 18}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 13, 3, 5, 0 },
0, 5, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_ROAR, I_INSECT,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG
},
{
@@ -1946,46 +1946,46 @@ static monsterentry mondata[] = {
// frogs ('F')
{
MONS_GIANT_FROG, 'F', GREEN, "giant frog",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_NO_FLAGS,
500, 10, MONS_GIANT_FROG, MONS_GIANT_FROG, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 9}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 4, 3, 5, 0 },
0, 12, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL,
- HT_LAND, 15, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
+ HT_AMPHIBIOUS_LAND, 15, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
},
{
MONS_GIANT_BROWN_FROG, 'F', BROWN, "giant brown frog",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_NO_FLAGS,
890, 10, MONS_GIANT_FROG, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 14}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 8, 3, 5, 0 },
2, 11, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_CROAK, I_ANIMAL,
- HT_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
+ HT_AMPHIBIOUS_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
},
{
MONS_SPINY_FROG, 'F', YELLOW, "spiny frog",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_RES_POISON,
1000, 10, MONS_GIANT_FROG, MONS_SPINY_FROG, MH_NATURAL, -3,
{ {AT_STING, AF_POISON_MEDIUM, 26}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 7, 3, 5, 0 },
6, 9, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_CROAK, I_ANIMAL,
- HT_LAND, 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
+ HT_AMPHIBIOUS_LAND, 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
},
{
MONS_BLINK_FROG, 'F', LIGHTGREEN, "blink frog",
- M_COLD_BLOOD | M_AMPHIBIOUS | M_SPECIAL_ABILITY,
+ M_COLD_BLOOD | M_SPECIAL_ABILITY,
MR_NO_FLAGS,
800, 12, MONS_GIANT_FROG, MONS_BLINK_FROG, MH_NATURAL, -5,
{ {AT_HIT, AF_BLINK, 20}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 6, 3, 5, 0 },
3, 12, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL,
- HT_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE
+ HT_AMPHIBIOUS_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE
},
// eyes and spores ('G')
@@ -2143,24 +2143,24 @@ static monsterentry mondata[] = {
{
MONS_JELLY, 'J', LIGHTRED, "jelly",
- M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS | M_ACID_SPLASH,
+ M_SEE_INVIS | M_SPLITS | M_ACID_SPLASH,
MR_RES_POISON | MR_RES_ASPHYX | mrd(MR_RES_ACID, 3),
0, 13, MONS_JELLY, MONS_JELLY, MH_NATURAL, -3,
{ {AT_HIT, AF_ACID, 8}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 3, 5, 5, 0 },
0, 2, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- HT_LAND, 9, DEFAULT_ENERGY, MONUSE_EATS_ITEMS, SIZE_MEDIUM
+ HT_AMPHIBIOUS_LAND, 9, DEFAULT_ENERGY, MONUSE_EATS_ITEMS, SIZE_MEDIUM
},
{
MONS_SLIME_CREATURE, 'J', GREEN, "slime creature",
- M_AMPHIBIOUS,
+ M_NO_FLAGS,
MR_RES_POISON,
0, 5, MONS_SLIME_CREATURE, MONS_SLIME_CREATURE, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 22}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 11, 3, 5, 0 },
1, 4, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
},
{
@@ -2176,13 +2176,13 @@ static monsterentry mondata[] = {
{
MONS_GIANT_AMOEBA, 'J', BLUE, "giant amoeba",
- M_NO_SKELETON | M_SENSE_INVIS | M_AMPHIBIOUS,
+ M_NO_SKELETON | M_SENSE_INVIS,
MR_RES_POISON,
1000, 10, MONS_GIANT_AMOEBA, MONS_GIANT_AMOEBA, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 25}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 12, 3, 5, 0 },
0, 4, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE
},
{
@@ -2523,24 +2523,24 @@ static monsterentry mondata[] = {
{
MONS_SNAKE, 'S', LIGHTGREEN, "snake",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_NO_FLAGS,
200, 10, MONS_SNAKE, MONS_SNAKE, MH_NATURAL, -3,
{ {AT_BITE, AF_POISON, 5}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 2, 3, 5, 0 },
1, 15, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT,
- HT_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
+ HT_AMPHIBIOUS_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL
},
{
MONS_BROWN_SNAKE, 'S', BROWN, "brown snake",
- M_COLD_BLOOD | M_AMPHIBIOUS,
+ M_COLD_BLOOD,
MR_RES_POISON,
300, 10, MONS_SNAKE, MONS_BROWN_SNAKE, MH_NATURAL, -3,
{ {AT_BITE, AF_POISON_MEDIUM, 10}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
{ 4, 3, 5, 0 },
2, 15, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_INSECT,
- HT_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
+ HT_AMPHIBIOUS_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
},
{
@@ -2652,14 +2652,14 @@ static monsterentry mondata[] = {
{
MONS_POLAR_BEAR, 'U', WHITE, "polar bear",
- M_WARM_BLOOD | M_AMPHIBIOUS,
+ M_WARM_BLOOD,
MR_RES_COLD,
2500, 10, MONS_BEAR, MONS_POLAR_BEAR, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 5}, {AT_CLAW, AF_PLAIN, 5},
AT_NO_ATK },
{ 7, 5, 3, 0 },
7, 8, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG
},
{
@@ -2793,13 +2793,13 @@ static monsterentry mondata[] = {
{
MONS_TENTACLED_MONSTROSITY, 'X', GREEN, "tentacled monstrosity",
- M_SEE_INVIS | M_AMPHIBIOUS | M_EVIL,
+ M_SEE_INVIS | M_EVIL,
MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
0, 10, MONS_TENTACLED_MONSTROSITY, MONS_TENTACLED_MONSTROSITY, MH_DEMONIC, -5,
{ {AT_HIT, AF_PLAIN, 22}, {AT_HIT, AF_PLAIN, 17}, {AT_HIT, AF_PLAIN, 13} },
{ 25, 3, 5, 0 },
5, 5, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- HT_LAND, 9, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_GIANT,
+ HT_AMPHIBIOUS_LAND, 9, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_GIANT
},
{
@@ -3887,13 +3887,13 @@ static monsterentry mondata[] = {
// Antaeus is now demonic so that he'll resist torment. -- bwr
{
MONS_ANTAEUS, 'C', LIGHTCYAN, "Antaeus",
- M_FIGHTER | M_SPELLCASTER | M_EVIL | M_SPEAKS | M_UNIQUE | M_AMPHIBIOUS,
+ M_FIGHTER | M_SPELLCASTER | M_EVIL | M_SPEAKS | M_UNIQUE,
MR_RES_ELEC | MR_VUL_FIRE | mrd(MR_RES_COLD, 2),
0, 15, MONS_HILL_GIANT, MONS_ANTAEUS, MH_DEMONIC, -9,
{ {AT_HIT, AF_COLD, 75}, {AT_HIT, AF_COLD, 30}, AT_NO_ATK, AT_NO_ATK },
{ 22, 0, 0, 700 },
28, 4, MST_ANTAEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- HT_LAND, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT
+ HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT
},
{
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index e1394d70ca..16dfa071c6 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -107,6 +107,7 @@ dungeon_feature_type habitat2grid(habitat_type ht)
{
switch (ht)
{
+ case HT_AMPHIBIOUS_WATER:
case HT_WATER:
return (DNGN_DEEP_WATER);
case HT_LAVA:
@@ -114,6 +115,7 @@ dungeon_feature_type habitat2grid(habitat_type ht)
case HT_ROCK:
return (DNGN_ROCK_WALL);
case HT_LAND:
+ case HT_AMPHIBIOUS_LAND:
default:
return (DNGN_FLOOR);
}
@@ -387,11 +389,6 @@ bool mons_class_is_slowable(int mc)
return (smc->resist_magic < MAG_IMMUNE);
}
-bool mons_is_wall_shielded(int mc)
-{
- return (mons_habitat_by_type(mc) == HT_ROCK);
-}
-
bool mons_class_is_stationary(int mc)
{
return mons_class_flag(mc, M_STATIONARY);
@@ -1274,10 +1271,10 @@ flight_type mons_flies(const monsters *mon)
return (mon->ghost->fly);
}
- const int type = mons_is_zombified(mon) ? mons_zombie_base(mon)
- : mon->type;
+ const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type;
- const flight_type ret = mons_class_flies( type );
+ const flight_type ret = mons_class_flies(montype);
return (ret ? ret
: (_scan_mon_inv_randarts(mon, RAP_LEVITATE) > 0) ? FL_LEVITATE
: FL_NONE);
@@ -1285,15 +1282,27 @@ flight_type mons_flies(const monsters *mon)
bool mons_class_amphibious(int mc)
{
- return mons_class_flag(mc, M_AMPHIBIOUS);
+ habitat_type ht = mons_class_habitat(mc);
+ return (ht == HT_AMPHIBIOUS_LAND || ht == HT_AMPHIBIOUS_WATER);
}
bool mons_amphibious(const monsters *mon)
{
- const int type = mons_is_zombified(mon) ? mons_zombie_base(mon)
- : mon->type;
+ const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type;
+ return (mons_class_amphibious(montype));
+}
+
+bool mons_class_wall_shielded(int mc)
+{
+ return (mons_class_habitat(mc) == HT_ROCK);
+}
- return (mons_class_amphibious(type));
+bool mons_wall_shielded(const monsters *mon)
+{
+ const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type;
+ return (mons_class_wall_shielded(montype));
}
// This nice routine we keep in exactly the way it was.
@@ -2007,22 +2016,53 @@ mon_intel_type mons_intel(int mc)
return (smc->intel);
}
-habitat_type mons_habitat_by_type(int mc)
+habitat_type mons_class_habitat(int mc)
{
const monsterentry *me = get_monster_data(mc);
return (me ? me->habitat : HT_LAND);
}
-habitat_type mons_habitat(const monsters *m)
+habitat_type mons_habitat(const monsters *mon)
+{
+ return mons_class_habitat(mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type);
+}
+
+habitat_type mons_class_primary_habitat(int mc)
{
- return mons_habitat_by_type( mons_is_zombified(m) ? mons_zombie_base(m)
- : m->type );
+ habitat_type ht = mons_class_habitat(mc);
+ if (ht == HT_AMPHIBIOUS_LAND)
+ ht = HT_LAND;
+ else if (ht == HT_AMPHIBIOUS_WATER)
+ ht = HT_WATER;
+ return (ht);
}
-bool intelligent_ally(const monsters *monster)
+habitat_type mons_primary_habitat(const monsters *mon)
{
- return (monster->attitude == ATT_FRIENDLY
- && mons_intel(monster->type) >= I_NORMAL);
+ return mons_class_primary_habitat(mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type);
+}
+
+habitat_type mons_class_secondary_habitat(int mc)
+{
+ habitat_type ht = mons_class_habitat(mc);
+ if (ht == HT_AMPHIBIOUS_LAND)
+ ht = HT_WATER;
+ else if (ht == HT_AMPHIBIOUS_WATER || ht == HT_ROCK)
+ ht = HT_LAND;
+ return (ht);
+}
+
+habitat_type mons_secondary_habitat(const monsters *mon)
+{
+ return mons_class_secondary_habitat(mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type);
+}
+
+bool intelligent_ally(const monsters *mon)
+{
+ return (mon->attitude == ATT_FRIENDLY && mons_intel(mon->type) >= I_NORMAL);
}
int mons_power(int mc)
@@ -2984,7 +3024,7 @@ void monsters::init_with(const monsters &mon)
bool monsters::swimming() const
{
const dungeon_feature_type grid = grd(pos());
- return (grid_is_watery(grid) && mons_habitat(this) == HT_WATER);
+ return (grid_is_watery(grid) && mons_primary_habitat(this) == HT_WATER);
}
bool monsters::wants_submerge() const
@@ -3030,15 +3070,15 @@ bool monsters::floundering() const
return (grid_is_water(grid)
// Can't use monster_habitable_grid because that'll return true
// for non-water monsters in shallow water.
- && mons_habitat(this) != HT_WATER
+ && mons_primary_habitat(this) != HT_WATER
&& !mons_amphibious(this)
&& !mons_flies(this)
&& !extra_balanced());
}
-bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid)
+bool mons_class_can_pass(int mc, const dungeon_feature_type grid)
{
- if (mons_is_wall_shielded(mclass))
+ if (mons_class_wall_shielded(mc))
{
// Permanent walls can't be passed through.
return (!grid_is_solid(grid)
@@ -3048,9 +3088,16 @@ bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid)
return !grid_is_solid(grid);
}
+bool mons_can_pass(const monsters *mon, dungeon_feature_type grid)
+{
+ const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon)
+ : mon->type;
+ return mons_class_can_pass(montype, grid);
+}
+
bool monsters::can_pass_through_feat(dungeon_feature_type grid) const
{
- return mons_class_can_pass(type, grid);
+ return mons_can_pass(this, grid);
}
bool monsters::can_drown() const
@@ -6679,9 +6726,9 @@ int monsters::action_energy(energy_use_type et) const
// [ds] Amphibious monsters get a significant speed boost
// when swimming, as discussed with dpeg. We do not
// distinguish between amphibians that favour land
- // (HT_LAND, such as hydras) and those that favour water
- // (HT_WATER, such as merfolk), but that's something we
- // can think about.
+ // (HT_AMPHIBIOUS_LAND, such as hydras) and those that
+ // favour water (HT_AMPHIBIOUS_WATER, such as merfolk), but
+ // that's something we can think about.
if (mons_class_amphibious(type))
return div_rand_round(mu.swim * 7, 10);
else
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index 07c83658e5..e4f6a510b7 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -99,7 +99,7 @@ enum mons_class_flags
M_CONFUSED = (1<<10), // monster is perma-confused,
M_BATTY = (1<<11), // monster is batty
M_SPLITS = (1<<12), // monster can split
- M_AMPHIBIOUS = (1<<13), // monster can swim in water
+
M_STATIONARY = (1<<14), // monster is stationary
M_BLOOD_SCENT = (1<<15), // monster can smell blood
M_COLD_BLOOD = (1<<16), // susceptible to cold,
@@ -150,10 +150,12 @@ enum mon_intel_type // Must be in increasing intelligence order
enum habitat_type
{
// Flying monsters will appear in all categories except rock walls
- HT_LAND = 0, // Land critters
- HT_WATER, // Water critters
- HT_LAVA, // Lava critters
- HT_ROCK, // Rock critters
+ HT_LAND = 0, // Land critters
+ HT_AMPHIBIOUS_LAND, // Amphibious land-preferring critters
+ HT_AMPHIBIOUS_WATER, // Amphibious water-preferring critters
+ HT_WATER, // Water critters
+ HT_LAVA, // Lava critters
+ HT_ROCK, // Rock critters
NUM_HABITATS
};
@@ -444,6 +446,8 @@ flight_type mons_flies(const monsters *mon);
bool mons_class_amphibious(int mc);
bool mons_amphibious(const monsters *mon);
+bool mons_class_wall_shielded(int mc);
+bool mons_wall_shielded(const monsters *mon);
// last updated XXmay2000 {dlb}
/* ***********************************************************************
@@ -543,10 +547,14 @@ bool mons_is_shapeshifter(const monsters *m);
* *********************************************************************** */
mon_intel_type mons_intel(int mc);
-// Use mons_habitat(const monster *) wherever possible since the other
-// variant does not handle zombies correctly.
-habitat_type mons_habitat(const monsters *m);
-habitat_type mons_habitat_by_type(int mc);
+// Use mons_habitat() and mons_primary_habitat() wherever possible,
+// since the class variants do not handle zombies correctly.
+habitat_type mons_class_habitat(int mc);
+habitat_type mons_habitat(const monsters *mon);
+habitat_type mons_class_primary_habitat(int mc);
+habitat_type mons_primary_habitat(const monsters *mon);
+habitat_type mons_class_secondary_habitat(int mc);
+habitat_type mons_secondary_habitat(const monsters *mon);
bool intelligent_ally(const monsters *mon);
@@ -730,7 +738,6 @@ bool mons_class_is_confusable(int mc);
bool mons_class_is_slowable(int mc);
bool mons_class_is_stationary(int mc);
bool mons_is_stationary(const monsters *mon);
-bool mons_is_wall_shielded(int mc);
bool mons_is_insubstantial(int mc);
bool mons_has_blood(int mc);
bool mons_is_submerged(const monsters *m);
@@ -793,7 +800,8 @@ std::string get_mon_shape_str(const monsters *mon);
std::string get_mon_shape_str(const int type);
std::string get_mon_shape_str(const mon_body_shape shape);
-bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid);
+bool mons_class_can_pass(int mc, const dungeon_feature_type grid);
+bool mons_can_pass(const monsters *mon, dungeon_feature_type grid);
mon_inv_type equip_slot_to_mslot(equipment_type eq);
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 5070f80348..f61fab8780 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -116,10 +116,16 @@ bool monster_habitable_grid(int monster_class,
int flies, bool paralysed)
{
const dungeon_feature_type preferred_habitat =
- habitat2grid( mons_habitat_by_type(monster_class) );
+ habitat2grid(mons_class_primary_habitat(monster_class));
+ const dungeon_feature_type nonpreferred_habitat =
+ habitat2grid(mons_class_secondary_habitat(monster_class));
- if (grid_compatible(preferred_habitat, actual_grid))
+ if (grid_compatible(preferred_habitat, actual_grid)
+ || (nonpreferred_habitat != preferred_habitat
+ && grid_compatible(nonpreferred_habitat, actual_grid)))
+ {
return (true);
+ }
// [dshaligram] Flying creatures are all DNGN_FLOOR, so we
// only have to check for the additional valid grids of deep
@@ -130,24 +136,6 @@ bool monster_habitable_grid(int monster_class,
return (true);
}
- // Amphibious critters are happy in water or on land.
- if (mons_class_amphibious(monster_class)
- && (preferred_habitat == DNGN_FLOOR
- && grid_compatible(DNGN_DEEP_WATER, actual_grid)
- || preferred_habitat == DNGN_DEEP_WATER
- && grid_compatible(DNGN_FLOOR, actual_grid)))
- {
- return (true);
- }
-
- // Rock wall critters are native to walls but are happy on
- // the floor as well.
- if (preferred_habitat == DNGN_ROCK_WALL
- && grid_compatible(DNGN_FLOOR, actual_grid))
- {
- return (true);
- }
-
return (false);
}
@@ -158,11 +146,11 @@ bool monster_can_submerge(const monsters *mons, dungeon_feature_type grid)
return (!find_trap(mons->pos()));
// Zombies of watery critters can not submerge.
- switch (mons_habitat(mons))
+ switch (mons_primary_habitat(mons))
{
case HT_WATER:
// Monsters can submerge in shallow water - this is intentional.
- return grid_is_watery(grid);
+ return (grid_is_watery(grid));
case HT_LAVA:
return (grid == DNGN_LAVA);
@@ -552,8 +540,10 @@ static bool _valid_monster_location(const mgen_data &mg,
{
const int montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
: mg.cls);
- dungeon_feature_type grid_wanted =
- habitat2grid(mons_habitat_by_type(montype));
+ const dungeon_feature_type grid_preferred =
+ habitat2grid(mons_class_primary_habitat(montype));
+ const dungeon_feature_type grid_nonpreferred =
+ habitat2grid(mons_class_secondary_habitat(montype));
if (!in_bounds(mg_pos))
return (false);
@@ -563,8 +553,12 @@ static bool _valid_monster_location(const mgen_data &mg,
return (false);
// Is the monster happy where we want to put it?
- if (!grid_compatible(grid_wanted, grd(mg_pos), !force_location))
+ if (!grid_compatible(grid_preferred, grd(mg_pos), !force_location)
+ && (grid_nonpreferred == grid_preferred
+ || !grid_compatible(grid_nonpreferred, grd(mg_pos), !force_location)))
+ {
return (false);
+ }
if (mg.behaviour != BEH_FRIENDLY && is_sanctuary(mg_pos))
return (false);
@@ -1954,8 +1948,7 @@ static dungeon_feature_type _monster_habitat_feature(int mtype)
{
if (mtype == RANDOM_MONSTER)
return DNGN_FLOOR;
-
- return habitat2grid( mons_habitat_by_type(mtype) );
+ return habitat2grid(mons_class_primary_habitat(mtype));
}
class newmons_square_find : public travel_pathfind
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 53c2c9dd5c..0380716a15 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2204,7 +2204,7 @@ static bool _choose_random_patrol_target_grid(monsters *mon)
return (false);
const bool patrol_seen = mon->mon_see_grid(mon->patrol_point,
- habitat2grid(mons_habitat(mon)));
+ habitat2grid(mons_primary_habitat(mon)));
if (intel == I_PLANT && !patrol_seen)
{
@@ -2351,7 +2351,7 @@ static void _mark_neighbours_target_unreachable(monsters *mon)
const bool flies = mons_flies(mon);
const bool amphibious = mons_amphibious(mon);
- const habitat_type habit = mons_habitat(mon);
+ const habitat_type habit = mons_primary_habitat(mon);
for (radius_iterator ri(mon->pos(), 2, true, false); ri; ++ri)
{
@@ -2374,7 +2374,7 @@ static void _mark_neighbours_target_unreachable(monsters *mon)
continue;
// Monsters of differing habitats might prefer different routes.
- if (mons_habitat(m) != habit)
+ if (mons_primary_habitat(m) != habit)
continue;
// A flying monster has an advantage over a non-flying one.
@@ -2824,7 +2824,7 @@ static void _handle_behaviour(monsters *mon)
|| !mons_has_ranged_spell(mon)
&& !mons_has_ranged_attack(mon)))
{
- const habitat_type habit = mons_habitat(mon);
+ const habitat_type habit = mons_primary_habitat(mon);
if (you.lava_in_sight > 0 && habit != HT_LAVA
|| you.water_in_sight > 0 && habit != HT_WATER
&& can_move != DNGN_DEEP_WATER)
@@ -5442,7 +5442,7 @@ static void _monster_regenerate(monsters *monster)
}
// Non-land creatures out of their element cannot regenerate.
- if (mons_habitat(monster) != HT_LAND
+ if (mons_primary_habitat(monster) != HT_LAND
&& !monster_habitable_grid(monster, grd(monster->pos())))
{
return;
@@ -6649,7 +6649,7 @@ static bool _mon_can_move_to_pos(const monsters *monster,
}
const dungeon_feature_type target_grid = grd(targ);
- const habitat_type habitat = mons_habitat(monster);
+ const habitat_type habitat = mons_primary_habitat(monster);
// Effectively slows down monster movement across water.
// Fire elementals can't cross at all.
@@ -6846,7 +6846,7 @@ static bool _monster_move(monsters *monster)
FixedArray < bool, 3, 3 > good_move;
int count_x, count_y, count;
- const habitat_type habitat = mons_habitat(monster);
+ const habitat_type habitat = mons_primary_habitat(monster);
bool deep_water_available = false;
if (monster->type == MONS_TRAPDOOR_SPIDER)