summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/monstuff.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r--crawl-ref/source/monstuff.cc123
1 files changed, 40 insertions, 83 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 92bf884a85..d306f3a745 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -909,30 +909,8 @@ static bool valid_morph( struct monsters *monster, int new_mclass )
return (false);
}
- /* Not fair to instakill a monster like this --
- order of evaluation of inner conditional important */
- if (current_tile == DNGN_LAVA || current_tile == DNGN_DEEP_WATER)
- {
- if (!mons_class_flies(new_mclass)
- || monster_habitat(new_mclass) != current_tile)
- {
- return (false);
- }
- }
-
- // not fair to strand a water monster on dry land, either. :)
- if (monster_habitat(new_mclass) == DNGN_DEEP_WATER
- && current_tile != DNGN_DEEP_WATER
- && current_tile != DNGN_SHALLOW_WATER)
- {
- return (false);
- }
-
- // and putting lava monsters on non-lava sqaures is a no-no, too
- if (monster_habitat(new_mclass) == DNGN_LAVA && current_tile != DNGN_LAVA)
- return (false);
-
- return (true);
+ // Determine if the monster is happy on current tile
+ return (monster_habitable_grid(new_mclass, current_tile));
} // end valid_morph()
// note that power is (as of yet) unused within this function -
@@ -958,9 +936,11 @@ bool monster_polymorph( struct monsters *monster, int targetc, int power )
{
do
{
- targetc = random2( NUM_MONSTERS );
+ // Pick a monster that's guaranteed happy at this grid
+ targetc = random_monster_at_grid(monster->x, monster->y);
- // valid targets are always base classes
+ // valid targets are always base classes ([ds] which is unfortunate
+ // in that well-populated monster classes will dominate polymorphs)
targetc = mons_species( targetc );
target_power = mons_power( targetc );
@@ -1119,45 +1099,7 @@ bool random_near_space(int ox, int oy, int &tx, int &ty, bool allow_adjacent,
static bool habitat_okay( struct monsters *monster, int targ )
{
- bool ret = false;
- const int habitat = monster_habitat( monster->type );
-
- if (mons_flies( monster ))
- {
- // flying monsters don't care
- ret = true;
- }
- else if (mons_class_flag( monster->type, M_AMPHIBIOUS )
- && (targ == DNGN_DEEP_WATER || targ == DNGN_SHALLOW_WATER))
- {
- // Amphibious creatures are "land" by default in mon-data,
- // we allow them to swim here. -- bwr
- ret = true;
- }
- else if (monster->type == MONS_WATER_ELEMENTAL && targ >= DNGN_DEEP_WATER)
- {
- // water elementals can crawl out over the land
- ret = true;
- }
- else if (habitat == DNGN_FLOOR
- && (targ >= DNGN_FLOOR || targ == DNGN_SHALLOW_WATER))
- {
- // FLOOR habitat monster going to a non-bad place
- ret = true;
- }
- else if (habitat == DNGN_DEEP_WATER
- && (targ == DNGN_DEEP_WATER || targ == DNGN_SHALLOW_WATER))
- {
- // Water monster to water
- ret = true;
- }
- else if (habitat == DNGN_LAVA && targ == DNGN_LAVA)
- {
- // Lava monster to lava
- ret = true;
- }
-
- return (ret);
+ return (monster_habitable_grid(monster, targ));
}
// This doesn't really swap places, it just sets the monster's
@@ -4387,12 +4329,11 @@ static void monster_move(struct monsters *monster)
for (count_y = 0; count_y < 3; count_y++)
{
good_move[count_x][count_y] = true;
+
const int targ_x = monster->x + count_x - 1;
const int targ_y = monster->y + count_y - 1;
- int target_grid = grd[targ_x][targ_y];
-
- const int targ_cloud = env.cgrid[ targ_x ][ targ_y ];
- const int curr_cloud = env.cgrid[ monster->x ][ monster->y ];
+ // [ds] Bounds check was after grd[targ_x][targ_y] which would
+ // trigger an ASSERT. Moved it up.
// bounds check - don't consider moving out of grid!
if (targ_x < 0 || targ_x >= GXM || targ_y < 0 || targ_y >= GYM)
@@ -4401,6 +4342,18 @@ static void monster_move(struct monsters *monster)
continue;
}
+ int target_grid = grd[targ_x][targ_y];
+
+ const int targ_cloud_num = env.cgrid[ targ_x ][ targ_y ];
+ const int targ_cloud_type =
+ targ_cloud_num == EMPTY_CLOUD? CLOUD_NONE
+ : env.cloud[targ_cloud_num].type;
+
+ const int curr_cloud_num = env.cgrid[ monster->x ][ monster->y ];
+ const int curr_cloud_type =
+ curr_cloud_num == EMPTY_CLOUD? CLOUD_NONE
+ : env.cloud[curr_cloud_num].type;
+
if (target_grid == DNGN_DEEP_WATER)
deep_water_available = true;
@@ -4443,10 +4396,10 @@ static void monster_move(struct monsters *monster)
// Water elementals avoid fire and heat
if (monster->type == MONS_WATER_ELEMENTAL
&& (target_grid == DNGN_LAVA
- || targ_cloud == CLOUD_FIRE
- || targ_cloud == CLOUD_FIRE_MON
- || targ_cloud == CLOUD_STEAM
- || targ_cloud == CLOUD_STEAM_MON))
+ || targ_cloud_type == CLOUD_FIRE
+ || targ_cloud_type == CLOUD_FIRE_MON
+ || targ_cloud_type == CLOUD_STEAM
+ || targ_cloud_type == CLOUD_STEAM_MON))
{
good_move[count_x][count_y] = false;
continue;
@@ -4457,8 +4410,8 @@ static void monster_move(struct monsters *monster)
&& (target_grid == DNGN_DEEP_WATER
|| target_grid == DNGN_SHALLOW_WATER
|| target_grid == DNGN_BLUE_FOUNTAIN
- || targ_cloud == CLOUD_COLD
- || targ_cloud == CLOUD_COLD_MON))
+ || targ_cloud_type == CLOUD_COLD
+ || targ_cloud_type == CLOUD_COLD_MON))
{
good_move[count_x][count_y] = false;
continue;
@@ -4466,12 +4419,14 @@ static void monster_move(struct monsters *monster)
// Submerged water creatures avoid the shallows where
// they would be forced to surface. -- bwr
+ // [dshaligram] Monsters now prefer to head for deep water only if
+ // they're low on hitpoints. No point in hiding if they want a
+ // fight.
if (habitat == DNGN_DEEP_WATER
&& (targ_x != you.x_pos || targ_y != you.y_pos)
&& target_grid != DNGN_DEEP_WATER
&& grd[monster->x][monster->y] == DNGN_DEEP_WATER
- && (mons_has_ench( monster, ENCH_SUBMERGED )
- || monster->hit_points < (monster->max_hit_points * 3) / 4))
+ && monster->hit_points < (monster->max_hit_points * 3) / 4)
{
good_move[count_x][count_y] = false;
continue;
@@ -4509,15 +4464,15 @@ static void monster_move(struct monsters *monster)
}
}
- if (targ_cloud != EMPTY_CLOUD)
+ if (targ_cloud_num != EMPTY_CLOUD)
{
- if (curr_cloud != EMPTY_CLOUD
- && env.cloud[targ_cloud].type == env.cloud[curr_cloud].type)
+ if (curr_cloud_num != EMPTY_CLOUD
+ && targ_cloud_type == curr_cloud_type)
{
continue;
}
- switch (env.cloud[ targ_cloud ].type)
+ switch (targ_cloud_type)
{
case CLOUD_FIRE:
case CLOUD_FIRE_MON:
@@ -4621,14 +4576,16 @@ static void monster_move(struct monsters *monster)
} // done door-eating jellies
- // water creatures have a preferance for water they can hide in -- bwr
+ // water creatures have a preference for water they can hide in -- bwr
+ // [ds] Weakened the powerful attraction to deep water if the monster
+ // is in good health.
if (habitat == DNGN_DEEP_WATER
&& deep_water_available
&& grd[monster->x][monster->y] != DNGN_DEEP_WATER
&& grd[monster->x + mmov_x][monster->y + mmov_y] != DNGN_DEEP_WATER
&& (monster->x + mmov_x != you.x_pos
|| monster->y + mmov_y != you.y_pos)
- && (coinflip()
+ && (one_chance_in(3)
|| monster->hit_points <= (monster->max_hit_points * 3) / 4))
{
count = 0;