Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef REPLAY_H_INCLUDED
00022 #define REPLAY_H_INCLUDED
00023
00024 #include "config.hpp"
00025 #include "map_location.hpp"
00026 #include "rng.hpp"
00027
00028 #include <deque>
00029
00030 class game_display;
00031 class terrain_label;
00032 class unit_map;
00033 class play_controller;
00034 struct time_of_day;
00035
00036 class chat_msg {
00037 public:
00038 const std::string &text() const { return text_; }
00039 const std::string &nick() const { return nick_; }
00040 const std::string &color() const { return color_; }
00041 chat_msg(const config &cfg);
00042 virtual ~chat_msg();
00043 private:
00044 std::string color_;
00045 std::string nick_;
00046 std::string text_;
00047 };
00048
00049 class replay: public rand_rng::rng
00050 {
00051 public:
00052 replay();
00053 explicit replay(const config& cfg);
00054
00055 void append(const config& cfg);
00056
00057 void set_skip(bool skip);
00058 bool is_skipping() const;
00059
00060 void add_start();
00061 void add_recruit(int unit_index, const map_location& loc, const map_location& from);
00062 void add_recall(const std::string& unit_id, const map_location& loc, const map_location& from);
00063 void add_disband(const std::string& unit_id);
00064 void add_countdown_update(int value,int team);
00065 void add_movement(const std::vector<map_location>& steps);
00066 void add_attack(const map_location& a, const map_location& b,
00067 int att_weapon, int def_weapon, const std::string& attacker_type_id,
00068 const std::string& defender_type_id, int attacker_lvl,
00069 int defender_lvl, const size_t turn, const time_of_day &t);
00070 void add_seed(const char* child_name, int seed);
00071 void user_input(const std::string &, const config &);
00072 void add_label(const terrain_label*);
00073 void clear_labels(const std::string&, bool);
00074 void add_rename(const std::string& name, const map_location& loc);
00075 void init_side();
00076 void end_turn();
00077 void add_event(const std::string& name,
00078 const map_location& loc=map_location::null_location);
00079 void add_unit_checksum(const map_location& loc,config* const cfg);
00080 void add_checksum_check(const map_location& loc);
00081 void add_log_data(const std::string &key, const std::string &var);
00082 void add_log_data(const std::string &category, const std::string &key, const std::string &var);
00083 void add_log_data(const std::string &category, const std::string &key, const config& c);
00084
00085
00086
00087
00088 void add_expected_advancement(const map_location& loc);
00089
00090
00091
00092
00093 const std::deque<map_location>& expected_advancements() const;
00094
00095
00096
00097
00098 void pop_expected_advancement();
00099
00100
00101
00102
00103
00104 void add_advancement(const map_location& loc);
00105
00106 void add_chat_message_location();
00107 void speak(const config& cfg);
00108 const std::vector<chat_msg>& build_chat_log();
00109
00110
00111
00112
00113
00114
00115
00116
00117 enum DATA_TYPE { ALL_DATA, NON_UNDO_DATA };
00118 config get_data_range(int cmd_start, int cmd_end, DATA_TYPE data_type=ALL_DATA);
00119 config get_last_turn(int num_turns=1);
00120 const config& get_replay_data() const { return cfg_; }
00121
00122 void undo();
00123
00124 void start_replay();
00125 void revert_action();
00126 config* get_next_action();
00127 void pre_replay();
00128
00129 bool at_end() const;
00130 void set_to_end();
00131
00132 void clear();
00133 bool empty();
00134
00135 enum MARK_SENT { MARK_AS_UNSENT, MARK_AS_SENT };
00136 void add_config(const config& cfg, MARK_SENT mark=MARK_AS_UNSENT);
00137
00138 int ncommands() const;
00139
00140 static void process_error(const std::string& msg);
00141
00142 private:
00143
00144 void add_pos(const std::string& type,
00145 const map_location& a, const map_location& b);
00146
00147 void add_chat_log_entry(const config &speak, std::back_insert_iterator< std::vector<chat_msg> > &i) const;
00148
00149 config &command(int);
00150 void remove_command(int);
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 config* add_command(bool update_random_context=true);
00163 config cfg_;
00164 int pos_;
00165
00166 config* current_;
00167
00168 bool skip_;
00169
00170 std::vector<int> message_locations;
00171
00172
00173
00174
00175
00176 std::deque<map_location> expected_advancements_;
00177 };
00178
00179 replay& get_replay_source();
00180
00181 extern replay recorder;
00182
00183
00184
00185 bool do_replay(int side_num, replay *obj = NULL);
00186
00187 bool do_replay_handle(int side_num, const std::string &do_untill);
00188
00189
00190
00191 struct replay_undo
00192 {
00193 replay_undo(replay& obj) : obj_(&obj) {}
00194 ~replay_undo() { if(obj_) obj_->undo(); }
00195 void confirm_transaction() { obj_ = NULL; }
00196
00197 private:
00198 replay* obj_;
00199 };
00200
00201 class replay_network_sender
00202 {
00203 public:
00204 replay_network_sender(replay& obj);
00205 ~replay_network_sender();
00206
00207 void sync_non_undoable();
00208 void commit_and_sync();
00209 private:
00210 replay& obj_;
00211 int upto_;
00212 };
00213
00214 namespace mp_sync {
00215
00216
00217
00218
00219
00220
00221 struct user_choice
00222 {
00223 virtual ~user_choice() {}
00224 virtual config query_user() const = 0;
00225 virtual config random_choice(rand_rng::simple_rng &) const = 0;
00226 };
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 config get_user_choice(const std::string &name, const user_choice &uch,
00255 int side = 0, bool force_sp = false);
00256
00257 }
00258
00259 #endif