00001 /* 00002 * File: state.h 00003 * Summary: Game state. 00004 * Written by: Linley Henzell 00005 */ 00006 00007 #ifndef STATE_H 00008 #define STATE_H 00009 00010 #include "player.h" 00011 #include <vector> 00012 00013 class monster; 00014 class mon_acting; 00015 00016 struct god_act_state 00017 { 00018 public: 00019 00020 god_act_state(); 00021 void reset(); 00022 00023 god_type which_god; 00024 bool retribution; 00025 int depth; 00026 }; 00027 00028 // Track various aspects of Crawl game state. 00029 struct game_state 00030 { 00031 std::vector<std::string> command_line_arguments; 00032 00033 bool game_crashed; // The game crashed and is now in the process of 00034 // dumping crash info. 00035 00036 // An assert was triggered, but an emergency save here should be possible 00037 // without corruption. 00038 bool game_wants_emergency_save; 00039 00040 bool mouse_enabled; // True if mouse input is currently relevant. 00041 00042 bool waiting_for_command; // True when the game is waiting for a command. 00043 bool terminal_resized; // True if the term was resized and we need to 00044 // take action to handle it. 00045 00046 bool io_inited; // Is curses or the equivalent initialised? 00047 bool need_save; // Set to true when game has started. 00048 bool saving_game; // Set to true while in save_game. 00049 bool updating_scores; // Set to true while updating hiscores. 00050 00051 int seen_hups; // Set to true if SIGHUP received. 00052 00053 bool map_stat_gen; // Set if we're generating stats on maps. 00054 00055 game_type type; 00056 bool arena_suspended; // Set if the arena has been temporarily 00057 // suspended. 00058 00059 bool dump_maps; // Dump map Lua to stderr on fresh parse. 00060 bool test; // Set if we want to run self-tests and exit. 00061 bool script; // Set if we want to run a Lua script and exit. 00062 bool build_db; // Set if we want to rebuild the db and exit. 00063 std::vector<std::string> tests_selected; // Tests to be run. 00064 std::vector<std::string> script_args; // Arguments to scripts. 00065 00066 bool unicode_ok; // Is unicode support available? 00067 00068 bool show_more_prompt; // Set to false to disable --more-- prompts. 00069 00070 std::string sprint_map; // Sprint map set on command line, if any. 00071 00072 std::string (*glyph2strfn)(unsigned glyph); 00073 int (*multibyte_strlen)(const std::string &s); 00074 void (*terminal_resize_handler)(); 00075 void (*terminal_resize_check)(); 00076 00077 bool doing_prev_cmd_again; 00078 command_type prev_cmd; 00079 std::deque<int> prev_cmd_keys; 00080 00081 command_type repeat_cmd; 00082 bool cmd_repeat_start; 00083 command_type prev_repeat_cmd; 00084 int prev_cmd_repeat_goal; 00085 bool cmd_repeat_started_unsafe; 00086 00087 std::vector<std::string> startup_errors; 00088 00089 bool level_annotation_shown; 00090 00091 #ifndef USE_TILE 00092 // Are we currently targeting using the mlist? 00093 // This is global because the monster pane uses this when 00094 // drawing. 00095 bool mlist_targeting; 00096 #else 00097 bool title_screen; 00098 #endif 00099 00100 // Range beyond which view should be darkend, -1 == disabled. 00101 int darken_range; 00102 00103 // Any changes to macros that need to be changed? 00104 bool unsaved_macros; 00105 00106 // Version of the last character save. 00107 int minorVersion; 00108 00109 protected: 00110 void reset_cmd_repeat(); 00111 void reset_cmd_again(); 00112 00113 god_act_state god_act; 00114 std::vector<god_act_state> god_act_stack; 00115 00116 monster* mon_act; 00117 std::vector<monster* > mon_act_stack; 00118 00119 public: 00120 game_state(); 00121 00122 void add_startup_error(const std::string &error); 00123 void show_startup_errors(); 00124 00125 bool is_replaying_keys() const; 00126 00127 bool is_repeating_cmd() const; 00128 00129 void cancel_cmd_repeat(std::string reason = ""); 00130 void cancel_cmd_again(std::string reason = ""); 00131 void cancel_cmd_all(std::string reason = ""); 00132 00133 void cant_cmd_repeat(std::string reason = ""); 00134 void cant_cmd_again(std::string reason = ""); 00135 void cant_cmd_any(std::string reason = ""); 00136 00137 void zero_turns_taken(); 00138 00139 void check_term_size() const 00140 { 00141 if (terminal_resize_check) 00142 (*terminal_resize_check)(); 00143 } 00144 00145 bool is_god_acting() const; 00146 bool is_god_retribution() const; 00147 god_type which_god_acting() const; 00148 void inc_god_acting(bool is_retribution = false); 00149 void inc_god_acting(god_type which_god, bool is_retribution = false); 00150 void dec_god_acting(); 00151 void dec_god_acting(god_type which_god); 00152 void clear_god_acting(); 00153 00154 std::vector<god_act_state> other_gods_acting() const; 00155 00156 bool is_mon_acting() const; 00157 monster* which_mon_acting() const; 00158 void inc_mon_acting(monster* mon); 00159 void dec_mon_acting(monster* mon); 00160 void clear_mon_acting(); 00161 void mon_gone(monster* mon); 00162 00163 void dump(); 00164 bool player_is_dead() const; 00165 00166 bool game_standard_levelgen() const; 00167 bool game_is_normal() const; 00168 bool game_is_tutorial() const; 00169 bool game_is_arena() const; 00170 bool game_is_sprint() const; 00171 bool game_is_zotdef() const; 00172 bool game_is_hints() const; 00173 00174 // Save subdirectory used for games such as Sprint. 00175 std::string game_type_name() const; 00176 std::string game_savedir_path() const; 00177 std::string game_type_qualifier() const; 00178 00179 static std::string game_type_name_for(game_type gt); 00180 00181 friend class mon_acting; 00182 }; 00183 00184 #ifdef DEBUG_GLOBALS 00185 #define crawl_state (*real_crawl_state) 00186 #endif 00187 extern game_state crawl_state; 00188 00189 class god_acting 00190 { 00191 public: 00192 god_acting(bool is_retribution = false) 00193 : god(you.religion) 00194 { 00195 crawl_state.inc_god_acting(god, is_retribution); 00196 } 00197 god_acting(god_type who, bool is_retribution = false) 00198 : god(who) 00199 { 00200 crawl_state.inc_god_acting(god, is_retribution); 00201 } 00202 ~god_acting() 00203 { 00204 crawl_state.dec_god_acting(god); 00205 } 00206 private: 00207 god_type god; 00208 }; 00209 00210 class mon_acting 00211 { 00212 public: 00213 mon_acting(monster* _mon) : mon(_mon) 00214 { 00215 crawl_state.inc_mon_acting(_mon); 00216 } 00217 00218 ~mon_acting() 00219 { 00220 // Monster might have died in the meantime. 00221 if (mon == crawl_state.mon_act) 00222 crawl_state.dec_mon_acting(mon); 00223 } 00224 00225 private: 00226 monster* mon; 00227 }; 00228 00229 #endif