From 9c8871bc3e50d51e3898ff5594b9d4f73f15c55b Mon Sep 17 00:00:00 2001 From: zelgadis Date: Tue, 20 Jan 2009 10:41:45 +0000 Subject: Make extra-sure that a monster won't be announced to have come into view, only to immediately move out of view, by introducing the notion of the currently acting monster to crawl_state, and only flushing out the "comes into view" message in mpr() for the currently acting monster. Not sure if it's worth it just for the sake of avoiding doing a "has this monster just now come into view" check in every place that a monster might issue a message, but at least this way we won't miss any places such a check should be placed. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8623 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/acr.cc | 10 +++++--- crawl-ref/source/message.cc | 5 ++-- crawl-ref/source/mon-util.cc | 2 ++ crawl-ref/source/monspeak.cc | 2 ++ crawl-ref/source/monstuff.cc | 7 ++++++ crawl-ref/source/state.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++ crawl-ref/source/state.h | 35 ++++++++++++++++++++++++++++ crawl-ref/source/view.cc | 21 +++++++++++++++++ crawl-ref/source/view.h | 1 + 9 files changed, 132 insertions(+), 6 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 88cec101ae..835615e60e 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -1499,6 +1499,8 @@ static void _center_cursor() // static void _input() { + crawl_state.clear_mon_acting(); + religion_turn_start(); check_beholders(); @@ -3113,12 +3115,14 @@ static void _check_sanctuary() void world_reacts() { - you.turn_is_over = true; + crawl_state.clear_mon_acting(); if (!crawl_state.arena) + { + you.turn_is_over = true; religion_turn_end(); - - crawl_state.clear_god_acting(); + crawl_state.clear_god_acting(); + } #ifdef USE_TILE tiles.clear_text_tags(TAG_TUTORIAL); diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc index 467b899600..063f6fa59e 100644 --- a/crawl-ref/source/message.cc +++ b/crawl-ref/source/message.cc @@ -463,11 +463,10 @@ void mpr(const char *inf, msg_channel_type channel, int param) // Flush out any "comes into view" monster announcements before the // monster has a chance to give any other messages. - if (!_updating_view && you.turn_is_over - && (you_are_delayed() || crawl_state.is_repeating_cmd())) + if (!_updating_view) { _updating_view = true; - update_monsters_in_view(); + flush_comes_into_view(); _updating_view = false; } diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 8298020cad..b9c61d5881 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -7907,6 +7907,8 @@ void monsters::react_to_damage(int damage, beam_type flavour) if (type == MONS_ROYAL_JELLY && flavour != BEAM_TORMENT_DAMAGE && alive() && damage > 8 && x_chance_in_y(damage, 50)) { + mon_acting mact(this); + const int tospawn = 1 + random2avg(1 + std::min((damage - 8) / 8, 5), 2); #ifdef DEBUG_DIAGNOSTICS diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc index b147cf3fa5..448a8c1017 100644 --- a/crawl-ref/source/monspeak.cc +++ b/crawl-ref/source/monspeak.cc @@ -737,6 +737,8 @@ void mons_speaks_msg(const monsters *monster, const std::string &msg, if (!mons_near(monster)) return; + mon_acting mact(const_cast(monster)); + // We have a speech string, now parse and act on it. std::string _msg = do_mon_str_replacements(msg, monster); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index f59f53f4ce..088619dde6 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1030,6 +1030,8 @@ int monster_die(monsters *monster, killer_type killer, if (!silent && _monster_avoided_death(monster, killer, killer_index)) return (-1); + crawl_state.inc_mon_acting(monster); + mons_clear_trapping_net(monster); // Update list of monsters beholding player. @@ -1662,6 +1664,7 @@ int monster_die(monsters *monster, killer_type killer, // don't clutter up mitm[] monster->destroy_inventory(); + crawl_state.dec_mon_acting(monster); monster_cleanup(monster); // Force redraw for monsters that die. @@ -1676,6 +1679,8 @@ int monster_die(monsters *monster, killer_type killer, void monster_cleanup(monsters *monster) { + crawl_state.mon_gone(monster); + unsigned int monster_killed = monster_index(monster); monster->reset(); @@ -6739,6 +6744,8 @@ static void _handle_monster_move(int i, monsters *monster) return; } + mon_acting mact(monster); + _monster_add_energy(monster); // Handle clouds on nonmoving monsters. diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc index c232b8f6f3..55cb88d0ff 100644 --- a/crawl-ref/source/state.cc +++ b/crawl-ref/source/state.cc @@ -374,6 +374,61 @@ std::vector game_state::other_gods_acting() const return god_act_stack; } +bool game_state::is_mon_acting() const +{ + return (mon_act != NULL); +} + +monsters* game_state::which_mon_acting() const +{ + return (mon_act); +} + +void game_state::inc_mon_acting(monsters* mon) +{ + ASSERT(!invalid_monster(mon)); + + if (mon_act != NULL) + mon_act_stack.push_back(mon_act); + + mon_act = mon; +} + +void game_state::dec_mon_acting(monsters* mon) +{ + ASSERT(mon_act == mon); + + mon_act = NULL; + + if (mon_act_stack.size() > 0) + { + mon_act = *(mon_act_stack.end()); + ASSERT(!invalid_monster(mon_act)); + mon_act_stack.pop_back(); + } +} + +void game_state::clear_mon_acting() +{ + mon_act = NULL; + mon_act_stack.clear(); +} + +void game_state::mon_gone(monsters* mon) +{ + for (unsigned int i = 0, size = mon_act_stack.size(); i < size; i++) + { + if (mon_act_stack[i] == mon) + { + mon_act_stack.erase(mon_act_stack.begin() + i); + i--; + } + } + + if (mon_act == mon) + dec_mon_acting(mon); +} + void game_state::dump(FILE* file) { fprintf(file, EOL "Game state:" EOL EOL); diff --git a/crawl-ref/source/state.h b/crawl-ref/source/state.h index 23c6675dfd..58bfa30090 100644 --- a/crawl-ref/source/state.h +++ b/crawl-ref/source/state.h @@ -13,6 +13,9 @@ #include #include +class monsters; +class mon_acting; + struct god_act_state { public: @@ -83,6 +86,9 @@ protected: god_act_state god_act; std::vector god_act_stack; + monsters* mon_act; + std::vector mon_act_stack; + public: game_state(); @@ -120,7 +126,16 @@ public: std::vector other_gods_acting() const; + bool is_mon_acting() const; + monsters* which_mon_acting() const; + void inc_mon_acting(monsters* mon); + void dec_mon_acting(monsters* mon); + void clear_mon_acting(); + void mon_gone(monsters* mon); + void dump(FILE* file); + + friend class mon_acting; }; extern game_state crawl_state; @@ -146,4 +161,24 @@ private: god_type god; }; +class mon_acting +{ +public: + mon_acting(monsters* _mon) : mon(_mon) + { + crawl_state.inc_mon_acting(_mon); + } + + ~mon_acting() + { + // Monster might have died in the meantime. + if (mon == crawl_state.mon_act) + crawl_state.dec_mon_acting(mon); + } + +private: + monsters *mon; +}; + + #endif diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index f7a62bc8a7..b691992e32 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -972,6 +972,25 @@ static void _handle_seen_interrupt(monsters* monster) seen_monster( monster ); } +void flush_comes_into_view() +{ + if (!you.turn_is_over + || (!you_are_delayed() && !crawl_state.is_repeating_cmd())) + { + return; + } + + monsters* mon = crawl_state.which_mon_acting(); + + if (!mon || !mon->alive() || (mon->flags & MF_WAS_IN_VIEW) + || !you.can_see(mon)) + { + return; + } + + _handle_seen_interrupt(mon); +} + void handle_monster_shouts(monsters* monster, bool force) { if (!force && (!you.turn_is_over @@ -998,6 +1017,8 @@ void handle_monster_shouts(monsters* monster, bool force) return; } + mon_acting mact(monster); + std::string default_msg_key = ""; switch (s_type) diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h index 49ebf4693b..43977a523c 100644 --- a/crawl-ref/source/view.h +++ b/crawl-ref/source/view.h @@ -252,6 +252,7 @@ void flash_monster_colour(const monsters *mon, unsigned char fmc_colour, #endif void viewwindow(bool draw_it, bool do_updates); void update_monsters_in_view(); +void flush_comes_into_view(); struct ray_def; bool find_ray( const coord_def& source, const coord_def& target, -- cgit v1.2.3-54-g00ecf