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.cc84
1 files changed, 55 insertions, 29 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index e445e42665..cc73d8a844 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1752,7 +1752,7 @@ bool monster_blink(monsters *monster)
seen_monster(monster);
monster->check_redraw(oldplace);
- monster->apply_location_effects();
+ monster->apply_location_effects(oldplace);
return (true);
}
@@ -2225,7 +2225,7 @@ void behaviour_event(monsters *mon, int event, int src,
mon->behaviour = old_behaviour;
}
else if (wasLurking && mon->has_ench(ENCH_SUBMERGED)
- && !mon->del_ench(ENCH_SUBMERGED))
+ && !mon->del_ench(ENCH_SUBMERGED))
{
// The same goes for lurking submerged monsters, if they can't
// unsubmerge.
@@ -3766,7 +3766,7 @@ static void _handle_nearby_ability(monsters *monster)
{
if (!mons_near(monster)
|| mons_is_sleeping(monster)
- || monster->has_ench(ENCH_SUBMERGED))
+ || mons_is_submerged(monster))
{
return;
}
@@ -3881,7 +3881,7 @@ static bool _handle_special_ability(monsters *monster, bolt & beem)
if (!mons_near(monster)
|| mons_is_sleeping(monster)
- || monster->has_ench(ENCH_SUBMERGED))
+ || mons_is_submerged(monster))
{
return (false);
}
@@ -4395,7 +4395,7 @@ static bool _handle_reaching(monsters *monster)
bool ret = false;
const int wpn = monster->inv[MSLOT_WEAPON];
- if (monster->has_ench(ENCH_SUBMERGED))
+ if (mons_is_submerged(monster))
return (false);
if (mons_aligned(monster_index(monster), monster->foe))
@@ -4450,8 +4450,8 @@ static bool _handle_scroll(monsters *monster)
{
// Yes, there is a logic to this ordering {dlb}:
if (mons_is_sleeping(monster)
- || monster->has_ench(ENCH_CONFUSION)
- || monster->has_ench(ENCH_SUBMERGED)
+ || mons_is_confused(monster)
+ || mons_is_submerged(monster)
|| monster->inv[MSLOT_SCROLL] == NON_ITEM
|| !one_chance_in(3))
{
@@ -4953,7 +4953,7 @@ static bool _handle_spell(monsters *monster, bolt &beem)
// Yes, there is a logic to this ordering {dlb}:
if (mons_is_sleeping(monster)
- || monster->has_ench(ENCH_SUBMERGED)
+ || mons_is_submerged(monster)
|| !mons_class_flag(monster->type, M_SPELLCASTER)
&& draco_breath == SPELL_NO_SPELL)
{
@@ -4978,7 +4978,7 @@ static bool _handle_spell(monsters *monster, bolt &beem)
return (false);
}
else if (random2(200) > monster->hit_dice + 50
- || (monster->type == MONS_BALL_LIGHTNING && coinflip()))
+ || monster->type == MONS_BALL_LIGHTNING && coinflip())
{
return (false);
}
@@ -5124,7 +5124,7 @@ static bool _handle_spell(monsters *monster, bolt &beem)
// emergency spells harmful to the area.
if (spell_cast != SPELL_NO_SPELL
&& mons_is_pacified(monster)
- && spell_harms_area(spell_cast))
+ && spell_harms_area(spell_cast))
{
spell_cast = SPELL_NO_SPELL;
}
@@ -5138,6 +5138,14 @@ static bool _handle_spell(monsters *monster, bolt &beem)
if (spell_cast == SPELL_NO_SPELL)
continue;
+ // Friendly monsters don't use polymorph, for fear of harming
+ // the player.
+ if (spell_cast == SPELL_POLYMORPH_OTHER
+ && mons_friendly(monster))
+ {
+ continue;
+ }
+
// Setup the spell.
setup_mons_cast(monster, beem, spell_cast);
@@ -5628,7 +5636,7 @@ static void _handle_monster_move(int i, monsters *monster)
// Handle clouds on nonmoving monsters.
if (monster->speed == 0
&& env.cgrid(monster->pos()) != EMPTY_CLOUD
- && !monster->has_ench(ENCH_SUBMERGED))
+ && !mons_is_submerged(monster))
{
_mons_in_cloud( monster );
}
@@ -5714,7 +5722,7 @@ static void _handle_monster_move(int i, monsters *monster)
if (env.cgrid(monster->pos()) != EMPTY_CLOUD)
{
- if (monster->has_ench(ENCH_SUBMERGED))
+ if (mons_is_submerged(monster))
{
monster->speed_increment -= entry->energy_usage.swim;
break;
@@ -5796,7 +5804,7 @@ static void _handle_monster_move(int i, monsters *monster)
if (monster->foe != MHITNOT
&& grid_distance(monster->target, monster->pos()) <= 1)
{
- if (monster->has_ench(ENCH_SUBMERGED))
+ if (mons_is_submerged(monster))
{
// Don't unsubmerge if the monster is too damaged or
// if the monster is afraid.
@@ -5837,7 +5845,7 @@ static void _handle_monster_move(int i, monsters *monster)
if (mons_is_confused(monster)
|| monster->type == MONS_AIR_ELEMENTAL
- && monster->has_ench(ENCH_SUBMERGED))
+ && mons_is_submerged(monster))
{
std::vector<coord_def> moves;
@@ -6155,7 +6163,7 @@ static bool _handle_pickup(monsters *monster)
int item = NON_ITEM;
if (mons_is_sleeping(monster)
- || monster->has_ench(ENCH_SUBMERGED))
+ || mons_is_submerged(monster))
{
return (false);
}
@@ -6383,8 +6391,8 @@ static bool _monster_swaps_places( monsters *mon, const coord_def& delta )
immobile_monster[m2i] = true;
mon->check_redraw(c);
- mon->apply_location_effects();
- m2->apply_location_effects();
+ mon->apply_location_effects(c);
+ m2->apply_location_effects(n);
return (false);
}
@@ -6419,6 +6427,12 @@ static bool _do_move_monster(monsters *monster, const coord_def& delta)
// This appears to be the real one, ie where the movement occurs:
_swim_or_move_energy(monster);
+ if (grd(monster->pos()) == DNGN_DEEP_WATER && grd(f) != DNGN_DEEP_WATER
+ && !monster_habitable_grid(monster, DNGN_DEEP_WATER))
+ {
+ mpr("set seen_context...");
+ monster->seen_context = "emerges from the water";
+ }
mgrd(monster->pos()) = NON_MONSTER;
monster->pos() = f;
@@ -6426,12 +6440,13 @@ static bool _do_move_monster(monsters *monster, const coord_def& delta)
mgrd(monster->pos()) = monster_index(monster);
monster->check_redraw(monster->pos() - delta);
- monster->apply_location_effects();
+ monster->apply_location_effects(monster->pos() - delta);
return (true);
}
-void mons_check_pool(monsters *mons, killer_type killer, int killnum)
+void mons_check_pool(monsters *mons, const coord_def &oldpos,
+ killer_type killer, int killnum)
{
// Levitating/flying monsters don't make contact with the terrain.
if (mons->airborne())
@@ -6445,7 +6460,7 @@ void mons_check_pool(monsters *mons, killer_type killer, int killnum)
// Don't worry about invisibility - you should be able to
// see if something has fallen into the lava.
- if (message)
+ if (message && (oldpos == mons->pos() || grd(oldpos) != grid))
{
mprf("%s falls into the %s!",
mons->name(DESC_CAP_THE).c_str(),
@@ -6471,11 +6486,6 @@ void mons_check_pool(monsters *mons, killer_type killer, int killnum)
simple_monster_message( mons, " falls apart.",
MSGCH_MONSTER_DAMAGE, MDAM_DEAD);
}
- else if (mons_is_zombified(mons))
- {
- simple_monster_message( mons, " sinks like a rock.",
- MSGCH_MONSTER_DAMAGE, MDAM_DEAD);
- }
else
{
simple_monster_message( mons, " drowns.",
@@ -6518,8 +6528,8 @@ static int _estimated_trap_damage(trap_type trap)
// Check whether a given trap (described by trap position) can be
// regarded as safe. Takes into account monster intelligence and
-// allegiance. (just_check is used for intelligent monsters trying to
-// avoid traps.)
+// allegiance.
+// (just_check is used for intelligent monsters trying to avoid traps.)
static bool _is_trap_safe(const monsters *monster, const coord_def& where,
bool just_check)
{
@@ -6678,6 +6688,15 @@ static void _mons_open_door(monsters* monster, const coord_def &pos)
monster->lose_energy(EUT_MOVE);
}
+static bool _no_habitable_adjacent_grids(const monsters *mon)
+{
+ for (adjacent_iterator ai(mon->pos()); ai; ++ai)
+ if (_habitat_okay(mon, grd(*ai)))
+ return (false);
+
+ return (true);
+}
+
// Check whether a monster can move to given square (described by its relative
// coordinates to the current monster position). just_check is true only for
// calls from is_trap_safe when checking the surrounding squares of a trap.
@@ -6685,7 +6704,6 @@ static bool _mon_can_move_to_pos(const monsters *monster,
const coord_def& delta, bool just_check)
{
const coord_def targ = monster->pos() + delta;
-
// Bounds check - don't consider moving out of grid!
if (!inside_level_bounds(targ))
return (false);
@@ -6743,6 +6761,14 @@ static bool _mon_can_move_to_pos(const monsters *monster,
}
else if (!_habitat_okay( monster, target_grid ))
{
+ // If the monster somehow ended up in this habitat (and is
+ // not dead by now), give it a chance to get out again.
+ if (grd(monster->pos()) == target_grid
+ && _no_habitable_adjacent_grids(monster))
+ {
+ return (true);
+ }
+
return (false);
}
@@ -6907,7 +6933,7 @@ static bool _monster_move(monsters *monster)
if (monster->type == MONS_TRAPDOOR_SPIDER)
{
- if(monster->has_ench(ENCH_SUBMERGED))
+ if(mons_is_submerged(monster))
return (false);
// Trapdoor spiders hide if they can't see their target.