summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/beam.cc6
-rw-r--r--crawl-ref/source/debug.cc2
-rw-r--r--crawl-ref/source/delay.cc2
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/mon-util.cc28
-rw-r--r--crawl-ref/source/monstuff.cc84
-rw-r--r--crawl-ref/source/monstuff.h4
-rw-r--r--crawl-ref/source/mstuff2.cc2
-rw-r--r--crawl-ref/source/player.cc8
-rw-r--r--crawl-ref/source/state.cc1
-rw-r--r--crawl-ref/source/terrain.cc2
-rw-r--r--crawl-ref/source/traps.cc13
-rw-r--r--crawl-ref/source/view.cc2
13 files changed, 101 insertions, 55 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 39f87e2a24..24f554c6a4 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2328,7 +2328,8 @@ static void _beam_paralyses_monster(bolt &pbolt, monsters *monster)
if (simple_monster_message(monster, " suddenly stops moving!"))
pbolt.obvious_effect = true;
- mons_check_pool(monster, pbolt.killer(), pbolt.beam_source);
+ mons_check_pool(monster, monster->pos(), pbolt.killer(),
+ pbolt.beam_source);
}
}
@@ -2365,7 +2366,8 @@ static void _beam_petrifies_monster(bolt &pbolt, monsters *monster)
if (simple_monster_message(monster, " is moving more slowly."))
pbolt.obvious_effect = true;
- mons_check_pool(monster, pbolt.killer(), pbolt.beam_source);
+ mons_check_pool(monster, monster->pos(), pbolt.killer(),
+ pbolt.beam_source);
}
}
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 9982ca961e..1cb95ba97c 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -4219,7 +4219,7 @@ static void _move_player(const coord_def& where)
static void _move_monster(const coord_def& where, int mid1)
{
dist moves;
- direction(moves, DIR_NONE, TARG_ANY, -1, true, false, true, true,
+ direction(moves, DIR_NONE, TARG_ANY, -1, false, false, true, true,
"Move monster to where?");
if (!moves.isValid || !in_bounds(moves.target))
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 1ecb5c8cf0..b8752d97d0 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -1686,6 +1686,8 @@ inline static void _monster_warning(activity_interrupt_type ai,
text += "realm of bugdom";
text += ".";
}
+ else if (at.context.find("emerges") != std::string::npos)
+ text += " emerges from the water.";
else
text += " comes into view.";
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index a295870f46..1a439d5a68 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1111,7 +1111,7 @@ public:
void mark_summoned(int longevity, bool mark_items_summoned );
bool has_action_energy() const;
void check_redraw(const coord_def &oldpos) const;
- void apply_location_effects();
+ void apply_location_effects(const coord_def &oldpos);
void moveto(const coord_def& c);
bool move_to_pos(const coord_def &newpos);
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 2dd6061fde..8019db9368 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2387,7 +2387,16 @@ mon_attitude_type mons_attitude(const monsters *m)
bool mons_is_submerged(const monsters *m)
{
// FIXME, switch to 4.1's MF_SUBMERGED system which is much cleaner.
- return (m->has_ench(ENCH_SUBMERGED));
+ if (m->has_ench(ENCH_SUBMERGED))
+ return (true);
+
+ if (grd(m->pos()) == DNGN_DEEP_WATER
+ && !monster_habitable_grid(m, DNGN_DEEP_WATER))
+ {
+ return (true);
+ }
+
+ return (false);
}
bool mons_is_paralysed(const monsters *m)
@@ -3207,7 +3216,9 @@ bool monsters::wants_submerge() const
if (env.cgrid(pos()) != EMPTY_CLOUD
|| (hit_points < max_hit_points / 2
&& random2(max_hit_points + 1) >= hit_points))
+ {
return (true);
+ }
const bool has_ranged_attack =
type == MONS_ELECTRICAL_EEL
@@ -3284,7 +3295,6 @@ bool monsters::can_drown() const
|| mons_genus(type) == MONS_MUMMY
|| mons_genus(type) == MONS_GHOUL
|| mons_genus(type) == MONS_VAMPIRE
- || mons_is_zombified(this)
|| holiness() == MH_DEMONIC);
}
@@ -5681,9 +5691,11 @@ static bool _prepare_del_ench(monsters* mon, const mon_enchant &me)
int okay_squares = 0;
for ( adjacent_iterator ai; ai; ++ai )
- if (mgrd(*ai) == NON_MONSTER && monster_can_submerge(mon, grd(*ai)))
- if (one_chance_in(++okay_squares))
- target_square = *ai;
+ if (mgrd(*ai) == NON_MONSTER && monster_can_submerge(mon, grd(*ai))
+ && one_chance_in(++okay_squares))
+ {
+ target_square = *ai;
+ }
if (okay_squares > 0)
{
@@ -5703,7 +5715,7 @@ static bool _prepare_del_ench(monsters* mon, const mon_enchant &me)
// The terrain changed and the monster can't remain submerged.
// Try to move to an adjacent square where it would be happy.
- for ( adjacent_iterator ai; ai; ++ai )
+ for (adjacent_iterator ai; ai; ++ai)
{
if (mgrd(*ai) == NON_MONSTER
&& monster_habitable_grid(mon, grd(*ai))
@@ -6782,7 +6794,7 @@ void monsters::check_redraw(const coord_def &old) const
}
}
-void monsters::apply_location_effects()
+void monsters::apply_location_effects(const coord_def &oldpos)
{
dungeon_events.fire_position_event(DET_MONSTER_MOVED, pos());
@@ -6792,7 +6804,7 @@ void monsters::apply_location_effects()
ptrap->trigger(*this);
if (alive())
- mons_check_pool(this);
+ mons_check_pool(this, oldpos);
if (alive() && has_ench(ENCH_SUBMERGED)
&& (!monster_can_submerge(this, grd(pos()))
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.
diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h
index c41dc6daa7..cbc301a19f 100644
--- a/crawl-ref/source/monstuff.h
+++ b/crawl-ref/source/monstuff.h
@@ -87,8 +87,8 @@ bool monster_polymorph(monsters *monster, monster_type targetc,
void monster_die(monsters *monster, killer_type killer,
int killer_index, bool silent = false, bool wizard = false);
-void mons_check_pool(monsters *monster, killer_type killer = KILL_NONE,
- int killnum = -1);
+void mons_check_pool(monsters *monster, const coord_def &oldpos,
+ killer_type killer = KILL_NONE, int killnum = -1);
// last updated: 17dec2000 {gdl}
/* ***********************************************************************
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 68c41c5592..3e7a06f2fd 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -696,7 +696,7 @@ void monster_teleport(monsters *monster, bool instan, bool silent)
seen_monster(monster);
monster->check_redraw(oldplace);
- monster->apply_location_effects();
+ monster->apply_location_effects(oldplace);
// Teleporting mimics change form - if they reappear out of LOS, they are
// no longer known.
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index d0817e4580..775a2cc810 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -112,9 +112,9 @@ bool move_player_to_grid( const coord_def& p, bool stepped, bool allow_shift,
ASSERT( you.can_pass_through_feat( new_grid ) );
// Better not be an unsubmerged monster either.
- ASSERT(swapping && mgrd(p) != NON_MONSTER ||
- !swapping && (mgrd(p) == NON_MONSTER
- || mons_is_submerged( &menv[ mgrd(p) ])));
+ ASSERT(swapping && mgrd(p) != NON_MONSTER
+ || !swapping && (mgrd(p) == NON_MONSTER
+ || mons_is_submerged( &menv[ mgrd(p) ])));
const int cloud = env.cgrid(p);
if (cloud != EMPTY_CLOUD && !you.confused())
@@ -2604,7 +2604,7 @@ int player_see_invis(bool calc_unid)
// to find if the square the monster is in los see mons_near().
bool player_monster_visible( const monsters *mon )
{
- if (mon->has_ench(ENCH_SUBMERGED)
+ if (mons_is_submerged(mon)
|| mon->invisible() && !player_see_invis())
{
return (false);
diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc
index 91845abd51..b1997ef4ba 100644
--- a/crawl-ref/source/state.cc
+++ b/crawl-ref/source/state.cc
@@ -142,6 +142,7 @@ void game_state::zero_turns_taken()
bool interrupt_cmd_repeat( activity_interrupt_type ai,
const activity_interrupt_data &at )
{
+ mpr("in interrupt_cmd_repeat");
if (crawl_state.cmd_repeat_start)
return (false);
diff --git a/crawl-ref/source/terrain.cc b/crawl-ref/source/terrain.cc
index f1eef97a51..60b8c03dee 100644
--- a/crawl-ref/source/terrain.cc
+++ b/crawl-ref/source/terrain.cc
@@ -499,7 +499,7 @@ static void _dgn_check_terrain_monsters(const coord_def &pos)
if (grid_is_solid(grd(pos)))
monster_teleport(mons, true, false);
else
- mons_check_pool(mons, KILL_MISC, -1);
+ mons_check_pool(mons, mons->pos(), KILL_MISC, -1);
}
}
diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc
index b03d2d0cb6..826448d22f 100644
--- a/crawl-ref/source/traps.cc
+++ b/crawl-ref/source/traps.cc
@@ -141,12 +141,13 @@ std::string trap_def::name(description_level_type desc) const
bool trap_def::is_known(const actor* act) const
{
- bool rc = false;
const bool player_knows = (grd(pos) != DNGN_UNDISCOVERED_TRAP);
if (act == NULL || act->atype() == ACT_PLAYER)
- rc = player_knows;
- else if (act->atype() == ACT_MONSTER)
+ return (player_knows);
+
+ bool rc = false;
+ if (act->atype() == ACT_MONSTER)
{
const monsters* monster = dynamic_cast<const monsters*>(act);
const bool mechanical = (this->category() == DNGN_TRAP_MECHANICAL);
@@ -162,8 +163,8 @@ bool trap_def::is_known(const actor* act) const
rc = (intel >= I_NORMAL && mechanical
&& (mons_is_native_in_branch(monster)
- || (mons_wont_attack(monster) && player_knows)
- || (intel >= I_HIGH && one_chance_in(3))));
+ || mons_wont_attack(monster) && player_knows
+ || intel >= I_HIGH && one_chance_in(3)));
}
return rc;
}
@@ -260,7 +261,7 @@ void monster_caught_in_net(monsters *mon, bolt &pbolt)
if (mon_flies)
{
simple_monster_message(mon, " falls like a stone!");
- mons_check_pool(mon, pbolt.killer(), pbolt.beam_source);
+ mons_check_pool(mon, mon->pos(), pbolt.killer(), pbolt.beam_source);
}
}
}
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 1197b70d53..25b4bac322 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -1116,8 +1116,10 @@ void handle_monster_shouts(monsters* monster, bool force)
if (mons_is_submerged(monster))
{
if (!monster->del_ench(ENCH_SUBMERGED))
+ {
// Couldn't unsubmerge.
return;
+ }
if (you.can_see(monster))
{