summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/state.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-19 01:19:56 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-19 01:19:56 +0000
commit725cb5b4d5a3ade5c5e7b04a6210cedc839c2bdd (patch)
treed2644ce5f13e7ab649b27b49f7bdcde18802a6b1 /crawl-ref/source/state.cc
parent1a36197574afe860feff7208cd883770a5d28946 (diff)
downloadcrawl-ref-725cb5b4d5a3ade5c5e7b04a6210cedc839c2bdd.tar.gz
crawl-ref-725cb5b4d5a3ade5c5e7b04a6210cedc839c2bdd.zip
Added new commands "re-do previous command" (bound to `) and "repeat
next command" (bound to 0). Though this is just an interface change, it changes code in the core input processing function (input() in acr.cc), and also messes around with the input buffer, so it could probably do with more testing before merging it into the 0.3 branch. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2137 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/state.cc')
-rw-r--r--crawl-ref/source/state.cc235
1 files changed, 235 insertions, 0 deletions
diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc
new file mode 100644
index 0000000000..a664a3464b
--- /dev/null
+++ b/crawl-ref/source/state.cc
@@ -0,0 +1,235 @@
+/*
+ * File: state.cc
+ * Summary: Game state functions.
+ * Written by: Matthew Cline
+ *
+ * Modified for Crawl Reference by $Author$ on $Date$
+ *
+ * Change History (most recent first):
+ *
+ * <1> 09/18/07 MPC Created
+ */
+
+#include "AppHdr.h"
+#include "externs.h"
+
+#include "delay.h"
+#include "direct.h"
+#include "macro.h"
+#include "mon-util.h"
+#include "menu.h" // For print_formatted_paragraph()
+#include "player.h"
+#include "state.h"
+#include "tutorial.h"
+#include "view.h"
+
+game_state::game_state()
+ : mouse_enabled(false), waiting_for_command(false),
+ terminal_resized(false), io_inited(false), need_save(false),
+ saving_game(false), updating_scores(false), seen_hups(0),
+ map_stat_gen(false), unicode_ok(false), glyph2strfn(NULL),
+ multibyte_strlen(NULL), terminal_resize_handler(NULL),
+ terminal_resize_check(NULL), doing_prev_cmd_again(false),
+ prev_cmd(CMD_NO_CMD), repeat_cmd(CMD_NO_CMD), cmd_repeat_count(0),
+ cmd_repeat_goal(0), prev_repetition_turn(0),
+ cmd_repeat_started_unsafe(false), input_line_curr(0)
+{
+ reset_cmd_repeat();
+ reset_cmd_again();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Repeating commands and doing the previous command over again.
+
+bool game_state::is_replaying_keys() const
+{
+ return (crawl_state.doing_prev_cmd_again
+ || (crawl_state.is_repeating_cmd()
+ && !crawl_state.cmd_repeat_start));
+}
+
+bool game_state::is_repeating_cmd() const
+{
+ ASSERT((cmd_repeat_goal == 0 && cmd_repeat_count == 0
+ && repeat_cmd == CMD_NO_CMD && !cmd_repeat_start)
+ || (cmd_repeat_goal > 0 && cmd_repeat_count <= cmd_repeat_goal
+ && repeat_cmd != CMD_NO_CMD));
+
+ return (repeat_cmd != CMD_NO_CMD);
+}
+
+void game_state::cancel_cmd_repeat(std::string reason)
+{
+ if (!is_repeating_cmd())
+ return;
+
+ if (is_replaying_keys())
+ flush_input_buffer(FLUSH_KEY_REPLAY_CANCEL);
+
+ if (is_processing_macro())
+ flush_input_buffer(FLUSH_ABORT_MACRO);
+
+ reset_cmd_repeat();
+
+ if (reason != "")
+ mpr(reason.c_str());
+}
+
+void game_state::cancel_cmd_again(std::string reason)
+{
+ if (!doing_prev_cmd_again)
+ return;
+
+ flush_input_buffer(FLUSH_KEY_REPLAY_CANCEL);
+
+ if (is_processing_macro())
+ flush_input_buffer(FLUSH_ABORT_MACRO);
+
+ reset_cmd_again();
+
+ if (reason != "")
+ mpr(reason.c_str());
+}
+
+void game_state::cant_cmd_repeat(std::string reason)
+{
+ if (reason == "")
+ reason = "Can't repeat that command.";
+
+ cancel_cmd_repeat(reason);
+}
+
+void game_state::cant_cmd_again(std::string reason)
+{
+ if (reason == "")
+ reason = "Can't redo that command.";
+
+ cancel_cmd_again(reason);
+}
+
+// The mehtod is called to prevent the "no repeating zero turns
+// commands" message that input() generates (in the abscence of
+// cancelling the repeition) for a repeated command that took no
+// turns. A wrapper around cancel_cmd_repeat(), its only purpose it
+// to make it clear why cancel_cmd_repeat() is being called.
+void game_state::zero_turns_taken()
+{
+ ASSERT(!you.turn_is_over);
+ cancel_cmd_repeat();
+}
+
+bool interrupt_cmd_repeat( activity_interrupt_type ai,
+ const activity_interrupt_data &at )
+{
+ if (crawl_state.cmd_repeat_start)
+ return false;
+
+ // If command repitition is being used to immitate the rest command,
+ // then everything interrupts it.
+ if (crawl_state.repeat_cmd == CMD_MOVE_NOWHERE
+ || crawl_state.repeat_cmd == CMD_SEARCH)
+ {
+ return true;
+ }
+
+ if (crawl_state.repeat_cmd == CMD_WIZARD)
+ return false;
+
+ switch (ai)
+ {
+ case AI_STATUE:
+ case AI_HUNGRY:
+ case AI_TELEPORT:
+ case AI_FORCE_INTERRUPT:
+ case AI_HP_LOSS:
+ case AI_MONSTER_ATTACKS:
+ crawl_state.cancel_cmd_repeat("Command repetition interrupted.");
+ return true;
+
+ default:
+ break;
+ }
+
+ if (ai == AI_SEE_MONSTER)
+ {
+ const monsters* mon = static_cast<const monsters*>(at.data);
+ if (!mon->visible())
+ return false;
+
+ if (crawl_state.cmd_repeat_started_unsafe
+ && at.context != "newly seen")
+ {
+ return false;
+ }
+
+ crawl_state.cancel_cmd_repeat();
+
+#ifndef DEBUG_DIAGNOSTICS
+ if (at.context == "newly seen")
+ {
+ std::string text = get_monster_desc(mon, false);
+ text += " comes into view.";
+ print_formatted_paragraph(text, get_number_of_cols(), MSGCH_WARN);
+ }
+
+ if (Options.tutorial_left)
+ {
+ // enforce that this message comes first
+ tutorial_first_monster(*mon);
+ if (get_mons_colour(mon) != mon->colour)
+ learned_something_new(TUT_MONSTER_BRAND);
+ }
+#else
+ formatted_string fs( channel_to_colour(MSGCH_WARN) );
+ fs.cprintf("%s (", mon->name(DESC_PLAIN, true).c_str());
+ fs.add_glyph( mon );
+ fs.cprintf(") in view: (%d,%d), see_grid: %s",
+ mon->x, mon->y,
+ see_grid(mon->x, mon->y)? "yes" : "no");
+ formatted_mpr(fs, MSGCH_WARN);
+#endif
+
+ return true;
+ }
+
+ if (crawl_state.cmd_repeat_started_unsafe)
+ return false;
+
+ if (ai == AI_HIT_MONSTER)
+ {
+ // This check is for when command repetition is used to
+ // whack away at a 0xp monster, since the player feels safe
+ // when the only monsters around are 0xp.
+ const monsters* mon = static_cast<const monsters*>(at.data);
+
+ if (mons_class_flag(mon->type, M_NO_EXP_GAIN)
+ && player_monster_visible(mon))
+ {
+ return false;
+ }
+
+ crawl_state.cancel_cmd_repeat("Command repetition interrupted.");
+ return true;
+ }
+
+ return false;
+}
+
+void game_state::reset_cmd_repeat()
+{
+ repeat_cmd = CMD_NO_CMD;
+ cmd_repeat_count = 0;
+ cmd_repeat_goal = 0;
+ cmd_repeat_start = false;
+ prev_repetition_turn = 0;
+
+ repeat_cmd_keys.clear();
+}
+
+void game_state::reset_cmd_again()
+{
+ doing_prev_cmd_again = false;
+ prev_cmd = CMD_NO_CMD;
+
+ prev_cmd_keys.clear();
+}