diff options
-rw-r--r-- | crawl-ref/source/beam.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/delay.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 28 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 84 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/state.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/terrain.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/traps.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 2 |
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)) { |