diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index 47ed2a9e..67036eb0 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -41,6 +41,7 @@ #include "tools/enum_map.hpp" #include #include +#include rectangle item_screen_button_rects[9] = { {125,10,141,28},{125,40,141,58},{125,68,141,86},{125,98,141,116},{125,126,141,144},{125,156,141,174}, @@ -108,6 +109,7 @@ extern sf::RenderWindow mini_map; extern std::shared_ptr text_sbar,item_sbar,shop_sbar; extern short shop_identify_cost, shop_recharge_amount; +extern bool record_advance_time; const char *dir_string[] = {"North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West", "NorthWest"}; char get_new_terrain(); @@ -1622,6 +1624,40 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) { } void advance_time(bool did_something, bool need_redraw, bool need_reprint) { + if(recording && record_advance_time){ + std::map info; + info["did_something"] = bool_to_str(did_something); + info["need_redraw"] = bool_to_str(need_redraw); + info["need_reprint"] = bool_to_str(need_reprint); + record_action("advance_time", info); + } + if(replaying && record_advance_time){ + if(next_action_type() == "advance_time"){ + Element& element = pop_next_action(); + std::map info = info_from_action(element); + std::ostringstream sstr; + sstr << std::boolalpha; + bool wrong_args = false; + if(did_something != str_to_bool(info["did_something"])){ + wrong_args = true; + sstr << "did_something: expected " << !did_something << ", was " << did_something << ". "; + } + if(need_redraw != str_to_bool(info["need_redraw"])){ + wrong_args = true; + sstr << "need_redraw: expected " << !need_redraw << ", was " << need_redraw << ". "; + } + if(need_reprint != str_to_bool(info["need_reprint"])){ + wrong_args = true; + sstr << "need_reprint: expected " << !need_reprint << ", was " << need_reprint << ". "; + } + if(wrong_args){ + throw std::string { "Replay system internal error! advance_time() was called with the wrong args. " } + sstr.str(); + } + }else{ + throw std::string { "Replay system internal error! advance_time() was called following an action which does not advance time: " } + last_action_type; + } + } + // MARK: At this point, see if any specials have been queued up, and deal with them // Note: We just check once here instead of looping because run_special also pulls from the queue. if(!special_queue.empty()) { diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp index 7a2c8acf..f3ce48fa 100644 --- a/src/game/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -234,6 +234,8 @@ static void init_ui() { init_buttons(); } +bool record_advance_time = false; + static void process_args(int argc, char* argv[]) { preprocess_args(argc, argv); clara::Args args(argc, argv); @@ -243,6 +245,7 @@ static void process_args(int argc, char* argv[]) { boost::optional replay_speed; cli |= clara::Opt(record_to, "record")["--record"]("Records a replay of your session to the specified XML file."); cli |= clara::Opt(record_unique)["--unique"]("When recording, automatically insert a timestamp into the filename to guarantee uniqueness."); + cli |= clara::Opt(record_advance_time)["--advance-time"]("Record and validate advance_time() calls for internal testing of the replay system."); cli |= clara::Opt(replay, "replay-file")["--replay"]("Replays a previously-recorded session from the specified XML file."); cli |= clara::Opt(replay_speed, "fps")["--replay-speed"]("Specifies how quickly actions are processed while replaying"); cli |= clara::Arg(saved_game, "save-file")("Launch and load a saved game file."); @@ -535,6 +538,12 @@ static void replay_next_action() { handle_monster_info_menu(boost::lexical_cast(next_action.GetText())); }else if(t == "cancel_item_target"){ cancel_item_target(); + }else if(t == "advance_time"){ + if(record_advance_time){ + throw std::string { "Replay system internal error! advance_time() was supposed to be called by the last action, but wasn't." }; + }else{ + throw std::string { "The action log you're replaying contains advance_time() recordings. The additional --advance-time flag is required to process it." }; + } }else{ std::ostringstream sstr; sstr << "Couldn't replay action: " << next_action; diff --git a/src/tools/replay.cpp b/src/tools/replay.cpp index 83622a93..00dda3fe 100644 --- a/src/tools/replay.cpp +++ b/src/tools/replay.cpp @@ -25,6 +25,8 @@ using base64 = cppcodec::base64_rfc4648; bool recording = false; bool replaying = false; +std::string last_action_type; + using namespace ticpp; Document log_document; std::string log_file; @@ -154,6 +156,8 @@ Element& pop_next_action(std::string expected_action_type) { replay_fps_limit->frame_finished(); } + last_action_type = to_return->Value(); + return *to_return; } diff --git a/src/tools/replay.hpp b/src/tools/replay.hpp index b62ee7b8..269cd2a1 100644 --- a/src/tools/replay.hpp +++ b/src/tools/replay.hpp @@ -18,6 +18,8 @@ struct word_rect_t; extern bool recording; extern bool replaying; +extern std::string last_action_type; + extern bool init_action_log(std::string command, std::string file); extern void record_action(std::string action_type, std::string inner_text, bool cdata = false); extern void record_action(std::string action_type, std::map info);