From d1c8b49df4e22ba1ec4c1488d15e81f33956e0bc Mon Sep 17 00:00:00 2001 From: Dave White Date: Sat, 4 Oct 2003 23:34:36 +0000 Subject: [PATCH] fixed problems in multiplayer --- src/actions.cpp | 4 ++-- src/playturn.cpp | 18 +++++++-------- src/replay.cpp | 57 +++++++++++++++++++++++++++++++++++++++--------- src/replay.hpp | 2 ++ src/unit.cpp | 2 +- 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index dcd5c9d8523..bd986c0a23a 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -324,7 +324,7 @@ void attack(display& gui, const gamemap& map, while(stats.nattacks > 0 || stats.ndefends > 0) { if(stats.nattacks > 0) { - const double roll = double(recorder.get_random()%1000)/1000.0; + const double roll = double(get_random()%1000)/1000.0; const bool hits = roll < stats.chance_to_hit_defender; const bool dies = gui.unit_attack(attacker,defender, hits ? stats.damage_defender_takes : 0, @@ -381,7 +381,7 @@ void attack(display& gui, const gamemap& map, } if(stats.ndefends > 0) { - const double roll = double(recorder.get_random()%1000)/1000.0; + const double roll = double(get_random()%1000)/1000.0; const bool hits = roll < stats.chance_to_hit_attacker; const bool dies = gui.unit_attack(defender,attacker, hits ? stats.damage_attacker_takes : 0, diff --git a/src/playturn.cpp b/src/playturn.cpp index f2bf9135d14..1eddb480340 100644 --- a/src/playturn.cpp +++ b/src/playturn.cpp @@ -527,9 +527,9 @@ void play_turn(game_data& gameinfo, game_state& state_of_game, } const int recruit_res = - gui::show_dialog(gui,NULL,"", - string_table["recruit_unit"] + ":\n", - gui::OK_CANCEL,&items,&sample_units); + gui::show_dialog(gui,NULL,"", + string_table["recruit_unit"] + ":\n", + gui::OK_CANCEL,&items,&sample_units); if(recruit_res != -1) { const std::string& name = item_keys[recruit_res]; const std::map::const_iterator @@ -541,17 +541,17 @@ void play_turn(game_data& gameinfo, game_state& state_of_game, string_table["not_enough_gold_to_recruit"], gui::OK_ONLY); } else { - recorder.add_recruit(recruit_res,last_hex); - //create a unit with traits + recorder.add_recruit(recruit_res,last_hex); unit new_unit(&(u_type->second),team_num,true); const std::string& msg = - recruit_unit(map,team_num,units,new_unit, - last_hex,&gui); - if(msg.empty()) + recruit_unit(map,team_num,units,new_unit,last_hex,&gui); + if(msg.empty()) { current_team.spend_gold(u_type->second.cost()); - else + } else { + recorder.undo(); gui::show_dialog(gui,NULL,"",msg,gui::OK_ONLY); + } undo_stack.clear(); redo_stack.clear(); diff --git a/src/replay.cpp b/src/replay.cpp index 65a4da05258..ee218b2f054 100644 --- a/src/replay.cpp +++ b/src/replay.cpp @@ -31,6 +31,33 @@ replay recorder; +namespace { + +replay* random_generator = &recorder; + +struct set_random_generator { + + set_random_generator(replay* r) : old_(random_generator) + { + random_generator = r; + } + + ~set_random_generator() + { + random_generator = old_; + } + +private: + replay* old_; +}; + +} + +int get_random() +{ + return random_generator->get_random(); +} + replay::replay() : pos_(0), current_(NULL), skip_(0) {} @@ -291,9 +318,12 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, std::vector& teams, int team_num, const gamestatus& state, game_state& state_of_game, replay* obj) { - replay& recorder = obj != NULL ? *obj : recorder; + log_scope("do replay"); + replay& replayer = (obj != NULL) ? *obj : recorder; - update_locker lock_update(disp,recorder.skipping()); + const set_random_generator generator_setter(&replayer); + + update_locker lock_update(disp,replayer.skipping()); //a list of units that have promoted from the last attack std::deque advancing_units; @@ -301,7 +331,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, team& current_team = teams[team_num-1]; for(;;) { - config* const cfg = recorder.get_next_action(); + config* const cfg = replayer.get_next_action(); std::map >::iterator it; @@ -334,13 +364,13 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, //if there is nothing more in the records else if(cfg == NULL) { - recorder.set_skip(0); + replayer.set_skip(0); return false; } //if there is an end turn directive else if(cfg->children.find("end_turn") != cfg->children.end()) { - recorder.next_skip(); + replayer.next_skip(); return true; } @@ -356,11 +386,18 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, std::advance(itor,val); const std::map::const_iterator u_type = gameinfo.unit_types.find(*itor); - if(u_type == gameinfo.unit_types.end()) + if(u_type == gameinfo.unit_types.end()) { + std::cerr << "recruiting illegal unit\n"; throw replay::error(); + } unit new_unit(&(u_type->second),team_num,true); - recruit_unit(map,team_num,units,new_unit,loc); + const std::string& res = + recruit_unit(map,team_num,units,new_unit,loc); + if(!res.empty()) { + std::cerr << "cannot recruit unit: " << res << "\n"; + throw replay::error(); + } current_team.spend_gold(u_type->second.cost()); } @@ -408,7 +445,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, paths paths_list(map,gameinfo,units,src,teams,ignore_zocs,teleport); paths_wiper wiper(disp); - if(!recorder.skipping()) { + if(!replayer.skipping()) { disp.set_paths(&paths_list); disp.scroll_to_tiles(src.x,src.y,dst.x,dst.y); @@ -426,7 +463,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, rt->second.steps.push_back(dst); - if(!recorder.skipping()) + if(!replayer.skipping()) disp.move_unit(rt->second.steps,current_unit); current_unit.set_movement(rt->second.move_left); @@ -436,7 +473,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo, get_tower(dst,teams,team_num-1); } - if(!recorder.skipping()) { + if(!replayer.skipping()) { disp.draw_tile(dst.x,dst.y); disp.update_display(); } diff --git a/src/replay.hpp b/src/replay.hpp index 8a022e64460..0a06d88212d 100644 --- a/src/replay.hpp +++ b/src/replay.hpp @@ -17,6 +17,8 @@ #include "display.hpp" #include "map.hpp" +int get_random(); + class replay { public: diff --git a/src/unit.cpp b/src/unit.cpp index 8c55b8e10d6..bb0514bc8da 100644 --- a/src/unit.cpp +++ b/src/unit.cpp @@ -71,7 +71,7 @@ unit::unit(const unit_type* t, int side, bool use_traits) : if(use_traits && traits.size() >= num_traits) { std::set chosen_traits; for(size_t i = 0; i != num_traits; ++i) { - int num = recorder.get_random()%(traits.size()-i); + int num = get_random()%(traits.size()-i); while(chosen_traits.count(num)) { ++num; }