summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc10
-rw-r--r--crawl-ref/source/message.cc5
-rw-r--r--crawl-ref/source/mon-util.cc2
-rw-r--r--crawl-ref/source/monspeak.cc2
-rw-r--r--crawl-ref/source/monstuff.cc7
-rw-r--r--crawl-ref/source/state.cc55
-rw-r--r--crawl-ref/source/state.h35
-rw-r--r--crawl-ref/source/view.cc21
-rw-r--r--crawl-ref/source/view.h1
9 files changed, 132 insertions, 6 deletions
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<monsters*>(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<god_act_state> 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 <vector>
#include <stdio.h>
+class monsters;
+class mon_acting;
+
struct god_act_state
{
public:
@@ -83,6 +86,9 @@ protected:
god_act_state god_act;
std::vector<god_act_state> god_act_stack;
+ monsters* mon_act;
+ std::vector<monsters*> mon_act_stack;
+
public:
game_state();
@@ -120,7 +126,16 @@ public:
std::vector<god_act_state> 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,